diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/startup_stm32l1xx_hd.s b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/startup_stm32l1xx_hd.s new file mode 100644 index 0000000000..4c2c3a814a --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/startup_stm32l1xx_hd.s @@ -0,0 +1,329 @@ +; STM32L1xx Ultra Low Power High-density Devices vector table for MDK ARM_MICRO toolchain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright (c) 2014, STMicroelectronics +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; 1. Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; 3. Neither the name of STMicroelectronics nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 + EXPORT __initial_sp + +Stack_Mem SPACE Stack_Size +__initial_sp EQU 0x20014000 ; Top of RAM (80 KB for STM32L152RE) + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000000 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 + EXPORT __heap_base + EXPORT __heap_limit + +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window Watchdog + DCD PVD_IRQHandler ; PVD through EXTI Line detect + DCD TAMPER_STAMP_IRQHandler ; Tamper and Time Stamp + DCD RTC_WKUP_IRQHandler ; RTC Wakeup + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_IRQHandler ; EXTI Line 0 + DCD EXTI1_IRQHandler ; EXTI Line 1 + DCD EXTI2_IRQHandler ; EXTI Line 2 + DCD EXTI3_IRQHandler ; EXTI Line 3 + DCD EXTI4_IRQHandler ; EXTI Line 4 + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 + DCD ADC1_IRQHandler ; ADC1 + DCD USB_HP_IRQHandler ; USB High Priority + DCD USB_LP_IRQHandler ; USB Low Priority + DCD DAC_IRQHandler ; DAC + DCD COMP_IRQHandler ; COMP through EXTI Line + DCD EXTI9_5_IRQHandler ; EXTI Line 9..5 + DCD LCD_IRQHandler ; LCD + DCD TIM9_IRQHandler ; TIM9 + DCD TIM10_IRQHandler ; TIM10 + DCD TIM11_IRQHandler ; TIM11 + DCD TIM2_IRQHandler ; TIM2 + DCD TIM3_IRQHandler ; TIM3 + DCD TIM4_IRQHandler ; TIM4 + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD EXTI15_10_IRQHandler ; EXTI Line 15..10 + DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line + DCD USB_FS_WKUP_IRQHandler ; USB FS Wakeup from suspend + DCD TIM6_IRQHandler ; TIM6 + DCD TIM7_IRQHandler ; TIM7 + DCD SDIO_IRQHandler ; SDIO + DCD TIM5_IRQHandler ; TIM5 + DCD SPI3_IRQHandler ; SPI3 + DCD UART4_IRQHandler ; UART4 + DCD UART5_IRQHandler ; UART5 + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 + DCD AES_IRQHandler ; AES + DCD COMP_ACQ_IRQHandler ; Comparator Channel Acquisition + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_IRQHandler [WEAK] + EXPORT TAMPER_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT USB_HP_IRQHandler [WEAK] + EXPORT USB_LP_IRQHandler [WEAK] + EXPORT DAC_IRQHandler [WEAK] + EXPORT COMP_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT LCD_IRQHandler [WEAK] + EXPORT TIM9_IRQHandler [WEAK] + EXPORT TIM10_IRQHandler [WEAK] + EXPORT TIM11_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM4_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT USB_FS_WKUP_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT SDIO_IRQHandler [WEAK] + EXPORT TIM5_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT DMA2_Channel1_IRQHandler [WEAK] + EXPORT DMA2_Channel2_IRQHandler [WEAK] + EXPORT DMA2_Channel3_IRQHandler [WEAK] + EXPORT DMA2_Channel4_IRQHandler [WEAK] + EXPORT DMA2_Channel5_IRQHandler [WEAK] + EXPORT AES_IRQHandler [WEAK] + EXPORT COMP_ACQ_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_IRQHandler +TAMPER_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +ADC1_IRQHandler +USB_HP_IRQHandler +USB_LP_IRQHandler +DAC_IRQHandler +COMP_IRQHandler +EXTI9_5_IRQHandler +LCD_IRQHandler +TIM9_IRQHandler +TIM10_IRQHandler +TIM11_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM4_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +USB_FS_WKUP_IRQHandler +TIM6_IRQHandler +TIM7_IRQHandler +SDIO_IRQHandler +TIM5_IRQHandler +SPI3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +DMA2_Channel1_IRQHandler +DMA2_Channel2_IRQHandler +DMA2_Channel3_IRQHandler +DMA2_Channel4_IRQHandler +DMA2_Channel5_IRQHandler +AES_IRQHandler +COMP_ACQ_IRQHandler + + B . + + ENDP + + ALIGN + END diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/stm32l1xx.sct b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/stm32l1xx.sct new file mode 100644 index 0000000000..39a6b4566b --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/stm32l1xx.sct @@ -0,0 +1,49 @@ +; Scatter-Loading Description File +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright (c) 2014, STMicroelectronics +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; 1. Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; 3. Neither the name of STMicroelectronics nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; STM32L152RE: 512KB FLASH (0x80000) + 80KB RAM (0x14000) +; STM32L152RC: 256KB FLASH (0x40000) + 32KB RAM (0x08000) + +;LR_IROM1 0x08000000 0x80000 { ; load region size_region + LR_IROM1 0x08000000 0x40000 { ; load region size_region +; ER_IROM1 0x08000000 0x80000 { ; load address = execution address + ER_IROM1 0x08000000 0x40000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + + ; 73 vectors = 292 bytes (0x124) to be reserved in RAM +; RW_IRAM1 (0x20000000+0x124) (0x14000-0x124) { ; RW data + RW_IRAM1 (0x20000000+0x124) (0x08000-0x124) { ; RW data + .ANY (+RW +ZI) + } + +} + diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/sys.cpp b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/sys.cpp new file mode 100644 index 0000000000..bb665909b9 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/sys.cpp @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library - stackheap + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern char Image$$RW_IRAM1$$ZI$$Limit[]; + +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t sp_limit = __current_sp(); + + zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned + + struct __initial_stackheap r; + r.heap_base = zi_limit; + r.heap_limit = sp_limit; + return r; +} + +#ifdef __cplusplus +} +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/startup_stm32l1xx_hd.s b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/startup_stm32l1xx_hd.s new file mode 100644 index 0000000000..6cd13c930f --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/startup_stm32l1xx_hd.s @@ -0,0 +1,302 @@ +; STM32L1xx Ultra Low Power High-density Devices vector table for MDK ARM_STD toolchain +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright (c) 2014, STMicroelectronics +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; 1. Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; 3. Neither the name of STMicroelectronics nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +__initial_sp EQU 0x20014000 ; Top of RAM (512 KB) + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window Watchdog + DCD PVD_IRQHandler ; PVD through EXTI Line detect + DCD TAMPER_STAMP_IRQHandler ; Tamper and Time Stamp + DCD RTC_WKUP_IRQHandler ; RTC Wakeup + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_IRQHandler ; EXTI Line 0 + DCD EXTI1_IRQHandler ; EXTI Line 1 + DCD EXTI2_IRQHandler ; EXTI Line 2 + DCD EXTI3_IRQHandler ; EXTI Line 3 + DCD EXTI4_IRQHandler ; EXTI Line 4 + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 + DCD ADC1_IRQHandler ; ADC1 + DCD USB_HP_IRQHandler ; USB High Priority + DCD USB_LP_IRQHandler ; USB Low Priority + DCD DAC_IRQHandler ; DAC + DCD COMP_IRQHandler ; COMP through EXTI Line + DCD EXTI9_5_IRQHandler ; EXTI Line 9..5 + DCD LCD_IRQHandler ; LCD + DCD TIM9_IRQHandler ; TIM9 + DCD TIM10_IRQHandler ; TIM10 + DCD TIM11_IRQHandler ; TIM11 + DCD TIM2_IRQHandler ; TIM2 + DCD TIM3_IRQHandler ; TIM3 + DCD TIM4_IRQHandler ; TIM4 + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD EXTI15_10_IRQHandler ; EXTI Line 15..10 + DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line + DCD USB_FS_WKUP_IRQHandler ; USB FS Wakeup from suspend + DCD TIM6_IRQHandler ; TIM6 + DCD TIM7_IRQHandler ; TIM7 + DCD SDIO_IRQHandler ; SDIO + DCD TIM5_IRQHandler ; TIM5 + DCD SPI3_IRQHandler ; SPI3 + DCD UART4_IRQHandler ; UART4 + DCD UART5_IRQHandler ; UART5 + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 + DCD AES_IRQHandler ; AES + DCD COMP_ACQ_IRQHandler ; Comparator Channel Acquisition + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_IRQHandler [WEAK] + EXPORT TAMPER_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT USB_HP_IRQHandler [WEAK] + EXPORT USB_LP_IRQHandler [WEAK] + EXPORT DAC_IRQHandler [WEAK] + EXPORT COMP_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT LCD_IRQHandler [WEAK] + EXPORT TIM9_IRQHandler [WEAK] + EXPORT TIM10_IRQHandler [WEAK] + EXPORT TIM11_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM4_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT USB_FS_WKUP_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT SDIO_IRQHandler [WEAK] + EXPORT TIM5_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT DMA2_Channel1_IRQHandler [WEAK] + EXPORT DMA2_Channel2_IRQHandler [WEAK] + EXPORT DMA2_Channel3_IRQHandler [WEAK] + EXPORT DMA2_Channel4_IRQHandler [WEAK] + EXPORT DMA2_Channel5_IRQHandler [WEAK] + EXPORT AES_IRQHandler [WEAK] + EXPORT COMP_ACQ_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_IRQHandler +TAMPER_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +ADC1_IRQHandler +USB_HP_IRQHandler +USB_LP_IRQHandler +DAC_IRQHandler +COMP_IRQHandler +EXTI9_5_IRQHandler +LCD_IRQHandler +TIM9_IRQHandler +TIM10_IRQHandler +TIM11_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM4_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +USB_FS_WKUP_IRQHandler +TIM6_IRQHandler +TIM7_IRQHandler +SDIO_IRQHandler +TIM5_IRQHandler +SPI3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +DMA2_Channel1_IRQHandler +DMA2_Channel2_IRQHandler +DMA2_Channel3_IRQHandler +DMA2_Channel4_IRQHandler +DMA2_Channel5_IRQHandler +AES_IRQHandler +COMP_ACQ_IRQHandler + + B . + + ENDP + + ALIGN + END diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/stm32l1xx.sct b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/stm32l1xx.sct new file mode 100644 index 0000000000..266482f56a --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/stm32l1xx.sct @@ -0,0 +1,44 @@ +; Scatter-Loading Description File +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright (c) 2014, STMicroelectronics +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; 1. Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; 3. Neither the name of STMicroelectronics nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +LR_IROM1 0x08000000 0x80000 { ; load region size_region (512 KB) + + ER_IROM1 0x08000000 0x80000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + + ; 73 vectors = 292 bytes (0x124) to be reserved in RAM + RW_IRAM1 (0x20000000+0x124) (0x14000-0x124) { ; RW data + .ANY (+RW +ZI) + } + +} + diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/sys.cpp b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/sys.cpp new file mode 100644 index 0000000000..bb665909b9 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/sys.cpp @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library - stackheap + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern char Image$$RW_IRAM1$$ZI$$Limit[]; + +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t sp_limit = __current_sp(); + + zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned + + struct __initial_stackheap r; + r.heap_base = zi_limit; + r.heap_limit = sp_limit; + return r; +} + +#ifdef __cplusplus +} +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis.h new file mode 100644 index 0000000000..8c32259ba3 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis.h @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * A generic CMSIS include header + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "stm32l1xx.h" +#include "cmsis_nvic.h" + +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis_nvic.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis_nvic.c new file mode 100644 index 0000000000..2da63fc9af --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis_nvic.c @@ -0,0 +1,55 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis_nvic.h" + +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM +#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { + uint32_t *vectors = (uint32_t *)SCB->VTOR; + uint32_t i; + + // Copy and switch to dynamic vectors if the first time called + if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { + uint32_t *old_vectors = vectors; + vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; + for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; + } + vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + +uint32_t NVIC_GetVector(IRQn_Type IRQn) { + uint32_t *vectors = (uint32_t*)SCB->VTOR; + return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; +} diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis_nvic.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis_nvic.h new file mode 100644 index 0000000000..232bc2ca2b --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/cmsis_nvic.h @@ -0,0 +1,55 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +// STM32F152RE +// CORE: 16 vectors = 64 bytes from 0x00 to 0x3F +// MCU Peripherals: 57 vectors = 228 bytes from 0x40 to 0x123 +// Total: 73 vectors = 292 bytes (0x124) to be reserved in RAM (see scatter file) +#define NVIC_NUM_VECTORS 73 +#define NVIC_USER_IRQ_OFFSET 16 + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/misc.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/misc.c new file mode 100644 index 0000000000..921bf1a790 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/misc.c @@ -0,0 +1,251 @@ +/** + ****************************************************************************** + * @file misc.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides all the miscellaneous firmware functions (add-on + * to CMSIS functions). + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "misc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup MISC + * @brief MISC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup MISC_Private_Functions + * @{ + */ +/** + * +@verbatim + ******************************************************************************* + ##### Interrupts configuration functions ##### + ******************************************************************************* + [..] This section provide functions allowing to configure the NVIC interrupts + (IRQ).The Cortex-M3 exceptions are managed by CMSIS functions. + (#) Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig() + function according to the following table. + The table below gives the allowed values of the preemption priority + and subpriority according to the Priority Grouping configuration + performed by NVIC_PriorityGroupConfig function. + ============================================================================================================================ + NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description + ============================================================================================================================ + NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for preemption priority + | | | 4 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for preemption priority + | | | 3 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for preemption priority + | | | 2 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for preemption priority + | | | 1 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for preemption priority + | | | 0 bits for subpriority + ============================================================================================================================ + + + (#) Enable and Configure the priority of the selected IRQ Channels. + + -@- When the NVIC_PriorityGroup_0 is selected, it will no any nested interrupt, + the IRQ priority will be managed only by subpriority. + The sub-priority is only used to sort pending exception priorities, + and does not affect active exceptions. + -@- Lower priority values gives higher priority. + -@- Priority Order: + (#@) Lowest Preemption priority. + (#@) Lowest Subpriority. + (#@) Lowest hardware priority (IRQn position). + +@endverbatim +*/ + +/** + * @brief Configures the priority grouping: preemption priority and subpriority. + * @param NVIC_PriorityGroup: specifies the priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PriorityGroup_0: 0 bits for preemption priority + * 4 bits for subpriority. + * @note When NVIC_PriorityGroup_0 is selected, it will no be any nested + * interrupt. This interrupts priority is managed only with subpriority. + * @arg NVIC_PriorityGroup_1: 1 bits for preemption priority. + * 3 bits for subpriority. + * @arg NVIC_PriorityGroup_2: 2 bits for preemption priority. + * 2 bits for subpriority. + * @arg NVIC_PriorityGroup_3: 3 bits for preemption priority. + * 1 bits for subpriority. + * @arg NVIC_PriorityGroup_4: 4 bits for preemption priority. + * 0 bits for subpriority. + * @retval None + */ +void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); + + /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ + SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; +} + +/** + * @brief Initializes the NVIC peripheral according to the specified + * parameters in the NVIC_InitStruct. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains + * the configuration information for the specified NVIC peripheral. + * @retval None + */ +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) +{ + uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); + assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); + + if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) + { + /* Compute the Corresponding IRQ Priority --------------------------------*/ + tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; + tmppre = (0x4 - tmppriority); + tmpsub = tmpsub >> tmppriority; + + tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; + tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub); + tmppriority = tmppriority << 0x04; + + NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; + + /* Enable the Selected IRQ Channels --------------------------------------*/ + NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } + else + { + /* Disable the Selected IRQ Channels -------------------------------------*/ + NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } +} + +/** + * @brief Sets the vector table location and Offset. + * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. + * This parameter can be one of the following values: + * @arg NVIC_VectTab_RAM: Vector Table in internal SRAM. + * @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH. + * @param Offset: Vector Table base offset field. This value must be a multiple of 0x200. + * @retval None + */ +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) +{ + /* Check the parameters */ + assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); + assert_param(IS_NVIC_OFFSET(Offset)); + + SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); +} + +/** + * @brief Selects the condition for the system to enter low power mode. + * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. + * This parameter can be one of the following values: + * @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend. + * @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request. + * @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit. + * @param NewState: new state of LP condition. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_NVIC_LP(LowPowerMode)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + SCB->SCR |= LowPowerMode; + } + else + { + SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); + } +} + +/** + * @brief Configures the SysTick clock source. + * @param SysTick_CLKSource: specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. + * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); + + if (SysTick_CLKSource == SysTick_CLKSource_HCLK) + { + SysTick->CTRL |= SysTick_CLKSource_HCLK; + } + else + { + SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/misc.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/misc.h new file mode 100644 index 0000000000..74d7b29e47 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/misc.h @@ -0,0 +1,202 @@ +/** + ****************************************************************************** + * @file misc.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the miscellaneous + * firmware library functions (add-on to CMSIS functions). + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MISC_H +#define __MISC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup MISC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief NVIC Init Structure definition + */ + +typedef struct +{ + uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. + This parameter can be a value of @ref IRQn_Type + (For the complete STM32 Devices IRQ Channels list, please + refer to stm32l1xx.h file) */ + + uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel + specified in NVIC_IRQChannel. This parameter can be a value + between 0 and 15 as described in the table @ref NVIC_Priority_Table */ + + uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified + in NVIC_IRQChannel. This parameter can be a value + between 0 and 15 as described in the table @ref NVIC_Priority_Table */ + + FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel + will be enabled or disabled. + This parameter can be set either to ENABLE or DISABLE */ +} NVIC_InitTypeDef; + +/** + * +@verbatim + The table below gives the allowed values of the pre-emption priority and subpriority according + to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function + ============================================================================================================================ + NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description + ============================================================================================================================ + NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority + | | | 4 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority + | | | 3 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority + | | | 2 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority + | | | 1 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority + | | | 0 bits for subpriority + ============================================================================================================================ +@endverbatim +*/ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup MISC_Exported_Constants + * @{ + */ + +/** @defgroup Vector_Table_Base + * @{ + */ + +#define NVIC_VectTab_RAM ((uint32_t)0x20000000) +#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) +#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ + ((VECTTAB) == NVIC_VectTab_FLASH)) +/** + * @} + */ + +/** @defgroup System_Low_Power + * @{ + */ + +#define NVIC_LP_SEVONPEND ((uint8_t)0x10) +#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) +#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) +#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ + ((LP) == NVIC_LP_SLEEPDEEP) || \ + ((LP) == NVIC_LP_SLEEPONEXIT)) +/** + * @} + */ + +/** @defgroup Preemption_Priority_Group + * @{ + */ + +#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority + 4 bits for subpriority */ +#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority + 3 bits for subpriority */ +#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority + 2 bits for subpriority */ +#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority + 1 bits for subpriority */ +#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority + 0 bits for subpriority */ + +#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ + ((GROUP) == NVIC_PriorityGroup_1) || \ + ((GROUP) == NVIC_PriorityGroup_2) || \ + ((GROUP) == NVIC_PriorityGroup_3) || \ + ((GROUP) == NVIC_PriorityGroup_4)) + +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x0005FFFF) + +/** + * @} + */ + +/** @defgroup SysTick_clock_source + * @{ + */ + +#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) +#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) +#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ + ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); +void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); + +#ifdef __cplusplus +} +#endif + +#endif /* __MISC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx.h new file mode 100644 index 0000000000..65093609bd --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx.h @@ -0,0 +1,6355 @@ +/** + ****************************************************************************** + * @file stm32l1xx.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File. + * This file contains all the peripheral register's definitions, bits + * definitions and memory mapping for STM32L1xx High-density, Medium-density + * and Medium-density Plus devices. + * + * 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 + * "#define USE_STDPERIPH_DRIVER" + * - 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 + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32l1xx + * @{ + */ + +#ifndef __STM32L1XX_H +#define __STM32L1XX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup Library_configuration_section + * @{ + */ + +/* Uncomment the line below according to the target STM32L device used in your + application + */ + +#if !defined (STM32L1XX_MD) && !defined (STM32L1XX_MDP) && !defined (STM32L1XX_HD) + +/* #define STM32L1XX_MD */ /*!< - Ultra Low Power Medium-density devices: STM32L151x6xx, STM32L151x8xx, + STM32L151xBxx, STM32L152x6xx, STM32L152x8xx and STM32L152xBxx. + - Ultra Low Power Medium-density Value Line devices: STM32L100x6xx, + STM32L100x8xx and STM32L100xBxx. */ + +//#define STM32L1XX_MDP /*!< - Ultra Low Power Medium-density Plus devices: STM32L151xCxx, STM32L152xCxx and STM32L162xCxx +// - Ultra Low Power Medium-density Plus Value Line devices: STM32L100xCxx */ + +#define STM32L1XX_HD /*!< Ultra Low Power High-density devices: STM32L151xDxx, STM32L152xDxx and STM32L162xDxx */ +#endif +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ + +#if !defined (STM32L1XX_MD) && !defined (STM32L1XX_MDP) && !defined (STM32L1XX_HD) + #error "Please select first the target STM32L1xx device used in your application (in stm32l1xx.h file)" +#endif + +#if !defined USE_STDPERIPH_DRIVER +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ +#define USE_STDPERIPH_DRIVER +#endif + +/** + * @brief In the following line adjust the value of External High Speed oscillator (HSE) + used in your application + + Tip: To avoid modifying this file each time you need to use different HSE, you + can define the HSE value in your toolchain compiler preprocessor. + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ +#endif + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ +#endif + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + Timeout value + */ +#if !defined (HSI_STARTUP_TIMEOUT) +#define HSI_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSI start up */ +#endif + +#if !defined (HSI_VALUE) +#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal High Speed oscillator in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif + +#if !defined (LSI_VALUE) +#define LSI_VALUE ((uint32_t)37000) /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +#endif + +#if !defined (LSE_VALUE) +#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif + +/** + * @brief STM32L1xx Standard Peripheral Library version number V1.2.0 + */ +#define __STM32L1XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32L1XX_STDPERIPH_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */ +#define __STM32L1XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32L1XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32L1XX_STDPERIPH_VERSION ( (__STM32L1XX_STDPERIPH_VERSION_MAIN << 24)\ + |(__STM32L1XX_STDPERIPH_VERSION_SUB1 << 16)\ + |(__STM32L1XX_STDPERIPH_VERSION_SUB2 << 8)\ + |(__STM32L1XX_STDPERIPH_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief STM32L1xx Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +#define __CM3_REV 0x200 /*!< Cortex-M3 Revision r2p0 */ +#define __MPU_PRESENT 1 /*!< STM32L1 provides MPU */ +#define __NVIC_PRIO_BITS 4 /*!< STM32L1 uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/*!< Interrupt Number Definition */ +typedef enum IRQn +{ +/****** Cortex-M3 Processor Exceptions Numbers ******************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVC_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** STM32L specific Interrupt Numbers ***********************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMPER_STAMP_IRQn = 2, /*!< Tamper and Time Stamp through EXTI Line Interrupts */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup Timer through EXTI Line Interrupt */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */ + DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */ + DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */ + DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */ + DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */ + DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */ + DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */ + ADC1_IRQn = 18, /*!< ADC1 global Interrupt */ + USB_HP_IRQn = 19, /*!< USB High Priority Interrupt */ + USB_LP_IRQn = 20, /*!< USB Low Priority Interrupt */ + DAC_IRQn = 21, /*!< DAC Interrupt */ + COMP_IRQn = 22, /*!< Comparator through EXTI Line Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + LCD_IRQn = 24, /*!< LCD Interrupt */ + TIM9_IRQn = 25, /*!< TIM9 global Interrupt */ + TIM10_IRQn = 26, /*!< TIM10 global Interrupt */ + TIM11_IRQn = 27, /*!< TIM11 global Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + USB_FS_WKUP_IRQn = 42, /*!< USB FS WakeUp from suspend through EXTI Line Interrupt */ + TIM6_IRQn = 43, /*!< TIM6 global Interrupt */ +#ifdef STM32L1XX_MD + TIM7_IRQn = 44 /*!< TIM7 global Interrupt */ +#endif /* STM32L1XX_MD */ + +#ifdef STM32L1XX_MDP + TIM7_IRQn = 44, /*!< TIM7 global Interrupt */ + TIM5_IRQn = 46, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 47, /*!< SPI3 global Interrupt */ + DMA2_Channel1_IRQn = 50, /*!< DMA2 Channel 1 global Interrupt */ + DMA2_Channel2_IRQn = 51, /*!< DMA2 Channel 2 global Interrupt */ + DMA2_Channel3_IRQn = 52, /*!< DMA2 Channel 3 global Interrupt */ + DMA2_Channel4_IRQn = 53, /*!< DMA2 Channel 4 global Interrupt */ + DMA2_Channel5_IRQn = 54, /*!< DMA2 Channel 5 global Interrupt */ + AES_IRQn = 55, /*!< AES global Interrupt */ + COMP_ACQ_IRQn = 56 /*!< Comparator Channel Acquisition global Interrupt */ +#endif /* STM32L1XX_MDP */ + +#ifdef STM32L1XX_HD + TIM7_IRQn = 44, /*!< TIM7 global Interrupt */ + SDIO_IRQn = 45, /*!< SDIO global Interrupt */ + TIM5_IRQn = 46, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 47, /*!< SPI3 global Interrupt */ + UART4_IRQn = 48, /*!< UART4 global Interrupt */ + UART5_IRQn = 49, /*!< UART5 global Interrupt */ + DMA2_Channel1_IRQn = 50, /*!< DMA2 Channel 1 global Interrupt */ + DMA2_Channel2_IRQn = 51, /*!< DMA2 Channel 2 global Interrupt */ + DMA2_Channel3_IRQn = 52, /*!< DMA2 Channel 3 global Interrupt */ + DMA2_Channel4_IRQn = 53, /*!< DMA2 Channel 4 global Interrupt */ + DMA2_Channel5_IRQn = 54, /*!< DMA2 Channel 5 global Interrupt */ + AES_IRQn = 55, /*!< AES global Interrupt */ + COMP_ACQ_IRQn = 56 /*!< Comparator Channel Acquisition global Interrupt */ +#endif /* STM32L1XX_HD */ +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm3.h" +#include "system_stm32l1xx.h" +#include + +/** @addtogroup Exported_types + * @{ + */ + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/** + * @brief __RAM_FUNC definition + */ +#if defined ( __CC_ARM ) +/* ARM Compiler + ------------ + RAM functions are defined using the toolchain options. + Functions that are executed in RAM should reside in a separate source module. + Using the 'Options for File' dialog you can simply change the 'Code / Const' + area of a module to a memory space in physical RAM. + Available memory areas are declared in the 'Target' tab of the 'Options for Target' + dialog. +*/ + #define __RAM_FUNC FLASH_Status + +#elif defined ( __ICCARM__ ) +/* ICCARM Compiler + --------------- + RAM functions are defined using a specific toolchain keyword "__ramfunc". +*/ + #define __RAM_FUNC __ramfunc FLASH_Status + +#elif defined ( __GNUC__ ) +/* GNU Compiler + ------------ + RAM functions are defined using a specific toolchain attribute + "__attribute__((section(".data")))". +*/ + #define __RAM_FUNC FLASH_Status __attribute__((section(".data"))) + +#elif defined ( __TASKING__ ) +/* TASKING Compiler + ---------------- + RAM functions are defined using a specific toolchain pragma. This pragma is + defined in the stm32l1xx_flash_ramfunc.c +*/ + #define __RAM_FUNC FLASH_Status + +#endif + +/** + * @} + */ + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ + __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ + __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ + __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ + __IO uint32_t SMPR3; /*!< ADC sample time register 3, Address offset: 0x14 */ + __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x18 */ + __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x1C */ + __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x20 */ + __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x24 */ + __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x28 */ + __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x2C */ + __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x30 */ + __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x34 */ + __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x38 */ + __IO uint32_t SQR4; /*!< ADC regular sequence register 4, Address offset: 0x3C */ + __IO uint32_t SQR5; /*!< ADC regular sequence register 5, Address offset: 0x40 */ + __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x44 */ + __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x48 */ + __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x4C */ + __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x50 */ + __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x54 */ + __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x58 */ + __IO uint32_t SMPR0; /*!< ADC sample time register 0, Address offset: 0x5C */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< ADC common status register, Address offset: ADC1 base address + 0x300 */ + __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ +} ADC_Common_TypeDef; + + +/** + * @brief AES hardware accelerator + */ + +typedef struct +{ + __IO uint32_t CR; /*!< AES control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< AES status register, Address offset: 0x04 */ + __IO uint32_t DINR; /*!< AES data input register, Address offset: 0x08 */ + __IO uint32_t DOUTR; /*!< AES data output register, Address offset: 0x0C */ + __IO uint32_t KEYR0; /*!< AES key register 0, Address offset: 0x10 */ + __IO uint32_t KEYR1; /*!< AES key register 1, Address offset: 0x14 */ + __IO uint32_t KEYR2; /*!< AES key register 2, Address offset: 0x18 */ + __IO uint32_t KEYR3; /*!< AES key register 3, Address offset: 0x1C */ + __IO uint32_t IVR0; /*!< AES initialization vector register 0, Address offset: 0x20 */ + __IO uint32_t IVR1; /*!< AES initialization vector register 1, Address offset: 0x24 */ + __IO uint32_t IVR2; /*!< AES initialization vector register 2, Address offset: 0x28 */ + __IO uint32_t IVR3; /*!< AES initialization vector register 3, Address offset: 0x2C */ +} AES_TypeDef; + +/** + * @brief Comparator + */ + +typedef struct +{ + __IO uint32_t CSR; /*!< COMP comparator control and status register, Address offset: 0x00 */ +} COMP_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ +} CRC_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ +}DBGMCU_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CCR; /*!< DMA channel x configuration register */ + __IO uint32_t CNDTR; /*!< DMA channel x number of data register */ + __IO uint32_t CPAR; /*!< DMA channel x peripheral address register */ + __IO uint32_t CMAR; /*!< DMA channel x memory address register */ +} DMA_Channel_TypeDef; + +typedef struct +{ + __IO uint32_t ISR; /*!< DMA interrupt status register, Address offset: 0x00 */ + __IO uint32_t IFCR; /*!< DMA interrupt flag clear register, Address offset: 0x04 */ +} DMA_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; /*!< EXTI interrupt mask register, Address offset: 0x00 */ + __IO uint32_t EMR; /*!< EXTI event mask register, Address offset: 0x04 */ + __IO uint32_t RTSR; /*!< EXTI rising edge trigger selection register, Address offset: 0x08 */ + __IO uint32_t FTSR; /*!< EXTI Falling edge trigger selection register, Address offset: 0x0C */ + __IO uint32_t SWIER; /*!< EXTI software interrupt event register, Address offset: 0x10 */ + __IO uint32_t PR; /*!< EXTI pending register, Address offset: 0x14 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; /*!< Access control register, Address offset: 0x00 */ + __IO uint32_t PECR; /*!< Program/erase control register, Address offset: 0x04 */ + __IO uint32_t PDKEYR; /*!< Power down key register, Address offset: 0x08 */ + __IO uint32_t PEKEYR; /*!< Program/erase key register, Address offset: 0x0c */ + __IO uint32_t PRGKEYR; /*!< Program memory key register, Address offset: 0x10 */ + __IO uint32_t OPTKEYR; /*!< Option byte key register, Address offset: 0x14 */ + __IO uint32_t SR; /*!< Status register, Address offset: 0x18 */ + __IO uint32_t OBR; /*!< Option byte register, Address offset: 0x1c */ + __IO uint32_t WRPR; /*!< Write protection register, Address offset: 0x20 */ + uint32_t RESERVED[23]; /*!< Reserved, 0x24 */ + __IO uint32_t WRPR1; /*!< Write protection register 1, Address offset: 0x28 */ + __IO uint32_t WRPR2; /*!< Write protection register 2, Address offset: 0x2C */ +} FLASH_TypeDef; + +/** + * @brief Option Bytes Registers + */ + +typedef struct +{ + __IO uint32_t RDP; /*!< Read protection register, Address offset: 0x00 */ + __IO uint32_t USER; /*!< user register, Address offset: 0x04 */ + __IO uint32_t WRP01; /*!< write protection register 0 1, Address offset: 0x08 */ + __IO uint32_t WRP23; /*!< write protection register 2 3, Address offset: 0x0C */ + __IO uint32_t WRP45; /*!< write protection register 4 5, Address offset: 0x10 */ + __IO uint32_t WRP67; /*!< write protection register 6 7, Address offset: 0x14 */ + __IO uint32_t WRP89; /*!< write protection register 8 9, Address offset: 0x18 */ + __IO uint32_t WRP1011; /*!< write protection register 10 11, Address offset: 0x1C */ +} OB_TypeDef; + +/** + * @brief Operational Amplifier (OPAMP) + */ + +typedef struct +{ + __IO uint32_t CSR; /*!< OPAMP control/status register, Address offset: 0x00 */ + __IO uint32_t OTR; /*!< OPAMP offset trimming register for normal mode, Address offset: 0x04 */ + __IO uint32_t LPOTR; /*!< OPAMP offset trimming register for low power mode, Address offset: 0x08 */ +} OPAMP_TypeDef; + +/** + * @brief Flexible Static Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FSMC_Bank1_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ +} FSMC_Bank1E_TypeDef; + +/** + * @brief General Purpose IO + */ + +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; + +/** + * @brief SysTem Configuration + */ + +typedef struct +{ + __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ + __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ + __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ +} SYSCFG_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; /*!< Key register, Address offset: 0x00 */ + __IO uint32_t PR; /*!< Prescaler register, Address offset: 0x04 */ + __IO uint32_t RLR; /*!< Reload register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< Status register, Address offset: 0x0C */ +} IWDG_TypeDef; + + +/** + * @brief LCD + */ + +typedef struct +{ + __IO uint32_t CR; /*!< LCD control register, Address offset: 0x00 */ + __IO uint32_t FCR; /*!< LCD frame control register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< LCD status register, Address offset: 0x08 */ + __IO uint32_t CLR; /*!< LCD clear register, Address offset: 0x0C */ + uint32_t RESERVED; /*!< Reserved, Address offset: 0x10 */ + __IO uint32_t RAM[16]; /*!< LCD display memory, Address offset: 0x14-0x50 */ +} LCD_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ + __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32_t ICSCR; /*!< RCC Internal clock sources calibration register, Address offset: 0x04 */ + __IO uint32_t CFGR; /*!< RCC Clock configuration register, Address offset: 0x08 */ + __IO uint32_t CIR; /*!< RCC Clock interrupt register, Address offset: 0x0C */ + __IO uint32_t AHBRSTR; /*!< RCC AHB peripheral reset register, Address offset: 0x10 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x14 */ + __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x18 */ + __IO uint32_t AHBENR; /*!< RCC AHB peripheral clock enable register, Address offset: 0x1C */ + __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x20 */ + __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x24 */ + __IO uint32_t AHBLPENR; /*!< RCC AHB peripheral clock enable in low power mode register, Address offset: 0x28 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x2C */ + __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x30 */ + __IO uint32_t CSR; /*!< RCC Control/status register, Address offset: 0x34 */ +} RCC_TypeDef; + +/** + * @brief Routing Interface + */ + +typedef struct +{ + __IO uint32_t ICR; /*!< RI input capture register, Address offset: 0x00 */ + __IO uint32_t ASCR1; /*!< RI analog switches control register, Address offset: 0x04 */ + __IO uint32_t ASCR2; /*!< RI analog switch control register 2, Address offset: 0x08 */ + __IO uint32_t HYSCR1; /*!< RI hysteresis control register, Address offset: 0x0C */ + __IO uint32_t HYSCR2; /*!< RI Hysteresis control register, Address offset: 0x10 */ + __IO uint32_t HYSCR3; /*!< RI Hysteresis control register, Address offset: 0x14 */ + __IO uint32_t HYSCR4; /*!< RI Hysteresis control register, Address offset: 0x18 */ +} RI_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ + __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + __IO uint32_t CALR; /*!< RRTC calibration register, Address offset: 0x3C */ + __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR; /*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBSSR; /*!< RTC alarm B sub second register, Address offset: 0x48 */ + uint32_t RESERVED7; /*!< Reserved, 0x4C */ + __IO uint32_t BKP0R; /*!< RTC backup register 0, Address offset: 0x50 */ + __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ + __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ + __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ + __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ + __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ + __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ + __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ + __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ + __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ + __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ + __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ + __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ + __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ + __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ + __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ + __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ + __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ + __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ + __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ + __IO uint32_t BKP20R; /*!< RTC backup register 20, Address offset: 0xA0 */ + __IO uint32_t BKP21R; /*!< RTC backup register 21, Address offset: 0xA4 */ + __IO uint32_t BKP22R; /*!< RTC backup register 22, Address offset: 0xA8 */ + __IO uint32_t BKP23R; /*!< RTC backup register 23, Address offset: 0xAC */ + __IO uint32_t BKP24R; /*!< RTC backup register 24, Address offset: 0xB0 */ + __IO uint32_t BKP25R; /*!< RTC backup register 25, Address offset: 0xB4 */ + __IO uint32_t BKP26R; /*!< RTC backup register 26, Address offset: 0xB8 */ + __IO uint32_t BKP27R; /*!< RTC backup register 27, Address offset: 0xBC */ + __IO uint32_t BKP28R; /*!< RTC backup register 28, Address offset: 0xC0 */ + __IO uint32_t BKP29R; /*!< RTC backup register 29, Address offset: 0xC4 */ + __IO uint32_t BKP30R; /*!< RTC backup register 30, Address offset: 0xC8 */ + __IO uint32_t BKP31R; /*!< RTC backup register 31, Address offset: 0xCC */ +} RTC_TypeDef; + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ + uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ + __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ + uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ + __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SR; /*!< SPI status register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DR; /*!< SPI data register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} SPI_TypeDef; + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + uint16_t RESERVED10; /*!< Reserved, 0x2A */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + uint32_t RESERVED12; /*!< Reserved, 0x30 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + uint32_t RESERVED17; /*!< Reserved, 0x44 */ + __IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ + uint16_t RESERVED18; /*!< Reserved, 0x4A */ + __IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ + uint16_t RESERVED19; /*!< Reserved, 0x4E */ + __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ + uint16_t RESERVED20; /*!< Reserved, 0x52 */ +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ + __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ +} WWDG_TypeDef; + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ + +#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */ +#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ + +#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ + +#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) + +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) +#define LCD_BASE (APB1PERIPH_BASE + 0x2400) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) +#define COMP_BASE (APB1PERIPH_BASE + 0x7C00) +#define RI_BASE (APB1PERIPH_BASE + 0x7C04) +#define OPAMP_BASE (APB1PERIPH_BASE + 0x7C5C) + +#define SYSCFG_BASE (APB2PERIPH_BASE + 0x0000) +#define EXTI_BASE (APB2PERIPH_BASE + 0x0400) +#define TIM9_BASE (APB2PERIPH_BASE + 0x0800) +#define TIM10_BASE (APB2PERIPH_BASE + 0x0C00) +#define TIM11_BASE (APB2PERIPH_BASE + 0x1000) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) +#define ADC_BASE (APB2PERIPH_BASE + 0x2700) +#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define USART1_BASE (APB2PERIPH_BASE + 0x3800) + +#define GPIOA_BASE (AHBPERIPH_BASE + 0x0000) +#define GPIOB_BASE (AHBPERIPH_BASE + 0x0400) +#define GPIOC_BASE (AHBPERIPH_BASE + 0x0800) +#define GPIOD_BASE (AHBPERIPH_BASE + 0x0C00) +#define GPIOE_BASE (AHBPERIPH_BASE + 0x1000) +#define GPIOH_BASE (AHBPERIPH_BASE + 0x1400) +#define GPIOF_BASE (AHBPERIPH_BASE + 0x1800) +#define GPIOG_BASE (AHBPERIPH_BASE + 0x1C00) +#define CRC_BASE (AHBPERIPH_BASE + 0x3000) +#define RCC_BASE (AHBPERIPH_BASE + 0x3800) + + +#define FLASH_R_BASE (AHBPERIPH_BASE + 0x3C00) /*!< FLASH registers base address */ +#define OB_BASE ((uint32_t)0x1FF80000) /*!< FLASH Option Bytes base address */ + +#define DMA1_BASE (AHBPERIPH_BASE + 0x6000) +#define DMA1_Channel1_BASE (DMA1_BASE + 0x0008) +#define DMA1_Channel2_BASE (DMA1_BASE + 0x001C) +#define DMA1_Channel3_BASE (DMA1_BASE + 0x0030) +#define DMA1_Channel4_BASE (DMA1_BASE + 0x0044) +#define DMA1_Channel5_BASE (DMA1_BASE + 0x0058) +#define DMA1_Channel6_BASE (DMA1_BASE + 0x006C) +#define DMA1_Channel7_BASE (DMA1_BASE + 0x0080) + +#define DMA2_BASE (AHBPERIPH_BASE + 0x6400) +#define DMA2_Channel1_BASE (DMA2_BASE + 0x0008) +#define DMA2_Channel2_BASE (DMA2_BASE + 0x001C) +#define DMA2_Channel3_BASE (DMA2_BASE + 0x0030) +#define DMA2_Channel4_BASE (DMA2_BASE + 0x0044) +#define DMA2_Channel5_BASE (DMA2_BASE + 0x0058) + +#define AES_BASE ((uint32_t)0x50060000) + +#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) /*!< FSMC Bank1 registers base address */ +#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) /*!< FSMC Bank1E registers base address */ + +#define DBGMCU_BASE ((uint32_t)0xE0042000) /*!< Debug MCU registers base address */ + +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ + +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define LCD ((LCD_TypeDef *) LCD_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define DAC ((DAC_TypeDef *) DAC_BASE) +#define COMP ((COMP_TypeDef *) COMP_BASE) +#define RI ((RI_TypeDef *) RI_BASE) +#define OPAMP ((OPAMP_TypeDef *) OPAMP_BASE) +#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) + +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC ((ADC_Common_TypeDef *) ADC_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE) +#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE) +#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE) +#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE) +#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE) +#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE) +#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE) + +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA2_Channel1 ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE) +#define DMA2_Channel2 ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE) +#define DMA2_Channel3 ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE) +#define DMA2_Channel4 ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE) +#define DMA2_Channel5 ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE) + +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) + +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) + +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define OB ((OB_TypeDef *) OB_BASE) + +#define AES ((AES_TypeDef *) AES_BASE) + +#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) +#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) + +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + +/** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers Bits Definition */ +/******************************************************************************/ +/******************************************************************************/ +/* */ +/* Analog to Digital Converter (ADC) */ +/* */ +/******************************************************************************/ + +/******************** Bit definition for ADC_SR register ********************/ +#define ADC_SR_AWD ((uint32_t)0x00000001) /*!< Analog watchdog flag */ +#define ADC_SR_EOC ((uint32_t)0x00000002) /*!< End of conversion */ +#define ADC_SR_JEOC ((uint32_t)0x00000004) /*!< Injected channel end of conversion */ +#define ADC_SR_JSTRT ((uint32_t)0x00000008) /*!< Injected channel Start flag */ +#define ADC_SR_STRT ((uint32_t)0x00000010) /*!< Regular channel Start flag */ +#define ADC_SR_OVR ((uint32_t)0x00000020) /*!< Overrun flag */ +#define ADC_SR_ADONS ((uint32_t)0x00000040) /*!< ADC ON status */ +#define ADC_SR_RCNR ((uint32_t)0x00000100) /*!< Regular channel not ready flag */ +#define ADC_SR_JCNR ((uint32_t)0x00000200) /*!< Injected channel not ready flag */ + +/******************* Bit definition for ADC_CR1 register ********************/ +#define ADC_CR1_AWDCH ((uint32_t)0x0000001F) /*!< AWDCH[4:0] bits (Analog watchdog channel select bits) */ +#define ADC_CR1_AWDCH_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_CR1_AWDCH_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_CR1_AWDCH_2 ((uint32_t)0x00000004) /*!< Bit 2 */ +#define ADC_CR1_AWDCH_3 ((uint32_t)0x00000008) /*!< Bit 3 */ +#define ADC_CR1_AWDCH_4 ((uint32_t)0x00000010) /*!< Bit 4 */ + +#define ADC_CR1_EOCIE ((uint32_t)0x00000020) /*!< Interrupt enable for EOC */ +#define ADC_CR1_AWDIE ((uint32_t)0x00000040) /*!< Analog Watchdog interrupt enable */ +#define ADC_CR1_JEOCIE ((uint32_t)0x00000080) /*!< Interrupt enable for injected channels */ +#define ADC_CR1_SCAN ((uint32_t)0x00000100) /*!< Scan mode */ +#define ADC_CR1_AWDSGL ((uint32_t)0x00000200) /*!< Enable the watchdog on a single channel in scan mode */ +#define ADC_CR1_JAUTO ((uint32_t)0x00000400) /*!< Automatic injected group conversion */ +#define ADC_CR1_DISCEN ((uint32_t)0x00000800) /*!< Discontinuous mode on regular channels */ +#define ADC_CR1_JDISCEN ((uint32_t)0x00001000) /*!< Discontinuous mode on injected channels */ + +#define ADC_CR1_DISCNUM ((uint32_t)0x0000E000) /*!< DISCNUM[2:0] bits (Discontinuous mode channel count) */ +#define ADC_CR1_DISCNUM_0 ((uint32_t)0x00002000) /*!< Bit 0 */ +#define ADC_CR1_DISCNUM_1 ((uint32_t)0x00004000) /*!< Bit 1 */ +#define ADC_CR1_DISCNUM_2 ((uint32_t)0x00008000) /*!< Bit 2 */ + +#define ADC_CR1_PDD ((uint32_t)0x00010000) /*!< Power Down during Delay phase */ +#define ADC_CR1_PDI ((uint32_t)0x00020000) /*!< Power Down during Idle phase */ + +#define ADC_CR1_JAWDEN ((uint32_t)0x00400000) /*!< Analog watchdog enable on injected channels */ +#define ADC_CR1_AWDEN ((uint32_t)0x00800000) /*!< Analog watchdog enable on regular channels */ + +#define ADC_CR1_RES ((uint32_t)0x03000000) /*!< RES[1:0] bits (Resolution) */ +#define ADC_CR1_RES_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define ADC_CR1_RES_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + +#define ADC_CR1_OVRIE ((uint32_t)0x04000000) /*!< Overrun interrupt enable */ + +/******************* Bit definition for ADC_CR2 register ********************/ +#define ADC_CR2_ADON ((uint32_t)0x00000001) /*!< A/D Converter ON / OFF */ +#define ADC_CR2_CONT ((uint32_t)0x00000002) /*!< Continuous Conversion */ +#define ADC_CR2_CFG ((uint32_t)0x00000004) /*!< ADC Configuration */ + +#define ADC_CR2_DELS ((uint32_t)0x00000070) /*!< DELS[2:0] bits (Delay selection) */ +#define ADC_CR2_DELS_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define ADC_CR2_DELS_1 ((uint32_t)0x00000020) /*!< Bit 1 */ +#define ADC_CR2_DELS_2 ((uint32_t)0x00000040) /*!< Bit 2 */ + +#define ADC_CR2_DMA ((uint32_t)0x00000100) /*!< Direct Memory access mode */ +#define ADC_CR2_DDS ((uint32_t)0x00000200) /*!< DMA disable selection (Single ADC) */ +#define ADC_CR2_EOCS ((uint32_t)0x00000400) /*!< End of conversion selection */ +#define ADC_CR2_ALIGN ((uint32_t)0x00000800) /*!< Data Alignment */ + +#define ADC_CR2_JEXTSEL ((uint32_t)0x000F0000) /*!< JEXTSEL[3:0] bits (External event select for injected group) */ +#define ADC_CR2_JEXTSEL_0 ((uint32_t)0x00010000) /*!< Bit 0 */ +#define ADC_CR2_JEXTSEL_1 ((uint32_t)0x00020000) /*!< Bit 1 */ +#define ADC_CR2_JEXTSEL_2 ((uint32_t)0x00040000) /*!< Bit 2 */ +#define ADC_CR2_JEXTSEL_3 ((uint32_t)0x00080000) /*!< Bit 3 */ + +#define ADC_CR2_JEXTEN ((uint32_t)0x00300000) /*!< JEXTEN[1:0] bits (External Trigger Conversion mode for injected channels) */ +#define ADC_CR2_JEXTEN_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define ADC_CR2_JEXTEN_1 ((uint32_t)0x00200000) /*!< Bit 1 */ + +#define ADC_CR2_JSWSTART ((uint32_t)0x00400000) /*!< Start Conversion of injected channels */ + +#define ADC_CR2_EXTSEL ((uint32_t)0x0F000000) /*!< EXTSEL[3:0] bits (External Event Select for regular group) */ +#define ADC_CR2_EXTSEL_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define ADC_CR2_EXTSEL_1 ((uint32_t)0x02000000) /*!< Bit 1 */ +#define ADC_CR2_EXTSEL_2 ((uint32_t)0x04000000) /*!< Bit 2 */ +#define ADC_CR2_EXTSEL_3 ((uint32_t)0x08000000) /*!< Bit 3 */ + +#define ADC_CR2_EXTEN ((uint32_t)0x30000000) /*!< EXTEN[1:0] bits (External Trigger Conversion mode for regular channels) */ +#define ADC_CR2_EXTEN_0 ((uint32_t)0x10000000) /*!< Bit 0 */ +#define ADC_CR2_EXTEN_1 ((uint32_t)0x20000000) /*!< Bit 1 */ + +#define ADC_CR2_SWSTART ((uint32_t)0x40000000) /*!< Start Conversion of regular channels */ + +/****************** Bit definition for ADC_SMPR1 register *******************/ +#define ADC_SMPR1_SMP20 ((uint32_t)0x00000007) /*!< SMP20[2:0] bits (Channel 20 Sample time selection) */ +#define ADC_SMPR1_SMP20_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SMPR1_SMP20_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SMPR1_SMP20_2 ((uint32_t)0x00000004) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP21 ((uint32_t)0x00000038) /*!< SMP21[2:0] bits (Channel 21 Sample time selection) */ +#define ADC_SMPR1_SMP21_0 ((uint32_t)0x00000008) /*!< Bit 0 */ +#define ADC_SMPR1_SMP21_1 ((uint32_t)0x00000010) /*!< Bit 1 */ +#define ADC_SMPR1_SMP21_2 ((uint32_t)0x00000020) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP22 ((uint32_t)0x000001C0) /*!< SMP22[2:0] bits (Channel 22 Sample time selection) */ +#define ADC_SMPR1_SMP22_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define ADC_SMPR1_SMP22_1 ((uint32_t)0x00000080) /*!< Bit 1 */ +#define ADC_SMPR1_SMP22_2 ((uint32_t)0x00000100) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP23 ((uint32_t)0x00000E00) /*!< SMP23[2:0] bits (Channel 23 Sample time selection) */ +#define ADC_SMPR1_SMP23_0 ((uint32_t)0x00000200) /*!< Bit 0 */ +#define ADC_SMPR1_SMP23_1 ((uint32_t)0x00000400) /*!< Bit 1 */ +#define ADC_SMPR1_SMP23_2 ((uint32_t)0x00000800) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP24 ((uint32_t)0x00007000) /*!< SMP24[2:0] bits (Channel 24 Sample time selection) */ +#define ADC_SMPR1_SMP24_0 ((uint32_t)0x00001000) /*!< Bit 0 */ +#define ADC_SMPR1_SMP24_1 ((uint32_t)0x00002000) /*!< Bit 1 */ +#define ADC_SMPR1_SMP24_2 ((uint32_t)0x00004000) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP25 ((uint32_t)0x00038000) /*!< SMP25[2:0] bits (Channel 25 Sample time selection) */ +#define ADC_SMPR1_SMP25_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_SMPR1_SMP25_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_SMPR1_SMP25_2 ((uint32_t)0x00020000) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP26 ((uint32_t)0x001C0000) /*!< SMP26[2:0] bits (Channel 26 Sample time selection) */ +#define ADC_SMPR1_SMP26_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define ADC_SMPR1_SMP26_1 ((uint32_t)0x00080000) /*!< Bit 1 */ +#define ADC_SMPR1_SMP26_2 ((uint32_t)0x00100000) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP27 ((uint32_t)0x00E00000) /*!< SMP27[2:0] bits (Channel 27 Sample time selection) */ +#define ADC_SMPR1_SMP27_0 ((uint32_t)0x00200000) /*!< Bit 0 */ +#define ADC_SMPR1_SMP27_1 ((uint32_t)0x00400000) /*!< Bit 1 */ +#define ADC_SMPR1_SMP27_2 ((uint32_t)0x00800000) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP28 ((uint32_t)0x07000000) /*!< SMP28[2:0] bits (Channel 28 Sample time selection) */ +#define ADC_SMPR1_SMP28_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define ADC_SMPR1_SMP28_1 ((uint32_t)0x02000000) /*!< Bit 1 */ +#define ADC_SMPR1_SMP28_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + +#define ADC_SMPR1_SMP29 ((uint32_t)0x38000000) /*!< SMP29[2:0] bits (Channel 29 Sample time selection) */ +#define ADC_SMPR1_SMP29_0 ((uint32_t)0x08000000) /*!< Bit 0 */ +#define ADC_SMPR1_SMP29_1 ((uint32_t)0x10000000) /*!< Bit 1 */ +#define ADC_SMPR1_SMP29_2 ((uint32_t)0x20000000) /*!< Bit 2 */ + +/****************** Bit definition for ADC_SMPR2 register *******************/ +#define ADC_SMPR2_SMP10 ((uint32_t)0x00000007) /*!< SMP10[2:0] bits (Channel 10 Sample time selection) */ +#define ADC_SMPR2_SMP10_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SMPR2_SMP10_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SMPR2_SMP10_2 ((uint32_t)0x00000004) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP11 ((uint32_t)0x00000038) /*!< SMP11[2:0] bits (Channel 11 Sample time selection) */ +#define ADC_SMPR2_SMP11_0 ((uint32_t)0x00000008) /*!< Bit 0 */ +#define ADC_SMPR2_SMP11_1 ((uint32_t)0x00000010) /*!< Bit 1 */ +#define ADC_SMPR2_SMP11_2 ((uint32_t)0x00000020) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP12 ((uint32_t)0x000001C0) /*!< SMP12[2:0] bits (Channel 12 Sample time selection) */ +#define ADC_SMPR2_SMP12_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define ADC_SMPR2_SMP12_1 ((uint32_t)0x00000080) /*!< Bit 1 */ +#define ADC_SMPR2_SMP12_2 ((uint32_t)0x00000100) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP13 ((uint32_t)0x00000E00) /*!< SMP13[2:0] bits (Channel 13 Sample time selection) */ +#define ADC_SMPR2_SMP13_0 ((uint32_t)0x00000200) /*!< Bit 0 */ +#define ADC_SMPR2_SMP13_1 ((uint32_t)0x00000400) /*!< Bit 1 */ +#define ADC_SMPR2_SMP13_2 ((uint32_t)0x00000800) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP14 ((uint32_t)0x00007000) /*!< SMP14[2:0] bits (Channel 14 Sample time selection) */ +#define ADC_SMPR2_SMP14_0 ((uint32_t)0x00001000) /*!< Bit 0 */ +#define ADC_SMPR2_SMP14_1 ((uint32_t)0x00002000) /*!< Bit 1 */ +#define ADC_SMPR2_SMP14_2 ((uint32_t)0x00004000) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP15 ((uint32_t)0x00038000) /*!< SMP15[2:0] bits (Channel 5 Sample time selection) */ +#define ADC_SMPR2_SMP15_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_SMPR2_SMP15_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_SMPR2_SMP15_2 ((uint32_t)0x00020000) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP16 ((uint32_t)0x001C0000) /*!< SMP16[2:0] bits (Channel 16 Sample time selection) */ +#define ADC_SMPR2_SMP16_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define ADC_SMPR2_SMP16_1 ((uint32_t)0x00080000) /*!< Bit 1 */ +#define ADC_SMPR2_SMP16_2 ((uint32_t)0x00100000) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP17 ((uint32_t)0x00E00000) /*!< SMP17[2:0] bits (Channel 17 Sample time selection) */ +#define ADC_SMPR2_SMP17_0 ((uint32_t)0x00200000) /*!< Bit 0 */ +#define ADC_SMPR2_SMP17_1 ((uint32_t)0x00400000) /*!< Bit 1 */ +#define ADC_SMPR2_SMP17_2 ((uint32_t)0x00800000) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP18 ((uint32_t)0x07000000) /*!< SMP18[2:0] bits (Channel 18 Sample time selection) */ +#define ADC_SMPR2_SMP18_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define ADC_SMPR2_SMP18_1 ((uint32_t)0x02000000) /*!< Bit 1 */ +#define ADC_SMPR2_SMP18_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + +#define ADC_SMPR2_SMP19 ((uint32_t)0x38000000) /*!< SMP19[2:0] bits (Channel 19 Sample time selection) */ +#define ADC_SMPR2_SMP19_0 ((uint32_t)0x08000000) /*!< Bit 0 */ +#define ADC_SMPR2_SMP19_1 ((uint32_t)0x10000000) /*!< Bit 1 */ +#define ADC_SMPR2_SMP19_2 ((uint32_t)0x20000000) /*!< Bit 2 */ + +/****************** Bit definition for ADC_SMPR3 register *******************/ +#define ADC_SMPR3_SMP0 ((uint32_t)0x00000007) /*!< SMP0[2:0] bits (Channel 0 Sample time selection) */ +#define ADC_SMPR3_SMP0_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SMPR3_SMP0_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SMPR3_SMP0_2 ((uint32_t)0x00000004) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP1 ((uint32_t)0x00000038) /*!< SMP1[2:0] bits (Channel 1 Sample time selection) */ +#define ADC_SMPR3_SMP1_0 ((uint32_t)0x00000008) /*!< Bit 0 */ +#define ADC_SMPR3_SMP1_1 ((uint32_t)0x00000010) /*!< Bit 1 */ +#define ADC_SMPR3_SMP1_2 ((uint32_t)0x00000020) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP2 ((uint32_t)0x000001C0) /*!< SMP2[2:0] bits (Channel 2 Sample time selection) */ +#define ADC_SMPR3_SMP2_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define ADC_SMPR3_SMP2_1 ((uint32_t)0x00000080) /*!< Bit 1 */ +#define ADC_SMPR3_SMP2_2 ((uint32_t)0x00000100) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP3 ((uint32_t)0x00000E00) /*!< SMP3[2:0] bits (Channel 3 Sample time selection) */ +#define ADC_SMPR3_SMP3_0 ((uint32_t)0x00000200) /*!< Bit 0 */ +#define ADC_SMPR3_SMP3_1 ((uint32_t)0x00000400) /*!< Bit 1 */ +#define ADC_SMPR3_SMP3_2 ((uint32_t)0x00000800) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP4 ((uint32_t)0x00007000) /*!< SMP4[2:0] bits (Channel 4 Sample time selection) */ +#define ADC_SMPR3_SMP4_0 ((uint32_t)0x00001000) /*!< Bit 0 */ +#define ADC_SMPR3_SMP4_1 ((uint32_t)0x00002000) /*!< Bit 1 */ +#define ADC_SMPR3_SMP4_2 ((uint32_t)0x00004000) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP5 ((uint32_t)0x00038000) /*!< SMP5[2:0] bits (Channel 5 Sample time selection) */ +#define ADC_SMPR3_SMP5_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_SMPR3_SMP5_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_SMPR3_SMP5_2 ((uint32_t)0x00020000) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP6 ((uint32_t)0x001C0000) /*!< SMP6[2:0] bits (Channel 6 Sample time selection) */ +#define ADC_SMPR3_SMP6_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define ADC_SMPR3_SMP6_1 ((uint32_t)0x00080000) /*!< Bit 1 */ +#define ADC_SMPR3_SMP6_2 ((uint32_t)0x00100000) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP7 ((uint32_t)0x00E00000) /*!< SMP7[2:0] bits (Channel 7 Sample time selection) */ +#define ADC_SMPR3_SMP7_0 ((uint32_t)0x00200000) /*!< Bit 0 */ +#define ADC_SMPR3_SMP7_1 ((uint32_t)0x00400000) /*!< Bit 1 */ +#define ADC_SMPR3_SMP7_2 ((uint32_t)0x00800000) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP8 ((uint32_t)0x07000000) /*!< SMP8[2:0] bits (Channel 8 Sample time selection) */ +#define ADC_SMPR3_SMP8_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define ADC_SMPR3_SMP8_1 ((uint32_t)0x02000000) /*!< Bit 1 */ +#define ADC_SMPR3_SMP8_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP9 ((uint32_t)0x38000000) /*!< SMP9[2:0] bits (Channel 9 Sample time selection) */ +#define ADC_SMPR3_SMP9_0 ((uint32_t)0x08000000) /*!< Bit 0 */ +#define ADC_SMPR3_SMP9_1 ((uint32_t)0x10000000) /*!< Bit 1 */ +#define ADC_SMPR3_SMP9_2 ((uint32_t)0x20000000) /*!< Bit 2 */ + +/****************** Bit definition for ADC_JOFR1 register *******************/ +#define ADC_JOFR1_JOFFSET1 ((uint32_t)0x00000FFF) /*!< Data offset for injected channel 1 */ + +/****************** Bit definition for ADC_JOFR2 register *******************/ +#define ADC_JOFR2_JOFFSET2 ((uint32_t)0x00000FFF) /*!< Data offset for injected channel 2 */ + +/****************** Bit definition for ADC_JOFR3 register *******************/ +#define ADC_JOFR3_JOFFSET3 ((uint32_t)0x00000FFF) /*!< Data offset for injected channel 3 */ + +/****************** Bit definition for ADC_JOFR4 register *******************/ +#define ADC_JOFR4_JOFFSET4 ((uint32_t)0x00000FFF) /*!< Data offset for injected channel 4 */ + +/******************* Bit definition for ADC_HTR register ********************/ +#define ADC_HTR_HT ((uint32_t)0x00000FFF) /*!< Analog watchdog high threshold */ + +/******************* Bit definition for ADC_LTR register ********************/ +#define ADC_LTR_LT ((uint32_t)0x00000FFF) /*!< Analog watchdog low threshold */ + +/******************* Bit definition for ADC_SQR1 register *******************/ +#define ADC_SQR1_L ((uint32_t)0x00F00000) /*!< L[3:0] bits (Regular channel sequence length) */ +#define ADC_SQR1_L_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define ADC_SQR1_L_1 ((uint32_t)0x00200000) /*!< Bit 1 */ +#define ADC_SQR1_L_2 ((uint32_t)0x00400000) /*!< Bit 2 */ +#define ADC_SQR1_L_3 ((uint32_t)0x00800000) /*!< Bit 3 */ + +#define ADC_SQR1_SQ28 ((uint32_t)0x000F8000) /*!< SQ28[4:0] bits (25th conversion in regular sequence) */ +#define ADC_SQR1_SQ28_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_SQR1_SQ28_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_SQR1_SQ28_2 ((uint32_t)0x00020000) /*!< Bit 2 */ +#define ADC_SQR1_SQ28_3 ((uint32_t)0x00040000) /*!< Bit 3 */ +#define ADC_SQR1_SQ28_4 ((uint32_t)0x00080000) /*!< Bit 4 */ + +#define ADC_SQR1_SQ27 ((uint32_t)0x00007C00) /*!< SQ27[4:0] bits (27th conversion in regular sequence) */ +#define ADC_SQR1_SQ27_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define ADC_SQR1_SQ27_1 ((uint32_t)0x00000800) /*!< Bit 1 */ +#define ADC_SQR1_SQ27_2 ((uint32_t)0x00001000) /*!< Bit 2 */ +#define ADC_SQR1_SQ27_3 ((uint32_t)0x00002000) /*!< Bit 3 */ +#define ADC_SQR1_SQ27_4 ((uint32_t)0x00004000) /*!< Bit 4 */ + +#define ADC_SQR1_SQ26 ((uint32_t)0x000003E0) /*!< SQ26[4:0] bits (26th conversion in regular sequence) */ +#define ADC_SQR1_SQ26_0 ((uint32_t)0x00000020) /*!< Bit 0 */ +#define ADC_SQR1_SQ26_1 ((uint32_t)0x00000040) /*!< Bit 1 */ +#define ADC_SQR1_SQ26_2 ((uint32_t)0x00000080) /*!< Bit 2 */ +#define ADC_SQR1_SQ26_3 ((uint32_t)0x00000100) /*!< Bit 3 */ +#define ADC_SQR1_SQ26_4 ((uint32_t)0x00000200) /*!< Bit 4 */ + +#define ADC_SQR1_SQ25 ((uint32_t)0x0000001F) /*!< SQ25[4:0] bits (25th conversion in regular sequence) */ +#define ADC_SQR1_SQ25_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SQR1_SQ25_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SQR1_SQ25_2 ((uint32_t)0x00000004) /*!< Bit 2 */ +#define ADC_SQR1_SQ25_3 ((uint32_t)0x00000008) /*!< Bit 3 */ +#define ADC_SQR1_SQ25_4 ((uint32_t)0x00000010) /*!< Bit 4 */ + +/******************* Bit definition for ADC_SQR2 register *******************/ +#define ADC_SQR2_SQ19 ((uint32_t)0x0000001F) /*!< SQ19[4:0] bits (19th conversion in regular sequence) */ +#define ADC_SQR2_SQ19_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SQR2_SQ19_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SQR2_SQ19_2 ((uint32_t)0x00000004) /*!< Bit 2 */ +#define ADC_SQR2_SQ19_3 ((uint32_t)0x00000008) /*!< Bit 3 */ +#define ADC_SQR2_SQ19_4 ((uint32_t)0x00000010) /*!< Bit 4 */ + +#define ADC_SQR2_SQ20 ((uint32_t)0x000003E0) /*!< SQ20[4:0] bits (20th conversion in regular sequence) */ +#define ADC_SQR2_SQ20_0 ((uint32_t)0x00000020) /*!< Bit 0 */ +#define ADC_SQR2_SQ20_1 ((uint32_t)0x00000040) /*!< Bit 1 */ +#define ADC_SQR2_SQ20_2 ((uint32_t)0x00000080) /*!< Bit 2 */ +#define ADC_SQR2_SQ20_3 ((uint32_t)0x00000100) /*!< Bit 3 */ +#define ADC_SQR2_SQ20_4 ((uint32_t)0x00000200) /*!< Bit 4 */ + +#define ADC_SQR2_SQ21 ((uint32_t)0x00007C00) /*!< SQ21[4:0] bits (21th conversion in regular sequence) */ +#define ADC_SQR2_SQ21_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define ADC_SQR2_SQ21_1 ((uint32_t)0x00000800) /*!< Bit 1 */ +#define ADC_SQR2_SQ21_2 ((uint32_t)0x00001000) /*!< Bit 2 */ +#define ADC_SQR2_SQ21_3 ((uint32_t)0x00002000) /*!< Bit 3 */ +#define ADC_SQR2_SQ21_4 ((uint32_t)0x00004000) /*!< Bit 4 */ + +#define ADC_SQR2_SQ22 ((uint32_t)0x000F8000) /*!< SQ22[4:0] bits (22th conversion in regular sequence) */ +#define ADC_SQR2_SQ22_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_SQR2_SQ22_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_SQR2_SQ22_2 ((uint32_t)0x00020000) /*!< Bit 2 */ +#define ADC_SQR2_SQ22_3 ((uint32_t)0x00040000) /*!< Bit 3 */ +#define ADC_SQR2_SQ22_4 ((uint32_t)0x00080000) /*!< Bit 4 */ + +#define ADC_SQR2_SQ23 ((uint32_t)0x01F00000) /*!< SQ23[4:0] bits (23th conversion in regular sequence) */ +#define ADC_SQR2_SQ23_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define ADC_SQR2_SQ23_1 ((uint32_t)0x00200000) /*!< Bit 1 */ +#define ADC_SQR2_SQ23_2 ((uint32_t)0x00400000) /*!< Bit 2 */ +#define ADC_SQR2_SQ23_3 ((uint32_t)0x00800000) /*!< Bit 3 */ +#define ADC_SQR2_SQ23_4 ((uint32_t)0x01000000) /*!< Bit 4 */ + +#define ADC_SQR2_SQ24 ((uint32_t)0x3E000000) /*!< SQ24[4:0] bits (24th conversion in regular sequence) */ +#define ADC_SQR2_SQ24_0 ((uint32_t)0x02000000) /*!< Bit 0 */ +#define ADC_SQR2_SQ24_1 ((uint32_t)0x04000000) /*!< Bit 1 */ +#define ADC_SQR2_SQ24_2 ((uint32_t)0x08000000) /*!< Bit 2 */ +#define ADC_SQR2_SQ24_3 ((uint32_t)0x10000000) /*!< Bit 3 */ +#define ADC_SQR2_SQ24_4 ((uint32_t)0x20000000) /*!< Bit 4 */ + +/******************* Bit definition for ADC_SQR3 register *******************/ +#define ADC_SQR3_SQ13 ((uint32_t)0x0000001F) /*!< SQ13[4:0] bits (13th conversion in regular sequence) */ +#define ADC_SQR3_SQ13_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SQR3_SQ13_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SQR3_SQ13_2 ((uint32_t)0x00000004) /*!< Bit 2 */ +#define ADC_SQR3_SQ13_3 ((uint32_t)0x00000008) /*!< Bit 3 */ +#define ADC_SQR3_SQ13_4 ((uint32_t)0x00000010) /*!< Bit 4 */ + +#define ADC_SQR3_SQ14 ((uint32_t)0x000003E0) /*!< SQ14[4:0] bits (14th conversion in regular sequence) */ +#define ADC_SQR3_SQ14_0 ((uint32_t)0x00000020) /*!< Bit 0 */ +#define ADC_SQR3_SQ14_1 ((uint32_t)0x00000040) /*!< Bit 1 */ +#define ADC_SQR3_SQ14_2 ((uint32_t)0x00000080) /*!< Bit 2 */ +#define ADC_SQR3_SQ14_3 ((uint32_t)0x00000100) /*!< Bit 3 */ +#define ADC_SQR3_SQ14_4 ((uint32_t)0x00000200) /*!< Bit 4 */ + +#define ADC_SQR3_SQ15 ((uint32_t)0x00007C00) /*!< SQ15[4:0] bits (15th conversion in regular sequence) */ +#define ADC_SQR3_SQ15_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define ADC_SQR3_SQ15_1 ((uint32_t)0x00000800) /*!< Bit 1 */ +#define ADC_SQR3_SQ15_2 ((uint32_t)0x00001000) /*!< Bit 2 */ +#define ADC_SQR3_SQ15_3 ((uint32_t)0x00002000) /*!< Bit 3 */ +#define ADC_SQR3_SQ15_4 ((uint32_t)0x00004000) /*!< Bit 4 */ + +#define ADC_SQR3_SQ16 ((uint32_t)0x000F8000) /*!< SQ16[4:0] bits (16th conversion in regular sequence) */ +#define ADC_SQR3_SQ16_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_SQR3_SQ16_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_SQR3_SQ16_2 ((uint32_t)0x00020000) /*!< Bit 2 */ +#define ADC_SQR3_SQ16_3 ((uint32_t)0x00040000) /*!< Bit 3 */ +#define ADC_SQR3_SQ16_4 ((uint32_t)0x00080000) /*!< Bit 4 */ + +#define ADC_SQR3_SQ17 ((uint32_t)0x01F00000) /*!< SQ17[4:0] bits (17th conversion in regular sequence) */ +#define ADC_SQR3_SQ17_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define ADC_SQR3_SQ17_1 ((uint32_t)0x00200000) /*!< Bit 1 */ +#define ADC_SQR3_SQ17_2 ((uint32_t)0x00400000) /*!< Bit 2 */ +#define ADC_SQR3_SQ17_3 ((uint32_t)0x00800000) /*!< Bit 3 */ +#define ADC_SQR3_SQ17_4 ((uint32_t)0x01000000) /*!< Bit 4 */ + +#define ADC_SQR3_SQ18 ((uint32_t)0x3E000000) /*!< SQ18[4:0] bits (18th conversion in regular sequence) */ +#define ADC_SQR3_SQ18_0 ((uint32_t)0x02000000) /*!< Bit 0 */ +#define ADC_SQR3_SQ18_1 ((uint32_t)0x04000000) /*!< Bit 1 */ +#define ADC_SQR3_SQ18_2 ((uint32_t)0x08000000) /*!< Bit 2 */ +#define ADC_SQR3_SQ18_3 ((uint32_t)0x10000000) /*!< Bit 3 */ +#define ADC_SQR3_SQ18_4 ((uint32_t)0x20000000) /*!< Bit 4 */ + +/******************* Bit definition for ADC_SQR4 register *******************/ +#define ADC_SQR4_SQ7 ((uint32_t)0x0000001F) /*!< SQ7[4:0] bits (7th conversion in regular sequence) */ +#define ADC_SQR4_SQ7_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SQR4_SQ7_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SQR4_SQ7_2 ((uint32_t)0x00000004) /*!< Bit 2 */ +#define ADC_SQR4_SQ7_3 ((uint32_t)0x00000008) /*!< Bit 3 */ +#define ADC_SQR4_SQ7_4 ((uint32_t)0x00000010) /*!< Bit 4 */ + +#define ADC_SQR4_SQ8 ((uint32_t)0x000003E0) /*!< SQ8[4:0] bits (8th conversion in regular sequence) */ +#define ADC_SQR4_SQ8_0 ((uint32_t)0x00000020) /*!< Bit 0 */ +#define ADC_SQR4_SQ8_1 ((uint32_t)0x00000040) /*!< Bit 1 */ +#define ADC_SQR4_SQ8_2 ((uint32_t)0x00000080) /*!< Bit 2 */ +#define ADC_SQR4_SQ8_3 ((uint32_t)0x00000100) /*!< Bit 3 */ +#define ADC_SQR4_SQ8_4 ((uint32_t)0x00000200) /*!< Bit 4 */ + +#define ADC_SQR4_SQ9 ((uint32_t)0x00007C00) /*!< SQ9[4:0] bits (9th conversion in regular sequence) */ +#define ADC_SQR4_SQ9_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define ADC_SQR4_SQ9_1 ((uint32_t)0x00000800) /*!< Bit 1 */ +#define ADC_SQR4_SQ9_2 ((uint32_t)0x00001000) /*!< Bit 2 */ +#define ADC_SQR4_SQ9_3 ((uint32_t)0x00002000) /*!< Bit 3 */ +#define ADC_SQR4_SQ9_4 ((uint32_t)0x00004000) /*!< Bit 4 */ + +#define ADC_SQR4_SQ10 ((uint32_t)0x000F8000) /*!< SQ10[4:0] bits (10th conversion in regular sequence) */ +#define ADC_SQR4_SQ10_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_SQR4_SQ10_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_SQR4_SQ10_2 ((uint32_t)0x00020000) /*!< Bit 2 */ +#define ADC_SQR4_SQ10_3 ((uint32_t)0x00040000) /*!< Bit 3 */ +#define ADC_SQR4_SQ10_4 ((uint32_t)0x00080000) /*!< Bit 4 */ + +#define ADC_SQR4_SQ11 ((uint32_t)0x01F00000) /*!< SQ11[4:0] bits (11th conversion in regular sequence) */ +#define ADC_SQR4_SQ11_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define ADC_SQR4_SQ11_1 ((uint32_t)0x00200000) /*!< Bit 1 */ +#define ADC_SQR4_SQ11_2 ((uint32_t)0x00400000) /*!< Bit 2 */ +#define ADC_SQR4_SQ11_3 ((uint32_t)0x00800000) /*!< Bit 3 */ +#define ADC_SQR4_SQ11_4 ((uint32_t)0x01000000) /*!< Bit 4 */ + +#define ADC_SQR4_SQ12 ((uint32_t)0x3E000000) /*!< SQ12[4:0] bits (12th conversion in regular sequence) */ +#define ADC_SQR4_SQ12_0 ((uint32_t)0x02000000) /*!< Bit 0 */ +#define ADC_SQR4_SQ12_1 ((uint32_t)0x04000000) /*!< Bit 1 */ +#define ADC_SQR4_SQ12_2 ((uint32_t)0x08000000) /*!< Bit 2 */ +#define ADC_SQR4_SQ12_3 ((uint32_t)0x10000000) /*!< Bit 3 */ +#define ADC_SQR4_SQ12_4 ((uint32_t)0x20000000) /*!< Bit 4 */ + +/******************* Bit definition for ADC_SQR5 register *******************/ +#define ADC_SQR5_SQ1 ((uint32_t)0x0000001F) /*!< SQ1[4:0] bits (1st conversion in regular sequence) */ +#define ADC_SQR5_SQ1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SQR5_SQ1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SQR5_SQ1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ +#define ADC_SQR5_SQ1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ +#define ADC_SQR5_SQ1_4 ((uint32_t)0x00000010) /*!< Bit 4 */ + +#define ADC_SQR5_SQ2 ((uint32_t)0x000003E0) /*!< SQ2[4:0] bits (2nd conversion in regular sequence) */ +#define ADC_SQR5_SQ2_0 ((uint32_t)0x00000020) /*!< Bit 0 */ +#define ADC_SQR5_SQ2_1 ((uint32_t)0x00000040) /*!< Bit 1 */ +#define ADC_SQR5_SQ2_2 ((uint32_t)0x00000080) /*!< Bit 2 */ +#define ADC_SQR5_SQ2_3 ((uint32_t)0x00000100) /*!< Bit 3 */ +#define ADC_SQR5_SQ2_4 ((uint32_t)0x00000200) /*!< Bit 4 */ + +#define ADC_SQR5_SQ3 ((uint32_t)0x00007C00) /*!< SQ3[4:0] bits (3rd conversion in regular sequence) */ +#define ADC_SQR5_SQ3_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define ADC_SQR5_SQ3_1 ((uint32_t)0x00000800) /*!< Bit 1 */ +#define ADC_SQR5_SQ3_2 ((uint32_t)0x00001000) /*!< Bit 2 */ +#define ADC_SQR5_SQ3_3 ((uint32_t)0x00002000) /*!< Bit 3 */ +#define ADC_SQR5_SQ3_4 ((uint32_t)0x00004000) /*!< Bit 4 */ + +#define ADC_SQR5_SQ4 ((uint32_t)0x000F8000) /*!< SQ4[4:0] bits (4th conversion in regular sequence) */ +#define ADC_SQR5_SQ4_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_SQR5_SQ4_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_SQR5_SQ4_2 ((uint32_t)0x00020000) /*!< Bit 2 */ +#define ADC_SQR5_SQ4_3 ((uint32_t)0x00040000) /*!< Bit 3 */ +#define ADC_SQR5_SQ4_4 ((uint32_t)0x00080000) /*!< Bit 4 */ + +#define ADC_SQR5_SQ5 ((uint32_t)0x01F00000) /*!< SQ5[4:0] bits (5th conversion in regular sequence) */ +#define ADC_SQR5_SQ5_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define ADC_SQR5_SQ5_1 ((uint32_t)0x00200000) /*!< Bit 1 */ +#define ADC_SQR5_SQ5_2 ((uint32_t)0x00400000) /*!< Bit 2 */ +#define ADC_SQR5_SQ5_3 ((uint32_t)0x00800000) /*!< Bit 3 */ +#define ADC_SQR5_SQ5_4 ((uint32_t)0x01000000) /*!< Bit 4 */ + +#define ADC_SQR5_SQ6 ((uint32_t)0x3E000000) /*!< SQ6[4:0] bits (6th conversion in regular sequence) */ +#define ADC_SQR5_SQ6_0 ((uint32_t)0x02000000) /*!< Bit 0 */ +#define ADC_SQR5_SQ6_1 ((uint32_t)0x04000000) /*!< Bit 1 */ +#define ADC_SQR5_SQ6_2 ((uint32_t)0x08000000) /*!< Bit 2 */ +#define ADC_SQR5_SQ6_3 ((uint32_t)0x10000000) /*!< Bit 3 */ +#define ADC_SQR5_SQ6_4 ((uint32_t)0x20000000) /*!< Bit 4 */ + + +/******************* Bit definition for ADC_JSQR register *******************/ +#define ADC_JSQR_JSQ1 ((uint32_t)0x0000001F) /*!< JSQ1[4:0] bits (1st conversion in injected sequence) */ +#define ADC_JSQR_JSQ1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_JSQR_JSQ1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_JSQR_JSQ1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ +#define ADC_JSQR_JSQ1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ +#define ADC_JSQR_JSQ1_4 ((uint32_t)0x00000010) /*!< Bit 4 */ + +#define ADC_JSQR_JSQ2 ((uint32_t)0x000003E0) /*!< JSQ2[4:0] bits (2nd conversion in injected sequence) */ +#define ADC_JSQR_JSQ2_0 ((uint32_t)0x00000020) /*!< Bit 0 */ +#define ADC_JSQR_JSQ2_1 ((uint32_t)0x00000040) /*!< Bit 1 */ +#define ADC_JSQR_JSQ2_2 ((uint32_t)0x00000080) /*!< Bit 2 */ +#define ADC_JSQR_JSQ2_3 ((uint32_t)0x00000100) /*!< Bit 3 */ +#define ADC_JSQR_JSQ2_4 ((uint32_t)0x00000200) /*!< Bit 4 */ + +#define ADC_JSQR_JSQ3 ((uint32_t)0x00007C00) /*!< JSQ3[4:0] bits (3rd conversion in injected sequence) */ +#define ADC_JSQR_JSQ3_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define ADC_JSQR_JSQ3_1 ((uint32_t)0x00000800) /*!< Bit 1 */ +#define ADC_JSQR_JSQ3_2 ((uint32_t)0x00001000) /*!< Bit 2 */ +#define ADC_JSQR_JSQ3_3 ((uint32_t)0x00002000) /*!< Bit 3 */ +#define ADC_JSQR_JSQ3_4 ((uint32_t)0x00004000) /*!< Bit 4 */ + +#define ADC_JSQR_JSQ4 ((uint32_t)0x000F8000) /*!< JSQ4[4:0] bits (4th conversion in injected sequence) */ +#define ADC_JSQR_JSQ4_0 ((uint32_t)0x00008000) /*!< Bit 0 */ +#define ADC_JSQR_JSQ4_1 ((uint32_t)0x00010000) /*!< Bit 1 */ +#define ADC_JSQR_JSQ4_2 ((uint32_t)0x00020000) /*!< Bit 2 */ +#define ADC_JSQR_JSQ4_3 ((uint32_t)0x00040000) /*!< Bit 3 */ +#define ADC_JSQR_JSQ4_4 ((uint32_t)0x00080000) /*!< Bit 4 */ + +#define ADC_JSQR_JL ((uint32_t)0x00300000) /*!< JL[1:0] bits (Injected Sequence length) */ +#define ADC_JSQR_JL_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define ADC_JSQR_JL_1 ((uint32_t)0x00200000) /*!< Bit 1 */ + +/******************* Bit definition for ADC_JDR1 register *******************/ +#define ADC_JDR1_JDATA ((uint32_t)0x0000FFFF) /*!< Injected data */ + +/******************* Bit definition for ADC_JDR2 register *******************/ +#define ADC_JDR2_JDATA ((uint32_t)0x0000FFFF) /*!< Injected data */ + +/******************* Bit definition for ADC_JDR3 register *******************/ +#define ADC_JDR3_JDATA ((uint32_t)0x0000FFFF) /*!< Injected data */ + +/******************* Bit definition for ADC_JDR4 register *******************/ +#define ADC_JDR4_JDATA ((uint32_t)0x0000FFFF) /*!< Injected data */ + +/******************** Bit definition for ADC_DR register ********************/ +#define ADC_DR_DATA ((uint32_t)0x0000FFFF) /*!< Regular data */ + +/****************** Bit definition for ADC_SMPR0 register *******************/ +#define ADC_SMPR3_SMP30 ((uint32_t)0x00000007) /*!< SMP30[2:0] bits (Channel 30 Sample time selection) */ +#define ADC_SMPR3_SMP30_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define ADC_SMPR3_SMP30_1 ((uint32_t)0x00000002) /*!< Bit 1 */ +#define ADC_SMPR3_SMP30_2 ((uint32_t)0x00000004) /*!< Bit 2 */ + +#define ADC_SMPR3_SMP31 ((uint32_t)0x00000038) /*!< SMP31[2:0] bits (Channel 31 Sample time selection) */ +#define ADC_SMPR3_SMP31_0 ((uint32_t)0x00000008) /*!< Bit 0 */ +#define ADC_SMPR3_SMP31_1 ((uint32_t)0x00000010) /*!< Bit 1 */ +#define ADC_SMPR3_SMP31_2 ((uint32_t)0x00000020) /*!< Bit 2 */ + +/******************* Bit definition for ADC_CSR register ********************/ +#define ADC_CSR_AWD1 ((uint32_t)0x00000001) /*!< ADC1 Analog watchdog flag */ +#define ADC_CSR_EOC1 ((uint32_t)0x00000002) /*!< ADC1 End of conversion */ +#define ADC_CSR_JEOC1 ((uint32_t)0x00000004) /*!< ADC1 Injected channel end of conversion */ +#define ADC_CSR_JSTRT1 ((uint32_t)0x00000008) /*!< ADC1 Injected channel Start flag */ +#define ADC_CSR_STRT1 ((uint32_t)0x00000010) /*!< ADC1 Regular channel Start flag */ +#define ADC_CSR_OVR1 ((uint32_t)0x00000020) /*!< ADC1 overrun flag */ +#define ADC_CSR_ADONS1 ((uint32_t)0x00000040) /*!< ADON status of ADC1 */ + +/******************* Bit definition for ADC_CCR register ********************/ +#define ADC_CCR_ADCPRE ((uint32_t)0x00030000) /*!< ADC prescaler*/ +#define ADC_CCR_ADCPRE_0 ((uint32_t)0x00010000) /*!< Bit 0 */ +#define ADC_CCR_ADCPRE_1 ((uint32_t)0x00020000) /*!< Bit 1 */ +#define ADC_CCR_TSVREFE ((uint32_t)0x00800000) /*!< Temperature Sensor and VREFINT Enable */ + +/******************************************************************************/ +/* */ +/* Advanced Encryption Standard (AES) */ +/* */ +/******************************************************************************/ +/******************* Bit definition for AES_CR register *********************/ +#define AES_CR_EN ((uint32_t)0x00000001) /*!< AES Enable */ +#define AES_CR_DATATYPE ((uint32_t)0x00000006) /*!< Data type selection */ +#define AES_CR_DATATYPE_0 ((uint32_t)0x00000002) /*!< Bit 0 */ +#define AES_CR_DATATYPE_1 ((uint32_t)0x00000004) /*!< Bit 1 */ + +#define AES_CR_MODE ((uint32_t)0x00000018) /*!< AES Mode Of Operation */ +#define AES_CR_MODE_0 ((uint32_t)0x00000008) /*!< Bit 0 */ +#define AES_CR_MODE_1 ((uint32_t)0x00000010) /*!< Bit 1 */ + +#define AES_CR_CHMOD ((uint32_t)0x00000060) /*!< AES Chaining Mode */ +#define AES_CR_CHMOD_0 ((uint32_t)0x00000020) /*!< Bit 0 */ +#define AES_CR_CHMOD_1 ((uint32_t)0x00000040) /*!< Bit 1 */ + +#define AES_CR_CCFC ((uint32_t)0x00000080) /*!< Computation Complete Flag Clear */ +#define AES_CR_ERRC ((uint32_t)0x00000100) /*!< Error Clear */ +#define AES_CR_CCIE ((uint32_t)0x00000200) /*!< Computation Complete Interrupt Enable */ +#define AES_CR_ERRIE ((uint32_t)0x00000400) /*!< Error Interrupt Enable */ +#define AES_CR_DMAINEN ((uint32_t)0x00000800) /*!< DMA ENable managing the data input phase */ +#define AES_CR_DMAOUTEN ((uint32_t)0x00001000) /*!< DMA Enable managing the data output phase */ + +/******************* Bit definition for AES_SR register *********************/ +#define AES_SR_CCF ((uint32_t)0x00000001) /*!< Computation Complete Flag */ +#define AES_SR_RDERR ((uint32_t)0x00000002) /*!< Read Error Flag */ +#define AES_SR_WRERR ((uint32_t)0x00000004) /*!< Write Error Flag */ + +/******************* Bit definition for AES_DINR register *******************/ +#define AES_DINR ((uint32_t)0x0000FFFF) /*!< AES Data Input Register */ + +/******************* Bit definition for AES_DOUTR register ******************/ +#define AES_DOUTR ((uint32_t)0x0000FFFF) /*!< AES Data Output Register */ + +/******************* Bit definition for AES_KEYR0 register ******************/ +#define AES_KEYR0 ((uint32_t)0x0000FFFF) /*!< AES Key Register 0 */ + +/******************* Bit definition for AES_KEYR1 register ******************/ +#define AES_KEYR1 ((uint32_t)0x0000FFFF) /*!< AES Key Register 1 */ + +/******************* Bit definition for AES_KEYR2 register ******************/ +#define AES_KEYR2 ((uint32_t)0x0000FFFF) /*!< AES Key Register 2 */ + +/******************* Bit definition for AES_KEYR3 register ******************/ +#define AES_KEYR3 ((uint32_t)0x0000FFFF) /*!< AES Key Register 3 */ + +/******************* Bit definition for AES_IVR0 register *******************/ +#define AES_IVR0 ((uint32_t)0x0000FFFF) /*!< AES Initialization Vector Register 0 */ + +/******************* Bit definition for AES_IVR1 register *******************/ +#define AES_IVR1 ((uint32_t)0x0000FFFF) /*!< AES Initialization Vector Register 1 */ + +/******************* Bit definition for AES_IVR2 register *******************/ +#define AES_IVR2 ((uint32_t)0x0000FFFF) /*!< AES Initialization Vector Register 2 */ + +/******************* Bit definition for AES_IVR3 register *******************/ +#define AES_IVR3 ((uint32_t)0x0000FFFF) /*!< AES Initialization Vector Register 3 */ + +/******************************************************************************/ +/* */ +/* Analog Comparators (COMP) */ +/* */ +/******************************************************************************/ + +/****************** Bit definition for COMP_CSR register ********************/ +#define COMP_CSR_10KPU ((uint32_t)0x00000001) /*!< 10K pull-up resistor */ +#define COMP_CSR_400KPU ((uint32_t)0x00000002) /*!< 400K pull-up resistor */ +#define COMP_CSR_10KPD ((uint32_t)0x00000004) /*!< 10K pull-down resistor */ +#define COMP_CSR_400KPD ((uint32_t)0x00000008) /*!< 400K pull-down resistor */ + +#define COMP_CSR_CMP1EN ((uint32_t)0x00000010) /*!< Comparator 1 enable */ +#define COMP_CSR_SW1 ((uint32_t)0x00000020) /*!< SW1 analog switch enable */ +#define COMP_CSR_CMP1OUT ((uint32_t)0x00000080) /*!< Comparator 1 output */ + +#define COMP_CSR_SPEED ((uint32_t)0x00001000) /*!< Comparator 2 speed */ +#define COMP_CSR_CMP2OUT ((uint32_t)0x00002000) /*!< Comparator 2 ouput */ + +#define COMP_CSR_VREFOUTEN ((uint32_t)0x00010000) /*!< Comparator Vref Enable */ +#define COMP_CSR_WNDWE ((uint32_t)0x00020000) /*!< Window mode enable */ + +#define COMP_CSR_INSEL ((uint32_t)0x001C0000) /*!< INSEL[2:0] Inversion input Selection */ +#define COMP_CSR_INSEL_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define COMP_CSR_INSEL_1 ((uint32_t)0x00080000) /*!< Bit 1 */ +#define COMP_CSR_INSEL_2 ((uint32_t)0x00100000) /*!< Bit 2 */ + +#define COMP_CSR_OUTSEL ((uint32_t)0x00E00000) /*!< OUTSEL[2:0] comparator 2 output redirection */ +#define COMP_CSR_OUTSEL_0 ((uint32_t)0x00200000) /*!< Bit 0 */ +#define COMP_CSR_OUTSEL_1 ((uint32_t)0x00400000) /*!< Bit 1 */ +#define COMP_CSR_OUTSEL_2 ((uint32_t)0x00800000) /*!< Bit 2 */ + +#define COMP_CSR_FCH3 ((uint32_t)0x04000000) /*!< Bit 26 */ +#define COMP_CSR_FCH8 ((uint32_t)0x08000000) /*!< Bit 27 */ +#define COMP_CSR_RCH13 ((uint32_t)0x10000000) /*!< Bit 28 */ + +#define COMP_CSR_CAIE ((uint32_t)0x20000000) /*!< Bit 29 */ +#define COMP_CSR_CAIF ((uint32_t)0x40000000) /*!< Bit 30 */ +#define COMP_CSR_TSUSP ((uint32_t)0x80000000) /*!< Bit 31 */ + +/******************************************************************************/ +/* */ +/* Operational Amplifier (OPAMP) */ +/* */ +/******************************************************************************/ +/******************* Bit definition for OPAMP_CSR register ******************/ +#define OPAMP_CSR_OPA1PD ((uint32_t)0x00000001) /*!< OPAMP1 disable */ +#define OPAMP_CSR_S3SEL1 ((uint32_t)0x00000002) /*!< Switch 3 for OPAMP1 Enable */ +#define OPAMP_CSR_S4SEL1 ((uint32_t)0x00000004) /*!< Switch 4 for OPAMP1 Enable */ +#define OPAMP_CSR_S5SEL1 ((uint32_t)0x00000008) /*!< Switch 5 for OPAMP1 Enable */ +#define OPAMP_CSR_S6SEL1 ((uint32_t)0x00000010) /*!< Switch 6 for OPAMP1 Enable */ +#define OPAMP_CSR_OPA1CAL_L ((uint32_t)0x00000020) /*!< OPAMP1 Offset calibration for P differential pair */ +#define OPAMP_CSR_OPA1CAL_H ((uint32_t)0x00000040) /*!< OPAMP1 Offset calibration for N differential pair */ +#define OPAMP_CSR_OPA1LPM ((uint32_t)0x00000080) /*!< OPAMP1 Low power enable */ +#define OPAMP_CSR_OPA2PD ((uint32_t)0x00000100) /*!< OPAMP2 disable */ +#define OPAMP_CSR_S3SEL2 ((uint32_t)0x00000200) /*!< Switch 3 for OPAMP2 Enable */ +#define OPAMP_CSR_S4SEL2 ((uint32_t)0x00000400) /*!< Switch 4 for OPAMP2 Enable */ +#define OPAMP_CSR_S5SEL2 ((uint32_t)0x00000800) /*!< Switch 5 for OPAMP2 Enable */ +#define OPAMP_CSR_S6SEL2 ((uint32_t)0x00001000) /*!< Switch 6 for OPAMP2 Enable */ +#define OPAMP_CSR_OPA2CAL_L ((uint32_t)0x00002000) /*!< OPAMP2 Offset calibration for P differential pair */ +#define OPAMP_CSR_OPA2CAL_H ((uint32_t)0x00004000) /*!< OPAMP2 Offset calibration for N differential pair */ +#define OPAMP_CSR_OPA2LPM ((uint32_t)0x00008000) /*!< OPAMP2 Low power enable */ +#define OPAMP_CSR_OPA3PD ((uint32_t)0x00010000) /*!< OPAMP3 disable */ +#define OPAMP_CSR_S3SEL3 ((uint32_t)0x00020000) /*!< Switch 3 for OPAMP3 Enable */ +#define OPAMP_CSR_S4SEL3 ((uint32_t)0x00040000) /*!< Switch 4 for OPAMP3 Enable */ +#define OPAMP_CSR_S5SEL3 ((uint32_t)0x00080000) /*!< Switch 5 for OPAMP3 Enable */ +#define OPAMP_CSR_S6SEL3 ((uint32_t)0x00100000) /*!< Switch 6 for OPAMP3 Enable */ +#define OPAMP_CSR_OPA3CAL_L ((uint32_t)0x00200000) /*!< OPAMP3 Offset calibration for P differential pair */ +#define OPAMP_CSR_OPA3CAL_H ((uint32_t)0x00400000) /*!< OPAMP3 Offset calibration for N differential pair */ +#define OPAMP_CSR_OPA3LPM ((uint32_t)0x00800000) /*!< OPAMP3 Low power enable */ +#define OPAMP_CSR_ANAWSEL1 ((uint32_t)0x01000000) /*!< Switch ANA Enable for OPAMP1 */ +#define OPAMP_CSR_ANAWSEL2 ((uint32_t)0x02000000) /*!< Switch ANA Enable for OPAMP2 */ +#define OPAMP_CSR_ANAWSEL3 ((uint32_t)0x04000000) /*!< Switch ANA Enable for OPAMP3 */ +#define OPAMP_CSR_S7SEL2 ((uint32_t)0x08000000) /*!< Switch 7 for OPAMP2 Enable */ +#define OPAMP_CSR_AOP_RANGE ((uint32_t)0x10000000) /*!< Power range selection */ +#define OPAMP_CSR_OPA1CALOUT ((uint32_t)0x20000000) /*!< OPAMP1 calibration output */ +#define OPAMP_CSR_OPA2CALOUT ((uint32_t)0x40000000) /*!< OPAMP2 calibration output */ +#define OPAMP_CSR_OPA3CALOUT ((uint32_t)0x80000000) /*!< OPAMP3 calibration output */ + +/******************* Bit definition for OPAMP_OTR register ******************/ +#define OPAMP_OTR_AO1_OPT_OFFSET_TRIM ((uint32_t)0x000003FF) /*!< Offset trim for OPAMP1 */ +#define OPAMP_OTR_AO2_OPT_OFFSET_TRIM ((uint32_t)0x000FFC00) /*!< Offset trim for OPAMP2 */ +#define OPAMP_OTR_AO3_OPT_OFFSET_TRIM ((uint32_t)0x3FF00000) /*!< Offset trim for OPAMP2 */ +#define OPAMP_OTR_OT_USER ((uint32_t)0x80000000) /*!< Switch to OPAMP offset user trimmed values */ + +/******************* Bit definition for OPAMP_LPOTR register ****************/ +#define OPAMP_LP_OTR_AO1_OPT_OFFSET_TRIM_LP ((uint32_t)0x000003FF) /*!< Offset trim in low power for OPAMP1 */ +#define OPAMP_LP_OTR_AO2_OPT_OFFSET_TRIM_LP ((uint32_t)0x000FFC00) /*!< Offset trim in low power for OPAMP2 */ +#define OPAMP_LP_OTR_AO3_OPT_OFFSET_TRIM_LP ((uint32_t)0x3FF00000) /*!< Offset trim in low power for OPAMP3 */ + +/******************************************************************************/ +/* */ +/* CRC calculation unit (CRC) */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for CRC_DR register *********************/ +#define CRC_DR_DR ((uint32_t)0xFFFFFFFF) /*!< Data register bits */ + +/******************* Bit definition for CRC_IDR register ********************/ +#define CRC_IDR_IDR ((uint8_t)0xFF) /*!< General-purpose 8-bit data register bits */ + +/******************** Bit definition for CRC_CR register ********************/ +#define CRC_CR_RESET ((uint32_t)0x00000001) /*!< RESET bit */ + +/******************************************************************************/ +/* */ +/* Digital to Analog Converter (DAC) */ +/* */ +/******************************************************************************/ + +/******************** Bit definition for DAC_CR register ********************/ +#define DAC_CR_EN1 ((uint32_t)0x00000001) /*!
© COPYRIGHT 2013 STMicroelectronics
+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_adc.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup ADC + * @brief ADC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* ADC DISCNUM mask */ +#define CR1_DISCNUM_RESET ((uint32_t)0xFFFF1FFF) + +/* ADC AWDCH mask */ +#define CR1_AWDCH_RESET ((uint32_t)0xFFFFFFE0) + +/* ADC Analog watchdog enable mode mask */ +#define CR1_AWDMODE_RESET ((uint32_t)0xFF3FFDFF) + +/* CR1 register Mask */ +#define CR1_CLEAR_MASK ((uint32_t)0xFCFFFEFF) + +/* ADC DELAY mask */ +#define CR2_DELS_RESET ((uint32_t)0xFFFFFF0F) + +/* ADC JEXTEN mask */ +#define CR2_JEXTEN_RESET ((uint32_t)0xFFCFFFFF) + +/* ADC JEXTSEL mask */ +#define CR2_JEXTSEL_RESET ((uint32_t)0xFFF0FFFF) + +/* CR2 register Mask */ +#define CR2_CLEAR_MASK ((uint32_t)0xC0FFF7FD) + +/* ADC SQx mask */ +#define SQR5_SQ_SET ((uint32_t)0x0000001F) +#define SQR4_SQ_SET ((uint32_t)0x0000001F) +#define SQR3_SQ_SET ((uint32_t)0x0000001F) +#define SQR2_SQ_SET ((uint32_t)0x0000001F) +#define SQR1_SQ_SET ((uint32_t)0x0000001F) + +/* ADC L Mask */ +#define SQR1_L_RESET ((uint32_t)0xFE0FFFFF) + +/* ADC JSQx mask */ +#define JSQR_JSQ_SET ((uint32_t)0x0000001F) + +/* ADC JL mask */ +#define JSQR_JL_SET ((uint32_t)0x00300000) +#define JSQR_JL_RESET ((uint32_t)0xFFCFFFFF) + +/* ADC SMPx mask */ +#define SMPR1_SMP_SET ((uint32_t)0x00000007) +#define SMPR2_SMP_SET ((uint32_t)0x00000007) +#define SMPR3_SMP_SET ((uint32_t)0x00000007) +#define SMPR0_SMP_SET ((uint32_t)0x00000007) + +/* ADC JDRx registers offset */ +#define JDR_OFFSET ((uint8_t)0x30) + +/* ADC CCR register Mask */ +#define CR_CLEAR_MASK ((uint32_t)0xFFFCFFFF) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup ADC_Private_Functions + * @{ + */ + +/** @defgroup ADC_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions. + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the ADC Prescaler. + (+) ADC Conversion Resolution (12bit..6bit). + (+) Scan Conversion Mode (multichannel or one channel) for regular group. + (+) ADC Continuous Conversion Mode (Continuous or Single conversion) for + regular group. + (+) External trigger Edge and source of regular group. + (+) Converted data alignment (left or right). + (+) The number of ADC conversions that will be done using the sequencer + for regular channel group. + (+) Enable or disable the ADC peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes ADC1 peripheral registers to their default reset values. + * @param None + * @retval None + */ +void ADC_DeInit(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + if(ADCx == ADC1) + { + /* Enable ADC1 reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE); + /* Release ADC1 from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE); + } +} + +/** + * @brief Initializes the ADCx peripheral according to the specified parameters + * in the ADC_InitStruct. + * @note This function is used to configure the global features of the ADC ( + * Resolution and Data Alignment), however, the rest of the configuration + * parameters are specific to the regular channels group (scan mode + * activation, continuous mode activation, External trigger source and + * edge, number of conversion in the regular channels group sequencer). + * @param ADCx: where x can be 1 to select the ADC peripheral. + * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains + * the configuration information for the specified ADC peripheral. + * @retval None + */ +void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) +{ + uint32_t tmpreg1 = 0; + uint8_t tmpreg2 = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->ADC_Resolution)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge)); + assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv)); + assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); + assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfConversion)); + + /*---------------------------- ADCx CR1 Configuration -----------------*/ + /* Get the ADCx CR1 value */ + tmpreg1 = ADCx->CR1; + /* Clear RES and SCAN bits */ + tmpreg1 &= CR1_CLEAR_MASK; + /* Configure ADCx: scan conversion mode and resolution */ + /* Set SCAN bit according to ADC_ScanConvMode value */ + /* Set RES bit according to ADC_Resolution value */ + tmpreg1 |= (uint32_t)(((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8) | ADC_InitStruct->ADC_Resolution); + /* Write to ADCx CR1 */ + ADCx->CR1 = tmpreg1; + + /*---------------------------- ADCx CR2 Configuration -----------------*/ + /* Get the ADCx CR2 value */ + tmpreg1 = ADCx->CR2; + /* Clear CONT, ALIGN, EXTEN and EXTSEL bits */ + tmpreg1 &= CR2_CLEAR_MASK; + /* Configure ADCx: external trigger event and edge, data alignment and continuous conversion mode */ + /* Set ALIGN bit according to ADC_DataAlign value */ + /* Set EXTEN bits according to ADC_ExternalTrigConvEdge value */ + /* Set EXTSEL bits according to ADC_ExternalTrigConv value */ + /* Set CONT bit according to ADC_ContinuousConvMode value */ + tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ExternalTrigConv | + ADC_InitStruct->ADC_ExternalTrigConvEdge | ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1)); + /* Write to ADCx CR2 */ + ADCx->CR2 = tmpreg1; + + /*---------------------------- ADCx SQR1 Configuration -----------------*/ + /* Get the ADCx SQR1 value */ + tmpreg1 = ADCx->SQR1; + /* Clear L bits */ + tmpreg1 &= SQR1_L_RESET; + /* Configure ADCx: regular channel sequence length */ + /* Set L bits according to ADC_NbrOfConversion value */ + tmpreg2 |= (uint8_t)(ADC_InitStruct->ADC_NbrOfConversion - (uint8_t)1); + tmpreg1 |= ((uint32_t)tmpreg2 << 20); + /* Write to ADCx SQR1 */ + ADCx->SQR1 = tmpreg1; +} + +/** + * @brief Fills each ADC_InitStruct member with its default value. + * @note This function is used to initialize the global features of the ADC ( + * Resolution and Data Alignment), however, the rest of the configuration + * parameters are specific to the regular channels group (scan mode + * activation, continuous mode activation, External trigger source and + * edge, number of conversion in the regular channels group sequencer). + * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) +{ + /* Reset ADC init structure parameters values */ + /* Initialize the ADC_Resolution member */ + ADC_InitStruct->ADC_Resolution = ADC_Resolution_12b; + + /* Initialize the ADC_ScanConvMode member */ + ADC_InitStruct->ADC_ScanConvMode = DISABLE; + + /* Initialize the ADC_ContinuousConvMode member */ + ADC_InitStruct->ADC_ContinuousConvMode = DISABLE; + + /* Initialize the ADC_ExternalTrigConvEdge member */ + ADC_InitStruct->ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; + + /* Initialize the ADC_ExternalTrigConv member */ + ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; + + /* Initialize the ADC_DataAlign member */ + ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right; + + /* Initialize the ADC_NbrOfConversion member */ + ADC_InitStruct->ADC_NbrOfConversion = 1; +} + +/** + * @brief Initializes the ADCs peripherals according to the specified parameters + * in the ADC_CommonInitStruct. + * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure + * that contains the configuration information (Prescaler) for ADC1 peripheral. + * @retval None + */ +void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ADC_PRESCALER(ADC_CommonInitStruct->ADC_Prescaler)); + + /*---------------------------- ADC CCR Configuration -----------------*/ + /* Get the ADC CCR value */ + tmpreg = ADC->CCR; + + /* Clear ADCPRE bit */ + tmpreg &= CR_CLEAR_MASK; + + /* Configure ADCx: ADC prescaler according to ADC_Prescaler */ + tmpreg |= (uint32_t)(ADC_CommonInitStruct->ADC_Prescaler); + + /* Write to ADC CCR */ + ADC->CCR = tmpreg; +} + +/** + * @brief Fills each ADC_CommonInitStruct member with its default value. + * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure + * which will be initialized. + * @retval None + */ +void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) +{ + /* Reset ADC init structure parameters values */ + /* Initialize the ADC_Prescaler member */ + ADC_CommonInitStruct->ADC_Prescaler = ADC_Prescaler_Div1; +} + +/** + * @brief Enables or disables the specified ADC peripheral. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the ADCx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the ADON bit to wake up the ADC from power down mode */ + ADCx->CR2 |= (uint32_t)ADC_CR2_ADON; + } + else + { + /* Disable the selected ADC peripheral */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_ADON); + } +} + +/** + * @brief Selects the specified ADC Channels Bank. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_Bank: ADC Channels Bank. + * @arg ADC_Bank_A: ADC Channels Bank A. + * @arg ADC_Bank_B: ADC Channels Bank B. + * @retval None + */ +void ADC_BankSelection(ADC_TypeDef* ADCx, uint8_t ADC_Bank) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_BANK(ADC_Bank)); + + if (ADC_Bank != ADC_Bank_A) + { + /* Set the ADC_CFG bit to select the ADC Bank B channels */ + ADCx->CR2 |= (uint32_t)ADC_CR2_CFG; + } + else + { + /* Reset the ADC_CFG bit to select the ADC Bank A channels */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_CFG); + } +} + +/** + * @} + */ + +/** @defgroup ADC_Group2 Power saving functions + * @brief Power saving functions + * +@verbatim + =============================================================================== + ##### Power saving functions ##### + =============================================================================== + [..] This section provides functions allowing to reduce power consumption. + [..] The two function must be combined to get the maximal benefits: + When the ADC frequency is higher than the CPU one, it is recommended to: + (#) Insert a freeze delay : + ==> using ADC_DelaySelectionConfig(ADC1, ADC_DelayLength_Freeze). + (#) Enable the power down in Idle and Delay phases : + ==> using ADC_PowerDownCmd(ADC1, ADC_PowerDown_Idle_Delay, ENABLE). + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the ADC Power Down during Delay and/or Idle phase. + * @note ADC power-on and power-off can be managed by hardware to cut the + * consumption when the ADC is not converting. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_PowerDown: The ADC power down configuration. + * This parameter can be one of the following values: + * @arg ADC_PowerDown_Delay: ADC is powered down during delay phase. + * @arg ADC_PowerDown_Idle: ADC is powered down during Idle phase. + * @arg ADC_PowerDown_Idle_Delay: ADC is powered down during Delay and Idle phases. + * @note The ADC can be powered down: + * @note During the hardware delay insertion (using the ADC_PowerDown_Delay + * parameter). + * => The ADC is powered up again at the end of the delay. + * @note During the ADC is waiting for a trigger event ( using the + * ADC_PowerDown_Idle parameter). + * => The ADC is powered up at the next trigger event. + * @note During the hardware delay insertion or the ADC is waiting for a + * trigger event (using the ADC_PowerDown_Idle_Delay parameter). + * => The ADC is powered up only at the end of the delay and at the + * next trigger event. + * @param NewState: new state of the ADCx power down. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_PowerDownCmd(ADC_TypeDef* ADCx, uint32_t ADC_PowerDown, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_ADC_POWER_DOWN(ADC_PowerDown)); + + if (NewState != DISABLE) + { + /* Enable the ADC power-down during Delay and/or Idle phase */ + ADCx->CR1 |= ADC_PowerDown; + } + else + { + /* Disable The ADC power-down during Delay and/or Idle phase */ + ADCx->CR1 &= (uint32_t)~ADC_PowerDown; + } +} + +/** + * @brief Defines the length of the delay which is applied after a conversion + * or a sequence of conversion. + * @note When the CPU clock is not fast enough to manage the data rate, a + * Hardware delay can be introduced between ADC conversions to reduce + * this data rate. + * @note The Hardware delay is inserted after : + * - each regular conversion. + * - after each sequence of injected conversions. + * @note No Hardware delay is inserted between conversions of different groups. + * @note When the hardware delay is not enough, the Freeze Delay Mode can be + * selected and a new conversion can start only if all the previous data + * of the same group have been treated: + * - for a regular conversion: once the ADC conversion data register has + * been read (using ADC_GetConversionValue() function) or if the EOC + * Flag has been cleared (using ADC_ClearFlag() function). + * - for an injected conversion: when the JEOC bit has been cleared + * (using ADC_ClearFlag() function). + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_DelayLength: The length of delay which is applied after a + * conversion or a sequence of conversion. + * This parameter can be one of the following values: + * @arg ADC_DelayLength_None: No delay. + * @arg ADC_DelayLength_Freeze: Delay until the converted data has been read. + * @arg ADC_DelayLength_7Cycles: Delay length equal to 7 APB clock cycles. + * @arg ADC_DelayLength_15Cycles: Delay length equal to 15 APB clock cycles + * @arg ADC_DelayLength_31Cycles: Delay length equal to 31 APB clock cycles + * @arg ADC_DelayLength_63Cycles: Delay length equal to 63 APB clock cycles + * @arg ADC_DelayLength_127Cycles: Delay length equal to 127 APB clock cycles + * @arg ADC_DelayLength_255Cycles: Delay length equal to 255 APB clock cycles + * @retval None + */ +void ADC_DelaySelectionConfig(ADC_TypeDef* ADCx, uint8_t ADC_DelayLength) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_DELAY_LENGTH(ADC_DelayLength)); + + /* Get the old register value */ + tmpreg = ADCx->CR2; + /* Clear the old delay length */ + tmpreg &= CR2_DELS_RESET; + /* Set the delay length */ + tmpreg |= ADC_DelayLength; + /* Store the new register value */ + ADCx->CR2 = tmpreg; + +} + +/** + * @} + */ + +/** @defgroup ADC_Group3 Analog Watchdog configuration functions + * @brief Analog Watchdog configuration functions. + * +@verbatim + =============================================================================== + ##### Analog Watchdog configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to configure the Analog Watchdog + (AWD) feature in the ADC. + [..] A typical configuration Analog Watchdog is done following these steps : + (#) the ADC guarded channel(s) is (are) selected using the + ADC_AnalogWatchdogSingleChannelConfig() function. + (#) The Analog watchdog lower and higher threshold are configured using + the ADC_AnalogWatchdogThresholdsConfig() function. + (#) The Analog watchdog is enabled and configured to enable the check, + on one or more channels, using the ADC_AnalogWatchdogCmd() function. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the analog watchdog on single/all regular + * or injected channels. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_AnalogWatchdog: the ADC analog watchdog configuration. + * This parameter can be one of the following values: + * @arg ADC_AnalogWatchdog_SingleRegEnable: Analog watchdog on a single + * regular channel. + * @arg ADC_AnalogWatchdog_SingleInjecEnable: Analog watchdog on a single + * injected channel. + * @arg ADC_AnalogWatchdog_SingleRegOrInjecEnable: Analog watchdog on a + * single regular or injected channel. + * @arg ADC_AnalogWatchdog_AllRegEnable: Analog watchdog on all regular + * channel. + * @arg ADC_AnalogWatchdog_AllInjecEnable: Analog watchdog on all injected + * channel. + * @arg ADC_AnalogWatchdog_AllRegAllInjecEnable: Analog watchdog on all + * regular and injected channels. + * @arg ADC_AnalogWatchdog_None: No channel guarded by the analog watchdog. + * @retval None + */ +void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_ANALOG_WATCHDOG(ADC_AnalogWatchdog)); + + /* Get the old register value */ + tmpreg = ADCx->CR1; + /* Clear AWDEN, JAWDEN and AWDSGL bits */ + tmpreg &= CR1_AWDMODE_RESET; + /* Set the analog watchdog enable mode */ + tmpreg |= ADC_AnalogWatchdog; + /* Store the new register value */ + ADCx->CR1 = tmpreg; +} + +/** + * @brief Configures the high and low thresholds of the analog watchdog. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param HighThreshold: the ADC analog watchdog High threshold value. + * This parameter must be a 12bit value. + * @param LowThreshold: the ADC analog watchdog Low threshold value. + * This parameter must be a 12bit value. + * @retval None + */ +void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, + uint16_t LowThreshold) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_THRESHOLD(HighThreshold)); + assert_param(IS_ADC_THRESHOLD(LowThreshold)); + + /* Set the ADCx high threshold */ + ADCx->HTR = HighThreshold; + /* Set the ADCx low threshold */ + ADCx->LTR = LowThreshold; +} + +/** + * @brief Configures the analog watchdog guarded single channel. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_Channel: the ADC channel to configure for the analog watchdog. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @arg ADC_Channel_18: ADC Channel18 selected + * @arg ADC_Channel_19: ADC Channel19 selected + * @arg ADC_Channel_20: ADC Channel20 selected + * @arg ADC_Channel_21: ADC Channel21 selected + * @arg ADC_Channel_22: ADC Channel22 selected + * @arg ADC_Channel_23: ADC Channel23 selected + * @arg ADC_Channel_24: ADC Channel24 selected + * @arg ADC_Channel_25: ADC Channel25 selected + * @arg ADC_Channel_27: ADC Channel27 selected + * @arg ADC_Channel_28: ADC Channel28 selected + * @arg ADC_Channel_29: ADC Channel29 selected + * @arg ADC_Channel_30: ADC Channel30 selected + * @arg ADC_Channel_31: ADC Channel31 selected + * @arg ADC_Channel_0b: ADC Channel0b selected + * @arg ADC_Channel_1b: ADC Channel1b selected + * @arg ADC_Channel_2b: ADC Channel2b selected + * @arg ADC_Channel_3b: ADC Channel3b selected + * @arg ADC_Channel_6b: ADC Channel6b selected + * @arg ADC_Channel_7b: ADC Channel7b selected + * @arg ADC_Channel_8b: ADC Channel8b selected + * @arg ADC_Channel_9b: ADC Channel9b selected + * @arg ADC_Channel_10b: ADC Channel10b selected + * @arg ADC_Channel_11b: ADC Channel11b selected + * @arg ADC_Channel_12b: ADC Channel12b selected + * @retval None + */ +void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + + /* Get the old register value */ + tmpreg = ADCx->CR1; + /* Clear the Analog watchdog channel select bits */ + tmpreg &= CR1_AWDCH_RESET; + /* Set the Analog watchdog channel */ + tmpreg |= ADC_Channel; + /* Store the new register value */ + ADCx->CR1 = tmpreg; +} + +/** + * @} + */ + +/** @defgroup ADC_Group4 Temperature Sensor & Vrefint (Voltage Reference internal) management function + * @brief Temperature Sensor & Vrefint (Voltage Reference internal) management function. + * +@verbatim + ========================================================================================= + ##### Temperature Sensor and Vrefint (Voltage Reference internal) management function ##### + ========================================================================================= + [..] This section provides a function allowing to enable/ disable the internal + connections between the ADC and the Temperature Sensor and the Vrefint + source. + [..] A typical configuration to get the Temperature sensor and Vrefint channels + voltages is done following these steps : + (#) Enable the internal connection of Temperature sensor and Vrefint sources + with the ADC channels using ADC_TempSensorVrefintCmd() function. + (#) select the ADC_Channel_TempSensor and/or ADC_Channel_Vrefint using + ADC_RegularChannelConfig() or ADC_InjectedChannelConfig() functions. + (#) Get the voltage values, using ADC_GetConversionValue() or + ADC_GetInjectedConversionValue(). +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the temperature sensor and Vrefint channel. + * @param NewState: new state of the temperature sensor and Vref int channels. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_TempSensorVrefintCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the temperature sensor and Vrefint channel*/ + ADC->CCR |= (uint32_t)ADC_CCR_TSVREFE; + } + else + { + /* Disable the temperature sensor and Vrefint channel*/ + ADC->CCR &= (uint32_t)(~ADC_CCR_TSVREFE); + } +} + +/** + * @} + */ + +/** @defgroup ADC_Group5 Regular Channels Configuration functions + * @brief Regular Channels Configuration functions. + * +@verbatim + =============================================================================== + ##### Regular Channels Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to manage the ADC regular channels, + it is composed of 2 sub sections : + (#) Configuration and management functions for regular channels: This + subsection provides functions allowing to configure the ADC regular + channels : + (++) Configure the rank in the regular group sequencer for each channel. + (++) Configure the sampling time for each channel. + (++) select the conversion Trigger for regular channels. + (++) select the desired EOC event behavior configuration. + (++) Activate the continuous Mode (*). + (++) Activate the Discontinuous Mode. + -@@- Please Note that the following features for regular channels are + configurated using the ADC_Init() function : + (+@@) scan mode activation. + (+@@) continuous mode activation (**). + (+@@) External trigger source. + (+@@) External trigger edge. + (+@@) number of conversion in the regular channels group sequencer. + -@@- (*) and (**) are performing the same configuration. + (#) Get the conversion data: This subsection provides an important function + in the ADC peripheral since it returns the converted data of the current + regular channel. When the Conversion value is read, the EOC Flag is + automatically cleared. +@endverbatim + * @{ + */ + +/** + * @brief Configures for the selected ADC regular channel its corresponding + * rank in the sequencer and its sampling time. + * @param ADCx: where x can be 1 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @arg ADC_Channel_18: ADC Channel18 selected + * @arg ADC_Channel_19: ADC Channel19 selected + * @arg ADC_Channel_20: ADC Channel20 selected + * @arg ADC_Channel_21: ADC Channel21 selected + * @arg ADC_Channel_22: ADC Channel22 selected + * @arg ADC_Channel_23: ADC Channel23 selected + * @arg ADC_Channel_24: ADC Channel24 selected + * @arg ADC_Channel_25: ADC Channel25 selected + * @arg ADC_Channel_27: ADC Channel27 selected + * @arg ADC_Channel_28: ADC Channel28 selected + * @arg ADC_Channel_29: ADC Channel29 selected + * @arg ADC_Channel_30: ADC Channel30 selected + * @arg ADC_Channel_31: ADC Channel31 selected + * @arg ADC_Channel_0b: ADC Channel0b selected + * @arg ADC_Channel_1b: ADC Channel1b selected + * @arg ADC_Channel_2b: ADC Channel2b selected + * @arg ADC_Channel_3b: ADC Channel3b selected + * @arg ADC_Channel_6b: ADC Channel6b selected + * @arg ADC_Channel_7b: ADC Channel7b selected + * @arg ADC_Channel_8b: ADC Channel8b selected + * @arg ADC_Channel_9b: ADC Channel9b selected + * @arg ADC_Channel_10b: ADC Channel10b selected + * @arg ADC_Channel_11b: ADC Channel11b selected + * @arg ADC_Channel_12b: ADC Channel12b selected + * @param Rank: The rank in the regular group sequencer. This parameter + * must be between 1 to 28. + * @param ADC_SampleTime: The sample time value to be set for the selected + * channel. + * This parameter can be one of the following values: + * @arg ADC_SampleTime_4Cycles: Sample time equal to 4 cycles + * @arg ADC_SampleTime_9Cycles: Sample time equal to 9 cycles + * @arg ADC_SampleTime_16Cycles: Sample time equal to 16 cycles + * @arg ADC_SampleTime_24Cycles: Sample time equal to 24 cycles + * @arg ADC_SampleTime_48Cycles: Sample time equal to 48 cycles + * @arg ADC_SampleTime_96Cycles: Sample time equal to 96 cycles + * @arg ADC_SampleTime_192Cycles: Sample time equal to 192 cycles + * @arg ADC_SampleTime_384Cycles: Sample time equal to 384 cycles + * @retval None + */ +void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + assert_param(IS_ADC_REGULAR_RANK(Rank)); + assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); + + /* If ADC_Channel_30 or ADC_Channel_31 is selected */ + if (ADC_Channel > ADC_Channel_29) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR0; + /* Calculate the mask to clear */ + tmpreg2 = SMPR0_SMP_SET << (3 * (ADC_Channel - 30)); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 30)); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR0 = tmpreg1; + } + /* If ADC_Channel_20 ... ADC_Channel_29 is selected */ + else if (ADC_Channel > ADC_Channel_19) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR1; + /* Calculate the mask to clear */ + tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 20)); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 20)); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR1 = tmpreg1; + } + /* If ADC_Channel_10 ... ADC_Channel_19 is selected */ + else if (ADC_Channel > ADC_Channel_9) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR2; + /* Calculate the mask to clear */ + tmpreg2 = SMPR2_SMP_SET << (3 * (ADC_Channel - 10)); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR2 = tmpreg1; + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR3; + /* Calculate the mask to clear */ + tmpreg2 = SMPR3_SMP_SET << (3 * ADC_Channel); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR3 = tmpreg1; + } + /* For Rank 1 to 6 */ + if (Rank < 7) + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR5; + /* Calculate the mask to clear */ + tmpreg2 = SQR5_SQ_SET << (5 * (Rank - 1)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SQR5 = tmpreg1; + } + /* For Rank 7 to 12 */ + else if (Rank < 13) + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR4; + /* Calculate the mask to clear */ + tmpreg2 = SQR4_SQ_SET << (5 * (Rank - 7)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SQR4 = tmpreg1; + } + /* For Rank 13 to 18 */ + else if (Rank < 19) + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR3; + /* Calculate the mask to clear */ + tmpreg2 = SQR3_SQ_SET << (5 * (Rank - 13)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SQR3 = tmpreg1; + } + + /* For Rank 19 to 24 */ + else if (Rank < 25) + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR2; + /* Calculate the mask to clear */ + tmpreg2 = SQR2_SQ_SET << (5 * (Rank - 19)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 19)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SQR2 = tmpreg1; + } + + /* For Rank 25 to 28 */ + else + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR1; + /* Calculate the mask to clear */ + tmpreg2 = SQR1_SQ_SET << (5 * (Rank - 25)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 25)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SQR1 = tmpreg1; + } +} + +/** + * @brief Enables the selected ADC software start conversion of the regular channels. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @retval None + */ +void ADC_SoftwareStartConv(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Enable the selected ADC conversion for regular group */ + ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; +} + +/** + * @brief Gets the selected ADC Software start regular conversion Status. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @retval The new state of ADC software start conversion (SET or RESET). + */ +FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Check the status of SWSTART bit */ + if ((ADCx->CR2 & ADC_CR2_SWSTART) != (uint32_t)RESET) + { + /* SWSTART bit is set */ + bitstatus = SET; + } + else + { + /* SWSTART bit is reset */ + bitstatus = RESET; + } + /* Return the SWSTART bit status */ + return bitstatus; +} + +/** + * @brief Enables or disables the EOC on each regular channel conversion. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the selected ADC EOC flag rising + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC EOC rising on each regular channel conversion */ + ADCx->CR2 |= ADC_CR2_EOCS; + } + else + { + /* Disable the selected ADC EOC rising on each regular channel conversion */ + ADCx->CR2 &= (uint32_t)~ADC_CR2_EOCS; + } +} + +/** + * @brief Enables or disables the ADC continuous conversion mode. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the selected ADC continuous conversion mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC continuous conversion mode */ + ADCx->CR2 |= (uint32_t)ADC_CR2_CONT; + } + else + { + /* Disable the selected ADC continuous conversion mode */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_CONT); + } +} + +/** + * @brief Configures the discontinuous mode for the selected ADC regular + * group channel. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param Number: specifies the discontinuous mode regular channel count value. + * This number must be between 1 and 8. + * @retval None + */ +void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number) +{ + uint32_t tmpreg1 = 0; + uint32_t tmpreg2 = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number)); + + /* Get the old register value */ + tmpreg1 = ADCx->CR1; + /* Clear the old discontinuous mode channel count */ + tmpreg1 &= CR1_DISCNUM_RESET; + /* Set the discontinuous mode channel count */ + tmpreg2 = Number - 1; + tmpreg1 |= tmpreg2 << 13; + /* Store the new register value */ + ADCx->CR1 = tmpreg1; +} + +/** + * @brief Enables or disables the discontinuous mode on regular group + * channel for the specified ADC. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the selected ADC discontinuous mode on regular + * group channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC regular discontinuous mode */ + ADCx->CR1 |= (uint32_t)ADC_CR1_DISCEN; + } + else + { + /* Disable the selected ADC regular discontinuous mode */ + ADCx->CR1 &= (uint32_t)(~ADC_CR1_DISCEN); + } +} + +/** + * @brief Returns the last ADCx conversion result data for regular channel. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @retval The Data conversion value. + */ +uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Return the selected ADC conversion value */ + return (uint16_t) ADCx->DR; +} + +/** + * @} + */ + +/** @defgroup ADC_Group6 Regular Channels DMA Configuration functions + * @brief Regular Channels DMA Configuration functions. + * +@verbatim + =============================================================================== + ##### Regular Channels DMA Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to configure the DMA for ADC regular + channels.Since converted regular channel values are stored into a unique + data register, it is useful to use DMA for conversion of more than one + regular channel. This avoids the loss of the data already stored in the + ADC Data register. + When the DMA mode is enabled (using the ADC_DMACmd() function), after each + conversion of a regular channel, a DMA request is generated. + [..] Depending on the "DMA disable selection" configuration (using the + ADC_DMARequestAfterLastTransferCmd() function), at the end of the last DMA + transfer, two possibilities are allowed: + (+) No new DMA request is issued to the DMA controller (feature DISABLED). + (+) Requests can continue to be generated (feature ENABLED). + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified ADC DMA request. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the selected ADC DMA transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_DMA_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC DMA request */ + ADCx->CR2 |= (uint32_t)ADC_CR2_DMA; + } + else + { + /* Disable the selected ADC DMA request */ + ADCx->CR2 &= (uint32_t)(~ADC_CR2_DMA); + } +} + + +/** + * @brief Enables or disables the ADC DMA request after last transfer (Single-ADC mode). + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the selected ADC EOC flag rising + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC DMA request after last transfer */ + ADCx->CR2 |= ADC_CR2_DDS; + } + else + { + /* Disable the selected ADC DMA request after last transfer */ + ADCx->CR2 &= (uint32_t)~ADC_CR2_DDS; + } +} + +/** + * @} + */ + +/** @defgroup ADC_Group7 Injected channels Configuration functions + * @brief Injected channels Configuration functions. + * +@verbatim + =============================================================================== + ##### Injected channels Configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to configure the ADC Injected channels, + it is composed of 2 sub sections : + (#) Configuration functions for Injected channels: This subsection provides + functions allowing to configure the ADC injected channels : + (++) Configure the rank in the injected group sequencer for each channel. + (++) Configure the sampling time for each channel. + (++) Activate the Auto injected Mode. + (++) Activate the Discontinuous Mode. + (++) scan mode activation. + (++) External/software trigger source. + (++) External trigger edge. + (++) injected channels sequencer. + + (#) Get the Specified Injected channel conversion data: This subsection + provides an important function in the ADC peripheral since it returns + the converted data of the specific injected channel. + +@endverbatim + * @{ + */ + +/** + * @brief Configures for the selected ADC injected channel its corresponding + * rank in the sequencer and its sample time. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_Channel: the ADC channel to configure. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @arg ADC_Channel_18: ADC Channel18 selected + * @arg ADC_Channel_19: ADC Channel19 selected + * @arg ADC_Channel_20: ADC Channel20 selected + * @arg ADC_Channel_21: ADC Channel21 selected + * @arg ADC_Channel_22: ADC Channel22 selected + * @arg ADC_Channel_23: ADC Channel23 selected + * @arg ADC_Channel_24: ADC Channel24 selected + * @arg ADC_Channel_25: ADC Channel25 selected + * @arg ADC_Channel_27: ADC Channel27 selected + * @arg ADC_Channel_28: ADC Channel28 selected + * @arg ADC_Channel_29: ADC Channel29 selected + * @arg ADC_Channel_30: ADC Channel30 selected + * @arg ADC_Channel_31: ADC Channel31 selected + * @arg ADC_Channel_0b: ADC Channel0b selected + * @arg ADC_Channel_1b: ADC Channel1b selected + * @arg ADC_Channel_2b: ADC Channel2b selected + * @arg ADC_Channel_3b: ADC Channel3b selected + * @arg ADC_Channel_6b: ADC Channel6b selected + * @arg ADC_Channel_7b: ADC Channel7b selected + * @arg ADC_Channel_8b: ADC Channel8b selected + * @arg ADC_Channel_9b: ADC Channel9b selected + * @arg ADC_Channel_10b: ADC Channel10b selected + * @arg ADC_Channel_11b: ADC Channel11b selected + * @arg ADC_Channel_12b: ADC Channel12b selected + * @param Rank: The rank in the injected group sequencer. This parameter + * must be between 1 to 4. + * @param ADC_SampleTime: The sample time value to be set for the selected + * channel. This parameter can be one of the following values: + * @arg ADC_SampleTime_4Cycles: Sample time equal to 4 cycles + * @arg ADC_SampleTime_9Cycles: Sample time equal to 9 cycles + * @arg ADC_SampleTime_16Cycles: Sample time equal to 16 cycles + * @arg ADC_SampleTime_24Cycles: Sample time equal to 24 cycles + * @arg ADC_SampleTime_48Cycles: Sample time equal to 48 cycles + * @arg ADC_SampleTime_96Cycles: Sample time equal to 96 cycles + * @arg ADC_SampleTime_192Cycles: Sample time equal to 192 cycles + * @arg ADC_SampleTime_384Cycles: Sample time equal to 384 cycles + * @retval None + */ +void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + assert_param(IS_ADC_INJECTED_RANK(Rank)); + assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); + + /* If ADC_Channel_30 or ADC_Channel_31 is selected */ + if (ADC_Channel > ADC_Channel_29) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR0; + /* Calculate the mask to clear */ + tmpreg2 = SMPR0_SMP_SET << (3 * (ADC_Channel - 30)); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 30)); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR0 = tmpreg1; + } + /* If ADC_Channel_20 ... ADC_Channel_29 is selected */ + else if (ADC_Channel > ADC_Channel_19) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR1; + /* Calculate the mask to clear */ + tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 20)); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 20)); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR1 = tmpreg1; + } + /* If ADC_Channel_10 ... ADC_Channel_19 is selected */ + else if (ADC_Channel > ADC_Channel_9) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR2; + /* Calculate the mask to clear */ + tmpreg2 = SMPR2_SMP_SET << (3 * (ADC_Channel - 10)); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR2 = tmpreg1; + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR3; + /* Calculate the mask to clear */ + tmpreg2 = SMPR3_SMP_SET << (3 * ADC_Channel); + /* Clear the old sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); + /* Set the new sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR3 = tmpreg1; + } + + /* Rank configuration */ + /* Get the old register value */ + tmpreg1 = ADCx->JSQR; + /* Get JL value: Number = JL+1 */ + tmpreg3 = (tmpreg1 & JSQR_JL_SET)>> 20; + /* Calculate the mask to clear: ((Rank-1)+(4- (JL+1))) */ + tmpreg2 = (uint32_t)(JSQR_JSQ_SET << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1)))); + /* Clear the old JSQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set: ((Rank-1)+(4- (JL+1))) */ + tmpreg2 = (uint32_t)(((uint32_t)(ADC_Channel)) << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1)))); + /* Set the JSQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->JSQR = tmpreg1; +} + +/** + * @brief Configures the sequencer length for injected channels. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param Length: The sequencer length. + * This parameter must be a number between 1 to 4. + * @retval None + */ +void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) +{ + uint32_t tmpreg1 = 0; + uint32_t tmpreg2 = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_LENGTH(Length)); + + /* Get the old register value */ + tmpreg1 = ADCx->JSQR; + /* Clear the old injected sequence length JL bits */ + tmpreg1 &= JSQR_JL_RESET; + /* Set the injected sequence length JL bits */ + tmpreg2 = Length - 1; + tmpreg1 |= tmpreg2 << 20; + /* Store the new register value */ + ADCx->JSQR = tmpreg1; +} + +/** + * @brief Set the injected channels conversion value offset. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_InjectedChannel: the ADC injected channel to set its offset. + * This parameter can be one of the following values: + * @arg ADC_InjectedChannel_1: Injected Channel1 selected. + * @arg ADC_InjectedChannel_2: Injected Channel2 selected. + * @arg ADC_InjectedChannel_3: Injected Channel3 selected. + * @arg ADC_InjectedChannel_4: Injected Channel4 selected. + * @param Offset: the offset value for the selected ADC injected channel + * This parameter must be a 12bit value. + * @retval None + */ +void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); + assert_param(IS_ADC_OFFSET(Offset)); + + tmp = (uint32_t)ADCx; + tmp += ADC_InjectedChannel; + + /* Set the selected injected channel data offset */ + *(__IO uint32_t *) tmp = (uint32_t)Offset; +} + +/** + * @brief Configures the ADCx external trigger for injected channels conversion. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_ExternalTrigInjecConv: specifies the ADC trigger to start injected + * conversion. This parameter can be one of the following values: + * @arg ADC_ExternalTrigInjecConv_T9_CC1: Timer9 capture compare1 selected + * @arg ADC_ExternalTrigInjecConv_T9_TRGO: Timer9 TRGO event selected + * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected + * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected + * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected + * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected + * @arg ADC_ExternalTrigInjecConv_T4_CC1: Timer4 capture compare1 selected + * @arg ADC_ExternalTrigInjecConv_T4_CC2: Timer4 capture compare2 selected + * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected + * @arg ADC_ExternalTrigInjecConv_T10_CC1: Timer10 capture compare1 selected + * @arg ADC_ExternalTrigInjecConv_T7_TRGO: Timer7 TRGO event selected + * @arg ADC_ExternalTrigInjecConv_Ext_IT15: External interrupt line 15 event selected + * @retval None + */ +void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_EXT_INJEC_TRIG(ADC_ExternalTrigInjecConv)); + + /* Get the old register value */ + tmpreg = ADCx->CR2; + /* Clear the old external event selection for injected group */ + tmpreg &= CR2_JEXTSEL_RESET; + /* Set the external event selection for injected group */ + tmpreg |= ADC_ExternalTrigInjecConv; + /* Store the new register value */ + ADCx->CR2 = tmpreg; +} + +/** + * @brief Configures the ADCx external trigger edge for injected channels conversion. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_ExternalTrigInjecConvEdge: specifies the ADC external trigger + * edge to start injected conversion. + * This parameter can be one of the following values: + * @arg ADC_ExternalTrigConvEdge_None: external trigger disabled for + * injected conversion. + * @arg ADC_ExternalTrigConvEdge_Rising: detection on rising edge + * @arg ADC_ExternalTrigConvEdge_Falling: detection on falling edge + * @arg ADC_ExternalTrigConvEdge_RisingFalling: detection on + * both rising and falling edge + * @retval None + */ +void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(ADC_ExternalTrigInjecConvEdge)); + + /* Get the old register value */ + tmpreg = ADCx->CR2; + /* Clear the old external trigger edge for injected group */ + tmpreg &= CR2_JEXTEN_RESET; + /* Set the new external trigger edge for injected group */ + tmpreg |= ADC_ExternalTrigInjecConvEdge; + /* Store the new register value */ + ADCx->CR2 = tmpreg; +} + +/** + * @brief Enables the selected ADC software start conversion of the injected + * channels. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @retval None + */ +void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Enable the selected ADC conversion for injected group */ + ADCx->CR2 |= (uint32_t)ADC_CR2_JSWSTART; +} + +/** + * @brief Gets the selected ADC Software start injected conversion Status. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @retval The new state of ADC software start injected conversion (SET or RESET). + */ +FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + /* Check the status of JSWSTART bit */ + if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET) + { + /* JSWSTART bit is set */ + bitstatus = SET; + } + else + { + /* JSWSTART bit is reset */ + bitstatus = RESET; + } + /* Return the JSWSTART bit status */ + return bitstatus; +} + +/** + * @brief Enables or disables the selected ADC automatic injected group + * conversion after regular one. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the selected ADC auto injected + * conversion. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC automatic injected group conversion */ + ADCx->CR1 |= (uint32_t)ADC_CR1_JAUTO; + } + else + { + /* Disable the selected ADC automatic injected group conversion */ + ADCx->CR1 &= (uint32_t)(~ADC_CR1_JAUTO); + } +} + +/** + * @brief Enables or disables the discontinuous mode for injected group + * channel for the specified ADC. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param NewState: new state of the selected ADC discontinuous mode + * on injected group channel. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC injected discontinuous mode */ + ADCx->CR1 |= (uint32_t)ADC_CR1_JDISCEN; + } + else + { + /* Disable the selected ADC injected discontinuous mode */ + ADCx->CR1 &= (uint32_t)(~ADC_CR1_JDISCEN); + } +} + +/** + * @brief Returns the ADC injected channel conversion result. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_InjectedChannel: the converted ADC injected channel. + * This parameter can be one of the following values: + * @arg ADC_InjectedChannel_1: Injected Channel1 selected + * @arg ADC_InjectedChannel_2: Injected Channel2 selected + * @arg ADC_InjectedChannel_3: Injected Channel3 selected + * @arg ADC_InjectedChannel_4: Injected Channel4 selected + * @retval The Data conversion value. + */ +uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); + + tmp = (uint32_t)ADCx; + tmp += ADC_InjectedChannel + JDR_OFFSET; + + /* Returns the selected injected channel conversion data value */ + return (uint16_t) (*(__IO uint32_t*) tmp); +} + +/** + * @} + */ + +/** @defgroup ADC_Group8 Interrupts and flags management functions + * @brief Interrupts and flags management functions. + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + [..] This section provides functions allowing to configure the ADC Interrupts + and get the status and clear flags and Interrupts pending bits. + + [..] The ADC provide 4 Interrupts sources and 9 Flags which can be divided into + 3 groups: + *** Flags and Interrupts for ADC regular channels *** + ===================================================== + [..] + (+)Flags : + (##) ADC_FLAG_OVR : Overrun detection when regular converted data are + lost. + (##) ADC_FLAG_EOC : Regular channel end of conversion + to indicate + (depending on EOCS bit, managed by ADC_EOCOnEachRegularChannelCmd() ) + the end of : + (+++) a regular CHANNEL conversion. + (+++) sequence of regular GROUP conversions. + + + (##) ADC_FLAG_STRT: Regular channel start + to indicate when regular + CHANNEL conversion starts. + (##) ADC_FLAG_RCNR: Regular channel not ready + to indicate if a new + regular conversion can be launched. + (+)Interrupts : + (##) ADC_IT_OVR : specifies the interrupt source for Overrun detection + event. + (##) ADC_IT_EOC : specifies the interrupt source for Regular channel + end of conversion event. + + *** Flags and Interrupts for ADC Injected channels *** + ====================================================== + (+)Flags : + (##) ADC_FLAG_JEOC : Injected channel end of conversion+ to indicate at + the end of injected GROUP conversion. + (##) ADC_FLAG_JSTRT: Injected channel start + to indicate hardware when + injected GROUP conversion starts. + (##) ADC_FLAG_JCNR: Injected channel not ready + to indicate if a new + injected conversion can be launched. + (+)Interrupts + (##) ADC_IT_JEOC : specifies the interrupt source for Injected channel + end of conversion event. + *** General Flags and Interrupts for the ADC *** + ================================================ + (+)Flags : + (##) ADC_FLAG_AWD: Analog watchdog + to indicate if the converted voltage + crosses the programmed thresholds values. + (##) ADC_FLAG_ADONS: ADC ON status + to indicate if the ADC is ready + to convert. + (+)Interrupts : + (##) ADC_IT_AWD : specifies the interrupt source for Analog watchdog + event. + + [..] The user should identify which mode will be used in his application to + manage the ADC controller events: Polling mode or Interrupt mode. + + [..] In the Polling Mode it is advised to use the following functions: + (+) ADC_GetFlagStatus() : to check if flags events occur. + (+) ADC_ClearFlag() : to clear the flags events. + + [..] In the Interrupt Mode it is advised to use the following functions: + (+) ADC_ITConfig() : to enable or disable the interrupt source. + (+) ADC_GetITStatus() : to check if Interrupt occurs. + (+) ADC_ClearITPendingBit() : to clear the Interrupt pending Bit + (corresponding Flag). +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified ADC interrupts. + * @param ADCx: where x can be 1 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt + * @arg ADC_IT_AWD: Analog watchdog interrupt + * @arg ADC_IT_JEOC: End of injected conversion interrupt + * @arg ADC_IT_OVR: overrun interrupt + * @param NewState: new state of the specified ADC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState) +{ + uint32_t itmask = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_ADC_IT(ADC_IT)); + + /* Get the ADC IT index */ + itmask = (uint8_t)ADC_IT; + itmask = (uint32_t)0x01 << itmask; + + if (NewState != DISABLE) + { + /* Enable the selected ADC interrupts */ + ADCx->CR1 |= itmask; + } + else + { + /* Disable the selected ADC interrupts */ + ADCx->CR1 &= (~(uint32_t)itmask); + } +} + +/** + * @brief Checks whether the specified ADC flag is set or not. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg ADC_FLAG_AWD: Analog watchdog flag + * @arg ADC_FLAG_EOC: End of conversion flag + * @arg ADC_FLAG_JEOC: End of injected group conversion flag + * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag + * @arg ADC_FLAG_STRT: Start of regular group conversion flag + * @arg ADC_FLAG_OVR: Overrun flag + * @arg ADC_FLAG_ADONS: ADC ON status + * @arg ADC_FLAG_RCNR: Regular channel not ready + * @arg ADC_FLAG_JCNR: Injected channel not ready + * @retval The new state of ADC_FLAG (SET or RESET). + */ +FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint16_t ADC_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); + + /* Check the status of the specified ADC flag */ + if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET) + { + /* ADC_FLAG is set */ + bitstatus = SET; + } + else + { + /* ADC_FLAG is reset */ + bitstatus = RESET; + } + /* Return the ADC_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the ADCx's pending flags. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg ADC_FLAG_AWD: Analog watchdog flag + * @arg ADC_FLAG_EOC: End of conversion flag + * @arg ADC_FLAG_JEOC: End of injected group conversion flag + * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag + * @arg ADC_FLAG_STRT: Start of regular group conversion flag + * @arg ADC_FLAG_OVR: overrun flag + * @retval None + */ +void ADC_ClearFlag(ADC_TypeDef* ADCx, uint16_t ADC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG)); + + /* Clear the selected ADC flags */ + ADCx->SR = ~(uint32_t)ADC_FLAG; +} + +/** + * @brief Checks whether the specified ADC interrupt has occurred or not. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_IT: specifies the ADC interrupt source to check. + * This parameter can be one of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt + * @arg ADC_IT_AWD: Analog watchdog interrupt + * @arg ADC_IT_JEOC: End of injected conversion interrupt + * @arg ADC_IT_OVR: Overrun interrupt + * @retval The new state of ADC_IT (SET or RESET). + */ +ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t itmask = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_IT(ADC_IT)); + + /* Get the ADC IT index */ + itmask = (uint32_t)((uint32_t)ADC_IT >> 8); + + /* Get the ADC_IT enable bit status */ + enablestatus = (ADCx->CR1 & ((uint32_t)0x01 << (uint8_t)ADC_IT)); + + /* Check the status of the specified ADC interrupt */ + if (((uint32_t)(ADCx->SR & (uint32_t)itmask) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) + { + /* ADC_IT is set */ + bitstatus = SET; + } + else + { + /* ADC_IT is reset */ + bitstatus = RESET; + } + /* Return the ADC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the ADCx's interrupt pending bits. + * @param ADCx: where x can be 1 to select the ADC1 peripheral. + * @param ADC_IT: specifies the ADC interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt + * @arg ADC_IT_AWD: Analog watchdog interrupt + * @arg ADC_IT_JEOC: End of injected conversion interrupt + * @arg ADC_IT_OVR: Overrun interrupt + * @retval None + */ +void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) +{ + uint8_t itmask = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_IT(ADC_IT)); + + /* Get the ADC IT index */ + itmask = (uint8_t)(ADC_IT >> 8); + + /* Clear the selected ADC interrupt pending bits */ + ADCx->SR = ~(uint32_t)itmask; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_adc.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_adc.h new file mode 100644 index 0000000000..6b1fc4c8cb --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_adc.h @@ -0,0 +1,650 @@ +/** + ****************************************************************************** + * @file stm32l1xx_adc.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the ADC firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_ADC_H +#define __STM32L1xx_ADC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief ADC Init structure definition + */ + +typedef struct +{ + uint32_t ADC_Resolution; /*!< Selects the resolution of the conversion. + This parameter can be a value of @ref ADC_Resolution */ + + FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion is performed in + Scan (multichannel) or Single (one channel) mode. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in + Continuous or Single mode. + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t ADC_ExternalTrigConvEdge; /*!< Selects the external trigger Edge and enables the + trigger of a regular group. This parameter can be a value + of @ref ADC_external_trigger_edge_for_regular_channels_conversion */ + + uint32_t ADC_ExternalTrigConv; /*!< Defines the external trigger used to start the analog + to digital conversion of regular channels. This parameter + can be a value of @ref ADC_external_trigger_sources_for_regular_channels_conversion */ + + uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right. + This parameter can be a value of @ref ADC_data_align */ + + uint8_t ADC_NbrOfConversion; /*!< Specifies the number of ADC conversions that will be done + using the sequencer for regular channel group. + This parameter must range from 1 to 27. */ +}ADC_InitTypeDef; + +typedef struct +{ + uint32_t ADC_Prescaler; /*!< Selects the ADC prescaler. + This parameter can be a value + of @ref ADC_Prescaler */ +}ADC_CommonInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Constants + * @{ + */ +#define IS_ADC_ALL_PERIPH(PERIPH) ((PERIPH) == ADC1) +#define IS_ADC_DMA_PERIPH(PERIPH) ((PERIPH) == ADC1) + +/** @defgroup ADC_Power_down_during_Idle_and_or_Delay_phase + * @{ + */ +#define ADC_PowerDown_Delay ((uint32_t)0x00010000) +#define ADC_PowerDown_Idle ((uint32_t)0x00020000) +#define ADC_PowerDown_Idle_Delay ((uint32_t)0x00030000) + +#define IS_ADC_POWER_DOWN(DWON) (((DWON) == ADC_PowerDown_Delay) || \ + ((DWON) == ADC_PowerDown_Idle) || \ + ((DWON) == ADC_PowerDown_Idle_Delay)) +/** + * @} + */ + + +/** @defgroup ADC_Prescaler + * @{ + */ +#define ADC_Prescaler_Div1 ((uint32_t)0x00000000) +#define ADC_Prescaler_Div2 ((uint32_t)0x00010000) +#define ADC_Prescaler_Div4 ((uint32_t)0x00020000) + +#define IS_ADC_PRESCALER(PRESCALER) (((PRESCALER) == ADC_Prescaler_Div1) || \ + ((PRESCALER) == ADC_Prescaler_Div2) || \ + ((PRESCALER) == ADC_Prescaler_Div4)) +/** + * @} + */ + + + +/** @defgroup ADC_Resolution + * @{ + */ +#define ADC_Resolution_12b ((uint32_t)0x00000000) +#define ADC_Resolution_10b ((uint32_t)0x01000000) +#define ADC_Resolution_8b ((uint32_t)0x02000000) +#define ADC_Resolution_6b ((uint32_t)0x03000000) + +#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \ + ((RESOLUTION) == ADC_Resolution_10b) || \ + ((RESOLUTION) == ADC_Resolution_8b) || \ + ((RESOLUTION) == ADC_Resolution_6b)) + +/** + * @} + */ + +/** @defgroup ADC_external_trigger_edge_for_regular_channels_conversion + * @{ + */ +#define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000) +#define ADC_ExternalTrigConvEdge_Rising ((uint32_t)0x10000000) +#define ADC_ExternalTrigConvEdge_Falling ((uint32_t)0x20000000) +#define ADC_ExternalTrigConvEdge_RisingFalling ((uint32_t)0x30000000) + +#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \ + ((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \ + ((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \ + ((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling)) +/** + * @} + */ + +/** @defgroup ADC_external_trigger_sources_for_regular_channels_conversion + * @{ + */ + +/* TIM2 */ +#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x02000000) +#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x03000000) +#define ADC_ExternalTrigConv_T2_TRGO ((uint32_t)0x06000000) + +/* TIM3 */ +#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x07000000) +#define ADC_ExternalTrigConv_T3_CC3 ((uint32_t)0x08000000) +#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x04000000) + +/* TIM4 */ +#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x05000000) +#define ADC_ExternalTrigConv_T4_TRGO ((uint32_t)0x09000000) + +/* TIM6 */ +#define ADC_ExternalTrigConv_T6_TRGO ((uint32_t)0x0A000000) + +/* TIM9 */ +#define ADC_ExternalTrigConv_T9_CC2 ((uint32_t)0x00000000) +#define ADC_ExternalTrigConv_T9_TRGO ((uint32_t)0x01000000) + +/* EXTI */ +#define ADC_ExternalTrigConv_Ext_IT11 ((uint32_t)0x0F000000) + +#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T9_CC2) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T9_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T3_CC3) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T4_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T6_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11)) +/** + * @} + */ + +/** @defgroup ADC_data_align + * @{ + */ + +#define ADC_DataAlign_Right ((uint32_t)0x00000000) +#define ADC_DataAlign_Left ((uint32_t)0x00000800) + +#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \ + ((ALIGN) == ADC_DataAlign_Left)) +/** + * @} + */ + +/** @defgroup ADC_channels + * @{ + */ +/* ADC Bank A Channels -------------------------------------------------------*/ +#define ADC_Channel_0 ((uint8_t)0x00) +#define ADC_Channel_1 ((uint8_t)0x01) +#define ADC_Channel_2 ((uint8_t)0x02) +#define ADC_Channel_3 ((uint8_t)0x03) + +#define ADC_Channel_6 ((uint8_t)0x06) +#define ADC_Channel_7 ((uint8_t)0x07) +#define ADC_Channel_8 ((uint8_t)0x08) +#define ADC_Channel_9 ((uint8_t)0x09) +#define ADC_Channel_10 ((uint8_t)0x0A) +#define ADC_Channel_11 ((uint8_t)0x0B) +#define ADC_Channel_12 ((uint8_t)0x0C) + + +/* ADC Bank B Channels -------------------------------------------------------*/ +#define ADC_Channel_0b ADC_Channel_0 +#define ADC_Channel_1b ADC_Channel_1 +#define ADC_Channel_2b ADC_Channel_2 +#define ADC_Channel_3b ADC_Channel_3 + +#define ADC_Channel_6b ADC_Channel_6 +#define ADC_Channel_7b ADC_Channel_7 +#define ADC_Channel_8b ADC_Channel_8 +#define ADC_Channel_9b ADC_Channel_9 +#define ADC_Channel_10b ADC_Channel_10 +#define ADC_Channel_11b ADC_Channel_11 +#define ADC_Channel_12b ADC_Channel_12 + +/* ADC Common Channels (ADC Bank A and B) ------------------------------------*/ +#define ADC_Channel_4 ((uint8_t)0x04) +#define ADC_Channel_5 ((uint8_t)0x05) + +#define ADC_Channel_13 ((uint8_t)0x0D) +#define ADC_Channel_14 ((uint8_t)0x0E) +#define ADC_Channel_15 ((uint8_t)0x0F) +#define ADC_Channel_16 ((uint8_t)0x10) +#define ADC_Channel_17 ((uint8_t)0x11) +#define ADC_Channel_18 ((uint8_t)0x12) +#define ADC_Channel_19 ((uint8_t)0x13) +#define ADC_Channel_20 ((uint8_t)0x14) +#define ADC_Channel_21 ((uint8_t)0x15) +#define ADC_Channel_22 ((uint8_t)0x16) +#define ADC_Channel_23 ((uint8_t)0x17) +#define ADC_Channel_24 ((uint8_t)0x18) +#define ADC_Channel_25 ((uint8_t)0x19) + +#define ADC_Channel_27 ((uint8_t)0x1B) +#define ADC_Channel_28 ((uint8_t)0x1C) +#define ADC_Channel_29 ((uint8_t)0x1D) +#define ADC_Channel_30 ((uint8_t)0x1E) +#define ADC_Channel_31 ((uint8_t)0x1F) + +#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16) +#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17) + +#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || ((CHANNEL) == ADC_Channel_1) || \ + ((CHANNEL) == ADC_Channel_2) || ((CHANNEL) == ADC_Channel_3) || \ + ((CHANNEL) == ADC_Channel_4) || ((CHANNEL) == ADC_Channel_5) || \ + ((CHANNEL) == ADC_Channel_6) || ((CHANNEL) == ADC_Channel_7) || \ + ((CHANNEL) == ADC_Channel_8) || ((CHANNEL) == ADC_Channel_9) || \ + ((CHANNEL) == ADC_Channel_10) || ((CHANNEL) == ADC_Channel_11) || \ + ((CHANNEL) == ADC_Channel_12) || ((CHANNEL) == ADC_Channel_13) || \ + ((CHANNEL) == ADC_Channel_14) || ((CHANNEL) == ADC_Channel_15) || \ + ((CHANNEL) == ADC_Channel_16) || ((CHANNEL) == ADC_Channel_17) || \ + ((CHANNEL) == ADC_Channel_18) || ((CHANNEL) == ADC_Channel_19) || \ + ((CHANNEL) == ADC_Channel_20) || ((CHANNEL) == ADC_Channel_21) || \ + ((CHANNEL) == ADC_Channel_22) || ((CHANNEL) == ADC_Channel_23) || \ + ((CHANNEL) == ADC_Channel_24) || ((CHANNEL) == ADC_Channel_25) || \ + ((CHANNEL) == ADC_Channel_27) || ((CHANNEL) == ADC_Channel_28) || \ + ((CHANNEL) == ADC_Channel_29) || ((CHANNEL) == ADC_Channel_30) || \ + ((CHANNEL) == ADC_Channel_31)) +/** + * @} + */ + +/** @defgroup ADC_sampling_times + * @{ + */ + +#define ADC_SampleTime_4Cycles ((uint8_t)0x00) +#define ADC_SampleTime_9Cycles ((uint8_t)0x01) +#define ADC_SampleTime_16Cycles ((uint8_t)0x02) +#define ADC_SampleTime_24Cycles ((uint8_t)0x03) +#define ADC_SampleTime_48Cycles ((uint8_t)0x04) +#define ADC_SampleTime_96Cycles ((uint8_t)0x05) +#define ADC_SampleTime_192Cycles ((uint8_t)0x06) +#define ADC_SampleTime_384Cycles ((uint8_t)0x07) + +#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_4Cycles) || \ + ((TIME) == ADC_SampleTime_9Cycles) || \ + ((TIME) == ADC_SampleTime_16Cycles) || \ + ((TIME) == ADC_SampleTime_24Cycles) || \ + ((TIME) == ADC_SampleTime_48Cycles) || \ + ((TIME) == ADC_SampleTime_96Cycles) || \ + ((TIME) == ADC_SampleTime_192Cycles) || \ + ((TIME) == ADC_SampleTime_384Cycles)) +/** + * @} + */ + +/** @defgroup ADC_Delay_length + * @{ + */ + +#define ADC_DelayLength_None ((uint8_t)0x00) +#define ADC_DelayLength_Freeze ((uint8_t)0x10) +#define ADC_DelayLength_7Cycles ((uint8_t)0x20) +#define ADC_DelayLength_15Cycles ((uint8_t)0x30) +#define ADC_DelayLength_31Cycles ((uint8_t)0x40) +#define ADC_DelayLength_63Cycles ((uint8_t)0x50) +#define ADC_DelayLength_127Cycles ((uint8_t)0x60) +#define ADC_DelayLength_255Cycles ((uint8_t)0x70) + +#define IS_ADC_DELAY_LENGTH(LENGTH) (((LENGTH) == ADC_DelayLength_None) || \ + ((LENGTH) == ADC_DelayLength_Freeze) || \ + ((LENGTH) == ADC_DelayLength_7Cycles) || \ + ((LENGTH) == ADC_DelayLength_15Cycles) || \ + ((LENGTH) == ADC_DelayLength_31Cycles) || \ + ((LENGTH) == ADC_DelayLength_63Cycles) || \ + ((LENGTH) == ADC_DelayLength_127Cycles) || \ + ((LENGTH) == ADC_DelayLength_255Cycles)) + +/** + * @} + */ + +/** @defgroup ADC_external_trigger_edge_for_injected_channels_conversion + * @{ + */ +#define ADC_ExternalTrigInjecConvEdge_None ((uint32_t)0x00000000) +#define ADC_ExternalTrigInjecConvEdge_Rising ((uint32_t)0x00100000) +#define ADC_ExternalTrigInjecConvEdge_Falling ((uint32_t)0x00200000) +#define ADC_ExternalTrigInjecConvEdge_RisingFalling ((uint32_t)0x00300000) + +#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigInjecConvEdge_None) || \ + ((EDGE) == ADC_ExternalTrigInjecConvEdge_Rising) || \ + ((EDGE) == ADC_ExternalTrigInjecConvEdge_Falling) || \ + ((EDGE) == ADC_ExternalTrigInjecConvEdge_RisingFalling)) +/** + * @} + */ + + +/** @defgroup ADC_external_trigger_sources_for_injected_channels_conversion + * @{ + */ + + +/* TIM2 */ +#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00020000) +#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00030000) + +/* TIM3 */ +#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00040000) + +/* TIM4 */ +#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00050000) +#define ADC_ExternalTrigInjecConv_T4_CC1 ((uint32_t)0x00060000) +#define ADC_ExternalTrigInjecConv_T4_CC2 ((uint32_t)0x00070000) +#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00080000) + +/* TIM7 */ +#define ADC_ExternalTrigInjecConv_T7_TRGO ((uint32_t)0x000A0000) + +/* TIM9 */ +#define ADC_ExternalTrigInjecConv_T9_CC1 ((uint32_t)0x00000000) +#define ADC_ExternalTrigInjecConv_T9_TRGO ((uint32_t)0x00010000) + +/* TIM10 */ +#define ADC_ExternalTrigInjecConv_T10_CC1 ((uint32_t)0x00090000) + +/* EXTI */ +#define ADC_ExternalTrigInjecConv_Ext_IT15 ((uint32_t)0x000F0000) + +#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T9_CC1) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T9_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC1) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC2) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T10_CC1) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T7_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15)) +/** + * @} + */ + +/** @defgroup ADC_injected_channel_selection + * @{ + */ +#define ADC_InjectedChannel_1 ((uint8_t)0x18) +#define ADC_InjectedChannel_2 ((uint8_t)0x1C) +#define ADC_InjectedChannel_3 ((uint8_t)0x20) +#define ADC_InjectedChannel_4 ((uint8_t)0x24) + +#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \ + ((CHANNEL) == ADC_InjectedChannel_2) || \ + ((CHANNEL) == ADC_InjectedChannel_3) || \ + ((CHANNEL) == ADC_InjectedChannel_4)) +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_selection + * @{ + */ + +#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200) +#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200) +#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200) +#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000) +#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000) +#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000) +#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000) + +#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_None)) +/** + * @} + */ + +/** @defgroup ADC_interrupts_definition + * @{ + */ + +#define ADC_IT_AWD ((uint16_t)0x0106) +#define ADC_IT_EOC ((uint16_t)0x0205) +#define ADC_IT_JEOC ((uint16_t)0x0407) +#define ADC_IT_OVR ((uint16_t)0x201A) + +#define IS_ADC_IT(IT) (((IT) == ADC_IT_AWD) || ((IT) == ADC_IT_EOC) || \ + ((IT) == ADC_IT_JEOC)|| ((IT) == ADC_IT_OVR)) +/** + * @} + */ + +/** @defgroup ADC_flags_definition + * @{ + */ + +#define ADC_FLAG_AWD ((uint16_t)0x0001) +#define ADC_FLAG_EOC ((uint16_t)0x0002) +#define ADC_FLAG_JEOC ((uint16_t)0x0004) +#define ADC_FLAG_JSTRT ((uint16_t)0x0008) +#define ADC_FLAG_STRT ((uint16_t)0x0010) +#define ADC_FLAG_OVR ((uint16_t)0x0020) +#define ADC_FLAG_ADONS ((uint16_t)0x0040) +#define ADC_FLAG_RCNR ((uint16_t)0x0100) +#define ADC_FLAG_JCNR ((uint16_t)0x0200) + +#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFFC0) == 0x00) && ((FLAG) != 0x00)) + +#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || ((FLAG) == ADC_FLAG_EOC) || \ + ((FLAG) == ADC_FLAG_JEOC) || ((FLAG)== ADC_FLAG_JSTRT) || \ + ((FLAG) == ADC_FLAG_STRT) || ((FLAG)== ADC_FLAG_OVR) || \ + ((FLAG) == ADC_FLAG_ADONS) || ((FLAG)== ADC_FLAG_RCNR) || \ + ((FLAG) == ADC_FLAG_JCNR)) +/** + * @} + */ + +/** @defgroup ADC_thresholds + * @{ + */ + +#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF) + +/** + * @} + */ + +/** @defgroup ADC_injected_offset + * @{ + */ + +#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF) + +/** + * @} + */ + +/** @defgroup ADC_injected_length + * @{ + */ + +#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4)) + +/** + * @} + */ + +/** @defgroup ADC_injected_rank + * @{ + */ + +#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4)) + +/** + * @} + */ + +/** @defgroup ADC_regular_length + * @{ + */ + +#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 1) && ((LENGTH) <= 28)) + +/** + * @} + */ + +/** @defgroup ADC_regular_rank + * @{ + */ + +#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 1) && ((RANK) <= 28)) + +/** + * @} + */ + +/** @defgroup ADC_regular_discontinuous_mode_number + * @{ + */ + +#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8)) + +/** + * @} + */ + +/** @defgroup ADC_Bank_Selection + * @{ + */ +#define ADC_Bank_A ((uint8_t)0x00) +#define ADC_Bank_B ((uint8_t)0x01) +#define IS_ADC_BANK(BANK) (((BANK) == ADC_Bank_A) || ((BANK) == ADC_Bank_B)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the ADC configuration to the default reset state *****/ +void ADC_DeInit(ADC_TypeDef* ADCx); + +/* Initialization and Configuration functions *********************************/ +void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); +void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); +void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct); +void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct); +void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_BankSelection(ADC_TypeDef* ADCx, uint8_t ADC_Bank); + +/* Power saving functions *****************************************************/ +void ADC_PowerDownCmd(ADC_TypeDef* ADCx, uint32_t ADC_PowerDown, FunctionalState NewState); +void ADC_DelaySelectionConfig(ADC_TypeDef* ADCx, uint8_t ADC_DelayLength); + +/* Analog Watchdog configuration functions ************************************/ +void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog); +void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold); +void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); + +/* Temperature Sensor & Vrefint (Voltage Reference internal) management function */ +void ADC_TempSensorVrefintCmd(FunctionalState NewState); + +/* Regular Channels Configuration functions ***********************************/ +void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); +void ADC_SoftwareStartConv(ADC_TypeDef* ADCx); +FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); +void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); +void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); + +/* Regular Channels DMA Configuration functions *******************************/ +void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState); + +/* Injected channels Configuration functions **********************************/ +void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); +void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length); +void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset); +void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv); +void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge); +void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx); +FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx); +void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel); + +/* Interrupts and flags management functions **********************************/ +void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); +FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint16_t ADC_FLAG); +void ADC_ClearFlag(ADC_TypeDef* ADCx, uint16_t ADC_FLAG); +ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT); +void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_ADC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes.c new file mode 100644 index 0000000000..9f9681439a --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes.c @@ -0,0 +1,599 @@ +/** + ****************************************************************************** + * @file stm32l1xx_aes.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the AES peripheral: + * + Configuration + * + Read/Write operations + * + DMA transfers management + * + Interrupts and flags management + * + * @verbatim + =============================================================================== + ##### AES Peripheral features ##### + =============================================================================== +....[..] + (#) The Advanced Encryption Standard hardware accelerator (AES) can be used + to both encipher and decipher data using AES algorithm. + (#) The AES supports 4 operation modes: + (++) Encryption: It consumes 214 clock cycle when processing one 128-bit block + (++) Decryption: It consumes 214 clock cycle when processing one 128-bit block + (++) Key derivation for decryption: It consumes 80 clock cycle when processing one 128-bit block + (++) Key Derivation and decryption: It consumes 288 clock cycle when processing one 128-bit blobk + (#) Moreover 3 chaining modes are supported: + (++) Electronic codebook (ECB): Each plain text is encrypted/decrypted separately + (++) Cipher block chaining (CBC): Each block is XORed with the previous block + (++) Counter mode (CTR): A 128-bit counter is encrypted and then XORed with the + plain text to give the cipher text + (#) The AES peripheral supports data swapping: 1-bit, 8-bit, 16-bit and 32-bit. + (#) The AES peripheral supports write/read error handling with interrupt capability. + (#) Automatic data flow control with support of direct memory access (DMA) using + 2 channels, one for incoming data (DMA2 Channel5), and one for outcoming data + (DMA2 Channel3). + + ##### How to use this driver ##### + =============================================================================== + [..] + (#) AES AHB clock must be enabled to get write access to AES registers + using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_AES, ENABLE). + (#) Initialize the key using AES_KeyInit(). + (#) Configure the AES operation mode using AES_Init(). + (#) If required, enable interrupt source using AES_ITConfig() and + enable the AES interrupt vector using NVIC_Init(). + (#) If required, when using the DMA mode. + (##) Configure the DMA using DMA_Init(). + (##) Enable DMA requests using AES_DMAConfig(). + (#) Enable the AES peripheral using AES_Cmd(). + @endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_aes.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup AES + * @brief AES driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define CR_CLEAR_MASK ((uint32_t)0xFFFFFF81) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup AES_Private_Functions + * @{ + */ + +/** @defgroup AES_Group1 Initialization and configuration + * @brief Initialization and configuration. + * +@verbatim + =============================================================================== + ##### Initialization and configuration ##### + =============================================================================== + +@endverbatim + * @{ + */ + + /** + * @brief Deinitializes AES peripheral registers to their default reset values. + * @param None + * @retval None + */ +void AES_DeInit(void) +{ + /* Enable AES reset state */ + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_AES, ENABLE); + /* Release AES from reset state */ + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_AES, DISABLE); +} + +/** + * @brief Initializes the AES peripheral according to the specified parameters + * in the AES_InitStruct: + * - AES_Operation: specifies the operation mode (encryption, decryption...). + * - AES_Chaining: specifies the chaining mode (ECB, CBC or CTR). + * - AES_DataType: specifies the data swapping type: 32-bit, 16-bit, 8-bit or 1-bit. + * @note If AES is already enabled, use AES_Cmd(DISABLE) before setting the new + * configuration (When AES is enabled, setting configuration is forbidden). + * @param AES_InitStruct: pointer to an AES_InitTypeDef structure that contains + * the configuration information for AES peripheral. + * @retval None + */ +void AES_Init(AES_InitTypeDef* AES_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_AES_MODE(AES_InitStruct->AES_Operation)); + assert_param(IS_AES_CHAINING(AES_InitStruct->AES_Chaining)); + assert_param(IS_AES_DATATYPE(AES_InitStruct->AES_DataType)); + + /* Get AES CR register value */ + tmpreg = AES->CR; + + /* Clear DATATYPE[1:0], MODE[1:0] and CHMOD[1:0] bits */ + tmpreg &= (uint32_t)CR_CLEAR_MASK; + + tmpreg |= (AES_InitStruct->AES_Operation | AES_InitStruct->AES_Chaining | AES_InitStruct->AES_DataType); + + AES->CR = (uint32_t) tmpreg; +} + +/** + * @brief Initializes the AES Keys according to the specified parameters in the AES_KeyInitStruct. + * @param AES_KeyInitStruct: pointer to an AES_KeyInitTypeDef structure that + * contains the configuration information for the specified AES Keys. + * @note This function must be called while the AES is disabled. + * @note In encryption, key derivation and key derivation + decryption modes, + * AES_KeyInitStruct must contain the encryption key. + * In decryption mode, AES_KeyInitStruct must contain the decryption key. + * @retval None + */ +void AES_KeyInit(AES_KeyInitTypeDef* AES_KeyInitStruct) +{ + AES->KEYR0 = AES_KeyInitStruct->AES_Key0; + AES->KEYR1 = AES_KeyInitStruct->AES_Key1; + AES->KEYR2 = AES_KeyInitStruct->AES_Key2; + AES->KEYR3 = AES_KeyInitStruct->AES_Key3; +} + +/** + * @brief Initializes the AES Initialization Vector IV according to + * the specified parameters in the AES_IVInitStruct. + * @param AES_KeyInitStruct: pointer to an AES_IVInitTypeDef structure that + * contains the configuration information for the specified AES IV. + * @note When ECB chaining mode is selected, Initialization Vector IV has no + * meaning. + * When CTR chaining mode is selected, AES_IV0 contains the CTR value. + * AES_IV1, AES_IV2 and AES_IV3 contains nonce value. + * @retval None + */ +void AES_IVInit(AES_IVInitTypeDef* AES_IVInitStruct) +{ + AES->IVR0 = AES_IVInitStruct->AES_IV0; + AES->IVR1 = AES_IVInitStruct->AES_IV1; + AES->IVR2 = AES_IVInitStruct->AES_IV2; + AES->IVR3 = AES_IVInitStruct->AES_IV3; +} + +/** + * @brief Enable or disable the AES peripheral. + * @param NewState: new state of the AES peripheral. + * This parameter can be: ENABLE or DISABLE. + * @note The key must be written while AES is disabled. + * @retval None + */ +void AES_Cmd(FunctionalState NewState) +{ + /* Check the parameter */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the AES peripheral */ + AES->CR |= (uint32_t) AES_CR_EN; /**< AES Enable */ + } + else + { + /* Disable the AES peripheral */ + AES->CR &= (uint32_t)(~AES_CR_EN); /**< AES Disable */ + } +} + +/** + * @} + */ + +/** @defgroup AES_Group2 Structures initialization functions + * @brief Structures initialization. + * +@verbatim + =============================================================================== + ##### Structures initialization functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Fills each AES_InitStruct member with its default value. + * @param AES_InitStruct: pointer to an AES_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void AES_StructInit(AES_InitTypeDef* AES_InitStruct) +{ + AES_InitStruct->AES_Operation = AES_Operation_Encryp; + AES_InitStruct->AES_Chaining = AES_Chaining_ECB; + AES_InitStruct->AES_DataType = AES_DataType_32b; +} + +/** + * @brief Fills each AES_KeyInitStruct member with its default value. + * @param AES_KeyInitStruct: pointer to an AES_KeyInitStruct structure which + * will be initialized. + * @retval None + */ +void AES_KeyStructInit(AES_KeyInitTypeDef* AES_KeyInitStruct) +{ + AES_KeyInitStruct->AES_Key0 = 0x00000000; + AES_KeyInitStruct->AES_Key1 = 0x00000000; + AES_KeyInitStruct->AES_Key2 = 0x00000000; + AES_KeyInitStruct->AES_Key3 = 0x00000000; +} + +/** + * @brief Fills each AES_IVInitStruct member with its default value. + * @param AES_IVInitStruct: pointer to an AES_IVInitTypeDef structure which + * will be initialized. + * @retval None + */ +void AES_IVStructInit(AES_IVInitTypeDef* AES_IVInitStruct) +{ + AES_IVInitStruct->AES_IV0 = 0x00000000; + AES_IVInitStruct->AES_IV1 = 0x00000000; + AES_IVInitStruct->AES_IV2 = 0x00000000; + AES_IVInitStruct->AES_IV3 = 0x00000000; +} + +/** + * @} + */ + +/** @defgroup AES_Group3 AES Read and Write + * @brief AES Read and Write. + * +@verbatim + =============================================================================== + ##### AES Read and Write functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Write data in DINR register to be processed by AES peripheral. + * @note To process 128-bit data (4 * 32-bit), this function must be called + * four times to write the 128-bit data in the 32-bit register DINR. + * @note When an unexpected write to DOUTR register is detected, WRERR flag is + * set. + * @param Data: The data to be processed. + * @retval None + */ +void AES_WriteSubData(uint32_t Data) +{ + /* Write Data */ + AES->DINR = Data; +} + +/** + * @brief Returns the data in DOUTR register processed by AES peripheral. + * @note This function must be called four times to get the 128-bit data. + * @note When an unexpected read of DINR register is detected, RDERR flag is + * set. + * @retval The processed data. + */ +uint32_t AES_ReadSubData(void) +{ + /* Read Data */ + return AES->DOUTR; +} + +/** + * @brief Read the Key value. + * @param AES_KeyInitStruct: pointer to an AES_KeyInitTypeDef structure which + * will contain the key. + * @note When the key derivation mode is selected, AES must be disabled + * (AES_Cmd(DISABLE)) before reading the decryption key. + * Reading the key while the AES is enabled will return unpredictable + * value. + * @retval None + */ +void AES_ReadKey(AES_KeyInitTypeDef* AES_KeyInitStruct) +{ + AES_KeyInitStruct->AES_Key0 = AES->KEYR0; + AES_KeyInitStruct->AES_Key1 = AES->KEYR1; + AES_KeyInitStruct->AES_Key2 = AES->KEYR2; + AES_KeyInitStruct->AES_Key3 = AES->KEYR3; +} + +/** + * @brief Read the Initialization Vector IV value. + * @param AES_IVInitStruct: pointer to an AES_IVInitTypeDef structure which + * will contain the Initialization Vector IV. + * @note When the AES is enabled Reading the Initialization Vector IV value + * will return 0. The AES must be disabled using AES_Cmd(DISABLE) + * to get the right value. + * @note When ECB chaining mode is selected, Initialization Vector IV has no + * meaning. + * When CTR chaining mode is selected, AES_IV0 contains 32-bit Counter value. + * AES_IV1, AES_IV2 and AES_IV3 contains nonce value. + * @retval None + */ +void AES_ReadIV(AES_IVInitTypeDef* AES_IVInitStruct) +{ + AES_IVInitStruct->AES_IV0 = AES->IVR0; + AES_IVInitStruct->AES_IV1 = AES->IVR1; + AES_IVInitStruct->AES_IV2 = AES->IVR2; + AES_IVInitStruct->AES_IV3 = AES->IVR3; +} + +/** + * @} + */ + +/** @defgroup AES_Group4 DMA transfers management functions + * @brief DMA transfers management function. + * +@verbatim + =============================================================================== + ##### DMA transfers management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the AES DMA interface. + * @param AES_DMATransfer: Specifies the AES DMA transfer. + * This parameter can be one of the following values: + * @arg AES_DMATransfer_In: When selected, DMA manages the data input phase. + * @arg AES_DMATransfer_Out: When selected, DMA manages the data output phase. + * @arg AES_DMATransfer_InOut: When selected, DMA manages both the data input/output phases. + * @param NewState Indicates the new state of the AES DMA interface. + * This parameter can be: ENABLE or DISABLE. + * @note The DMA has no action in key derivation mode. + * @retval None + */ +void AES_DMAConfig(uint32_t AES_DMATransfer, FunctionalState NewState) +{ + /* Check the parameter */ + assert_param(IS_AES_DMA_TRANSFER(AES_DMATransfer)); + + if (NewState != DISABLE) + { + /* Enable the DMA transfer */ + AES->CR |= (uint32_t) AES_DMATransfer; + } + else + { + /* Disable the DMA transfer */ + AES->CR &= (uint32_t)(~AES_DMATransfer); + } +} + +/** + * @} + */ + +/** @defgroup AES_Group5 Interrupts and flags management functions + * @brief Interrupts and flags management functions. + * +@verbatim + + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified AES interrupt. + * @param AES_IT: Specifies the AES interrupt source to enable/disable. + * This parameter can be any combinations of the following values: + * @arg AES_IT_CC: Computation Complete Interrupt. If enabled, once CCF + * flag is set an interrupt is generated. + * @arg AES_IT_ERR: Error Interrupt. If enabled, once a read error + * flags (RDERR) or write error flag (WRERR) is set, + * an interrupt is generated. + * @param NewState: The new state of the AES interrupt source. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void AES_ITConfig(uint32_t AES_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_AES_IT(AES_IT)); + + if (NewState != DISABLE) + { + AES->CR |= (uint32_t) AES_IT; /**< AES_IT Enable */ + } + else + { + AES->CR &= (uint32_t)(~AES_IT); /**< AES_IT Disable */ + } +} + +/** + * @brief Checks whether the specified AES flag is set or not. + * @param AES_FLAG specifies the flag to check. + * This parameter can be one of the following values: + * @arg AES_FLAG_CCF: Computation Complete Flag is set by hardware when + * he computation phase is completed. + * @arg AES_FLAG_RDERR: Read Error Flag is set when an unexpected read + * operation of DOUTR register is detected. + * @arg AES_FLAG_WRERR: Write Error Flag is set when an unexpected write + * operation in DINR is detected. + * @retval FlagStatus (SET or RESET) + */ +FlagStatus AES_GetFlagStatus(uint32_t AES_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check parameters */ + assert_param(IS_AES_FLAG(AES_FLAG)); + + if ((AES->SR & AES_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + /* Return the AES_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the AES flags. + * @param AES_FLAG: specifies the flag to clear. + * This parameter can be: + * @arg AES_FLAG_CCF: Computation Complete Flag is cleared by setting CCFC + * bit in CR register. + * @arg AES_FLAG_RDERR: Read Error is cleared by setting ERRC bit in + * CR register. + * @arg AES_FLAG_WRERR: Write Error is cleared by setting ERRC bit in + * CR register. + * @retval None + */ +void AES_ClearFlag(uint32_t AES_FLAG) +{ + /* Check the parameters */ + assert_param(IS_AES_FLAG(AES_FLAG)); + + /* Check if AES_FLAG is AES_FLAG_CCF */ + if (AES_FLAG == AES_FLAG_CCF) + { + /* Clear CCF flag by setting CCFC bit */ + AES->CR |= (uint32_t) AES_CR_CCFC; + } + else /* AES_FLAG is AES_FLAG_RDERR or AES_FLAG_WRERR */ + { + /* Clear RDERR and WRERR flags by setting ERRC bit */ + AES->CR |= (uint32_t) AES_CR_ERRC; + } +} + +/** + * @brief Checks whether the specified AES interrupt has occurred or not. + * @param AES_IT: Specifies the AES interrupt pending bit to check. + * This parameter can be: + * @arg AES_IT_CC: Computation Complete Interrupt. + * @arg AES_IT_ERR: Error Interrupt. + * @retval ITStatus The new state of AES_IT (SET or RESET). + */ +ITStatus AES_GetITStatus(uint32_t AES_IT) +{ + ITStatus itstatus = RESET; + uint32_t cciebitstatus = RESET, ccfbitstatus = RESET; + + /* Check parameters */ + assert_param(IS_AES_GET_IT(AES_IT)); + + cciebitstatus = AES->CR & AES_CR_CCIE; + ccfbitstatus = AES->SR & AES_SR_CCF; + + /* Check if AES_IT is AES_IT_CC */ + if (AES_IT == AES_IT_CC) + { + /* Check the status of the specified AES interrupt */ + if (((cciebitstatus) != (uint32_t)RESET) && ((ccfbitstatus) != (uint32_t)RESET)) + { + /* Interrupt occurred */ + itstatus = SET; + } + else + { + /* Interrupt didn't occur */ + itstatus = RESET; + } + } + else /* AES_IT is AES_IT_ERR */ + { + /* Check the status of the specified AES interrupt */ + if ((AES->CR & AES_CR_ERRIE) != RESET) + { + /* Check if WRERR or RDERR flags are set */ + if ((AES->SR & (uint32_t)(AES_SR_WRERR | AES_SR_RDERR)) != (uint16_t)RESET) + { + /* Interrupt occurred */ + itstatus = SET; + } + else + { + /* Interrupt didn't occur */ + itstatus = RESET; + } + } + else + { + /* Interrupt didn't occur */ + itstatus = (ITStatus) RESET; + } + } + + /* Return the AES_IT status */ + return itstatus; +} + +/** + * @brief Clears the AES's interrupt pending bits. + * @param AES_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combinations of the following values: + * @arg AES_IT_CC: Computation Complete Interrupt. + * @arg AES_IT_ERR: Error Interrupt. + * @retval None + */ +void AES_ClearITPendingBit(uint32_t AES_IT) +{ + /* Check the parameters */ + assert_param(IS_AES_IT(AES_IT)); + + /* Clear the interrupt pending bit */ + AES->CR |= (uint32_t) (AES_IT >> (uint32_t) 0x00000002); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes.h new file mode 100644 index 0000000000..27792ac18d --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes.h @@ -0,0 +1,236 @@ +/** + ****************************************************************************** + * @file stm32l1xx_aes.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the AES firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_AES_H +#define __STM32L1xx_AES_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup AES + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief AES Init structure definition + */ +typedef struct +{ + uint32_t AES_Operation; /*!< Specifies the AES mode of operation. + This parameter can be a value of @ref AES_possible_Operation_modes */ + uint32_t AES_Chaining; /*!< Specifies the AES Chaining modes: ECB, CBC or CTR. + This parameter can be a value of @ref AES_possible_chaining_modes */ + uint32_t AES_DataType; /*!< Specifies the AES data swapping: 32-bit, 16-bit, 8-bit or 1-bit. + This parameter can be a value of @ref AES_Data_Types */ +}AES_InitTypeDef; + +/** + * @brief AES Key(s) structure definition + */ +typedef struct +{ + uint32_t AES_Key0; /*!< Key[31:0] */ + uint32_t AES_Key1; /*!< Key[63:32] */ + uint32_t AES_Key2; /*!< Key[95:64] */ + uint32_t AES_Key3; /*!< Key[127:96] */ +}AES_KeyInitTypeDef; + +/** + * @brief AES Initialization Vectors (IV) structure definition + */ +typedef struct +{ + uint32_t AES_IV0; /*!< Init Vector IV[31:0] */ + uint32_t AES_IV1; /*!< Init Vector IV[63:32] */ + uint32_t AES_IV2; /*!< Init Vector IV[95:64] */ + uint32_t AES_IV3; /*!< Init Vector IV[127:96] */ +}AES_IVInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup AES_Exported_Constants + * @{ + */ + +/** @defgroup AES_possible_Operation_modes + * @{ + */ +#define AES_Operation_Encryp ((uint32_t)0x00000000) /*!< AES in Encryption mode */ +#define AES_Operation_KeyDeriv AES_CR_MODE_0 /*!< AES in Key Derivation mode */ +#define AES_Operation_Decryp AES_CR_MODE_1 /*!< AES in Decryption mode */ +#define AES_Operation_KeyDerivAndDecryp AES_CR_MODE /*!< AES in Key Derivation and Decryption mode */ + +#define IS_AES_MODE(OPERATION) (((OPERATION) == AES_Operation_Encryp) || \ + ((OPERATION) == AES_Operation_KeyDeriv) || \ + ((OPERATION) == AES_Operation_Decryp) || \ + ((OPERATION) == AES_Operation_KeyDerivAndDecryp)) + +/** + * @} + */ + +/** @defgroup AES_possible_chaining_modes + * @{ + */ +#define AES_Chaining_ECB ((uint32_t)0x00000000) /*!< AES in ECB chaining mode */ +#define AES_Chaining_CBC AES_CR_CHMOD_0 /*!< AES in CBC chaining mode */ +#define AES_Chaining_CTR AES_CR_CHMOD_1 /*!< AES in CTR chaining mode */ + +#define IS_AES_CHAINING(CHAINING) (((CHAINING) == AES_Chaining_ECB) || \ + ((CHAINING) == AES_Chaining_CBC) || \ + ((CHAINING) == AES_Chaining_CTR)) +/** + * @} + */ + +/** @defgroup AES_Data_Types + * @{ + */ +#define AES_DataType_32b ((uint32_t)0x00000000) /*!< 32-bit data. No swapping */ +#define AES_DataType_16b AES_CR_DATATYPE_0 /*!< 16-bit data. Each half word is swapped */ +#define AES_DataType_8b AES_CR_DATATYPE_1 /*!< 8-bit data. All bytes are swapped */ +#define AES_DataType_1b AES_CR_DATATYPE /*!< 1-bit data. In the word all bits are swapped */ + +#define IS_AES_DATATYPE(DATATYPE) (((DATATYPE) == AES_DataType_32b) || \ + ((DATATYPE) == AES_DataType_16b)|| \ + ((DATATYPE) == AES_DataType_8b) || \ + ((DATATYPE) == AES_DataType_1b)) +/** + * @} + */ + +/** @defgroup AES_Flags + * @{ + */ +#define AES_FLAG_CCF AES_SR_CCF /*!< Computation Complete Flag */ +#define AES_FLAG_RDERR AES_SR_RDERR /*!< Read Error Flag */ +#define AES_FLAG_WRERR AES_SR_WRERR /*!< Write Error Flag */ + +#define IS_AES_FLAG(FLAG) (((FLAG) == AES_FLAG_CCF) || \ + ((FLAG) == AES_FLAG_RDERR) || \ + ((FLAG) == AES_FLAG_WRERR)) +/** + * @} + */ + +/** @defgroup AES_Interrupts + * @{ + */ +#define AES_IT_CC AES_CR_CCIE /*!< Computation Complete interrupt */ +#define AES_IT_ERR AES_CR_ERRIE /*!< Error interrupt */ + +#define IS_AES_IT(IT) ((((IT) & (uint32_t)0xFFFFF9FF) == 0x00) && ((IT) != 0x00)) +#define IS_AES_GET_IT(IT) (((IT) == AES_IT_CC) || ((IT) == AES_IT_ERR)) + +/** + * @} + */ + +/** @defgroup AES_DMA_Transfer_modes + * @{ + */ +#define AES_DMATransfer_In AES_CR_DMAINEN /*!< DMA requests enabled for input transfer phase */ +#define AES_DMATransfer_Out AES_CR_DMAOUTEN /*!< DMA requests enabled for input transfer phase */ +#define AES_DMATransfer_InOut (AES_CR_DMAINEN | AES_CR_DMAOUTEN) /*!< DMA requests enabled for both input and output phases */ + +#define IS_AES_DMA_TRANSFER(TRANSFER) (((TRANSFER) == AES_DMATransfer_In) || \ + ((TRANSFER) == AES_DMATransfer_Out) || \ + ((TRANSFER) == AES_DMATransfer_InOut)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Initialization and configuration functions *********************************/ +void AES_DeInit(void); +void AES_Init(AES_InitTypeDef* AES_InitStruct); +void AES_KeyInit(AES_KeyInitTypeDef* AES_KeyInitStruct); +void AES_IVInit(AES_IVInitTypeDef* AES_IVInitStruct); +void AES_Cmd(FunctionalState NewState); + +/* Structures initialization functions ****************************************/ +void AES_StructInit(AES_InitTypeDef* AES_InitStruct); +void AES_KeyStructInit(AES_KeyInitTypeDef* AES_KeyInitStruct); +void AES_IVStructInit(AES_IVInitTypeDef* AES_IVInitStruct); + +/* AES Read and Write functions **********************************************/ +void AES_WriteSubData(uint32_t Data); +uint32_t AES_ReadSubData(void); +void AES_ReadKey(AES_KeyInitTypeDef* AES_KeyInitStruct); +void AES_ReadIV(AES_IVInitTypeDef* AES_IVInitStruct); + +/* DMA transfers management function ******************************************/ +void AES_DMAConfig(uint32_t AES_DMATransfer, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void AES_ITConfig(uint32_t AES_IT, FunctionalState NewState); +FlagStatus AES_GetFlagStatus(uint32_t AES_FLAG); +void AES_ClearFlag(uint32_t AES_FLAG); +ITStatus AES_GetITStatus(uint32_t AES_IT); +void AES_ClearITPendingBit(uint32_t AES_IT); + +/* High Level AES functions **************************************************/ +ErrorStatus AES_ECB_Encrypt(uint8_t* Key, uint8_t* Input, uint32_t Ilength, uint8_t* Output); +ErrorStatus AES_ECB_Decrypt(uint8_t* Key, uint8_t* Input, uint32_t Ilength, uint8_t* Output); +ErrorStatus AES_CBC_Encrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output); +ErrorStatus AES_CBC_Decrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output); +ErrorStatus AES_CTR_Encrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output); +ErrorStatus AES_CTR_Decrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_AES_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes_util.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes_util.c new file mode 100644 index 0000000000..d49306a6ff --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_aes_util.c @@ -0,0 +1,679 @@ +/** + ****************************************************************************** + * @file stm32l1xx_aes_util.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides high level functions to encrypt and decrypt an + * input message using AES in ECB/CBC/CTR modes. + * + * @verbatim + +================================================================================ + ##### How to use this driver ##### +================================================================================ + [..] + (#) Enable The AES controller clock using + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_AES, ENABLE); function. + + (#) Use AES_ECB_Encrypt() function to encrypt an input message in ECB mode. + (#) Use AES_ECB_Decrypt() function to decrypt an input message in ECB mode. + + (#) Use AES_CBC_Encrypt() function to encrypt an input message in CBC mode. + (#) Use AES_CBC_Decrypt() function to decrypt an input message in CBC mode. + + (#) Use AES_CTR_Encrypt() function to encrypt an input message in CTR mode. + (#) Use AES_CTR_Decrypt() function to decrypt an input message in CTR mode. + + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_aes.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup AES + * @brief AES driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define AES_CC_TIMEOUT ((uint32_t) 0x00010000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup AES_Private_Functions + * @{ + */ + +/** @defgroup AES_Group6 High Level AES functions + * @brief High Level AES functions + * +@verbatim +================================================================================ + ##### High Level AES functions ##### +================================================================================ + +@endverbatim + * @{ + */ + +/** + * @brief Encrypt using AES in ECB Mode + * @param Key: Key used for AES algorithm. + * @param Input: pointer to the Input buffer. + * @param Ilength: length of the Input buffer, must be a multiple of 16 bytes. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus AES_ECB_Encrypt(uint8_t* Key, uint8_t* Input, uint32_t Ilength, uint8_t* Output) +{ + AES_InitTypeDef AES_InitStructure; + AES_KeyInitTypeDef AES_KeyInitStructure; + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + __IO uint32_t counter = 0; + uint32_t ccstatus = 0; + uint32_t i = 0; + + /* AES Key initialisation */ + AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr)); + AES_KeyInit(&AES_KeyInitStructure); + + /* AES configuration */ + AES_InitStructure.AES_Operation = AES_Operation_Encryp; + AES_InitStructure.AES_Chaining = AES_Chaining_ECB; + AES_InitStructure.AES_DataType = AES_DataType_8b; + AES_Init(&AES_InitStructure); + + /* Enable AES */ + AES_Cmd(ENABLE); + + for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16) + { + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + + /* Wait for CCF flag to be set */ + counter = 0; + do + { + ccstatus = AES_GetFlagStatus(AES_FLAG_CCF); + counter++; + }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET)); + + if (ccstatus == RESET) + { + status = ERROR; + } + else + { + /* Clear CCF flag */ + AES_ClearFlag(AES_FLAG_CCF); + /* Read cipher text */ + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + } + } + + /* Disable AES before starting new processing */ + AES_Cmd(DISABLE); + + return status; +} + +/** + * @brief Decrypt using AES in ECB Mode + * @param Key: Key used for AES algorithm. + * @param Input: pointer to the Input buffer. + * @param Ilength: length of the Input buffer, must be a multiple of 16 bytes. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus AES_ECB_Decrypt(uint8_t* Key, uint8_t* Input, uint32_t Ilength, uint8_t* Output) +{ + AES_InitTypeDef AES_InitStructure; + AES_KeyInitTypeDef AES_KeyInitStructure; + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + __IO uint32_t counter = 0; + uint32_t ccstatus = 0; + uint32_t i = 0; + + /* AES Key initialisation */ + AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr)); + AES_KeyInit(&AES_KeyInitStructure); + + /* AES configuration */ + AES_InitStructure.AES_Operation = AES_Operation_KeyDerivAndDecryp; + AES_InitStructure.AES_Chaining = AES_Chaining_ECB; + AES_InitStructure.AES_DataType = AES_DataType_8b; + AES_Init(&AES_InitStructure); + + /* Enable AES */ + AES_Cmd(ENABLE); + + for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16) + { + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + + /* Wait for CCF flag to be set */ + counter = 0; + do + { + ccstatus = AES_GetFlagStatus(AES_FLAG_CCF); + counter++; + }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET)); + + if (ccstatus == RESET) + { + status = ERROR; + } + else + { + /* Clear CCF flag */ + AES_ClearFlag(AES_FLAG_CCF); + + /* Read cipher text */ + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + } + } + + /* Disable AES before starting new processing */ + AES_Cmd(DISABLE); + + return status; +} + +/** + * @brief Encrypt using AES in CBC Mode + * @param InitVectors: Initialisation Vectors used for AES algorithm. + * @param Key: Key used for AES algorithm. + * @param Input: pointer to the Input buffer. + * @param Ilength: length of the Input buffer, must be a multiple of 16 bytes. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus AES_CBC_Encrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output) +{ + AES_InitTypeDef AES_InitStructure; + AES_KeyInitTypeDef AES_KeyInitStructure; + AES_IVInitTypeDef AES_IVInitStructure; + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + uint32_t ivaddr = (uint32_t)InitVectors; + __IO uint32_t counter = 0; + uint32_t ccstatus = 0; + uint32_t i = 0; + + /* AES Key initialisation*/ + AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr)); + AES_KeyInit(&AES_KeyInitStructure); + + /* AES Initialization Vectors */ + AES_IVInitStructure.AES_IV3 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV2 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV1 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV0 = __REV(*(uint32_t*)(ivaddr)); + AES_IVInit(&AES_IVInitStructure); + + /* AES configuration */ + AES_InitStructure.AES_Operation = AES_Operation_Encryp; + AES_InitStructure.AES_Chaining = AES_Chaining_CBC; + AES_InitStructure.AES_DataType = AES_DataType_8b; + AES_Init(&AES_InitStructure); + + /* Enable AES */ + AES_Cmd(ENABLE); + + for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16) + { + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + + /* Wait for CCF flag to be set */ + counter = 0; + do + { + ccstatus = AES_GetFlagStatus(AES_FLAG_CCF); + counter++; + }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET)); + + if (ccstatus == RESET) + { + status = ERROR; + } + else + { + /* Clear CCF flag */ + AES_ClearFlag(AES_FLAG_CCF); + + /* Read cipher text */ + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + } + } + + /* Disable AES before starting new processing */ + AES_Cmd(DISABLE); + + return status; +} + +/** + * @brief Decrypt using AES in CBC Mode + * @param InitVectors: Initialisation Vectors used for AES algorithm. + * @param Key: Key used for AES algorithm. + * @param Input: pointer to the Input buffer. + * @param Ilength: length of the Input buffer, must be a multiple of 16 bytes. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus AES_CBC_Decrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output) +{ + AES_InitTypeDef AES_InitStructure; + AES_KeyInitTypeDef AES_KeyInitStructure; + AES_IVInitTypeDef AES_IVInitStructure; + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + uint32_t ivaddr = (uint32_t)InitVectors; + __IO uint32_t counter = 0; + uint32_t ccstatus = 0; + uint32_t i = 0; + + /* AES Key initialisation*/ + AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr)); + AES_KeyInit(&AES_KeyInitStructure); + + /* AES Initialization Vectors */ + AES_IVInitStructure.AES_IV3 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV2 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV1 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV0 = __REV(*(uint32_t*)(ivaddr)); + AES_IVInit(&AES_IVInitStructure); + + /* AES configuration */ + AES_InitStructure.AES_Operation = AES_Operation_KeyDerivAndDecryp; + AES_InitStructure.AES_Chaining = AES_Chaining_CBC; + AES_InitStructure.AES_DataType = AES_DataType_8b; + AES_Init(&AES_InitStructure); + + /* Enable AES */ + AES_Cmd(ENABLE); + + for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16) + { + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + + /* Wait for CCF flag to be set */ + counter = 0; + do + { + ccstatus = AES_GetFlagStatus(AES_FLAG_CCF); + counter++; + }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET)); + + if (ccstatus == RESET) + { + status = ERROR; + } + else + { + /* Clear CCF flag */ + AES_ClearFlag(AES_FLAG_CCF); + + /* Read cipher text */ + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + } + } + + /* Disable AES before starting new processing */ + AES_Cmd(DISABLE); + + return status; +} + +/** + * @brief Encrypt using AES in CTR Mode + * @param InitVectors: Initialisation Vectors used for AES algorithm. + * @param Key: Key used for AES algorithm. + * @param Input: pointer to the Input buffer. + * @param Ilength: length of the Input buffer, must be a multiple of 16 bytes. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus AES_CTR_Encrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output) +{ + AES_InitTypeDef AES_InitStructure; + AES_KeyInitTypeDef AES_KeyInitStructure; + AES_IVInitTypeDef AES_IVInitStructure; + + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + uint32_t ivaddr = (uint32_t)InitVectors; + __IO uint32_t counter = 0; + uint32_t ccstatus = 0; + uint32_t i = 0; + + /* AES key initialisation*/ + AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr)); + AES_KeyInit(&AES_KeyInitStructure); + + /* AES Initialization Vectors */ + AES_IVInitStructure.AES_IV3 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV2= __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV1 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV0= __REV(*(uint32_t*)(ivaddr)); + AES_IVInit(&AES_IVInitStructure); + + /* AES configuration */ + AES_InitStructure.AES_Operation = AES_Operation_Encryp; + AES_InitStructure.AES_Chaining = AES_Chaining_CTR; + AES_InitStructure.AES_DataType = AES_DataType_8b; + AES_Init(&AES_InitStructure); + + /* Enable AES */ + AES_Cmd(ENABLE); + + for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16) + { + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + + /* Wait for CCF flag to be set */ + counter = 0; + do + { + ccstatus = AES_GetFlagStatus(AES_FLAG_CCF); + counter++; + }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET)); + + if (ccstatus == RESET) + { + status = ERROR; + } + else + { + /* Clear CCF flag */ + AES_ClearFlag(AES_FLAG_CCF); + + /* Read cipher text */ + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + } + } + + /* Disable AES before starting new processing */ + AES_Cmd(DISABLE); + + return status; +} + +/** + * @brief Decrypt using AES in CTR Mode + * @param InitVectors: Initialisation Vectors used for AES algorithm. + * @param Key: Key used for AES algorithm. + * @param Input: pointer to the Input buffer. + * @param Ilength: length of the Input buffer, must be a multiple of 16 bytes. + * @param Output: pointer to the returned buffer. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Operation done + * - ERROR: Operation failed + */ +ErrorStatus AES_CTR_Decrypt(uint8_t* Key, uint8_t InitVectors[16], uint8_t* Input, uint32_t Ilength, uint8_t* Output) +{ + AES_InitTypeDef AES_InitStructure; + AES_KeyInitTypeDef AES_KeyInitStructure; + AES_IVInitTypeDef AES_IVInitStructure; + + ErrorStatus status = SUCCESS; + uint32_t keyaddr = (uint32_t)Key; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + uint32_t ivaddr = (uint32_t)InitVectors; + __IO uint32_t counter = 0; + uint32_t ccstatus = 0; + uint32_t i = 0; + + /* AES Key initialisation*/ + AES_KeyInitStructure.AES_Key3 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key2 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key1 = __REV(*(uint32_t*)(keyaddr)); + keyaddr += 4; + AES_KeyInitStructure.AES_Key0 = __REV(*(uint32_t*)(keyaddr)); + AES_KeyInit(&AES_KeyInitStructure); + + /* AES Initialization Vectors */ + AES_IVInitStructure.AES_IV3 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV2 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV1 = __REV(*(uint32_t*)(ivaddr)); + ivaddr += 4; + AES_IVInitStructure.AES_IV0 = __REV(*(uint32_t*)(ivaddr)); + AES_IVInit(&AES_IVInitStructure); + + /* AES configuration */ + AES_InitStructure.AES_Operation = AES_Operation_KeyDerivAndDecryp; + AES_InitStructure.AES_Chaining = AES_Chaining_CTR; + AES_InitStructure.AES_DataType = AES_DataType_8b; + AES_Init(&AES_InitStructure); + + /* Enable AES */ + AES_Cmd(ENABLE); + + for(i = 0; ((i < Ilength) && (status != ERROR)); i += 16) + { + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + AES_WriteSubData(*(uint32_t*)(inputaddr)); + inputaddr += 4; + + /* Wait for CCF flag to be set */ + counter = 0; + do + { + ccstatus = AES_GetFlagStatus(AES_FLAG_CCF); + counter++; + }while((counter != AES_CC_TIMEOUT) && (ccstatus == RESET)); + + if (ccstatus == RESET) + { + status = ERROR; + } + else + { + /* Clear CCF flag */ + AES_ClearFlag(AES_FLAG_CCF); + + /* Read cipher text */ + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + *(uint32_t*)(outputaddr) = AES_ReadSubData(); + outputaddr += 4; + } + } + + /* Disable AES before starting new processing */ + AES_Cmd(DISABLE); + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_comp.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_comp.c new file mode 100644 index 0000000000..30f6945555 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_comp.c @@ -0,0 +1,378 @@ +/** + ****************************************************************************** + * @file stm32l1xx_comp.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the comparators (COMP1 and COMP2) peripheral: + * + Comparators configuration + * + Window mode control + * + Internal Reference Voltage (VREFINT) output + * + * @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] The device integrates two analog comparators COMP1 and COMP2: + (+) COMP1 is a fixed threshold (VREFINT) that shares the non inverting + input with the ADC channels. + (+) COMP2 is a rail-to-rail comparator whose the inverting input can be + selected among: DAC_OUT1, DAC_OUT2, 1/4 VREFINT, 1/2 VERFINT, 3/4 + VREFINT, VREFINT, PB3 and whose the output can be redirected to + embedded timers: TIM2, TIM3, TIM4, TIM10. + + (+) The two comparators COMP1 and COMP2 can be combined in window mode. + + -@- + (#@) Comparator APB clock must be enabled to get write access + to comparator register using + RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE). + + (#@) COMP1 comparator and ADC can't be used at the same time since + they share the same ADC switch matrix (analog switches). + + (#@) When an I/O is used as comparator input, the corresponding GPIO + registers should be configured in analog mode. + + (#@) Comparators outputs (CMP1OUT and CMP2OUT) are not mapped on + GPIO pin. They are only internal. + To get the comparator output level, use COMP_GetOutputLevel(). + + (#@) COMP1 and COMP2 outputs are internally connected to EXTI Line 21 + and EXTI Line 22 respectively. + Interrupts can be used by configuring the EXTI Line using the + EXTI peripheral driver. + + (#@) After enabling the comparator (COMP1 or COMP2), user should wait + for start-up time (tSTART) to get right output levels. + Please refer to product datasheet for more information on tSTART. + + (#@) Comparators cannot be used to exit the device from Sleep or Stop + mode when the internal reference voltage is switched off using + the PWR_UltraLowPowerCmd() function (ULP bit in the PWR_CR register). + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_comp.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup COMP + * @brief COMP driver modules. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup COMP_Private_Functions + * @{ + */ + +/** @defgroup COMP_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions. + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes COMP peripheral registers to their default reset values. + * @param None + * @retval None + */ +void COMP_DeInit(void) +{ + COMP->CSR = ((uint32_t)0x00000000); /*!< Set COMP->CSR to reset value */ +} + +/** + * @brief Initializes the COMP2 peripheral according to the specified parameters + * in the COMP_InitStruct. + * @note This function configures only COMP2. + * @note COMP2 comparator is enabled as soon as the INSEL[2:0] bits are + * different from "000". + * @param COMP_InitStruct: pointer to an COMP_InitTypeDef structure that contains + * the configuration information for the specified COMP peripheral. + * @retval None + */ +void COMP_Init(COMP_InitTypeDef* COMP_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_COMP_INVERTING_INPUT(COMP_InitStruct->COMP_InvertingInput)); + assert_param(IS_COMP_OUTPUT(COMP_InitStruct->COMP_OutputSelect)); + assert_param(IS_COMP_SPEED(COMP_InitStruct->COMP_Speed)); + + /*!< Get the COMP CSR value */ + tmpreg = COMP->CSR; + + /*!< Clear the INSEL[2:0], OUTSEL[1:0] and SPEED bits */ + tmpreg &= (uint32_t) (~(uint32_t) (COMP_CSR_OUTSEL | COMP_CSR_INSEL | COMP_CSR_SPEED)); + + /*!< Configure COMP: speed, inversion input selection and output redirection */ + /*!< Set SPEED bit according to COMP_InitStruct->COMP_Speed value */ + /*!< Set INSEL bits according to COMP_InitStruct->COMP_InvertingInput value */ + /*!< Set OUTSEL bits according to COMP_InitStruct->COMP_OutputSelect value */ + tmpreg |= (uint32_t)((COMP_InitStruct->COMP_Speed | COMP_InitStruct->COMP_InvertingInput + | COMP_InitStruct->COMP_OutputSelect)); + + /*!< The COMP2 comparator is enabled as soon as the INSEL[2:0] bits value are + different from "000" */ + /*!< Write to COMP_CSR register */ + COMP->CSR = tmpreg; +} + +/** + * @brief Enable or disable the COMP1 peripheral. + * @note After enabling COMP1, the following functions should be called to + * connect the selected GPIO input to COMP1 non inverting input: + * @note Enable switch control mode using SYSCFG_RISwitchControlModeCmd() + * @note Close VCOMP switch using SYSCFG_RIIOSwitchConfig() + * @note Close the I/O switch number n corresponding to the I/O + * using SYSCFG_RIIOSwitchConfig() + * @param NewState: new state of the COMP1 peripheral. + * This parameter can be: ENABLE or DISABLE. + * @note This function enables/disables only the COMP1. + * @retval None + */ +void COMP_Cmd(FunctionalState NewState) +{ + /* Check the parameter */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the COMP1 */ + COMP->CSR |= (uint32_t) COMP_CSR_CMP1EN; + } + else + { + /* Disable the COMP1 */ + COMP->CSR &= (uint32_t)(~COMP_CSR_CMP1EN); + } +} + +/** + * @brief Return the output level (high or low) of the selected comparator. + * @note Comparator output is low when the noninverting input is at a lower + * voltage than the inverting input. + * @note Comparator output is high when the noninverting input is at a higher + * voltage than the inverting input. + * @note Comparators outputs aren't available on GPIO (outputs levels are + * only internal). The COMP1 and COMP2 outputs are connected internally + * to the EXTI Line 21 and Line 22 respectively. + * @param COMP_Selection: the selected comparator. + * This parameter can be one of the following values: + * @arg COMP_Selection_COMP1: COMP1 selected + * @arg COMP_Selection_COMP2: COMP2 selected + * @retval Returns the selected comparator output level. + */ +uint8_t COMP_GetOutputLevel(uint32_t COMP_Selection) +{ + uint8_t compout = 0x0; + + /* Check the parameters */ + assert_param(IS_COMP_ALL_PERIPH(COMP_Selection)); + + /* Check if Comparator 1 is selected */ + if(COMP_Selection == COMP_Selection_COMP1) + { + /* Check if comparator 1 output level is high */ + if((COMP->CSR & COMP_CSR_CMP1OUT) != (uint8_t) RESET) + { + /* Get Comparator 1 output level */ + compout = (uint8_t) COMP_OutputLevel_High; + } + /* comparator 1 output level is low */ + else + { + /* Get Comparator 1 output level */ + compout = (uint8_t) COMP_OutputLevel_Low; + } + } + /* Comparator 2 is selected */ + else + { + /* Check if comparator 2 output level is high */ + if((COMP->CSR & COMP_CSR_CMP2OUT) != (uint8_t) RESET) + { + /* Get Comparator output level */ + compout = (uint8_t) COMP_OutputLevel_High; + } + /* comparator 2 output level is low */ + else + { + /* Get Comparator 2 output level */ + compout = (uint8_t) COMP_OutputLevel_Low; + } + } + /* Return the comparator output level */ + return (uint8_t)(compout); +} + +/** + * @brief Close or Open the SW1 switch. + * @param NewState: new state of the SW1 switch. + * This parameter can be: ENABLE or DISABLE. + * @note ENABLE to close the SW1 switch + * @note DISABLE to open the SW1 switch + * @retval None. + */ +void COMP_SW1SwitchConfig(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Close SW1 switch */ + COMP->CSR |= (uint32_t) COMP_CSR_SW1; + } + else + { + /* Open SW1 switch */ + COMP->CSR &= (uint32_t)(~COMP_CSR_SW1); + } +} + +/** + * @} + */ + +/** @defgroup COMP_Group2 Window mode control function + * @brief Window mode control function. + * +@verbatim + =============================================================================== + ##### Window mode control function ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the window mode. + * In window mode: + * @note COMP1 inverting input is fixed to VREFINT defining the first + * threshold. + * @note COMP2 inverting input is configurable (DAC_OUT1, DAC_OUT2, VREFINT + * sub-multiples, PB3) defining the second threshold. + * @note COMP1 and COMP2 non inverting inputs are connected together. + * @note In window mode, only the Group 6 (PB4 or PB5) can be used as + * noninverting inputs. + * @param NewState: new state of the window mode. + * This parameter can be ENABLE or DISABLE. + * @retval None + */ +void COMP_WindowCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the window mode */ + COMP->CSR |= (uint32_t) COMP_CSR_WNDWE; + } + else + { + /* Disable the window mode */ + COMP->CSR &= (uint32_t)(~COMP_CSR_WNDWE); + } +} + +/** + * @} + */ + +/** @defgroup COMP_Group3 Internal Reference Voltage output function + * @brief Internal Reference Voltage (VREFINT) output function. + * +@verbatim + =============================================================================== + ##### Internal Reference Voltage (VREFINT) output function ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the output of internal reference voltage (VREFINT). + * The VREFINT output can be routed to any I/O in group 3: CH8 (PB0) or + * CH9 (PB1). + * To correctly use this function, the SYSCFG_RIIOSwitchConfig() function + * should be called after. + * @param NewState: new state of the Vrefint output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void COMP_VrefintOutputCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the output of internal reference voltage */ + COMP->CSR |= (uint32_t) COMP_CSR_VREFOUTEN; + } + else + { + /* Disable the output of internal reference voltage */ + COMP->CSR &= (uint32_t) (~COMP_CSR_VREFOUTEN); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_comp.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_comp.h new file mode 100644 index 0000000000..c36d56ad51 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_comp.h @@ -0,0 +1,187 @@ +/** + ****************************************************************************** + * @file stm32l1xx_comp.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the COMP firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_COMP_H +#define __STM32L1xx_COMP_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup COMP + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief COMP Init structure definition + */ + +typedef struct +{ + uint32_t COMP_Speed; /*!< Defines the speed of comparator 2. + This parameter can be a value of @ref COMP_Speed */ + uint32_t COMP_InvertingInput; /*!< Selects the inverting input of the comparator 2. + This parameter can be a value of @ref COMP_InvertingInput */ + uint32_t COMP_OutputSelect; /*!< Selects the output redirection of the comparator 2. + This parameter can be a value of @ref COMP_OutputSelect */ + +}COMP_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup COMP_Exported_Constants + * @{ + */ + +#define COMP_OutputLevel_High ((uint32_t)0x00000001) +#define COMP_OutputLevel_Low ((uint32_t)0x00000000) + +/** @defgroup COMP_Selection + * @{ + */ + +#define COMP_Selection_COMP1 ((uint32_t)0x00000001) +#define COMP_Selection_COMP2 ((uint32_t)0x00000002) + +#define IS_COMP_ALL_PERIPH(PERIPH) (((PERIPH) == COMP_Selection_COMP1) || \ + ((PERIPH) == COMP_Selection_COMP2)) + +/** + * @} + */ + +/** @defgroup COMP_InvertingInput + * @{ + */ + +#define COMP_InvertingInput_None ((uint32_t)0x00000000) /* COMP2 is disabled when this parameter is selected */ +#define COMP_InvertingInput_IO ((uint32_t)0x00040000) +#define COMP_InvertingInput_VREFINT ((uint32_t)0x00080000) +#define COMP_InvertingInput_3_4VREFINT ((uint32_t)0x000C0000) +#define COMP_InvertingInput_1_2VREFINT ((uint32_t)0x00100000) +#define COMP_InvertingInput_1_4VREFINT ((uint32_t)0x00140000) +#define COMP_InvertingInput_DAC1 ((uint32_t)0x00180000) +#define COMP_InvertingInput_DAC2 ((uint32_t)0x001C0000) + +#define IS_COMP_INVERTING_INPUT(INPUT) (((INPUT) == COMP_InvertingInput_None) || \ + ((INPUT) == COMP_InvertingInput_IO) || \ + ((INPUT) == COMP_InvertingInput_VREFINT) || \ + ((INPUT) == COMP_InvertingInput_3_4VREFINT) || \ + ((INPUT) == COMP_InvertingInput_1_2VREFINT) || \ + ((INPUT) == COMP_InvertingInput_1_4VREFINT) || \ + ((INPUT) == COMP_InvertingInput_DAC1) || \ + ((INPUT) == COMP_InvertingInput_DAC2)) +/** + * @} + */ + +/** @defgroup COMP_OutputSelect + * @{ + */ + +#define COMP_OutputSelect_TIM2IC4 ((uint32_t)0x00000000) +#define COMP_OutputSelect_TIM2OCREFCLR ((uint32_t)0x00200000) +#define COMP_OutputSelect_TIM3IC4 ((uint32_t)0x00400000) +#define COMP_OutputSelect_TIM3OCREFCLR ((uint32_t)0x00600000) +#define COMP_OutputSelect_TIM4IC4 ((uint32_t)0x00800000) +#define COMP_OutputSelect_TIM4OCREFCLR ((uint32_t)0x00A00000) +#define COMP_OutputSelect_TIM10IC1 ((uint32_t)0x00C00000) +#define COMP_OutputSelect_None ((uint32_t)0x00E00000) + +#define IS_COMP_OUTPUT(OUTPUT) (((OUTPUT) == COMP_OutputSelect_TIM2IC4) || \ + ((OUTPUT) == COMP_OutputSelect_TIM2OCREFCLR) || \ + ((OUTPUT) == COMP_OutputSelect_TIM3IC4) || \ + ((OUTPUT) == COMP_OutputSelect_TIM3OCREFCLR) || \ + ((OUTPUT) == COMP_OutputSelect_TIM4IC4) || \ + ((OUTPUT) == COMP_OutputSelect_TIM4OCREFCLR) || \ + ((OUTPUT) == COMP_OutputSelect_TIM10IC1) || \ + ((OUTPUT) == COMP_OutputSelect_None)) +/** + * @} + */ + +/** @defgroup COMP_Speed + * @{ + */ + +#define COMP_Speed_Slow ((uint32_t)0x00000000) +#define COMP_Speed_Fast ((uint32_t)0x00001000) + +#define IS_COMP_SPEED(SPEED) (((SPEED) == COMP_Speed_Slow) || \ + ((SPEED) == COMP_Speed_Fast)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the COMP configuration to the default reset state ****/ +void COMP_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void COMP_Init(COMP_InitTypeDef* COMP_InitStruct); +void COMP_Cmd(FunctionalState NewState); +uint8_t COMP_GetOutputLevel(uint32_t COMP_Selection); +void COMP_SW1SwitchConfig(FunctionalState NewState); + +/* Window mode control function ***********************************************/ +void COMP_WindowCmd(FunctionalState NewState); + +/* Internal Reference Voltage (VREFINT) output function ***********************/ +void COMP_VrefintOutputCmd(FunctionalState NewState); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_COMP_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_conf.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_conf.h new file mode 100644 index 0000000000..873c8b1980 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_conf.h @@ -0,0 +1,85 @@ +/** + ****************************************************************************** + * @file Project/STM32L1xx_StdPeriph_Templates/stm32l1xx_conf.h + * @author MCD Application Team + * @version V1.1.1 + * @date 13-April-2012 + * @brief Library configuration file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_CONF_H +#define __STM32L1xx_CONF_H + +/* Includes ------------------------------------------------------------------*/ +/* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */ +#include "stm32l1xx_adc.h" +//#include "stm32l1xx_aes.h" +//#include "stm32l1xx_comp.h" +//#include "stm32l1xx_crc.h" +#include "stm32l1xx_dac.h" +#include "stm32l1xx_dbgmcu.h" +//#include "stm32l1xx_dma.h" +#include "stm32l1xx_exti.h" +//#include "stm32l1xx_flash.h" +//#include "stm32l1xx_fsmc.h" +#include "stm32l1xx_gpio.h" +#include "stm32l1xx_i2c.h" +//#include "stm32l1xx_iwdg.h" +//#include "stm32l1xx_lcd.h" +//#include "stm32l1xx_opamp.h" +#include "stm32l1xx_pwr.h" +#include "stm32l1xx_rcc.h" +#include "stm32l1xx_rtc.h" +#include "stm32l1xx_sdio.h" +#include "stm32l1xx_spi.h" +#include "stm32l1xx_syscfg.h" +#include "stm32l1xx_tim.h" +#include "stm32l1xx_usart.h" +//#include "stm32l1xx_wwdg.h" +#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Uncomment the line below to expanse the "assert_param" macro in the + Standard Peripheral Library drivers code */ +/* #define USE_FULL_ASSERT 1 */ + +/* Exported macro ------------------------------------------------------------*/ +#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 */ + +#endif /* __STM32L1xx_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_crc.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_crc.c new file mode 100644 index 0000000000..c7a0af28ac --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_crc.c @@ -0,0 +1,133 @@ +/** + ****************************************************************************** + * @file stm32l1xx_crc.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides all the CRC firmware functions. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_crc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup CRC + * @brief CRC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup CRC_Private_Functions + * @{ + */ + +/** + * @brief Resets the CRC Data register (DR). + * @param None + * @retval None + */ +void CRC_ResetDR(void) +{ + /* Reset CRC generator */ + CRC->CR = CRC_CR_RESET; +} + +/** + * @brief Computes the 32-bit CRC of a given data word(32-bit). + * @param Data: data word(32-bit) to compute its CRC. + * @retval 32-bit CRC + */ +uint32_t CRC_CalcCRC(uint32_t Data) +{ + CRC->DR = Data; + + return (CRC->DR); +} + +/** + * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit). + * @param pBuffer: pointer to the buffer containing the data to be computed. + * @param BufferLength: length of the buffer to be computed + * @retval 32-bit CRC + */ +uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength) +{ + uint32_t index = 0; + + for(index = 0; index < BufferLength; index++) + { + CRC->DR = pBuffer[index]; + } + return (CRC->DR); +} + +/** + * @brief Returns the current CRC value. + * @param None + * @retval 32-bit CRC + */ +uint32_t CRC_GetCRC(void) +{ + return (CRC->DR); +} + +/** + * @brief Stores a 8-bit data in the Independent Data(ID) register. + * @param IDValue: 8-bit value to be stored in the ID register + * @retval None + */ +void CRC_SetIDRegister(uint8_t IDValue) +{ + CRC->IDR = IDValue; +} + +/** + * @brief Returns the 8-bit data stored in the Independent Data(ID) register. + * @param None + * @retval 8-bit value of the ID register + */ +uint8_t CRC_GetIDRegister(void) +{ + return (CRC->IDR); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_crc.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_crc.h new file mode 100644 index 0000000000..38d1390ab6 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_crc.h @@ -0,0 +1,83 @@ +/** + ****************************************************************************** + * @file stm32l1xx_crc.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the CRC firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_CRC_H +#define __STM32L1xx_CRC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup CRC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CRC_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void CRC_ResetDR(void); +uint32_t CRC_CalcCRC(uint32_t Data); +uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); +uint32_t CRC_GetCRC(void); +void CRC_SetIDRegister(uint8_t IDValue); +uint8_t CRC_GetIDRegister(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_CRC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dac.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dac.c new file mode 100644 index 0000000000..834282a027 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dac.c @@ -0,0 +1,687 @@ +/** + ****************************************************************************** + * @file stm32l1xx_dac.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Digital-to-Analog Converter (DAC) peripheral: + * + DAC channels configuration: trigger, output buffer, data format + * + DMA management + * + Interrupts and flags management + + * @verbatim + * + =============================================================================== + ##### DAC Peripheral features ##### + =============================================================================== + [..] The device integrates two 12-bit Digital Analog Converters that can + be used independently or simultaneously (dual mode): + (#) DAC channel1 with DAC_OUT1 (PA4) as output. + (#) DAC channel2 with DAC_OUT2 (PA5) as output. + + [..] Digital to Analog conversion can be non-triggered using DAC_Trigger_None + and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register using + DAC_SetChannel1Data()/DAC_SetChannel2Data. + + [..] Digital to Analog conversion can be triggered by: + (#) External event: EXTI Line 9 (any GPIOx_Pin9) using DAC_Trigger_Ext_IT9. + The used pin (GPIOx_Pin9) must be configured in input mode. + (#) Timers TRGO: TIM2, TIM4, TIM6, TIM7 and TIM9 + (DAC_Trigger_T2_TRGO, DAC_Trigger_T4_TRGO...). + The timer TRGO event should be selected using TIM_SelectOutputTrigger() + (#) Software using DAC_Trigger_Software. + + [..] Each DAC channel integrates an output buffer that can be used to + reduce the output impedance, and to drive external loads directly + without having to add an external operational amplifier. + To enable, the output buffer use + DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; + + [..] Refer to the device datasheet for more details about output impedance + value with and without output buffer. + + [..] Both DAC channels can be used to generate: + (#) Noise wave using DAC_WaveGeneration_Noise + (#) Triangle wave using DAC_WaveGeneration_Triangle + + [..] Wave generation can be disabled using DAC_WaveGeneration_None. + + [..] The DAC data format can be: + (#) 8-bit right alignment using DAC_Align_8b_R + (#) 12-bit left alignment using DAC_Align_12b_L + (#) 12-bit right alignment using DAC_Align_12b_R + + [..] The analog output voltage on each DAC channel pin is determined + by the following equation: DAC_OUTx = VREF+ * DOR / 4095 + with DOR is the Data Output Register. + VEF+ is the input voltage reference (refer to the device datasheet) + e.g. To set DAC_OUT1 to 0.7V, use + DAC_SetChannel1Data(DAC_Align_12b_R, 868); + Assuming that VREF+ = 3.3, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V. + + [..] A DMA1 request can be generated when an external trigger (but not + a software trigger) occurs if DMA1 requests are enabled using + DAC_DMACmd() + [..] DMA1 requests are mapped as following: + (#) DAC channel1 is mapped on DMA1 channel3 which must be already + configured. + (#) DAC channel2 is mapped on DMA1 channel4 which must be already + configured. + + ##### How to use this driver ##### + =============================================================================== + [..] + (+) DAC APB clock must be enabled to get write access to DAC registers using + RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE) + (+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode. + (+) Configure the DAC channel using DAC_Init() + (+) Enable the DAC channel using DAC_Cmd() + + @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_dac.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup DAC + * @brief DAC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* CR register Mask */ +#define CR_CLEAR_MASK ((uint32_t)0x00000FFE) + +/* DAC Dual Channels SWTRIG masks */ +#define DUAL_SWTRIG_SET ((uint32_t)0x00000003) +#define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC) + +/* DHR registers offsets */ +#define DHR12R1_OFFSET ((uint32_t)0x00000008) +#define DHR12R2_OFFSET ((uint32_t)0x00000014) +#define DHR12RD_OFFSET ((uint32_t)0x00000020) + +/* DOR register offset */ +#define DOR_OFFSET ((uint32_t)0x0000002C) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup DAC_Private_Functions + * @{ + */ + +/** @defgroup DAC_Group1 DAC channels configuration + * @brief DAC channels configuration: trigger, output buffer, data format. + * +@verbatim + =============================================================================== + ##### DAC channels configuration: trigger, output buffer, data format ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the DAC peripheral registers to their default reset values. + * @param None + * @retval None + */ +void DAC_DeInit(void) +{ + /* Enable DAC reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE); + /* Release DAC from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE); +} + +/** + * @brief Initializes the DAC peripheral according to the specified + * parameters in the DAC_InitStruct. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected. + * @arg DAC_Channel_2: DAC Channel2 selected. + * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that + * contains the configuration information for the specified DAC channel. + * @retval None + */ +void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0; + + /* Check the DAC parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger)); + assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude)); + assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer)); + +/*---------------------------- DAC CR Configuration --------------------------*/ + /* Get the DAC CR value */ + tmpreg1 = DAC->CR; + /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */ + tmpreg1 &= ~(CR_CLEAR_MASK << DAC_Channel); + /* Configure for the selected DAC channel: buffer output, trigger, wave generation, + mask/amplitude for wave generation */ + /* Set TSELx and TENx bits according to DAC_Trigger value */ + /* Set WAVEx bits according to DAC_WaveGeneration value */ + /* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */ + /* Set BOFFx bit according to DAC_OutputBuffer value */ + tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration | + DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | DAC_InitStruct->DAC_OutputBuffer); + /* Calculate CR register value depending on DAC_Channel */ + tmpreg1 |= tmpreg2 << DAC_Channel; + /* Write to DAC CR */ + DAC->CR = tmpreg1; +} + +/** + * @brief Fills each DAC_InitStruct member with its default value. + * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct) +{ +/*--------------- Reset DAC init structure parameters values -----------------*/ + /* Initialize the DAC_Trigger member */ + DAC_InitStruct->DAC_Trigger = DAC_Trigger_None; + /* Initialize the DAC_WaveGeneration member */ + DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None; + /* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */ + DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; + /* Initialize the DAC_OutputBuffer member */ + DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable; +} + +/** + * @brief Enables or disables the specified DAC channel. + * @param DAC_Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the DAC channel. + * This parameter can be: ENABLE or DISABLE. + * @note When the DAC channel is enabled the trigger source can no more + * be modified. + * @retval None + */ +void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DAC channel */ + DAC->CR |= (DAC_CR_EN1 << DAC_Channel); + } + else + { + /* Disable the selected DAC channel */ + DAC->CR &= (~(DAC_CR_EN1 << DAC_Channel)); + } +} + +/** + * @brief Enables or disables the selected DAC channel software trigger. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the selected DAC channel software trigger. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable software trigger for the selected DAC channel */ + DAC->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4); + } + else + { + /* Disable software trigger for the selected DAC channel */ + DAC->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4)); + } +} + +/** + * @brief Enables or disables simultaneously the two DAC channels software + * triggers. + * @param NewState: new state of the DAC channels software triggers. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_DualSoftwareTriggerCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable software trigger for both DAC channels */ + DAC->SWTRIGR |= DUAL_SWTRIG_SET; + } + else + { + /* Disable software trigger for both DAC channels */ + DAC->SWTRIGR &= DUAL_SWTRIG_RESET; + } +} + +/** + * @brief Enables or disables the selected DAC channel wave generation. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_Wave: Specifies the wave type to enable or disable. + * This parameter can be one of the following values: + * @arg DAC_Wave_Noise: noise wave generation + * @arg DAC_Wave_Triangle: triangle wave generation + * @param NewState: new state of the selected DAC channel wave generation. + * This parameter can be: ENABLE or DISABLE. + * @note + * @retval None + */ +void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_WAVE(DAC_Wave)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected wave generation for the selected DAC channel */ + DAC->CR |= DAC_Wave << DAC_Channel; + } + else + { + /* Disable the selected wave generation for the selected DAC channel */ + DAC->CR &= ~(DAC_Wave << DAC_Channel); + } +} + +/** + * @brief Set the specified data holding register value for DAC channel1. + * @param DAC_Align: Specifies the data alignment for DAC channel1. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignment selected + * @arg DAC_Align_12b_L: 12bit left data alignment selected + * @arg DAC_Align_12b_R: 12bit right data alignment selected + * @param Data : Data to be loaded in the selected data holding register. + * @retval None + */ +void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data)); + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12R1_OFFSET + DAC_Align; + + /* Set the DAC channel1 selected data holding register */ + *(__IO uint32_t *) tmp = Data; +} + +/** + * @brief Set the specified data holding register value for DAC channel2. + * @param DAC_Align: Specifies the data alignment for DAC channel2. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignment selected + * @arg DAC_Align_12b_L: 12bit left data alignment selected + * @arg DAC_Align_12b_R: 12bit right data alignment selected + * @param Data : Data to be loaded in the selected data holding register. + * @retval None + */ +void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data)); + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12R2_OFFSET + DAC_Align; + + /* Set the DAC channel2 selected data holding register */ + *(__IO uint32_t *)tmp = Data; +} + +/** + * @brief Set the specified data holding register value for dual channel DAC. + * @param DAC_Align: Specifies the data alignment for dual channel DAC. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignment selected + * @arg DAC_Align_12b_L: 12bit left data alignment selected + * @arg DAC_Align_12b_R: 12bit right data alignment selected + * @param Data2: Data for DAC Channel2 to be loaded in the selected data + * holding register. + * @param Data1: Data for DAC Channel1 to be loaded in the selected data + * holding register. + * @note In dual mode, a unique register access is required to write in both + * DAC channels at the same time. + * @retval None + */ +void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1) +{ + uint32_t data = 0, tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data1)); + assert_param(IS_DAC_DATA(Data2)); + + /* Calculate and set dual DAC data holding register value */ + if (DAC_Align == DAC_Align_8b_R) + { + data = ((uint32_t)Data2 << 8) | Data1; + } + else + { + data = ((uint32_t)Data2 << 16) | Data1; + } + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12RD_OFFSET + DAC_Align; + + /* Set the dual DAC selected data holding register */ + *(__IO uint32_t *)tmp = data; +} + +/** + * @brief Returns the last data output value of the selected DAC channel. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @retval The selected DAC channel data output value. + */ +uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + + tmp = (uint32_t) DAC_BASE ; + tmp += DOR_OFFSET + ((uint32_t)DAC_Channel >> 2); + + /* Returns the DAC channel data output register value */ + return (uint16_t) (*(__IO uint32_t*) tmp); +} + +/** + * @} + */ + +/** @defgroup DAC_Group2 DMA management functions + * @brief DMA management functions + * +@verbatim + =============================================================================== + ##### DMA management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified DAC channel DMA request. + * When enabled DMA1 is generated when an external trigger (EXTI Line9, + * TIM2, TIM4, TIM6, TIM7 or TIM9 but not a software trigger) occurs. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the selected DAC channel DMA request. + * This parameter can be: ENABLE or DISABLE. + * @note The DAC channel1 (channel2) is mapped on DMA1 channel3 (channel4) which + * must be already configured. + * @retval None + */ +void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DAC channel DMA request */ + DAC->CR |= (DAC_CR_DMAEN1 << DAC_Channel); + } + else + { + /* Disable the selected DAC channel DMA request */ + DAC->CR &= (~(DAC_CR_DMAEN1 << DAC_Channel)); + } +} + +/** + * @} + */ + +/** @defgroup DAC_Group3 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified DAC interrupts. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled. + * This parameter can be the following value: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @note The DMA underrun occurs when a second external trigger arrives before + * the acknowledgement for the first external trigger is received (first request). + * @param NewState: new state of the specified DAC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_DAC_IT(DAC_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected DAC interrupts */ + DAC->CR |= (DAC_IT << DAC_Channel); + } + else + { + /* Disable the selected DAC interrupts */ + DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel)); + } +} + +/** + * @brief Checks whether the specified DAC flag is set or not. + * @param DAC_Channel: thee selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_FLAG: specifies the flag to check. + * This parameter can be only of the following value: + * @arg DAC_FLAG_DMAUDR: DMA underrun flag + * @note The DMA underrun occurs when a second external trigger arrives before + * the acknowledgement for the first external trigger is received (first request). + * @retval The new state of DAC_FLAG (SET or RESET). + */ +FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_FLAG(DAC_FLAG)); + + /* Check the status of the specified DAC flag */ + if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET) + { + /* DAC_FLAG is set */ + bitstatus = SET; + } + else + { + /* DAC_FLAG is reset */ + bitstatus = RESET; + } + /* Return the DAC_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the DAC channel's pending flags. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_FLAG: specifies the flag to clear. + * This parameter can be the following value: + * @arg DAC_FLAG_DMAUDR: DMA underrun flag + * @retval None + */ +void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_FLAG(DAC_FLAG)); + + /* Clear the selected DAC flags */ + DAC->SR = (DAC_FLAG << DAC_Channel); +} + +/** + * @brief Checks whether the specified DAC interrupt has occurred or not. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt source to check. + * This parameter can be the following values: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @note The DMA underrun occurs when a second external trigger arrives before + * the acknowledgement for the first external trigger is received (first request). + * @retval The new state of DAC_IT (SET or RESET). + */ +ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_IT(DAC_IT)); + + /* Get the DAC_IT enable bit status */ + enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ; + + /* Check the status of the specified DAC interrupt */ + if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus) + { + /* DAC_IT is set */ + bitstatus = SET; + } + else + { + /* DAC_IT is reset */ + bitstatus = RESET; + } + /* Return the DAC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the DAC channel's interrupt pending bits. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt pending bit to clear. + * This parameter can be the following values: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @retval None + */ +void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_IT(DAC_IT)); + + /* Clear the selected DAC interrupt pending bits */ + DAC->SR = (DAC_IT << DAC_Channel); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dac.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dac.h new file mode 100644 index 0000000000..2dddd74b14 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dac.h @@ -0,0 +1,305 @@ +/** + ****************************************************************************** + * @file stm32l1xx_dac.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the DAC firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_DAC_H +#define __STM32L1xx_DAC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DAC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief DAC Init structure definition + */ + +typedef struct +{ + uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel. + This parameter can be a value of @ref DAC_trigger_selection */ + + uint32_t DAC_WaveGeneration; /*!< Specifies whether DAC channel noise waves or triangle waves + are generated, or whether no wave is generated. + This parameter can be a value of @ref DAC_wave_generation */ + + uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or + the maximum amplitude triangle generation for the DAC channel. + This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */ + + uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. + This parameter can be a value of @ref DAC_output_buffer */ +}DAC_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DAC_Exported_Constants + * @{ + */ + +/** @defgroup DAC_trigger_selection + * @{ + */ + +#define DAC_Trigger_None ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register + has been loaded, and not by external trigger */ +#define DAC_Trigger_T6_TRGO ((uint32_t)0x00000004) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T7_TRGO ((uint32_t)0x00000014) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T9_TRGO ((uint32_t)0x0000001C) /*!< TIM9 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T2_TRGO ((uint32_t)0x00000024) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T4_TRGO ((uint32_t)0x0000002C) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_Ext_IT9 ((uint32_t)0x00000034) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_Software ((uint32_t)0x0000003C) /*!< Conversion started by software trigger for DAC channel */ + +#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_Trigger_None) || \ + ((TRIGGER) == DAC_Trigger_T6_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T7_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T9_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T2_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T4_TRGO) || \ + ((TRIGGER) == DAC_Trigger_Ext_IT9) || \ + ((TRIGGER) == DAC_Trigger_Software)) + +/** + * @} + */ + +/** @defgroup DAC_wave_generation + * @{ + */ + +#define DAC_WaveGeneration_None ((uint32_t)0x00000000) +#define DAC_WaveGeneration_Noise ((uint32_t)0x00000040) +#define DAC_WaveGeneration_Triangle ((uint32_t)0x00000080) +#define IS_DAC_GENERATE_WAVE(WAVE) (((WAVE) == DAC_WaveGeneration_None) || \ + ((WAVE) == DAC_WaveGeneration_Noise) || \ + ((WAVE) == DAC_WaveGeneration_Triangle)) +/** + * @} + */ + +/** @defgroup DAC_lfsrunmask_triangleamplitude + * @{ + */ + +#define DAC_LFSRUnmask_Bit0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ +#define DAC_LFSRUnmask_Bits1_0 ((uint32_t)0x00000100) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits2_0 ((uint32_t)0x00000200) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits3_0 ((uint32_t)0x00000300) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits4_0 ((uint32_t)0x00000400) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits5_0 ((uint32_t)0x00000500) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits6_0 ((uint32_t)0x00000600) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits7_0 ((uint32_t)0x00000700) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits8_0 ((uint32_t)0x00000800) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits9_0 ((uint32_t)0x00000900) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits10_0 ((uint32_t)0x00000A00) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits11_0 ((uint32_t)0x00000B00) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ +#define DAC_TriangleAmplitude_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */ +#define DAC_TriangleAmplitude_3 ((uint32_t)0x00000100) /*!< Select max triangle amplitude of 3 */ +#define DAC_TriangleAmplitude_7 ((uint32_t)0x00000200) /*!< Select max triangle amplitude of 7 */ +#define DAC_TriangleAmplitude_15 ((uint32_t)0x00000300) /*!< Select max triangle amplitude of 15 */ +#define DAC_TriangleAmplitude_31 ((uint32_t)0x00000400) /*!< Select max triangle amplitude of 31 */ +#define DAC_TriangleAmplitude_63 ((uint32_t)0x00000500) /*!< Select max triangle amplitude of 63 */ +#define DAC_TriangleAmplitude_127 ((uint32_t)0x00000600) /*!< Select max triangle amplitude of 127 */ +#define DAC_TriangleAmplitude_255 ((uint32_t)0x00000700) /*!< Select max triangle amplitude of 255 */ +#define DAC_TriangleAmplitude_511 ((uint32_t)0x00000800) /*!< Select max triangle amplitude of 511 */ +#define DAC_TriangleAmplitude_1023 ((uint32_t)0x00000900) /*!< Select max triangle amplitude of 1023 */ +#define DAC_TriangleAmplitude_2047 ((uint32_t)0x00000A00) /*!< Select max triangle amplitude of 2047 */ +#define DAC_TriangleAmplitude_4095 ((uint32_t)0x00000B00) /*!< Select max triangle amplitude of 4095 */ + +#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUnmask_Bit0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits1_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits2_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits3_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits4_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits5_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits6_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits7_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits8_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits9_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits10_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits11_0) || \ + ((VALUE) == DAC_TriangleAmplitude_1) || \ + ((VALUE) == DAC_TriangleAmplitude_3) || \ + ((VALUE) == DAC_TriangleAmplitude_7) || \ + ((VALUE) == DAC_TriangleAmplitude_15) || \ + ((VALUE) == DAC_TriangleAmplitude_31) || \ + ((VALUE) == DAC_TriangleAmplitude_63) || \ + ((VALUE) == DAC_TriangleAmplitude_127) || \ + ((VALUE) == DAC_TriangleAmplitude_255) || \ + ((VALUE) == DAC_TriangleAmplitude_511) || \ + ((VALUE) == DAC_TriangleAmplitude_1023) || \ + ((VALUE) == DAC_TriangleAmplitude_2047) || \ + ((VALUE) == DAC_TriangleAmplitude_4095)) +/** + * @} + */ + +/** @defgroup DAC_output_buffer + * @{ + */ + +#define DAC_OutputBuffer_Enable ((uint32_t)0x00000000) +#define DAC_OutputBuffer_Disable ((uint32_t)0x00000002) +#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OutputBuffer_Enable) || \ + ((STATE) == DAC_OutputBuffer_Disable)) +/** + * @} + */ + +/** @defgroup DAC_Channel_selection + * @{ + */ + +#define DAC_Channel_1 ((uint32_t)0x00000000) +#define DAC_Channel_2 ((uint32_t)0x00000010) +#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_Channel_1) || \ + ((CHANNEL) == DAC_Channel_2)) +/** + * @} + */ + +/** @defgroup DAC_data_alignment + * @{ + */ + +#define DAC_Align_12b_R ((uint32_t)0x00000000) +#define DAC_Align_12b_L ((uint32_t)0x00000004) +#define DAC_Align_8b_R ((uint32_t)0x00000008) +#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_Align_12b_R) || \ + ((ALIGN) == DAC_Align_12b_L) || \ + ((ALIGN) == DAC_Align_8b_R)) +/** + * @} + */ + +/** @defgroup DAC_wave_generation + * @{ + */ + +#define DAC_Wave_Noise ((uint32_t)0x00000040) +#define DAC_Wave_Triangle ((uint32_t)0x00000080) +#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_Wave_Noise) || \ + ((WAVE) == DAC_Wave_Triangle)) +/** + * @} + */ + +/** @defgroup DAC_data + * @{ + */ + +#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0) + +/** + * @} + */ + +/** @defgroup DAC_interrupts_definition + * @{ + */ + +#define DAC_IT_DMAUDR ((uint32_t)0x00002000) +#define IS_DAC_IT(IT) (((IT) == DAC_IT_DMAUDR)) + +/** + * @} + */ + + +/** @defgroup DAC_flags_definition + * @{ + */ + +#define DAC_FLAG_DMAUDR ((uint32_t)0x00002000) + +#define IS_DAC_FLAG(FLAG) (((FLAG) == DAC_FLAG_DMAUDR)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the DAC configuration to the default reset state *****/ +void DAC_DeInit(void); + +/* DAC channels configuration: trigger, output buffer, data format functions */ +void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct); +void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct); +void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState); +void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState); +void DAC_DualSoftwareTriggerCmd(FunctionalState NewState); +void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState); +void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data); +void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data); +void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1); +uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel); + +/* DMA management functions ***************************************************/ +void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState); +FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG); +void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG); +ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT); +void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_DAC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dbgmcu.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dbgmcu.c new file mode 100644 index 0000000000..24622360a2 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dbgmcu.c @@ -0,0 +1,181 @@ +/** + ****************************************************************************** + * @file stm32l1xx_dbgmcu.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides all the DBGMCU firmware functions. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_dbgmcu.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup DBGMCU + * @brief DBGMCU driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup DBGMCU_Private_Functions + * @{ + */ + +/** + * @brief Returns the device revision identifier. + * @param None + * @retval Device revision identifier + */ +uint32_t DBGMCU_GetREVID(void) +{ + return(DBGMCU->IDCODE >> 16); +} + +/** + * @brief Returns the device identifier. + * @param None + * @retval Device identifier + */ +uint32_t DBGMCU_GetDEVID(void) +{ + return(DBGMCU->IDCODE & IDCODE_DEVID_MASK); +} + +/** + * @brief Configures low power mode behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the low power mode. + * This parameter can be any combination of the following values: + * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode + * @arg DBGMCU_STOP: Keep debugger connection during STOP mode + * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode + * @param NewState: new state of the specified low power mode in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->CR |= DBGMCU_Periph; + } + else + { + DBGMCU->CR &= ~DBGMCU_Periph; + } +} + + +/** + * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the APB1 peripheral. + * This parameter can be any combination of the following values: + * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted + * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted + * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted + * @arg DBGMCU_TIM5_STOP: TIM5 counter stopped when Core is halted + * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted + * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted + * @arg DBGMCU_RTC_STOP: + * + On STM32L1xx Medium-density devices: RTC Wakeup counter stopped when + * Core is halted. + * + On STM32L1xx High-density and Medium-density Plus devices: RTC Calendar + * and Wakeup counter stopped when Core is halted. + * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted + * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted + * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when Core is + * halted + * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when Core is + * halted + * @param NewState: new state of the specified APB1 peripheral in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->APB1FZ |= DBGMCU_Periph; + } + else + { + DBGMCU->APB1FZ &= ~DBGMCU_Periph; + } +} + +/** + * @brief Configures APB2 peripheral behavior when the MCU is in Debug mode. + * @param DBGMCU_Periph: specifies the APB2 peripheral. + * This parameter can be any combination of the following values: + * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted + * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted + * @arg DBGMCU_TIM11_STOP: TIM11 counter stopped when Core is halted + * @param NewState: new state of the specified APB2 peripheral in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_APB2PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->APB2FZ |= DBGMCU_Periph; + } + else + { + DBGMCU->APB2FZ &= ~DBGMCU_Periph; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dbgmcu.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dbgmcu.h new file mode 100644 index 0000000000..7729480db2 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dbgmcu.h @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * @file stm32l1xx_dbgmcu.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the DBGMCU + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_DBGMCU_H +#define __STM32L1xx_DBGMCU_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DBGMCU + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DBGMCU_Exported_Constants + * @{ + */ + +#define DBGMCU_SLEEP ((uint32_t)0x00000001) +#define DBGMCU_STOP ((uint32_t)0x00000002) +#define DBGMCU_STANDBY ((uint32_t)0x00000004) +#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF8) == 0x00) && ((PERIPH) != 0x00)) + +#define DBGMCU_TIM2_STOP ((uint32_t)0x00000001) +#define DBGMCU_TIM3_STOP ((uint32_t)0x00000002) +#define DBGMCU_TIM4_STOP ((uint32_t)0x00000004) +#define DBGMCU_TIM5_STOP ((uint32_t)0x00000008) +#define DBGMCU_TIM6_STOP ((uint32_t)0x00000010) +#define DBGMCU_TIM7_STOP ((uint32_t)0x00000020) +#define DBGMCU_RTC_STOP ((uint32_t)0x00000400) +#define DBGMCU_WWDG_STOP ((uint32_t)0x00000800) +#define DBGMCU_IWDG_STOP ((uint32_t)0x00001000) +#define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00200000) +#define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00400000) +#define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xFF9FE3C0) == 0x00) && ((PERIPH) != 0x00)) + +#define DBGMCU_TIM9_STOP ((uint32_t)0x00000004) +#define DBGMCU_TIM10_STOP ((uint32_t)0x00000008) +#define DBGMCU_TIM11_STOP ((uint32_t)0x00000010) +#define IS_DBGMCU_APB2PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFE3) == 0x00) && ((PERIPH) != 0x00)) + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +uint32_t DBGMCU_GetREVID(void); +uint32_t DBGMCU_GetDEVID(void); +void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); +void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); +void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_DBGMCU_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dma.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dma.c new file mode 100644 index 0000000000..f416e266fd --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dma.c @@ -0,0 +1,866 @@ +/** + ****************************************************************************** + * @file stm32l1xx_dma.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Direct Memory Access controller (DMA): + * + Initialization and Configuration + * + Data Counter + * + Interrupts and flags management + * + * @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable The DMA controller clock using + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE) function for DMA1 or + using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE) function for DMA2. + (#) Enable and configure the peripheral to be connected to the DMA channel + (except for internal SRAM / FLASH memories: no initialization is + necessary). + (#) For a given Channel, program the Source and Destination addresses, + the transfer Direction, the Buffer Size, the Peripheral and Memory + Incrementation mode and Data Size, the Circular or Normal mode, + the channel transfer Priority and the Memory-to-Memory transfer + mode (if needed) using the DMA_Init() function. + (#) Enable the NVIC and the corresponding interrupt(s) using the function + DMA_ITConfig() if you need to use DMA interrupts. + (#) Enable the DMA channel using the DMA_Cmd() function. + (#) Activate the needed channel Request using PPP_DMACmd() function for + any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...) + The function allowing this operation is provided in each PPP peripheral + driver (ie. SPI_DMACmd for SPI peripheral). + (#) Optionally, you can configure the number of data to be transferred + when the channel is disabled (ie. after each Transfer Complete event + or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter(). + And you can get the number of remaining data to be transferred using + the function DMA_GetCurrDataCounter() at run time (when the DMA channel is + enabled and running). + (#) To control DMA events you can use one of the following two methods: + (##) Check on DMA channel flags using the function DMA_GetFlagStatus(). + (##) Use DMA interrupts through the function DMA_ITConfig() at initialization + phase and DMA_GetITStatus() function into interrupt routines in + communication phase. + After checking on a flag you should clear it using DMA_ClearFlag() + function. And after checking on an interrupt event you should + clear it using DMA_ClearITPendingBit() function. + @endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_dma.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup DMA + * @brief DMA driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* DMA1 Channelx interrupt pending bit masks */ +#define DMA1_CHANNEL1_IT_MASK ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1)) +#define DMA1_CHANNEL2_IT_MASK ((uint32_t)(DMA_ISR_GIF2 | DMA_ISR_TCIF2 | DMA_ISR_HTIF2 | DMA_ISR_TEIF2)) +#define DMA1_CHANNEL3_IT_MASK ((uint32_t)(DMA_ISR_GIF3 | DMA_ISR_TCIF3 | DMA_ISR_HTIF3 | DMA_ISR_TEIF3)) +#define DMA1_CHANNEL4_IT_MASK ((uint32_t)(DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4)) +#define DMA1_CHANNEL5_IT_MASK ((uint32_t)(DMA_ISR_GIF5 | DMA_ISR_TCIF5 | DMA_ISR_HTIF5 | DMA_ISR_TEIF5)) +#define DMA1_CHANNEL6_IT_MASK ((uint32_t)(DMA_ISR_GIF6 | DMA_ISR_TCIF6 | DMA_ISR_HTIF6 | DMA_ISR_TEIF6)) +#define DMA1_CHANNEL7_IT_MASK ((uint32_t)(DMA_ISR_GIF7 | DMA_ISR_TCIF7 | DMA_ISR_HTIF7 | DMA_ISR_TEIF7)) + +/* DMA2 Channelx interrupt pending bit masks */ +#define DMA2_CHANNEL1_IT_MASK ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1)) +#define DMA2_CHANNEL2_IT_MASK ((uint32_t)(DMA_ISR_GIF2 | DMA_ISR_TCIF2 | DMA_ISR_HTIF2 | DMA_ISR_TEIF2)) +#define DMA2_CHANNEL3_IT_MASK ((uint32_t)(DMA_ISR_GIF3 | DMA_ISR_TCIF3 | DMA_ISR_HTIF3 | DMA_ISR_TEIF3)) +#define DMA2_CHANNEL4_IT_MASK ((uint32_t)(DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4)) +#define DMA2_CHANNEL5_IT_MASK ((uint32_t)(DMA_ISR_GIF5 | DMA_ISR_TCIF5 | DMA_ISR_HTIF5 | DMA_ISR_TEIF5)) + +/* DMA FLAG mask */ +#define FLAG_MASK ((uint32_t)0x10000000) + +/* DMA registers Masks */ +#define CCR_CLEAR_MASK ((uint32_t)0xFFFF800F) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + + +/** @defgroup DMA_Private_Functions + * @{ + */ + +/** @defgroup DMA_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This subsection provides functions allowing to initialize the DMA channel + source and destination addresses, incrementation and data sizes, transfer + direction, buffer size, circular/normal mode selection, memory-to-memory + mode selection and channel priority value. + [..] The DMA_Init() function follows the DMA configuration procedures as described + in reference manual (RM0038). +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the DMAy Channelx registers to their default reset + * values. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and x can be + * 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @retval None + */ +void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + + /* Disable the selected DMAy Channelx */ + DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR1_EN); + + /* Reset DMAy Channelx control register */ + DMAy_Channelx->CCR = 0; + + /* Reset DMAy Channelx remaining bytes register */ + DMAy_Channelx->CNDTR = 0; + + /* Reset DMAy Channelx peripheral address register */ + DMAy_Channelx->CPAR = 0; + + /* Reset DMAy Channelx memory address register */ + DMAy_Channelx->CMAR = 0; + + if (DMAy_Channelx == DMA1_Channel1) + { + /* Reset interrupt pending bits for DMA1 Channel1 */ + DMA1->IFCR |= DMA1_CHANNEL1_IT_MASK; + } + else if (DMAy_Channelx == DMA1_Channel2) + { + /* Reset interrupt pending bits for DMA1 Channel2 */ + DMA1->IFCR |= DMA1_CHANNEL2_IT_MASK; + } + else if (DMAy_Channelx == DMA1_Channel3) + { + /* Reset interrupt pending bits for DMA1 Channel3 */ + DMA1->IFCR |= DMA1_CHANNEL3_IT_MASK; + } + else if (DMAy_Channelx == DMA1_Channel4) + { + /* Reset interrupt pending bits for DMA1 Channel4 */ + DMA1->IFCR |= DMA1_CHANNEL4_IT_MASK; + } + else if (DMAy_Channelx == DMA1_Channel5) + { + /* Reset interrupt pending bits for DMA1 Channel5 */ + DMA1->IFCR |= DMA1_CHANNEL5_IT_MASK; + } + else if (DMAy_Channelx == DMA1_Channel6) + { + /* Reset interrupt pending bits for DMA1 Channel6 */ + DMA1->IFCR |= DMA1_CHANNEL6_IT_MASK; + } + else if (DMAy_Channelx == DMA1_Channel7) + { + /* Reset interrupt pending bits for DMA1 Channel7 */ + DMA1->IFCR |= DMA1_CHANNEL7_IT_MASK; + } + else if (DMAy_Channelx == DMA2_Channel1) + { + /* Reset interrupt pending bits for DMA2 Channel1 */ + DMA2->IFCR |= DMA2_CHANNEL1_IT_MASK; + } + else if (DMAy_Channelx == DMA2_Channel2) + { + /* Reset interrupt pending bits for DMA2 Channel2 */ + DMA2->IFCR |= DMA2_CHANNEL2_IT_MASK; + } + else if (DMAy_Channelx == DMA2_Channel3) + { + /* Reset interrupt pending bits for DMA2 Channel3 */ + DMA2->IFCR |= DMA2_CHANNEL3_IT_MASK; + } + else if (DMAy_Channelx == DMA2_Channel4) + { + /* Reset interrupt pending bits for DMA2 Channel4 */ + DMA2->IFCR |= DMA2_CHANNEL4_IT_MASK; + } + else + { + if (DMAy_Channelx == DMA2_Channel5) + { + /* Reset interrupt pending bits for DMA2 Channel5 */ + DMA2->IFCR |= DMA2_CHANNEL5_IT_MASK; + } + } +} + +/** + * @brief Initializes the DMAy Channelx according to the specified + * parameters in the DMA_InitStruct. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and x can be + * 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that + * contains the configuration information for the specified DMA Channel. + * @retval None + */ +void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR)); + assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize)); + assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc)); + assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc)); + assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize)); + assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize)); + assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode)); + assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority)); + assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M)); + +/*--------------------------- DMAy Channelx CCR Configuration -----------------*/ + /* Get the DMAy_Channelx CCR value */ + tmpreg = DMAy_Channelx->CCR; + /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ + tmpreg &= CCR_CLEAR_MASK; + /* Configure DMAy Channelx: data transfer, data size, priority level and mode */ + /* Set DIR bit according to DMA_DIR value */ + /* Set CIRC bit according to DMA_Mode value */ + /* Set PINC bit according to DMA_PeripheralInc value */ + /* Set MINC bit according to DMA_MemoryInc value */ + /* Set PSIZE bits according to DMA_PeripheralDataSize value */ + /* Set MSIZE bits according to DMA_MemoryDataSize value */ + /* Set PL bits according to DMA_Priority value */ + /* Set the MEM2MEM bit according to DMA_M2M value */ + tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode | + DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc | + DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize | + DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M; + + /* Write to DMAy Channelx CCR */ + DMAy_Channelx->CCR = tmpreg; + +/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/ + /* Write to DMAy Channelx CNDTR */ + DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize; + +/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/ + /* Write to DMAy Channelx CPAR */ + DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr; + +/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/ + /* Write to DMAy Channelx CMAR */ + DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr; +} + +/** + * @brief Fills each DMA_InitStruct member with its default value. + * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) +{ +/*-------------- Reset DMA init structure parameters values ------------------*/ + /* Initialize the DMA_PeripheralBaseAddr member */ + DMA_InitStruct->DMA_PeripheralBaseAddr = 0; + /* Initialize the DMA_MemoryBaseAddr member */ + DMA_InitStruct->DMA_MemoryBaseAddr = 0; + /* Initialize the DMA_DIR member */ + DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralSRC; + /* Initialize the DMA_BufferSize member */ + DMA_InitStruct->DMA_BufferSize = 0; + /* Initialize the DMA_PeripheralInc member */ + DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable; + /* Initialize the DMA_MemoryInc member */ + DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable; + /* Initialize the DMA_PeripheralDataSize member */ + DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + /* Initialize the DMA_MemoryDataSize member */ + DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + /* Initialize the DMA_Mode member */ + DMA_InitStruct->DMA_Mode = DMA_Mode_Normal; + /* Initialize the DMA_Priority member */ + DMA_InitStruct->DMA_Priority = DMA_Priority_Low; + /* Initialize the DMA_M2M member */ + DMA_InitStruct->DMA_M2M = DMA_M2M_Disable; +} + +/** + * @brief Enables or disables the specified DMAy Channelx. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and x can be + * 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @param NewState: new state of the DMAy Channelx. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DMAy Channelx */ + DMAy_Channelx->CCR |= DMA_CCR1_EN; + } + else + { + /* Disable the selected DMAy Channelx */ + DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR1_EN); + } +} + +/** + * @} + */ + +/** @defgroup DMA_Group2 Data Counter functions + * @brief Data Counter functions + * +@verbatim + =============================================================================== + ##### Data Counter functions ##### + =============================================================================== + [..] This subsection provides function allowing to configure and read the buffer + size (number of data to be transferred).The DMA data counter can be written + only when the DMA channel is disabled (ie. after transfer complete event). + [..] The following function can be used to write the Channel data counter value: + (+) void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t + DataNumber). + -@- It is advised to use this function rather than DMA_Init() in situations + where only the Data buffer needs to be reloaded. + [..] The DMA data counter can be read to indicate the number of remaining transfers + for the relative DMA channel. This counter is decremented at the end of each + data transfer and when the transfer is complete: + (+) If Normal mode is selected: the counter is set to 0. + (+) If Circular mode is selected: the counter is reloaded with the initial + value(configured before enabling the DMA channel). + [..] The following function can be used to read the Channel data counter value: + (+) uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx). + +@endverbatim + * @{ + */ + +/** + * @brief Sets the number of data units in the current DMAy Channelx transfer. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and x can be + * 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @param DataNumber: The number of data units in the current DMAy Channelx + * transfer. + * @note This function can only be used when the DMAy_Channelx is disabled. + * @retval None. + */ +void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + +/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/ + /* Write to DMAy Channelx CNDTR */ + DMAy_Channelx->CNDTR = DataNumber; +} + +/** + * @brief Returns the number of remaining data units in the current + * DMAy Channelx transfer. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and x can be + * 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @retval The number of remaining data units in the current DMAy Channelx + * transfer. + */ +uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + /* Return the number of remaining data units for DMAy Channelx */ + return ((uint16_t)(DMAy_Channelx->CNDTR)); +} + +/** + * @} + */ + +/** @defgroup DMA_Group3 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + [..] This subsection provides functions allowing to configure the DMA Interrupts + sources and check or clear the flags or pending bits status. + The user should identify which mode will be used in his application to manage + the DMA controller events: Polling mode or Interrupt mode. + *** Polling Mode *** + ==================== + [..] Each DMA channel can be managed through 4 event Flags:(y : DMA Controller + number x : DMA channel number ). + (#) DMAy_FLAG_TCx : to indicate that a Transfer Complete event occurred. + (#) DMAy_FLAG_HTx : to indicate that a Half-Transfer Complete event occurred. + (#) DMAy_FLAG_TEx : to indicate that a Transfer Error occurred. + (#) DMAy_FLAG_GLx : to indicate that at least one of the events described + above occurred. + -@- Clearing DMAy_FLAG_GLx results in clearing all other pending flags of the + same channel (DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx). + [..]In this Mode it is advised to use the following functions: + (+) FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG); + (+) void DMA_ClearFlag(uint32_t DMA_FLAG); + + *** Interrupt Mode *** + ====================== + [..] Each DMA channel can be managed through 4 Interrupts: + (+) Interrupt Source + (##) DMA_IT_TC: specifies the interrupt source for the Transfer Complete + event. + (##) DMA_IT_HT : specifies the interrupt source for the Half-transfer Complete + event. + (##) DMA_IT_TE : specifies the interrupt source for the transfer errors event. + (##) DMA_IT_GL : to indicate that at least one of the interrupts described + above occurred. + -@@- Clearing DMA_IT_GL interrupt results in clearing all other interrupts of + the same channel (DMA_IT_TCx, DMA_IT_HT and DMA_IT_TE). + [..]In this Mode it is advised to use the following functions: + (+) void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, + FunctionalState NewState); + (+) ITStatus DMA_GetITStatus(uint32_t DMA_IT); + (+) void DMA_ClearITPendingBit(uint32_t DMA_IT); + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified DMAy Channelx interrupts. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and x can be + * 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @param DMA_IT: specifies the DMA interrupts sources to be enabled + * or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @param NewState: new state of the specified DMA interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_DMA_CONFIG_IT(DMA_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DMA interrupts */ + DMAy_Channelx->CCR |= DMA_IT; + } + else + { + /* Disable the selected DMA interrupts */ + DMAy_Channelx->CCR &= ~DMA_IT; + } +} + +/** + * @brief Checks whether the specified DMAy Channelx flag is set or not. + * @param DMAy_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag. + * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag. + * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag. + * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag. + * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag. + * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag. + * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag. + * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag. + * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag. + * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag. + * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag. + * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag. + * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag. + * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag. + * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag. + * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag. + * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag. + * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag. + * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag. + * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag. + * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag. + * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag. + * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag. + * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag. + * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag. + * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag. + * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag. + * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag. + * @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag. + * @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag. + * @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag. + * @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag. + * @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag. + * @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag. + * @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag. + * @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag. + * @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag. + * @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag. + * @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag. + * @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag. + * @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag. + * @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag. + * @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag. + * @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag. + * @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag. + * @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag. + * @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag. + * @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag. + * + * @note + * The Global flag (DMAy_FLAG_GLx) is set whenever any of the other flags + * relative to the same channel is set (Transfer Complete, Half-transfer + * Complete or Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx or + * DMAy_FLAG_TEx). + * + * @retval The new state of DMAy_FLAG (SET or RESET). + */ +FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_GET_FLAG(DMAy_FLAG)); + + /* Calculate the used DMAy */ + if ((DMAy_FLAG & FLAG_MASK) == (uint32_t)RESET) + { + /* Get DMA1 ISR register value */ + tmpreg = DMA1->ISR; + } + else + { + /* Get DMA2 ISR register value */ + tmpreg = DMA2->ISR; + } + + /* Check the status of the specified DMAy flag */ + if ((tmpreg & DMAy_FLAG) != (uint32_t)RESET) + { + /* DMAy_FLAG is set */ + bitstatus = SET; + } + else + { + /* DMAy_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the DMAy_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the DMAy Channelx's pending flags. + * @param DMAy_FLAG: specifies the flag to clear. + * This parameter can be any combination (for the same DMA) of the following values: + * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag. + * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag. + * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag. + * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag. + * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag. + * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag. + * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag. + * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag. + * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag. + * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag. + * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag. + * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag. + * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag. + * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag. + * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag. + * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag. + * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag. + * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag. + * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag. + * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag. + * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag. + * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag. + * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag. + * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag. + * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag. + * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag. + * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag. + * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag. + * @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag. + * @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag. + * @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag. + * @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag. + * @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag. + * @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag. + * @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag. + * @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag. + * @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag. + * @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag. + * @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag. + * @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag. + * @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag. + * @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag. + * @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag. + * @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag. + * @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag. + * @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag. + * @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag. + * @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag. + * + * @note + * Clearing the Global flag (DMAy_FLAG_GLx) results in clearing all other flags + * relative to the same channel (Transfer Complete, Half-transfer Complete and + * Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx). + * + * @retval None + */ +void DMA_ClearFlag(uint32_t DMAy_FLAG) +{ + /* Check the parameters */ + assert_param(IS_DMA_CLEAR_FLAG(DMAy_FLAG)); + + if ((DMAy_FLAG & FLAG_MASK) == (uint32_t)RESET) + { + /* Clear the selected DMAy flags */ + DMA1->IFCR = DMAy_FLAG; + } + else + { + /* Clear the selected DMAy flags */ + DMA2->IFCR = DMAy_FLAG; + } +} + +/** + * @brief Checks whether the specified DMAy Channelx interrupt has occurred or not. + * @param DMAy_IT: specifies the DMAy interrupt source to check. + * This parameter can be one of the following values: + * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt. + * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt. + * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt. + * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt. + * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt. + * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt. + * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt. + * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt. + * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt. + * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt. + * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt. + * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt. + * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt. + * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt. + * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt. + * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt. + * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt. + * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt. + * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt. + * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt. + * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt. + * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt. + * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt. + * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt. + * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt. + * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt. + * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt. + * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt. + * @arg DMA2_IT_GL1: DMA2 Channel1 global interrupt. + * @arg DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt. + * @arg DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt. + * @arg DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt. + * @arg DMA2_IT_GL2: DMA2 Channel2 global interrupt. + * @arg DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt. + * @arg DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt. + * @arg DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt. + * @arg DMA2_IT_GL3: DMA2 Channel3 global interrupt. + * @arg DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt. + * @arg DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt. + * @arg DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt. + * @arg DMA2_IT_GL4: DMA2 Channel4 global interrupt. + * @arg DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt. + * @arg DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt. + * @arg DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt. + * @arg DMA2_IT_GL5: DMA2 Channel5 global interrupt. + * @arg DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt. + * @arg DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt. + * @arg DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt. + * + * @note + * The Global interrupt (DMAy_FLAG_GLx) is set whenever any of the other + * interrupts relative to the same channel is set (Transfer Complete, + * Half-transfer Complete or Transfer Error interrupts: DMAy_IT_TCx, + * DMAy_IT_HTx or DMAy_IT_TEx). + * + * @retval The new state of DMAy_IT (SET or RESET). + */ +ITStatus DMA_GetITStatus(uint32_t DMAy_IT) +{ + ITStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_GET_IT(DMAy_IT)); + + /* Calculate the used DMAy */ + if ((DMAy_IT & FLAG_MASK) == (uint32_t)RESET) + { + /* Get DMA1 ISR register value */ + tmpreg = DMA1->ISR; + } + else + { + /* Get DMA2 ISR register value */ + tmpreg = DMA2->ISR; + } + + /* Check the status of the specified DMAy interrupt */ + if ((tmpreg & DMAy_IT) != (uint32_t)RESET) + { + /* DMAy_IT is set */ + bitstatus = SET; + } + else + { + /* DMAy_IT is reset */ + bitstatus = RESET; + } + /* Return the DMAy_IT status */ + return bitstatus; +} + +/** + * @brief Clears the DMAy Channelx's interrupt pending bits. + * @param DMAy_IT: specifies the DMAy interrupt pending bit to clear. + * This parameter can be any combination (for the same DMA) of the following values: + * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt. + * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt. + * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt. + * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt. + * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt. + * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt. + * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt. + * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt. + * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt. + * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt. + * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt. + * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt. + * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt. + * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt. + * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt. + * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt. + * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt. + * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt. + * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt. + * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt. + * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt. + * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt. + * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt. + * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt. + * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt. + * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt. + * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt. + * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt. + * @arg DMA2_IT_GL1: DMA2 Channel1 global interrupt. + * @arg DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt. + * @arg DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt. + * @arg DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt. + * @arg DMA2_IT_GL2: DMA2 Channel2 global interrupt. + * @arg DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt. + * @arg DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt. + * @arg DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt. + * @arg DMA2_IT_GL3: DMA2 Channel3 global interrupt. + * @arg DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt. + * @arg DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt. + * @arg DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt. + * @arg DMA2_IT_GL4: DMA2 Channel4 global interrupt. + * @arg DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt. + * @arg DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt. + * @arg DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt. + * @arg DMA2_IT_GL5: DMA2 Channel5 global interrupt. + * @arg DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt. + * @arg DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt. + * @arg DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt. + * + * @note + * Clearing the Global interrupt (DMAy_IT_GLx) results in clearing all other + * interrupts relative to the same channel (Transfer Complete, Half-transfer + * Complete and Transfer Error interrupts: DMAy_IT_TCx, DMAy_IT_HTx and + * DMAy_IT_TEx). + * + * @retval None + */ +void DMA_ClearITPendingBit(uint32_t DMAy_IT) +{ + /* Check the parameters */ + assert_param(IS_DMA_CLEAR_IT(DMAy_IT)); + + /* Calculate the used DMAy */ + if ((DMAy_IT & FLAG_MASK) == (uint32_t)RESET) + { + /* Clear the selected DMAy interrupt pending bits */ + DMA1->IFCR = DMAy_IT; + } + else + { + /* Clear the selected DMAy interrupt pending bits */ + DMA2->IFCR = DMAy_IT; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dma.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dma.h new file mode 100644 index 0000000000..d090535d10 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_dma.h @@ -0,0 +1,435 @@ +/** + ****************************************************************************** + * @file stm32l1xx_dma.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the DMA firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_DMA_H +#define __STM32L1xx_DMA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DMA + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief DMA Init structure definition + */ + +typedef struct +{ + uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */ + + uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */ + + uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination. + This parameter can be a value of @ref DMA_data_transfer_direction */ + + uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel. + The data unit is equal to the configuration set in DMA_PeripheralDataSize + or DMA_MemoryDataSize members depending in the transfer direction. */ + + uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not. + This parameter can be a value of @ref DMA_peripheral_incremented_mode */ + + uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not. + This parameter can be a value of @ref DMA_memory_incremented_mode */ + + uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. + This parameter can be a value of @ref DMA_peripheral_data_size */ + + uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. + This parameter can be a value of @ref DMA_memory_data_size */ + + uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx. + This parameter can be a value of @ref DMA_circular_normal_mode + @note: The circular buffer mode cannot be used if the memory-to-memory + data transfer is configured on the selected Channel */ + + uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx. + This parameter can be a value of @ref DMA_priority_level */ + + uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer. + This parameter can be a value of @ref DMA_memory_to_memory */ +}DMA_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Constants + * @{ + */ + +#define IS_DMA_ALL_PERIPH(PERIPH) (((PERIPH) == DMA1_Channel1) || \ + ((PERIPH) == DMA1_Channel2) || \ + ((PERIPH) == DMA1_Channel3) || \ + ((PERIPH) == DMA1_Channel4) || \ + ((PERIPH) == DMA1_Channel5) || \ + ((PERIPH) == DMA1_Channel6) || \ + ((PERIPH) == DMA1_Channel7) || \ + ((PERIPH) == DMA2_Channel1) || \ + ((PERIPH) == DMA2_Channel2) || \ + ((PERIPH) == DMA2_Channel3) || \ + ((PERIPH) == DMA2_Channel4) || \ + ((PERIPH) == DMA2_Channel5)) + +/** @defgroup DMA_data_transfer_direction + * @{ + */ + +#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010) +#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000) +#define IS_DMA_DIR(DIR) (((DIR) == DMA_DIR_PeripheralDST) || \ + ((DIR) == DMA_DIR_PeripheralSRC)) +/** + * @} + */ + +/** @defgroup DMA_peripheral_incremented_mode + * @{ + */ + +#define DMA_PeripheralInc_Enable ((uint32_t)0x00000040) +#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000) +#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PeripheralInc_Enable) || \ + ((STATE) == DMA_PeripheralInc_Disable)) +/** + * @} + */ + +/** @defgroup DMA_memory_incremented_mode + * @{ + */ + +#define DMA_MemoryInc_Enable ((uint32_t)0x00000080) +#define DMA_MemoryInc_Disable ((uint32_t)0x00000000) +#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MemoryInc_Enable) || \ + ((STATE) == DMA_MemoryInc_Disable)) +/** + * @} + */ + +/** @defgroup DMA_peripheral_data_size + * @{ + */ + +#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) +#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100) +#define DMA_PeripheralDataSize_Word ((uint32_t)0x00000200) +#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PeripheralDataSize_Byte) || \ + ((SIZE) == DMA_PeripheralDataSize_HalfWord) || \ + ((SIZE) == DMA_PeripheralDataSize_Word)) +/** + * @} + */ + +/** @defgroup DMA_memory_data_size + * @{ + */ + +#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) +#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400) +#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800) +#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MemoryDataSize_Byte) || \ + ((SIZE) == DMA_MemoryDataSize_HalfWord) || \ + ((SIZE) == DMA_MemoryDataSize_Word)) +/** + * @} + */ + +/** @defgroup DMA_circular_normal_mode + * @{ + */ + +#define DMA_Mode_Circular ((uint32_t)0x00000020) +#define DMA_Mode_Normal ((uint32_t)0x00000000) +#define IS_DMA_MODE(MODE) (((MODE) == DMA_Mode_Circular) || ((MODE) == DMA_Mode_Normal)) +/** + * @} + */ + +/** @defgroup DMA_priority_level + * @{ + */ + +#define DMA_Priority_VeryHigh ((uint32_t)0x00003000) +#define DMA_Priority_High ((uint32_t)0x00002000) +#define DMA_Priority_Medium ((uint32_t)0x00001000) +#define DMA_Priority_Low ((uint32_t)0x00000000) +#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_Priority_VeryHigh) || \ + ((PRIORITY) == DMA_Priority_High) || \ + ((PRIORITY) == DMA_Priority_Medium) || \ + ((PRIORITY) == DMA_Priority_Low)) +/** + * @} + */ + +/** @defgroup DMA_memory_to_memory + * @{ + */ + +#define DMA_M2M_Enable ((uint32_t)0x00004000) +#define DMA_M2M_Disable ((uint32_t)0x00000000) +#define IS_DMA_M2M_STATE(STATE) (((STATE) == DMA_M2M_Enable) || ((STATE) == DMA_M2M_Disable)) + +/** + * @} + */ + +/** @defgroup DMA_interrupts_definition + * @{ + */ + +#define DMA_IT_TC ((uint32_t)0x00000002) +#define DMA_IT_HT ((uint32_t)0x00000004) +#define DMA_IT_TE ((uint32_t)0x00000008) +#define IS_DMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFFF1) == 0x00) && ((IT) != 0x00)) + +#define DMA1_IT_GL1 ((uint32_t)0x00000001) +#define DMA1_IT_TC1 ((uint32_t)0x00000002) +#define DMA1_IT_HT1 ((uint32_t)0x00000004) +#define DMA1_IT_TE1 ((uint32_t)0x00000008) +#define DMA1_IT_GL2 ((uint32_t)0x00000010) +#define DMA1_IT_TC2 ((uint32_t)0x00000020) +#define DMA1_IT_HT2 ((uint32_t)0x00000040) +#define DMA1_IT_TE2 ((uint32_t)0x00000080) +#define DMA1_IT_GL3 ((uint32_t)0x00000100) +#define DMA1_IT_TC3 ((uint32_t)0x00000200) +#define DMA1_IT_HT3 ((uint32_t)0x00000400) +#define DMA1_IT_TE3 ((uint32_t)0x00000800) +#define DMA1_IT_GL4 ((uint32_t)0x00001000) +#define DMA1_IT_TC4 ((uint32_t)0x00002000) +#define DMA1_IT_HT4 ((uint32_t)0x00004000) +#define DMA1_IT_TE4 ((uint32_t)0x00008000) +#define DMA1_IT_GL5 ((uint32_t)0x00010000) +#define DMA1_IT_TC5 ((uint32_t)0x00020000) +#define DMA1_IT_HT5 ((uint32_t)0x00040000) +#define DMA1_IT_TE5 ((uint32_t)0x00080000) +#define DMA1_IT_GL6 ((uint32_t)0x00100000) +#define DMA1_IT_TC6 ((uint32_t)0x00200000) +#define DMA1_IT_HT6 ((uint32_t)0x00400000) +#define DMA1_IT_TE6 ((uint32_t)0x00800000) +#define DMA1_IT_GL7 ((uint32_t)0x01000000) +#define DMA1_IT_TC7 ((uint32_t)0x02000000) +#define DMA1_IT_HT7 ((uint32_t)0x04000000) +#define DMA1_IT_TE7 ((uint32_t)0x08000000) + +#define DMA2_IT_GL1 ((uint32_t)0x10000001) +#define DMA2_IT_TC1 ((uint32_t)0x10000002) +#define DMA2_IT_HT1 ((uint32_t)0x10000004) +#define DMA2_IT_TE1 ((uint32_t)0x10000008) +#define DMA2_IT_GL2 ((uint32_t)0x10000010) +#define DMA2_IT_TC2 ((uint32_t)0x10000020) +#define DMA2_IT_HT2 ((uint32_t)0x10000040) +#define DMA2_IT_TE2 ((uint32_t)0x10000080) +#define DMA2_IT_GL3 ((uint32_t)0x10000100) +#define DMA2_IT_TC3 ((uint32_t)0x10000200) +#define DMA2_IT_HT3 ((uint32_t)0x10000400) +#define DMA2_IT_TE3 ((uint32_t)0x10000800) +#define DMA2_IT_GL4 ((uint32_t)0x10001000) +#define DMA2_IT_TC4 ((uint32_t)0x10002000) +#define DMA2_IT_HT4 ((uint32_t)0x10004000) +#define DMA2_IT_TE4 ((uint32_t)0x10008000) +#define DMA2_IT_GL5 ((uint32_t)0x10010000) +#define DMA2_IT_TC5 ((uint32_t)0x10020000) +#define DMA2_IT_HT5 ((uint32_t)0x10040000) +#define DMA2_IT_TE5 ((uint32_t)0x10080000) + +#define IS_DMA_CLEAR_IT(IT) (((((IT) & 0xF0000000) == 0x00) || (((IT) & 0xEFF00000) == 0x00)) && ((IT) != 0x00)) + +#define IS_DMA_GET_IT(IT) (((IT) == DMA1_IT_GL1) || ((IT) == DMA1_IT_TC1) || \ + ((IT) == DMA1_IT_HT1) || ((IT) == DMA1_IT_TE1) || \ + ((IT) == DMA1_IT_GL2) || ((IT) == DMA1_IT_TC2) || \ + ((IT) == DMA1_IT_HT2) || ((IT) == DMA1_IT_TE2) || \ + ((IT) == DMA1_IT_GL3) || ((IT) == DMA1_IT_TC3) || \ + ((IT) == DMA1_IT_HT3) || ((IT) == DMA1_IT_TE3) || \ + ((IT) == DMA1_IT_GL4) || ((IT) == DMA1_IT_TC4) || \ + ((IT) == DMA1_IT_HT4) || ((IT) == DMA1_IT_TE4) || \ + ((IT) == DMA1_IT_GL5) || ((IT) == DMA1_IT_TC5) || \ + ((IT) == DMA1_IT_HT5) || ((IT) == DMA1_IT_TE5) || \ + ((IT) == DMA1_IT_GL6) || ((IT) == DMA1_IT_TC6) || \ + ((IT) == DMA1_IT_HT6) || ((IT) == DMA1_IT_TE6) || \ + ((IT) == DMA1_IT_GL7) || ((IT) == DMA1_IT_TC7) || \ + ((IT) == DMA1_IT_HT7) || ((IT) == DMA1_IT_TE7) || \ + ((IT) == DMA2_IT_GL1) || ((IT) == DMA2_IT_TC1) || \ + ((IT) == DMA2_IT_HT1) || ((IT) == DMA2_IT_TE1) || \ + ((IT) == DMA2_IT_GL2) || ((IT) == DMA2_IT_TC2) || \ + ((IT) == DMA2_IT_HT2) || ((IT) == DMA2_IT_TE2) || \ + ((IT) == DMA2_IT_GL3) || ((IT) == DMA2_IT_TC3) || \ + ((IT) == DMA2_IT_HT3) || ((IT) == DMA2_IT_TE3) || \ + ((IT) == DMA2_IT_GL4) || ((IT) == DMA2_IT_TC4) || \ + ((IT) == DMA2_IT_HT4) || ((IT) == DMA2_IT_TE4) || \ + ((IT) == DMA2_IT_GL5) || ((IT) == DMA2_IT_TC5) || \ + ((IT) == DMA2_IT_HT5) || ((IT) == DMA2_IT_TE5)) +/** + * @} + */ + +/** @defgroup DMA_flags_definition + * @{ + */ +#define DMA1_FLAG_GL1 ((uint32_t)0x00000001) +#define DMA1_FLAG_TC1 ((uint32_t)0x00000002) +#define DMA1_FLAG_HT1 ((uint32_t)0x00000004) +#define DMA1_FLAG_TE1 ((uint32_t)0x00000008) +#define DMA1_FLAG_GL2 ((uint32_t)0x00000010) +#define DMA1_FLAG_TC2 ((uint32_t)0x00000020) +#define DMA1_FLAG_HT2 ((uint32_t)0x00000040) +#define DMA1_FLAG_TE2 ((uint32_t)0x00000080) +#define DMA1_FLAG_GL3 ((uint32_t)0x00000100) +#define DMA1_FLAG_TC3 ((uint32_t)0x00000200) +#define DMA1_FLAG_HT3 ((uint32_t)0x00000400) +#define DMA1_FLAG_TE3 ((uint32_t)0x00000800) +#define DMA1_FLAG_GL4 ((uint32_t)0x00001000) +#define DMA1_FLAG_TC4 ((uint32_t)0x00002000) +#define DMA1_FLAG_HT4 ((uint32_t)0x00004000) +#define DMA1_FLAG_TE4 ((uint32_t)0x00008000) +#define DMA1_FLAG_GL5 ((uint32_t)0x00010000) +#define DMA1_FLAG_TC5 ((uint32_t)0x00020000) +#define DMA1_FLAG_HT5 ((uint32_t)0x00040000) +#define DMA1_FLAG_TE5 ((uint32_t)0x00080000) +#define DMA1_FLAG_GL6 ((uint32_t)0x00100000) +#define DMA1_FLAG_TC6 ((uint32_t)0x00200000) +#define DMA1_FLAG_HT6 ((uint32_t)0x00400000) +#define DMA1_FLAG_TE6 ((uint32_t)0x00800000) +#define DMA1_FLAG_GL7 ((uint32_t)0x01000000) +#define DMA1_FLAG_TC7 ((uint32_t)0x02000000) +#define DMA1_FLAG_HT7 ((uint32_t)0x04000000) +#define DMA1_FLAG_TE7 ((uint32_t)0x08000000) + +#define DMA2_FLAG_GL1 ((uint32_t)0x10000001) +#define DMA2_FLAG_TC1 ((uint32_t)0x10000002) +#define DMA2_FLAG_HT1 ((uint32_t)0x10000004) +#define DMA2_FLAG_TE1 ((uint32_t)0x10000008) +#define DMA2_FLAG_GL2 ((uint32_t)0x10000010) +#define DMA2_FLAG_TC2 ((uint32_t)0x10000020) +#define DMA2_FLAG_HT2 ((uint32_t)0x10000040) +#define DMA2_FLAG_TE2 ((uint32_t)0x10000080) +#define DMA2_FLAG_GL3 ((uint32_t)0x10000100) +#define DMA2_FLAG_TC3 ((uint32_t)0x10000200) +#define DMA2_FLAG_HT3 ((uint32_t)0x10000400) +#define DMA2_FLAG_TE3 ((uint32_t)0x10000800) +#define DMA2_FLAG_GL4 ((uint32_t)0x10001000) +#define DMA2_FLAG_TC4 ((uint32_t)0x10002000) +#define DMA2_FLAG_HT4 ((uint32_t)0x10004000) +#define DMA2_FLAG_TE4 ((uint32_t)0x10008000) +#define DMA2_FLAG_GL5 ((uint32_t)0x10010000) +#define DMA2_FLAG_TC5 ((uint32_t)0x10020000) +#define DMA2_FLAG_HT5 ((uint32_t)0x10040000) +#define DMA2_FLAG_TE5 ((uint32_t)0x10080000) + +#define IS_DMA_CLEAR_FLAG(FLAG) (((((FLAG) & 0xF0000000) == 0x00) || (((FLAG) & 0xEFF00000) == 0x00)) && ((FLAG) != 0x00)) + +#define IS_DMA_GET_FLAG(FLAG) (((FLAG) == DMA1_FLAG_GL1) || ((FLAG) == DMA1_FLAG_TC1) || \ + ((FLAG) == DMA1_FLAG_HT1) || ((FLAG) == DMA1_FLAG_TE1) || \ + ((FLAG) == DMA1_FLAG_GL2) || ((FLAG) == DMA1_FLAG_TC2) || \ + ((FLAG) == DMA1_FLAG_HT2) || ((FLAG) == DMA1_FLAG_TE2) || \ + ((FLAG) == DMA1_FLAG_GL3) || ((FLAG) == DMA1_FLAG_TC3) || \ + ((FLAG) == DMA1_FLAG_HT3) || ((FLAG) == DMA1_FLAG_TE3) || \ + ((FLAG) == DMA1_FLAG_GL4) || ((FLAG) == DMA1_FLAG_TC4) || \ + ((FLAG) == DMA1_FLAG_HT4) || ((FLAG) == DMA1_FLAG_TE4) || \ + ((FLAG) == DMA1_FLAG_GL5) || ((FLAG) == DMA1_FLAG_TC5) || \ + ((FLAG) == DMA1_FLAG_HT5) || ((FLAG) == DMA1_FLAG_TE5) || \ + ((FLAG) == DMA1_FLAG_GL6) || ((FLAG) == DMA1_FLAG_TC6) || \ + ((FLAG) == DMA1_FLAG_HT6) || ((FLAG) == DMA1_FLAG_TE6) || \ + ((FLAG) == DMA1_FLAG_GL7) || ((FLAG) == DMA1_FLAG_TC7) || \ + ((FLAG) == DMA1_FLAG_HT7) || ((FLAG) == DMA1_FLAG_TE7) || \ + ((FLAG) == DMA2_FLAG_GL1) || ((FLAG) == DMA2_FLAG_TC1) || \ + ((FLAG) == DMA2_FLAG_HT1) || ((FLAG) == DMA2_FLAG_TE1) || \ + ((FLAG) == DMA2_FLAG_GL2) || ((FLAG) == DMA2_FLAG_TC2) || \ + ((FLAG) == DMA2_FLAG_HT2) || ((FLAG) == DMA2_FLAG_TE2) || \ + ((FLAG) == DMA2_FLAG_GL3) || ((FLAG) == DMA2_FLAG_TC3) || \ + ((FLAG) == DMA2_FLAG_HT3) || ((FLAG) == DMA2_FLAG_TE3) || \ + ((FLAG) == DMA2_FLAG_GL4) || ((FLAG) == DMA2_FLAG_TC4) || \ + ((FLAG) == DMA2_FLAG_HT4) || ((FLAG) == DMA2_FLAG_TE4) || \ + ((FLAG) == DMA2_FLAG_GL5) || ((FLAG) == DMA2_FLAG_TC5) || \ + ((FLAG) == DMA2_FLAG_HT5) || ((FLAG) == DMA2_FLAG_TE5)) +/** + * @} + */ + +/** @defgroup DMA_Buffer_Size + * @{ + */ + +#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the DMA configuration to the default reset state *****/ +void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx); + +/* Initialization and Configuration functions *********************************/ +void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct); +void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct); +void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState); + +/* Data Counter functions *****************************************************/ +void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); +uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx); + +/* Interrupts and flags management functions **********************************/ +void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState); +FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG); +void DMA_ClearFlag(uint32_t DMAy_FLAG); +ITStatus DMA_GetITStatus(uint32_t DMAy_IT); +void DMA_ClearITPendingBit(uint32_t DMAy_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_DMA_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_exti.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_exti.c new file mode 100644 index 0000000000..07e8f3c134 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_exti.c @@ -0,0 +1,315 @@ +/** + ****************************************************************************** + * @file stm32l1xx_exti.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the EXTI peripheral: + * + Initialization and Configuration + * + Interrupts and flags management + * + * @verbatim + ============================================================================== + ##### EXTI features ##### + ============================================================================== + [..] External interrupt/event lines are mapped as following: + (#) All available GPIO pins are connected to the 16 external + interrupt/event lines from EXTI0 to EXTI15. + (#) EXTI line 16 is connected to the PVD output. + (#) EXTI line 17 is connected to the RTC Alarm event. + (#) EXTI line 18 is connected to the USB Device FS wakeup event. + (#) EXTI line 19 is connected to the RTC Tamper and TimeStamp events. + (#) EXTI line 20 is connected to the RTC Wakeup event. + (#) EXTI line 21 is connected to the Comparator 1 wakeup event. + (#) EXTI line 22 is connected to the Comparator 2 wakeup event. + (#) EXTI line 23 is connected to the Comparator channel acquisition wakeup event. + + + ##### How to use this driver ##### + ============================================================================== + [..] In order to use an I/O pin as an external interrupt source, follow + steps below: + (#) Configure the I/O in input mode using GPIO_Init() + (#) Select the input source pin for the EXTI line using + SYSCFG_EXTILineConfig() + (#) Select the mode(interrupt, event) and configure the trigger + selection (Rising, falling or both) using EXTI_Init() + (#) Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init() + [..] + (@) SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx + registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); + + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_exti.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup EXTI + * @brief EXTI driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define EXTI_LINENONE ((uint32_t)0x00000) /* No interrupt selected */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup EXTI_Private_Functions + * @{ + */ + +/** @defgroup EXTI_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the EXTI peripheral registers to their default reset values. + * @param None + * @retval None + */ +void EXTI_DeInit(void) +{ + EXTI->IMR = 0x00000000; + EXTI->EMR = 0x00000000; + EXTI->RTSR = 0x00000000; + EXTI->FTSR = 0x00000000; + EXTI->PR = 0x00FFFFFF; +} + +/** + * @brief Initializes the EXTI peripheral according to the specified + * parameters in the EXTI_InitStruct. + * EXTI_Line specifies the EXTI line (EXTI0....EXTI23). + * EXTI_Mode specifies which EXTI line is used as interrupt or an event. + * EXTI_Trigger selects the trigger. When the trigger occurs, interrupt + * pending bit will be set. + * EXTI_LineCmd controls (Enable/Disable) the EXTI line. + * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure + * that contains the configuration information for the EXTI peripheral. + * @retval None + */ +void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) +{ + uint32_t tmp = 0; + + /* 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)); + + tmp = (uint32_t)EXTI_BASE; + + if (EXTI_InitStruct->EXTI_LineCmd != DISABLE) + { + /* Clear EXTI line configuration */ + EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line; + EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line; + + tmp += EXTI_InitStruct->EXTI_Mode; + + *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; + + /* Clear Rising Falling edge configuration */ + EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line; + EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line; + + /* Select the trigger for the selected external interrupts */ + if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) + { + /* Rising Falling edge */ + EXTI->RTSR |= EXTI_InitStruct->EXTI_Line; + EXTI->FTSR |= EXTI_InitStruct->EXTI_Line; + } + else + { + tmp = (uint32_t)EXTI_BASE; + tmp += EXTI_InitStruct->EXTI_Trigger; + + *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; + } + } + else + { + tmp += EXTI_InitStruct->EXTI_Mode; + + /* Disable the selected external lines */ + *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line; + } +} + +/** + * @brief Fills each EXTI_InitStruct member with its reset value. + * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) +{ + EXTI_InitStruct->EXTI_Line = EXTI_LINENONE; + EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling; + EXTI_InitStruct->EXTI_LineCmd = DISABLE; +} + +/** + * @brief Generates a Software interrupt on selected EXTI line. + * @param EXTI_Line: specifies the EXTI line on which the software interrupt + * will be generated. + * This parameter can be any combination of EXTI_Linex where x can be (0..23). + * @retval None + */ +void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->SWIER |= EXTI_Line; +} + +/** + * @} + */ + +/** @defgroup EXTI_Group2 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + ============================================================================== + ##### Interrupts and flags management functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Checks whether the specified EXTI line flag is set or not. + * @param EXTI_Line: specifies the EXTI line flag to check. + * This parameter can be: + * EXTI_Linex: External interrupt line x where x(0..23). + * @retval The new state of EXTI_Line (SET or RESET). + */ +FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the EXTI's line pending flags. + * @param EXTI_Line: specifies the EXTI lines flags to clear. + * This parameter can be any combination of EXTI_Linex where x can be (0..23). + * @retval None + */ +void EXTI_ClearFlag(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->PR = EXTI_Line; +} + +/** + * @brief Checks whether the specified EXTI line is asserted or not. + * @param EXTI_Line: specifies the EXTI line to check. + * This parameter can be: + * EXTI_Linex: External interrupt line x where x(0..23). + * @retval The new state of EXTI_Line (SET or RESET). + */ +ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the EXTI's line pending bits. + * @param EXTI_Line: specifies the EXTI lines to clear. + * This parameter can be any combination of EXTI_Linex where x can be (0..23). + * @retval None + */ +void EXTI_ClearITPendingBit(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->PR = EXTI_Line; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_exti.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_exti.h new file mode 100644 index 0000000000..1b437dc5d3 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_exti.h @@ -0,0 +1,199 @@ +/** + ****************************************************************************** + * @file stm32l1xx_exti.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the EXTI firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_EXTI_H +#define __STM32L1xx_EXTI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup EXTI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief EXTI mode enumeration + */ + +typedef enum +{ + EXTI_Mode_Interrupt = 0x00, + EXTI_Mode_Event = 0x04 +}EXTIMode_TypeDef; + +#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event)) + +/** + * @brief EXTI Trigger enumeration + */ + +typedef enum +{ + EXTI_Trigger_Rising = 0x08, + EXTI_Trigger_Falling = 0x0C, + EXTI_Trigger_Rising_Falling = 0x10 +}EXTITrigger_TypeDef; + +#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \ + ((TRIGGER) == EXTI_Trigger_Falling) || \ + ((TRIGGER) == EXTI_Trigger_Rising_Falling)) +/** + * @brief EXTI Init Structure definition + */ + +typedef struct +{ + uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. + This parameter can be any combination of @ref EXTI_Lines */ + + EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. + This parameter can be a value of @ref EXTIMode_TypeDef */ + + EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. + This parameter can be a value of @ref EXTITrigger_TypeDef */ + + FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. + This parameter can be set either to ENABLE or DISABLE */ +}EXTI_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup EXTI_Exported_Constants + * @{ + */ + +/** @defgroup EXTI_Lines + * @{ + */ + +#define EXTI_Line0 ((uint32_t)0x00000001) /*!< External interrupt line 0 */ +#define EXTI_Line1 ((uint32_t)0x00000002) /*!< External interrupt line 1 */ +#define EXTI_Line2 ((uint32_t)0x00000004) /*!< External interrupt line 2 */ +#define EXTI_Line3 ((uint32_t)0x00000008) /*!< External interrupt line 3 */ +#define EXTI_Line4 ((uint32_t)0x00000010) /*!< External interrupt line 4 */ +#define EXTI_Line5 ((uint32_t)0x00000020) /*!< External interrupt line 5 */ +#define EXTI_Line6 ((uint32_t)0x00000040) /*!< External interrupt line 6 */ +#define EXTI_Line7 ((uint32_t)0x00000080) /*!< External interrupt line 7 */ +#define EXTI_Line8 ((uint32_t)0x00000100) /*!< External interrupt line 8 */ +#define EXTI_Line9 ((uint32_t)0x00000200) /*!< External interrupt line 9 */ +#define EXTI_Line10 ((uint32_t)0x00000400) /*!< External interrupt line 10 */ +#define EXTI_Line11 ((uint32_t)0x00000800) /*!< External interrupt line 11 */ +#define EXTI_Line12 ((uint32_t)0x00001000) /*!< External interrupt line 12 */ +#define EXTI_Line13 ((uint32_t)0x00002000) /*!< External interrupt line 13 */ +#define EXTI_Line14 ((uint32_t)0x00004000) /*!< External interrupt line 14 */ +#define EXTI_Line15 ((uint32_t)0x00008000) /*!< External interrupt line 15 */ +#define EXTI_Line16 ((uint32_t)0x00010000) /*!< External interrupt line 16 + Connected to the PVD Output */ +#define EXTI_Line17 ((uint32_t)0x00020000) /*!< External interrupt line 17 + Connected to the RTC Alarm + event */ +#define EXTI_Line18 ((uint32_t)0x00040000) /*!< External interrupt line 18 + Connected to the USB Device + FS Wakeup from suspend event */ +#define EXTI_Line19 ((uint32_t)0x00080000) /*!< External interrupt line 19 + Connected to the RTC Tamper + and Time Stamp events */ +#define EXTI_Line20 ((uint32_t)0x00100000) /*!< External interrupt line 20 + Connected to the RTC Wakeup + event */ +#define EXTI_Line21 ((uint32_t)0x00200000) /*!< External interrupt line 21 + Connected to the Comparator 1 + event */ + +#define EXTI_Line22 ((uint32_t)0x00400000) /*!< External interrupt line 22 + Connected to the Comparator 2 + event */ + +#define EXTI_Line23 ((uint32_t)0x00800000) /*!< External interrupt line 23 + Comparator channel acquisition event */ + +#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFF000000) == 0x00) && ((LINE) != (uint16_t)0x00)) + +#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \ + ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \ + ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \ + ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \ + ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \ + ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \ + ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \ + ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \ + ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \ + ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19) || \ + ((LINE) == EXTI_Line20) || ((LINE) == EXTI_Line21) || \ + ((LINE) == EXTI_Line22) || ((LINE) == EXTI_Line23)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Function used to set the EXTI configuration to the default reset state *****/ +void EXTI_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); + +/* Interrupts and flags management functions **********************************/ +FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); +void EXTI_ClearFlag(uint32_t EXTI_Line); +ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); +void EXTI_ClearITPendingBit(uint32_t EXTI_Line); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_EXTI_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash.c new file mode 100644 index 0000000000..59a2627c85 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash.c @@ -0,0 +1,1843 @@ +/** + ****************************************************************************** + * @file stm32l1xx_flash.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides all the Flash firmware functions. These functions + * can be executed from Internal FLASH or Internal SRAM memories. + * The functions that should be called from SRAM are defined inside + * the "stm32l1xx_flash_ramfunc.c" file. + * This file provides firmware functions to manage the following + * functionalities of the FLASH peripheral: + * + FLASH Interface configuration + * + FLASH Memory Programming + * + DATA EEPROM Programming + * + Option Bytes Programming + * + Interrupts and flags management + * + * @verbatim + + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure and program the Flash + memory of all STM32L1xx devices. + [..] These functions are split in 5 groups: + (#) FLASH Interface configuration functions: this group includes + the management of following features: + (++) Set the latency. + (++) Enable/Disable the prefetch buffer. + (++) Enable/Disable the 64 bit Read Access. + (++) Enable/Disable the RUN PowerDown mode. + (++) Enable/Disable the SLEEP PowerDown mode. + + (#) FLASH Memory Programming functions: this group includes all + needed functions to erase and program the main memory: + (++) Lock and Unlock the Flash interface. + (++) Erase function: Erase Page. + (++) Program functions: Fast Word and Half Page(should be + executed from internal SRAM). + + (#) DATA EEPROM Programming functions: this group includes all + needed functions to erase and program the DATA EEPROM memory: + (++) Lock and Unlock the DATA EEPROM interface. + (++) Erase function: Erase Byte, erase HalfWord, erase Word, erase + (++) Double Word (should be executed from internal SRAM). + (++) Program functions: Fast Program Byte, Fast Program Half-Word, + FastProgramWord, Program Byte, Program Half-Word, + Program Word and Program Double-Word (should be executed + from internal SRAM). + + (#) FLASH Option Bytes Programming functions: this group includes + all needed functions to: + (++) Lock and Unlock the Flash Option bytes. + (++) Set/Reset the write protection. + (++) Set the Read protection Level. + (++) Set the BOR level. + (++) rogram the user option Bytes. + (++) Launch the Option Bytes loader. + (++) Get the Write protection. + (++) Get the read protection status. + (++) Get the BOR level. + (++) Get the user option bytes. + + (#) FLASH Interrupts and flag management functions: this group + includes all needed functions to: + (++) Enable/Disable the flash interrupt sources. + (++) Get flags status. + (++) Clear flags. + (++) Get Flash operation status. + (++) Wait for last flash operation. + + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_flash.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup FLASH + * @brief FLASH driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* FLASH Mask */ +#define WRP01_MASK ((uint32_t)0x0000FFFF) +#define WRP23_MASK ((uint32_t)0xFFFF0000) +#define WRP45_MASK ((uint32_t)0x0000FFFF) +#define WRP67_MASK ((uint32_t)0xFFFF0000) +#define WRP89_MASK ((uint32_t)0x0000FFFF) +#define WRP1011_MASK ((uint32_t)0xFFFF0000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup FLASH_Private_Functions + * @{ + */ + +/** @defgroup FLASH_Group1 FLASH Interface configuration functions + * @brief FLASH Interface configuration functions + * +@verbatim + ============================================================================== + ##### FLASH Interface configuration functions ##### + ============================================================================== + + [..] FLASH_Interface configuration_Functions, includes the following functions: + (+) void FLASH_SetLatency(uint32_t FLASH_Latency): + [..] To correctly read data from Flash memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the CPU clock + (HCLK) and the supply voltage of the device. + [..] + ---------------------------------------------------------------- + | Wait states | HCLK clock frequency (MHz) | + | |------------------------------------------------| + | (Latency) | voltage range | voltage range | + | | 1.65 V - 3.6 V | 2.0 V - 3.6 V | + | |----------------|---------------|---------------| + | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V | + |-------------- |----------------|---------------|---------------| + |0WS(1CPU cycle)|0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 | + |---------------|----------------|---------------|---------------| + |1WS(2CPU cycle)|2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32| + ---------------------------------------------------------------- + [..] + (+) void FLASH_PrefetchBufferCmd(FunctionalState NewState); + (+) void FLASH_ReadAccess64Cmd(FunctionalState NewState); + (+) void FLASH_RUNPowerDownCmd(FunctionalState NewState); + (+) void FLASH_SLEEPPowerDownCmd(FunctionalState NewState); + (+) void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); + [..] + Here below the allowed configuration of Latency, 64Bit access and prefetch buffer + [..] + -------------------------------------------------------------------------------- + | | ACC64 = 0 | ACC64 = 1 | + | Latency |----------------|---------------|---------------|---------------| + | | PRFTEN = 0 | PRFTEN = 1 | PRFTEN = 0 | PRFTEN = 1 | + |---------------|----------------|---------------|---------------|---------------| + |0WS(1CPU cycle)| YES | NO | YES | YES | + |---------------|----------------|---------------|---------------|---------------| + |1WS(2CPU cycle)| NO | NO | YES | YES | + -------------------------------------------------------------------------------- + [..] + All these functions don't need the unlock sequence. + +@endverbatim + * @{ + */ + +/** + * @brief Sets the code latency value. + * @param FLASH_Latency: specifies the FLASH Latency value. + * This parameter can be one of the following values: + * @arg FLASH_Latency_0: FLASH Zero Latency cycle. + * @arg FLASH_Latency_1: FLASH One Latency cycle. + * @retval None + */ +void FLASH_SetLatency(uint32_t FLASH_Latency) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_FLASH_LATENCY(FLASH_Latency)); + + /* Read the ACR register */ + tmpreg = FLASH->ACR; + + /* Sets the Latency value */ + tmpreg &= (uint32_t) (~((uint32_t)FLASH_ACR_LATENCY)); + tmpreg |= FLASH_Latency; + + /* Write the ACR register */ + FLASH->ACR = tmpreg; +} + +/** + * @brief Enables or disables the Prefetch Buffer. + * @param NewState: new state of the FLASH prefetch buffer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_PrefetchBufferCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState != DISABLE) + { + FLASH->ACR |= FLASH_ACR_PRFTEN; + } + else + { + FLASH->ACR &= (uint32_t)(~((uint32_t)FLASH_ACR_PRFTEN)); + } +} + +/** + * @brief Enables or disables read access to flash by 64 bits. + * @param NewState: new state of the FLASH read access mode. + * This parameter can be: ENABLE or DISABLE. + * @note If this bit is set, the Read access 64 bit is used. + * If this bit is reset, the Read access 32 bit is used. + * @note This bit cannot be written at the same time as the LATENCY and + * PRFTEN bits. + * To reset this bit, the LATENCY should be zero wait state and the + * prefetch off. + * @retval None + */ +void FLASH_ReadAccess64Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState != DISABLE) + { + FLASH->ACR |= FLASH_ACR_ACC64; + } + else + { + FLASH->ACR &= (uint32_t)(~((uint32_t)FLASH_ACR_ACC64)); + } +} + +/** + * @brief Enable or disable the power down mode during Sleep mode. + * @note This function is used to power down the FLASH when the system is in SLEEP LP mode. + * @param NewState: new state of the power down mode during sleep mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_SLEEPPowerDownCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the SLEEP_PD bit to put Flash in power down mode during sleep mode */ + FLASH->ACR |= FLASH_ACR_SLEEP_PD; + } + else + { + /* Clear the SLEEP_PD bit in to put Flash in idle mode during sleep mode */ + FLASH->ACR &= (uint32_t)(~((uint32_t)FLASH_ACR_SLEEP_PD)); + } +} + +/** + * @} + */ + +/** @defgroup FLASH_Group2 FLASH Memory Programming functions + * @brief FLASH Memory Programming functions + * +@verbatim + ============================================================================== + ##### FLASH Memory Programming functions ##### + ============================================================================== + + [..] The FLASH Memory Programming functions, includes the following functions: + (+) void FLASH_Unlock(void); + (+) void FLASH_Lock(void); + (+) FLASH_Status FLASH_ErasePage(uint32_t Page_Address); + (+) FLASH_Status FLASH_FastProgramWord(uint32_t Address, uint32_t Data); + + [..] Any operation of erase or program should follow these steps: + (#) Call the FLASH_Unlock() function to enable the flash control register and + program memory access. + (#) Call the desired function to erase page or program data. + (#) Call the FLASH_Lock() to disable the flash program memory access + (recommended to protect the FLASH memory against possible unwanted operation). + +@endverbatim + * @{ + */ + +/** + * @brief Unlocks the FLASH control register and program memory access. + * @param None + * @retval None + */ +void FLASH_Unlock(void) +{ + if((FLASH->PECR & FLASH_PECR_PRGLOCK) != RESET) + { + /* Unlocking the data memory and FLASH_PECR register access */ + DATA_EEPROM_Unlock(); + + /* Unlocking the program memory access */ + FLASH->PRGKEYR = FLASH_PRGKEY1; + FLASH->PRGKEYR = FLASH_PRGKEY2; + } +} + +/** + * @brief Locks the Program memory access. + * @param None + * @retval None + */ +void FLASH_Lock(void) +{ + /* Set the PRGLOCK Bit to lock the program memory access */ + FLASH->PECR |= FLASH_PECR_PRGLOCK; +} + +/** + * @brief Erases a specified page in program memory. + * @note To correctly run this function, the FLASH_Unlock() function + * must be called before. + * Call the FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation) + * @param Page_Address: The page address in program memory to be erased. + * @note A Page is erased in the Program memory only if the address to load + * is the start address of a page (multiple of 256 bytes). + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ErasePage(uint32_t Page_Address) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS(Page_Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to erase the page */ + + /* Set the ERASE bit */ + FLASH->PECR |= FLASH_PECR_ERASE; + + /* Set PROG bit */ + FLASH->PECR |= FLASH_PECR_PROG; + + /* Write 00000000h to the first word of the program page to erase */ + *(__IO uint32_t *)Page_Address = 0x00000000; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* If the erase operation is completed, disable the ERASE and PROG bits */ + FLASH->PECR &= (uint32_t)(~FLASH_PECR_PROG); + FLASH->PECR &= (uint32_t)(~FLASH_PECR_ERASE); + } + /* Return the Erase Status */ + return status; +} + +/** + * @brief Programs a word at a specified address in program memory. + * @note To correctly run this function, the FLASH_Unlock() function + * must be called before. + * Call the FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation). + * @param Address: specifies the address to be written. + * @param Data: specifies the data to be written. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_FastProgramWord(uint32_t Address, uint32_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to program the new word */ + *(__IO uint32_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + /* Return the Write Status */ + return status; +} + +/** + * @} + */ + +/** @defgroup FLASH_Group3 DATA EEPROM Programming functions + * @brief DATA EEPROM Programming functions + * +@verbatim + =============================================================================== + ##### DATA EEPROM Programming functions ##### + =============================================================================== + + [..] The DATA_EEPROM Programming_Functions, includes the following functions: + (+) void DATA_EEPROM_Unlock(void); + (+) void DATA_EEPROM_Lock(void); + (+) FLASH_Status DATA_EEPROM_EraseByte(uint32_t Address); + (+) FLASH_Status DATA_EEPROM_EraseHalfWord(uint32_t Address); + (+) FLASH_Status DATA_EEPROM_EraseWord(uint32_t Address); + (+) FLASH_Status DATA_EEPROM_FastProgramByte(uint32_t Address, uint8_t Data); + (+) FLASH_Status DATA_EEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data); + (+) FLASH_Status DATA_EEPROM_FastProgramWord(uint32_t Address, uint32_t Data); + (+) FLASH_Status DATA_EEPROM_ProgramByte(uint32_t Address, uint8_t Data); + (+) FLASH_Status DATA_EEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data); + (+) FLASH_Status DATA_EEPROM_ProgramWord(uint32_t Address, uint32_t Data); + + [..] Any operation of erase or program should follow these steps: + (#) Call the DATA_EEPROM_Unlock() function to enable the data EEPROM access + and Flash program erase control register access. + (#) Call the desired function to erase or program data. + (#) Call the DATA_EEPROM_Lock() to disable the data EEPROM access + and Flash program erase control register access(recommended + to protect the DATA_EEPROM against possible unwanted operation). + +@endverbatim + * @{ + */ + +/** + * @brief Unlocks the data memory and FLASH_PECR register access. + * @param None + * @retval None + */ +void DATA_EEPROM_Unlock(void) +{ + if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET) + { + /* Unlocking the Data memory and FLASH_PECR register access*/ + FLASH->PEKEYR = FLASH_PEKEY1; + FLASH->PEKEYR = FLASH_PEKEY2; + } +} + +/** + * @brief Locks the Data memory and FLASH_PECR register access. + * @param None + * @retval None + */ +void DATA_EEPROM_Lock(void) +{ + /* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */ + FLASH->PECR |= FLASH_PECR_PELOCK; +} + +/** + * @brief Enables or disables DATA EEPROM fixed Time programming (2*Tprog). + * @param NewState: new state of the DATA EEPROM fixed Time programming mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DATA_EEPROM_FixedTimeProgramCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState != DISABLE) + { + FLASH->PECR |= (uint32_t)FLASH_PECR_FTDW; + } + else + { + FLASH->PECR &= (uint32_t)(~((uint32_t)FLASH_PECR_FTDW)); + } +} + +/** + * @brief Erase a byte in data memory. + * @param Address: specifies the address to be erased. + * @note This function can be used only for STM32L1XX_HD and STM32L1XX_MDP + * density devices. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_EraseByte(uint32_t Address) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Write "00h" to valid address in the data memory" */ + *(__IO uint8_t *) Address = (uint8_t)0x00; + } + + /* Return the erase status */ + return status; +} + +/** + * @brief Erase a halfword in data memory. + * @param Address: specifies the address to be erased. + * @note This function can be used only for STM32L1XX_HD and STM32L1XX_MDP + * density devices. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_EraseHalfWord(uint32_t Address) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Write "0000h" to valid address in the data memory" */ + *(__IO uint16_t *) Address = (uint16_t)0x0000; + } + + /* Return the erase status */ + return status; +} + +/** + * @brief Erase a word in data memory. + * @param Address: specifies the address to be erased. + * @note For STM32L1XX_MD, A data memory word is erased in the data memory only + * if the address to load is the start address of a word (multiple of a word). + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_EraseWord(uint32_t Address) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Write "00000000h" to valid address in the data memory" */ + *(__IO uint32_t *) Address = 0x00000000; + } + + /* Return the erase status */ + return status; +} + +/** + * @brief Write a Byte at a specified address in data memory. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @param Address: specifies the address to be written. + * @param Data: specifies the data to be written. + * @note This function assumes that the is data word is already erased. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_FastProgramByte(uint32_t Address, uint8_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; +#if !defined (STM32L1XX_HD) && !defined (STM32L1XX_MDP) + uint32_t tmp = 0, tmpaddr = 0; +#endif + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Clear the FTDW bit */ + FLASH->PECR &= (uint32_t)(~((uint32_t)FLASH_PECR_FTDW)); + +#if !defined (STM32L1XX_HD) && !defined (STM32L1XX_MDP) + if(Data != (uint8_t)0x00) + { + /* If the previous operation is completed, proceed to write the new Data */ + *(__IO uint8_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + else + { + tmpaddr = Address & 0xFFFFFFFC; + tmp = * (__IO uint32_t *) tmpaddr; + tmpaddr = 0xFF << ((uint32_t) (0x8 * (Address & 0x3))); + tmp &= ~tmpaddr; + status = DATA_EEPROM_EraseWord(Address & 0xFFFFFFFC); + status = DATA_EEPROM_FastProgramWord((Address & 0xFFFFFFFC), tmp); + } +#elif defined (STM32L1XX_HD) || defined (STM32L1XX_MDP) + /* If the previous operation is completed, proceed to write the new Data */ + *(__IO uint8_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); +#endif + } + /* Return the Write Status */ + return status; +} + +/** + * @brief Writes a half word at a specified address in data memory. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @param Address: specifies the address to be written. + * @param Data: specifies the data to be written. + * @note This function assumes that the is data word is already erased. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; +#if !defined (STM32L1XX_HD) && !defined (STM32L1XX_MDP) + uint32_t tmp = 0, tmpaddr = 0; +#endif + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Clear the FTDW bit */ + FLASH->PECR &= (uint32_t)(~((uint32_t)FLASH_PECR_FTDW)); + +#if !defined (STM32L1XX_HD) && !defined (STM32L1XX_MDP) + if(Data != (uint16_t)0x0000) + { + /* If the previous operation is completed, proceed to write the new data */ + *(__IO uint16_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + else + { + if((Address & 0x3) != 0x3) + { + tmpaddr = Address & 0xFFFFFFFC; + tmp = * (__IO uint32_t *) tmpaddr; + tmpaddr = 0xFFFF << ((uint32_t) (0x8 * (Address & 0x3))); + tmp &= ~tmpaddr; + status = DATA_EEPROM_EraseWord(Address & 0xFFFFFFFC); + status = DATA_EEPROM_FastProgramWord((Address & 0xFFFFFFFC), tmp); + } + else + { + DATA_EEPROM_FastProgramByte(Address, 0x00); + DATA_EEPROM_FastProgramByte(Address + 1, 0x00); + } + } +#elif defined (STM32L1XX_HD) || defined (STM32L1XX_MDP) + /* If the previous operation is completed, proceed to write the new data */ + *(__IO uint16_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); +#endif + } + /* Return the Write Status */ + return status; +} + +/** + * @brief Programs a word at a specified address in data memory. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to the data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @param Address: specifies the address to be written. + * @param Data: specifies the data to be written. + * @note This function assumes that the is data word is already erased. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_FastProgramWord(uint32_t Address, uint32_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Clear the FTDW bit */ + FLASH->PECR &= (uint32_t)(~((uint32_t)FLASH_PECR_FTDW)); + + /* If the previous operation is completed, proceed to program the new data */ + *(__IO uint32_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + /* Return the Write Status */ + return status; +} + +/** + * @brief Write a Byte at a specified address in data memory without erase. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @note The function DATA_EEPROM_FixedTimeProgramCmd() can be called before + * this function to configure the Fixed Time Programming. + * @param Address: specifies the address to be written. + * @param Data: specifies the data to be written. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_ProgramByte(uint32_t Address, uint8_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; +#if !defined (STM32L1XX_HD) && !defined (STM32L1XX_MDP) + uint32_t tmp = 0, tmpaddr = 0; +#endif + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { +#if !defined (STM32L1XX_HD) && !defined (STM32L1XX_MDP) + if(Data != (uint8_t) 0x00) + { + *(__IO uint8_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + } + else + { + tmpaddr = Address & 0xFFFFFFFC; + tmp = * (__IO uint32_t *) tmpaddr; + tmpaddr = 0xFF << ((uint32_t) (0x8 * (Address & 0x3))); + tmp &= ~tmpaddr; + status = DATA_EEPROM_EraseWord(Address & 0xFFFFFFFC); + status = DATA_EEPROM_FastProgramWord((Address & 0xFFFFFFFC), tmp); + } +#elif defined (STM32L1XX_HD) || defined (STM32L1XX_MDP) + *(__IO uint8_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); +#endif + } + /* Return the Write Status */ + return status; +} + +/** + * @brief Writes a half word at a specified address in data memory without erase. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @note The function DATA_EEPROM_FixedTimeProgramCmd() can be called before + * this function to configure the Fixed Time Programming + * @param Address: specifies the address to be written. + * @param Data: specifies the data to be written. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; +#if !defined (STM32L1XX_HD) && !defined (STM32L1XX_MDP) + uint32_t tmp = 0, tmpaddr = 0; +#endif + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { +#if !defined (STM32L1XX_HD) && !defined (STM32L1XX_MDP) + if(Data != (uint16_t)0x0000) + { + *(__IO uint16_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + else + { + if((Address & 0x3) != 0x3) + { + tmpaddr = Address & 0xFFFFFFFC; + tmp = * (__IO uint32_t *) tmpaddr; + tmpaddr = 0xFFFF << ((uint32_t) (0x8 * (Address & 0x3))); + tmp &= ~tmpaddr; + status = DATA_EEPROM_EraseWord(Address & 0xFFFFFFFC); + status = DATA_EEPROM_FastProgramWord((Address & 0xFFFFFFFC), tmp); + } + else + { + DATA_EEPROM_FastProgramByte(Address, 0x00); + DATA_EEPROM_FastProgramByte(Address + 1, 0x00); + } + } +#elif defined (STM32L1XX_HD) || defined (STM32L1XX_MDP) + *(__IO uint16_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); +#endif + } + /* Return the Write Status */ + return status; +} + +/** + * @brief Programs a word at a specified address in data memory without erase. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @note The function DATA_EEPROM_FixedTimeProgramCmd() can be called before + * this function to configure the Fixed Time Programming. + * @param Address: specifies the address to be written. + * @param Data: specifies the data to be written. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status DATA_EEPROM_ProgramWord(uint32_t Address, uint32_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + *(__IO uint32_t *)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + /* Return the Write Status */ + return status; +} + +/** + * @} + */ + +/** @defgroup FLASH_Group4 Option Bytes Programming functions + * @brief Option Bytes Programming functions + * +@verbatim + ============================================================================== + ##### Option Bytes Programming functions ##### + ============================================================================== + + [..] The FLASH_Option Bytes Programming_functions, includes the following functions: + (+) void FLASH_OB_Unlock(void); + (+) void FLASH_OB_Lock(void); + (+) void FLASH_OB_Launch(void); + (+) FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState); + (+) FLASH_Status FLASH_OB_WRP1Config(uint32_t OB_WRP1, FunctionalState NewState); + (+) FLASH_Status FLASH_OB_WRP2Config(uint32_t OB_WRP2, FunctionalState NewState); + (+) FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP); + (+) FLASH_Status FLASH_OB_PCROPConfig(uint32_t OB_WRP, FunctionalState NewState); + (+) FLASH_Status FLASH_OB_PCROP1Config(uint32_t OB_WRP1, FunctionalState NewState); + (+) FLASH_Status FLASH_OB_PCROPSelectionConfig(uint16_t OB_PcROP); + (+) FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY); + (+) FLASH_Status FLASH_OB_BORConfig(uint8_t OB_BOR); + (+) uint8_t FLASH_OB_GetUser(void); + (+) uint32_t FLASH_OB_GetWRP(void); + (+) uint32_t FLASH_OB_GetWRP1(void); + (+) uint32_t FLASH_OB_GetWRP2(void); + (+) FlagStatus FLASH_OB_GetRDP(void); + (+) FlagStatus FLASH_OB_GetSPRMOD(void); + (+) uint8_t FLASH_OB_GetBOR(void); + (+) FLASH_Status FLASH_OB_BootConfig(uint16_t OB_BOOT); + + [..] Any operation of erase or program should follow these steps: + (#) Call the FLASH_OB_Unlock() function to enable the Flash option control + register access. + (#) Call one or several functions to program the desired option bytes. + (++) void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable + the desired sector write protection. + (++) void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level. + (++) void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure + the user option Bytes: IWDG, STOP and the Standby. + (++) void FLASH_OB_BORConfig(uint8_t OB_BOR) => to Set the BOR level. + (#) Once all needed option bytes to be programmed are correctly written, call the + FLASH_OB_Launch(void) function to launch the Option Bytes programming process. + (#) Call the FLASH_OB_Lock() to disable the Flash option control register access (recommended + to protect the option Bytes against possible unwanted operations). + + [..] Proprietary code Read Out Protection (PcROP): + (#) The PcROP sector is selected by using the same option bytes as the Write + protection (nWRPi bits). As a result, these 2 options are exclusive each other. + (#) In order to activate the PcROP (change the function of the nWRPi option bits), + the SPRMOD option bit must be activated. + (#) The active value of nWRPi bits is inverted when PCROP mode is active, this + means: if SPRMOD = 1 and nWRPi = 1 (default value), then the user sector "i" + is read/write protected. + (#) To activate PCROP mode for Flash sector(s), you need to follow the sequence below: + (++) For sector(s) within the first 128KB of the Flash, use this function + FLASH_OB_PCROPConfig(OB_WRP_Pagesxxx, ENABLE) + (++) For sector(s) within the second 128KB of the Flash, use this function + FLASH_OB_PCROP1Config(OB_WRP_Pagesxxx, ENABLE) + (++) Activate the PCROP mode using FLASH_OB_PCROPSelectionConfig(OB_PcROP_Enable) function + (#) PcROP is available only in STM32L1XX_MDP devices + +@endverbatim + * @{ + */ + +/** + * @brief Unlocks the option bytes block access. + * @param None + * @retval None + */ +void FLASH_OB_Unlock(void) +{ + if((FLASH->PECR & FLASH_PECR_OPTLOCK) != RESET) + { + /* Unlocking the data memory and FLASH_PECR register access */ + DATA_EEPROM_Unlock(); + + /* Unlocking the option bytes block access */ + FLASH->OPTKEYR = FLASH_OPTKEY1; + FLASH->OPTKEYR = FLASH_OPTKEY2; + } +} + +/** + * @brief Locks the option bytes block access. + * @param None + * @retval None + */ +void FLASH_OB_Lock(void) +{ + /* Set the OPTLOCK Bit to lock the option bytes block access */ + FLASH->PECR |= FLASH_PECR_OPTLOCK; +} + +/** + * @brief Launch the option byte loading. + * @param None + * @retval None + */ +void FLASH_OB_Launch(void) +{ + /* Set the OBL_Launch bit to lauch the option byte loading */ + FLASH->PECR |= FLASH_PECR_OBL_LAUNCH; +} + +/** + * @brief Write protects the desired pages of the first 128KB of the Flash. + * @param OB_WRP: specifies the address of the pages to be write protected. + * This parameter can be: + * @arg value between OB_WRP_Pages0to15 and OB_WRP_Pages496to511 + * @arg OB_WRP_AllPages + * @param NewState: new state of the specified FLASH Pages Wtite protection. + * This parameter can be: ENABLE or DISABLE. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) +{ + uint32_t WRP01_Data = 0, WRP23_Data = 0; + + FLASH_Status status = FLASH_COMPLETE; + uint32_t tmp1 = 0, tmp2 = 0; + + /* Check the parameters */ + assert_param(IS_OB_WRP(OB_WRP)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + if (NewState != DISABLE) + { + WRP01_Data = (uint16_t)(((OB_WRP & WRP01_MASK) | OB->WRP01)); + WRP23_Data = (uint16_t)((((OB_WRP & WRP23_MASK)>>16 | OB->WRP23))); + tmp1 = (uint32_t)(~(WRP01_Data) << 16)|(WRP01_Data); + OB->WRP01 = tmp1; + + tmp2 = (uint32_t)(~(WRP23_Data) << 16)|(WRP23_Data); + OB->WRP23 = tmp2; + } + + else + { + WRP01_Data = (uint16_t)(~OB_WRP & (WRP01_MASK & OB->WRP01)); + WRP23_Data = (uint16_t)((((~OB_WRP & WRP23_MASK)>>16 & OB->WRP23))); + + tmp1 = (uint32_t)((~WRP01_Data) << 16)|(WRP01_Data); + OB->WRP01 = tmp1; + + tmp2 = (uint32_t)((~WRP23_Data) << 16)|(WRP23_Data); + OB->WRP23 = tmp2; + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + + /* Return the write protection operation Status */ + return status; +} + +/** + * @brief Write protects the desired pages of the second 128KB of the Flash. + * @note This function can be used only for STM32L1XX_HD and STM32L1XX_MDP + * density devices. + * @param OB_WRP1: specifies the address of the pages to be write protected. + * This parameter can be: + * @arg value between OB_WRP_Pages512to527 and OB_WRP_Pages1008to1023 + * @arg OB_WRP_AllPages + * @param NewState: new state of the specified FLASH Pages Wtite protection. + * This parameter can be: ENABLE or DISABLE. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_WRP1Config(uint32_t OB_WRP1, FunctionalState NewState) +{ + uint32_t WRP45_Data = 0, WRP67_Data = 0; + + FLASH_Status status = FLASH_COMPLETE; + uint32_t tmp1 = 0, tmp2 = 0; + + /* Check the parameters */ + assert_param(IS_OB_WRP(OB_WRP1)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + if (NewState != DISABLE) + { + WRP45_Data = (uint16_t)(((OB_WRP1 & WRP45_MASK) | OB->WRP45)); + WRP67_Data = (uint16_t)((((OB_WRP1 & WRP67_MASK)>>16 | OB->WRP67))); + tmp1 = (uint32_t)(~(WRP45_Data) << 16)|(WRP45_Data); + OB->WRP45 = tmp1; + + tmp2 = (uint32_t)(~(WRP67_Data) << 16)|(WRP67_Data); + OB->WRP67 = tmp2; + } + + else + { + WRP45_Data = (uint16_t)(~OB_WRP1 & (WRP45_MASK & OB->WRP45)); + WRP67_Data = (uint16_t)((((~OB_WRP1 & WRP67_MASK)>>16 & OB->WRP67))); + + tmp1 = (uint32_t)((~WRP45_Data) << 16)|(WRP45_Data); + OB->WRP45 = tmp1; + + tmp2 = (uint32_t)((~WRP67_Data) << 16)|(WRP67_Data); + OB->WRP67 = tmp2; + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + + /* Return the write protection operation Status */ + return status; +} + +/** + * @brief Write protects the desired pages of the third 128KB of the Flash. + * @note This function can be used only for STM32L1XX_HD density devices. + * @param OB_WRP2: specifies the address of the pages to be write protected. + * This parameter can be: + * @arg value between OB_WRP_Pages1024to1039 and OB_WRP_Pages1520to1535 + * @arg OB_WRP_AllPages + * @param NewState: new state of the specified FLASH Pages Wtite protection. + * This parameter can be: ENABLE or DISABLE. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_WRP2Config(uint32_t OB_WRP2, FunctionalState NewState) +{ + uint32_t WRP89_Data = 0, WRP1011_Data = 0; + + FLASH_Status status = FLASH_COMPLETE; + uint32_t tmp1 = 0, tmp2 = 0; + + /* Check the parameters */ + assert_param(IS_OB_WRP(OB_WRP2)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + if (NewState != DISABLE) + { + WRP89_Data = (uint16_t)(((OB_WRP2 & WRP89_MASK) | OB->WRP89)); + WRP1011_Data = (uint16_t)((((OB_WRP2 & WRP1011_MASK)>>16 | OB->WRP1011))); + tmp1 = (uint32_t)(~(WRP89_Data) << 16)|(WRP89_Data); + OB->WRP89 = tmp1; + + tmp2 = (uint32_t)(~(WRP1011_Data) << 16)|(WRP1011_Data); + OB->WRP1011 = tmp2; + } + + else + { + WRP89_Data = (uint16_t)(~OB_WRP2 & (WRP89_MASK & OB->WRP89)); + WRP1011_Data = (uint16_t)((((~OB_WRP2 & WRP1011_MASK)>>16 & OB->WRP1011))); + + tmp1 = (uint32_t)((~WRP89_Data) << 16)|(WRP89_Data); + OB->WRP89 = tmp1; + + tmp2 = (uint32_t)((~WRP1011_Data) << 16)|(WRP1011_Data); + OB->WRP1011 = tmp2; + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + + /* Return the write protection operation Status */ + return status; +} + +/** + * @brief Enables or disables the read out protection. + * @note To correctly run this function, the FLASH_OB_Unlock() function + * must be called before. + * @param FLASH_ReadProtection_Level: specifies the read protection level. + * This parameter can be: + * @arg OB_RDP_Level_0: No protection + * @arg OB_RDP_Level_1: Read protection of the memory + * @arg OB_RDP_Level_2: Chip protection + * + * !!!Warning!!! When enabling OB_RDP_Level_2 it's no more possible to go back to level 1 or 0 + * + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP) +{ + FLASH_Status status = FLASH_COMPLETE; + uint8_t tmp1 = 0; + uint32_t tmp2 = 0; + + /* Check the parameters */ + assert_param(IS_OB_RDP(OB_RDP)); + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* calculate the option byte to write */ + tmp1 = (uint8_t)(~(OB_RDP )); + tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16)) | ((uint32_t)OB_RDP)); + + if(status == FLASH_COMPLETE) + { + /* program read protection level */ + OB->RDP = tmp2; + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* Return the Read protection operation Status */ + return status; +} + +/** + * @brief Enables or disables the read/write protection (PCROP) of the desired + * sectors, for the first 128KB of the Flash. + * @note This function can be used only for STM32L1XX_MDP devices + * @param OB_WRP: specifies the address of the pages to be write protected. + * This parameter can be: + * @arg value between OB_WRP_Pages0to15 and OB_WRP_Pages496to511 + * @arg OB_WRP_AllPages + * @param NewState: new state of the specified FLASH Pages Write protection. + * This parameter can be: ENABLE or DISABLE. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_PCROPConfig(uint32_t OB_WRP, FunctionalState NewState) +{ + uint32_t WRP01_Data = 0, WRP23_Data = 0; + + FLASH_Status status = FLASH_COMPLETE; + uint32_t tmp1 = 0, tmp2 = 0; + + /* Check the parameters */ + assert_param(IS_OB_WRP(OB_WRP)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + if (NewState != DISABLE) + { + WRP01_Data = (uint16_t)(~OB_WRP & (WRP01_MASK & OB->WRP01)); + WRP23_Data = (uint16_t)((((~OB_WRP & WRP23_MASK)>>16 & OB->WRP23))); + + tmp1 = (uint32_t)((~WRP01_Data) << 16)|(WRP01_Data); + OB->WRP01 = tmp1; + + tmp2 = (uint32_t)((~WRP23_Data) << 16)|(WRP23_Data); + OB->WRP23 = tmp2; + + } + + else + { + WRP01_Data = (uint16_t)((OB_WRP & WRP01_MASK) | OB->WRP01); + WRP23_Data = (uint16_t)(((OB_WRP & WRP23_MASK) >> 16) | OB->WRP23); + + tmp1 = (uint32_t)(~(WRP01_Data) << 16)|(WRP01_Data); + OB->WRP01 = tmp1; + + tmp2 = (uint32_t)(~(WRP23_Data) << 16)|(WRP23_Data); + OB->WRP23 = tmp2; + + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + + /* Return the write protection operation Status */ + return status; +} + +/** + * @brief Enables or disables the read/write protection (PCROP) of the desired + * sectors, for the second 128KB of the Flash. + * @note This function can be used only for STM32L1XX_MDP devices + * @param OB_WRP1: specifies the address of the pages to be write protected. + * This parameter can be: + * @arg value between OB_WRP_Pages512to527 and OB_WRP_Pages1008to1023 + * @arg OB_WRP_AllPages + * @param NewState: new state of the specified FLASH Pages Write protection. + * This parameter can be: ENABLE or DISABLE. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_PCROP1Config(uint32_t OB_WRP1, FunctionalState NewState) +{ + uint32_t WRP45_Data = 0, WRP67_Data = 0; + + FLASH_Status status = FLASH_COMPLETE; + uint32_t tmp1 = 0, tmp2 = 0; + + /* Check the parameters */ + assert_param(IS_OB_WRP(OB_WRP1)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + if (NewState != DISABLE) + { + WRP45_Data = (uint16_t)(~OB_WRP1 & (WRP45_MASK & OB->WRP45)); + WRP67_Data = (uint16_t)((((~OB_WRP1 & WRP67_MASK)>>16 & OB->WRP67))); + + tmp1 = (uint32_t)((~WRP45_Data) << 16)|(WRP45_Data); + OB->WRP45 = tmp1; + + tmp2 = (uint32_t)((~WRP67_Data) << 16)|(WRP67_Data); + OB->WRP67 = tmp2; + } + else + { + WRP45_Data = (uint16_t)((OB_WRP1 & WRP45_MASK) | OB->WRP45); + WRP67_Data = (uint16_t)(((OB_WRP1 & WRP67_MASK)>>16) | OB->WRP67); + tmp1 = (uint32_t)(~(WRP45_Data) << 16)|(WRP45_Data); + OB->WRP45 = tmp1; + + tmp2 = (uint32_t)(~(WRP67_Data) << 16)|(WRP67_Data); + OB->WRP67 = tmp2; + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + } + + /* Return the write protection operation Status */ + return status; +} + +/** + * @brief Select the Protection Mode (SPRMOD). + * @note This function can be used only for STM32L1XX_MDP devices + * @note Once SPRMOD bit is active, unprotection of a protected sector is not possible + * @note Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag + * @param OB_PcROP: Select the Protection Mode of nWPRi bits. + * This parameter can be: + * @arg OB_PcROP_Enable: nWRPi control the read&write protection (PcROP) of respective user sectors. + * @arg OB_PcROP_Disable: nWRPi control the write protection of respective user sectors. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_PCROPSelectionConfig(uint16_t OB_PcROP) +{ + FLASH_Status status = FLASH_COMPLETE; + uint16_t tmp1 = 0; + uint32_t tmp2 = 0; + uint8_t optiontmp = 0; + uint16_t optiontmp2 = 0; + + /* Check the parameters */ + assert_param(IS_OB_PCROP_SELECT(OB_PcROP)); + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* Mask RDP Byte */ + optiontmp = (uint8_t)(*(__IO uint8_t *)(OB_BASE)); + + /* Update Option Byte */ + optiontmp2 = (uint16_t)(OB_PcROP | optiontmp); + + + /* calculate the option byte to write */ + tmp1 = (uint16_t)(~(optiontmp2 )); + tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16)) | ((uint32_t)optiontmp2)); + + if(status == FLASH_COMPLETE) + { + /* program PCRop */ + OB->RDP = tmp2; + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* Return the Read protection operation Status */ + return status; +} + +/** + * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. + * @param OB_IWDG: Selects the WDG mode. + * This parameter can be one of the following values: + * @arg OB_IWDG_SW: Software WDG selected + * @arg OB_IWDG_HW: Hardware WDG selected + * @param OB_STOP: Reset event when entering STOP mode. + * This parameter can be one of the following values: + * @arg OB_STOP_NoRST: No reset generated when entering in STOP + * @arg OB_STOP_RST: Reset generated when entering in STOP + * @param OB_STDBY: Reset event when entering Standby mode. + * This parameter can be one of the following values: + * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY + * @arg OB_STDBY_RST: Reset generated when entering in STANDBY + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) +{ + FLASH_Status status = FLASH_COMPLETE; + uint32_t tmp = 0, tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_OB_IWDG_SOURCE(OB_IWDG)); + assert_param(IS_OB_STOP_SOURCE(OB_STOP)); + assert_param(IS_OB_STDBY_SOURCE(OB_STDBY)); + + /* Get the User Option byte register */ + tmp1 = (FLASH->OBR & 0x000F0000) >> 16; + + /* Calculate the user option byte to write */ + tmp = (uint32_t)(((uint32_t)~((uint32_t)((uint32_t)(OB_IWDG) | (uint32_t)(OB_STOP) | (uint32_t)(OB_STDBY) | tmp1))) << ((uint32_t)0x10)); + tmp |= ((uint32_t)(OB_IWDG) | ((uint32_t)OB_STOP) | (uint32_t)(OB_STDBY) | tmp1); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Write the User Option Byte */ + OB->USER = tmp; + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* Return the Option Byte program Status */ + return status; +} + +/** + * @brief Programs the FLASH brownout reset threshold level Option Byte. + * @param OB_BOR: Selects the brownout reset threshold level. + * This parameter can be one of the following values: + * @arg OB_BOR_OFF: BOR is disabled at power down, the reset is asserted when the VDD + * power supply reaches the PDR(Power Down Reset) threshold (1.5V) + * @arg OB_BOR_LEVEL1: BOR Reset threshold levels for 1.7V - 1.8V VDD power supply + * @arg OB_BOR_LEVEL2: BOR Reset threshold levels for 1.9V - 2.0V VDD power supply + * @arg OB_BOR_LEVEL3: BOR Reset threshold levels for 2.3V - 2.4V VDD power supply + * @arg OB_BOR_LEVEL4: BOR Reset threshold levels for 2.55V - 2.65V VDD power supply + * @arg OB_BOR_LEVEL5: BOR Reset threshold levels for 2.8V - 2.9V VDD power supply + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_BORConfig(uint8_t OB_BOR) +{ + FLASH_Status status = FLASH_COMPLETE; + uint32_t tmp = 0, tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_OB_BOR_LEVEL(OB_BOR)); + + /* Get the User Option byte register */ + tmp1 = (FLASH->OBR & 0x00F00000) >> 16; + + /* Calculate the option byte to write */ + tmp = (uint32_t)~(OB_BOR | tmp1)<<16; + tmp |= (OB_BOR | tmp1); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Write the BOR Option Byte */ + OB->USER = tmp; + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* Return the Option Byte program Status */ + return status; +} + +/** + * @brief Configures to boot from Bank1 or Bank2. + * @note This function can be used only for STM32L1XX_HD density devices. + * @param OB_BOOT: select the FLASH Bank to boot from. + * This parameter can be one of the following values: + * @arg OB_BOOT_BANK2: At startup, if boot pins are set in boot from user Flash + * position and this parameter is selected the device will boot from Bank2 or Bank1, + * depending on the activation of the bank. The active banks are checked in + * the following order: Bank2, followed by Bank1. + * The active bank is recognized by the value programmed at the base address + * of the respective bank (corresponding to the initial stack pointer value + * in the interrupt vector table). + * @arg OB_BOOT_BANK1: At startup, if boot pins are set in boot from user Flash + * position and this parameter is selected the device will boot from Bank1(Default). + * For more information, please refer to AN2606 from www.st.com. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_OB_BootConfig(uint8_t OB_BOOT) +{ + FLASH_Status status = FLASH_COMPLETE; + uint32_t tmp = 0, tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_OB_BOOT_BANK(OB_BOOT)); + + /* Get the User Option byte register */ + tmp1 = (FLASH->OBR & 0x007F0000) >> 16; + + /* Calculate the option byte to write */ + tmp = (uint32_t)~(OB_BOOT | tmp1)<<16; + tmp |= (OB_BOOT | tmp1); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* Write the BOOT Option Byte */ + OB->USER = tmp; + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* Return the Option Byte program Status */ + return status; +} + +/** + * @brief Returns the FLASH User Option Bytes values. + * @param None + * @retval The FLASH User Option Bytes. + */ +uint8_t FLASH_OB_GetUser(void) +{ + /* Return the User Option Byte */ + return (uint8_t)(FLASH->OBR >> 20); +} + +/** + * @brief Returns the FLASH Write Protection Option Bytes value. + * @param None + * @retval The FLASH Write Protection Option Bytes value. + */ +uint32_t FLASH_OB_GetWRP(void) +{ + /* Return the FLASH write protection Register value */ + return (uint32_t)(FLASH->WRPR); +} + +/** + * @brief Returns the FLASH Write Protection Option Bytes value. + * @note This function can be used only for STM32L1XX_HD and STM32L1XX_MDP + * density devices. + * @param None + * @retval The FLASH Write Protection Option Bytes value. + */ +uint32_t FLASH_OB_GetWRP1(void) +{ + /* Return the FLASH write protection Register value */ + return (uint32_t)(FLASH->WRPR1); +} + +/** + * @brief Returns the FLASH Write Protection Option Bytes value. + * @note This function can be used only for STM32L1XX_HD density devices. + * @param None + * @retval The FLASH Write Protection Option Bytes value. + */ +uint32_t FLASH_OB_GetWRP2(void) +{ + /* Return the FLASH write protection Register value */ + return (uint32_t)(FLASH->WRPR2); +} + +/** + * @brief Checks whether the FLASH Read out Protection Status is set or not. + * @param None + * @retval FLASH ReadOut Protection Status(SET or RESET). + */ +FlagStatus FLASH_OB_GetRDP(void) +{ + FlagStatus readstatus = RESET; + + if ((uint8_t)(FLASH->OBR) != (uint8_t)OB_RDP_Level_0) + { + readstatus = SET; + } + else + { + readstatus = RESET; + } + return readstatus; +} + +/** + * @brief Returns the SPRMOD Status. + * @note This function can be used only for STM32L1XX_MDP devices + * @param None + * @retval The SPRMOD Status. + */ +FlagStatus FLASH_OB_GetSPRMOD(void) +{ + FlagStatus readstatus = RESET; + uint16_t tmp = 0; + + /* Return the SPRMOD value */ + tmp = (uint16_t)(FLASH->OBR & (uint16_t)(0x0100)); + + if (tmp != (uint16_t)0x0000) + { + readstatus = SET; + } + else + { + readstatus = RESET; + } + return readstatus; +} + +/** + * @brief Returns the FLASH BOR level. + * @param None + * @retval The FLASH User Option Bytes. + */ +uint8_t FLASH_OB_GetBOR(void) +{ + /* Return the BOR level */ + return (uint8_t)((FLASH->OBR & (uint32_t)0x000F0000) >> 16); +} + +/** + * @} + */ + +/** @defgroup FLASH_Group5 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + ============================================================================== + ##### Interrupts and flags management functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified FLASH interrupts. + * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or + * disabled. + * This parameter can be any combination of the following values: + * @arg FLASH_IT_EOP: FLASH end of programming Interrupt + * @arg FLASH_IT_ERR: FLASH Error Interrupt + * @retval None + */ +void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FLASH_IT(FLASH_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState != DISABLE) + { + /* Enable the interrupt sources */ + FLASH->PECR |= FLASH_IT; + } + else + { + /* Disable the interrupt sources */ + FLASH->PECR &= ~(uint32_t)FLASH_IT; + } +} + +/** + * @brief Checks whether the specified FLASH flag is set or not. + * @param FLASH_FLAG: specifies the FLASH flag to check. + * This parameter can be one of the following values: + * @arg FLASH_FLAG_BSY: FLASH write/erase operations in progress flag + * @arg FLASH_FLAG_EOP: FLASH End of Operation flag + * @arg FLASH_FLAG_READY: FLASH Ready flag after low power mode + * @arg FLASH_FLAG_ENDHV: FLASH End of high voltage flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag + * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag + * @arg FLASH_FLAG_SIZERR: FLASH size error flag + * @arg FLASH_FLAG_OPTVERR: FLASH Option validity error flag + * @arg FLASH_FLAG_OPTVERRUSR: FLASH Option User validity error flag + * @arg FLASH_FLAG_RDERR: FLASH Read protected error flag (available only in STM32L1XX_MDP devices) + * @retval The new state of FLASH_FLAG (SET or RESET). + */ +FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)); + + if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the new state of FLASH_FLAG (SET or RESET) */ + return bitstatus; +} + +/** + * @brief Clears the FLASH's pending flags. + * @param FLASH_FLAG: specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg FLASH_FLAG_EOP: FLASH End of Operation flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag + * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag + * @arg FLASH_FLAG_SIZERR: FLASH size error flag + * @arg FLASH_FLAG_OPTVERR: FLASH Option validity error flag + * @arg FLASH_FLAG_OPTVERRUSR: FLASH Option User validity error flag + * @arg FLASH_FLAG_RDERR: FLASH Read protected error flag (available only in STM32L1XX_MDP devices) + * @retval None + */ +void FLASH_ClearFlag(uint32_t FLASH_FLAG) +{ + /* Check the parameters */ + assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)); + + /* Clear the flags */ + FLASH->SR = FLASH_FLAG; +} + +/** + * @brief Returns the FLASH Status. + * @param None + * @retval FLASH Status: The returned value can be: + * FLASH_BUSY, FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP or FLASH_COMPLETE. + */ +FLASH_Status FLASH_GetStatus(void) +{ + FLASH_Status FLASHstatus = FLASH_COMPLETE; + + if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) + { + FLASHstatus = FLASH_BUSY; + } + else + { + if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00) + { + FLASHstatus = FLASH_ERROR_WRP; + } + else + { + if((FLASH->SR & (uint32_t)0x1E00) != (uint32_t)0x00) + { + FLASHstatus = FLASH_ERROR_PROGRAM; + } + else + { + FLASHstatus = FLASH_COMPLETE; + } + } + } + /* Return the FLASH Status */ + return FLASHstatus; +} + + +/** + * @brief Waits for a FLASH operation to complete or a TIMEOUT to occur. + * @param Timeout: FLASH programming Timeout. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) +{ + __IO FLASH_Status status = FLASH_COMPLETE; + + /* Check for the FLASH Status */ + status = FLASH_GetStatus(); + + /* Wait for a FLASH operation to complete or a TIMEOUT to occur */ + while((status == FLASH_BUSY) && (Timeout != 0x00)) + { + status = FLASH_GetStatus(); + Timeout--; + } + + if(Timeout == 0x00 ) + { + status = FLASH_TIMEOUT; + } + /* Return the operation status */ + return status; +} + +/** + * @} + */ + +/** + * @} + */ + + /** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash.h new file mode 100644 index 0000000000..a0fa2ae61e --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash.h @@ -0,0 +1,482 @@ +/** + ****************************************************************************** + * @file stm32l1xx_flash.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the FLASH + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_FLASH_H +#define __STM32L1xx_FLASH_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief FLASH Status + */ +typedef enum +{ + FLASH_BUSY = 1, + FLASH_ERROR_WRP, + FLASH_ERROR_PROGRAM, + FLASH_COMPLETE, + FLASH_TIMEOUT +}FLASH_Status; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup FLASH_Exported_Constants + * @{ + */ + +/** @defgroup FLASH_Latency + * @{ + */ +#define FLASH_Latency_0 ((uint8_t)0x00) /*!< FLASH Zero Latency cycle */ +#define FLASH_Latency_1 ((uint8_t)0x01) /*!< FLASH One Latency cycle */ + +#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \ + ((LATENCY) == FLASH_Latency_1)) +/** + * @} + */ + +/** @defgroup FLASH_Interrupts + * @{ + */ + +#define FLASH_IT_EOP FLASH_PECR_EOPIE /*!< End of programming interrupt source */ +#define FLASH_IT_ERR FLASH_PECR_ERRIE /*!< Error interrupt source */ +#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFFFCFFFF) == 0x00000000) && (((IT) != 0x00000000))) +/** + * @} + */ + +/** @defgroup FLASH_Address + * @{ + */ + +#define IS_FLASH_DATA_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08080000) && ((ADDRESS) <= 0x08082FFF)) +#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) <= 0x0805FFFF)) + +/** + * @} + */ + +/** @defgroup Option_Bytes_Write_Protection + * @{ + */ + +#define OB_WRP_Pages0to15 ((uint32_t)0x00000001) /* Write protection of Sector0 */ +#define OB_WRP_Pages16to31 ((uint32_t)0x00000002) /* Write protection of Sector1 */ +#define OB_WRP_Pages32to47 ((uint32_t)0x00000004) /* Write protection of Sector2 */ +#define OB_WRP_Pages48to63 ((uint32_t)0x00000008) /* Write protection of Sector3 */ +#define OB_WRP_Pages64to79 ((uint32_t)0x00000010) /* Write protection of Sector4 */ +#define OB_WRP_Pages80to95 ((uint32_t)0x00000020) /* Write protection of Sector5 */ +#define OB_WRP_Pages96to111 ((uint32_t)0x00000040) /* Write protection of Sector6 */ +#define OB_WRP_Pages112to127 ((uint32_t)0x00000080) /* Write protection of Sector7 */ +#define OB_WRP_Pages128to143 ((uint32_t)0x00000100) /* Write protection of Sector8 */ +#define OB_WRP_Pages144to159 ((uint32_t)0x00000200) /* Write protection of Sector9 */ +#define OB_WRP_Pages160to175 ((uint32_t)0x00000400) /* Write protection of Sector10 */ +#define OB_WRP_Pages176to191 ((uint32_t)0x00000800) /* Write protection of Sector11 */ +#define OB_WRP_Pages192to207 ((uint32_t)0x00001000) /* Write protection of Sector12 */ +#define OB_WRP_Pages208to223 ((uint32_t)0x00002000) /* Write protection of Sector13 */ +#define OB_WRP_Pages224to239 ((uint32_t)0x00004000) /* Write protection of Sector14 */ +#define OB_WRP_Pages240to255 ((uint32_t)0x00008000) /* Write protection of Sector15 */ +#define OB_WRP_Pages256to271 ((uint32_t)0x00010000) /* Write protection of Sector16 */ +#define OB_WRP_Pages272to287 ((uint32_t)0x00020000) /* Write protection of Sector17 */ +#define OB_WRP_Pages288to303 ((uint32_t)0x00040000) /* Write protection of Sector18 */ +#define OB_WRP_Pages304to319 ((uint32_t)0x00080000) /* Write protection of Sector19 */ +#define OB_WRP_Pages320to335 ((uint32_t)0x00100000) /* Write protection of Sector20 */ +#define OB_WRP_Pages336to351 ((uint32_t)0x00200000) /* Write protection of Sector21 */ +#define OB_WRP_Pages352to367 ((uint32_t)0x00400000) /* Write protection of Sector22 */ +#define OB_WRP_Pages368to383 ((uint32_t)0x00800000) /* Write protection of Sector23 */ +#define OB_WRP_Pages384to399 ((uint32_t)0x01000000) /* Write protection of Sector24 */ +#define OB_WRP_Pages400to415 ((uint32_t)0x02000000) /* Write protection of Sector25 */ +#define OB_WRP_Pages416to431 ((uint32_t)0x04000000) /* Write protection of Sector26 */ +#define OB_WRP_Pages432to447 ((uint32_t)0x08000000) /* Write protection of Sector27 */ +#define OB_WRP_Pages448to463 ((uint32_t)0x10000000) /* Write protection of Sector28 */ +#define OB_WRP_Pages464to479 ((uint32_t)0x20000000) /* Write protection of Sector29 */ +#define OB_WRP_Pages480to495 ((uint32_t)0x40000000) /* Write protection of Sector30 */ +#define OB_WRP_Pages496to511 ((uint32_t)0x80000000) /* Write protection of Sector31 */ + +#define OB_WRP_AllPages ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Sectors */ + +#define OB_WRP1_Pages512to527 ((uint32_t)0x00000001) /* Write protection of Sector32 */ +#define OB_WRP1_Pages528to543 ((uint32_t)0x00000002) /* Write protection of Sector33 */ +#define OB_WRP1_Pages544to559 ((uint32_t)0x00000004) /* Write protection of Sector34 */ +#define OB_WRP1_Pages560to575 ((uint32_t)0x00000008) /* Write protection of Sector35 */ +#define OB_WRP1_Pages576to591 ((uint32_t)0x00000010) /* Write protection of Sector36 */ +#define OB_WRP1_Pages592to607 ((uint32_t)0x00000020) /* Write protection of Sector37 */ +#define OB_WRP1_Pages608to623 ((uint32_t)0x00000040) /* Write protection of Sector38 */ +#define OB_WRP1_Pages624to639 ((uint32_t)0x00000080) /* Write protection of Sector39 */ +#define OB_WRP1_Pages640to655 ((uint32_t)0x00000100) /* Write protection of Sector40 */ +#define OB_WRP1_Pages656to671 ((uint32_t)0x00000200) /* Write protection of Sector41 */ +#define OB_WRP1_Pages672to687 ((uint32_t)0x00000400) /* Write protection of Sector42 */ +#define OB_WRP1_Pages688to703 ((uint32_t)0x00000800) /* Write protection of Sector43 */ +#define OB_WRP1_Pages704to719 ((uint32_t)0x00001000) /* Write protection of Sector44 */ +#define OB_WRP1_Pages720to735 ((uint32_t)0x00002000) /* Write protection of Sector45 */ +#define OB_WRP1_Pages736to751 ((uint32_t)0x00004000) /* Write protection of Sector46 */ +#define OB_WRP1_Pages752to767 ((uint32_t)0x00008000) /* Write protection of Sector47 */ +#define OB_WRP1_Pages768to783 ((uint32_t)0x00010000) /* Write protection of Sector48 */ +#define OB_WRP1_Pages784to799 ((uint32_t)0x00020000) /* Write protection of Sector49 */ +#define OB_WRP1_Pages800to815 ((uint32_t)0x00040000) /* Write protection of Sector50 */ +#define OB_WRP1_Pages816to831 ((uint32_t)0x00080000) /* Write protection of Sector51 */ +#define OB_WRP1_Pages832to847 ((uint32_t)0x00100000) /* Write protection of Sector52 */ +#define OB_WRP1_Pages848to863 ((uint32_t)0x00200000) /* Write protection of Sector53 */ +#define OB_WRP1_Pages864to879 ((uint32_t)0x00400000) /* Write protection of Sector54 */ +#define OB_WRP1_Pages880to895 ((uint32_t)0x00800000) /* Write protection of Sector55 */ +#define OB_WRP1_Pages896to911 ((uint32_t)0x01000000) /* Write protection of Sector56 */ +#define OB_WRP1_Pages912to927 ((uint32_t)0x02000000) /* Write protection of Sector57 */ +#define OB_WRP1_Pages928to943 ((uint32_t)0x04000000) /* Write protection of Sector58 */ +#define OB_WRP1_Pages944to959 ((uint32_t)0x08000000) /* Write protection of Sector59 */ +#define OB_WRP1_Pages960to975 ((uint32_t)0x10000000) /* Write protection of Sector60 */ +#define OB_WRP1_Pages976to991 ((uint32_t)0x20000000) /* Write protection of Sector61 */ +#define OB_WRP1_Pages992to1007 ((uint32_t)0x40000000) /* Write protection of Sector62 */ +#define OB_WRP1_Pages1008to1023 ((uint32_t)0x80000000) /* Write protection of Sector63 */ + +#define OB_WRP1_AllPages ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Sectors */ + +#define OB_WRP2_Pages1024to1039 ((uint32_t)0x00000001) /* Write protection of Sector64 */ +#define OB_WRP2_Pages1040to1055 ((uint32_t)0x00000002) /* Write protection of Sector65 */ +#define OB_WRP2_Pages1056to1071 ((uint32_t)0x00000004) /* Write protection of Sector66 */ +#define OB_WRP2_Pages1072to1087 ((uint32_t)0x00000008) /* Write protection of Sector67 */ +#define OB_WRP2_Pages1088to1103 ((uint32_t)0x00000010) /* Write protection of Sector68 */ +#define OB_WRP2_Pages1104to1119 ((uint32_t)0x00000020) /* Write protection of Sector69 */ +#define OB_WRP2_Pages1120to1135 ((uint32_t)0x00000040) /* Write protection of Sector70 */ +#define OB_WRP2_Pages1136to1151 ((uint32_t)0x00000080) /* Write protection of Sector71 */ +#define OB_WRP2_Pages1152to1167 ((uint32_t)0x00000100) /* Write protection of Sector72 */ +#define OB_WRP2_Pages1168to1183 ((uint32_t)0x00000200) /* Write protection of Sector73 */ +#define OB_WRP2_Pages1184to1199 ((uint32_t)0x00000400) /* Write protection of Sector74 */ +#define OB_WRP2_Pages1200to1215 ((uint32_t)0x00000800) /* Write protection of Sector75 */ +#define OB_WRP2_Pages1216to1231 ((uint32_t)0x00001000) /* Write protection of Sector76 */ +#define OB_WRP2_Pages1232to1247 ((uint32_t)0x00002000) /* Write protection of Sector77 */ +#define OB_WRP2_Pages1248to1263 ((uint32_t)0x00004000) /* Write protection of Sector78 */ +#define OB_WRP2_Pages1264to1279 ((uint32_t)0x00008000) /* Write protection of Sector79 */ +#define OB_WRP2_Pages1280to1295 ((uint32_t)0x00010000) /* Write protection of Sector80 */ +#define OB_WRP2_Pages1296to1311 ((uint32_t)0x00020000) /* Write protection of Sector81 */ +#define OB_WRP2_Pages1312to1327 ((uint32_t)0x00040000) /* Write protection of Sector82 */ +#define OB_WRP2_Pages1328to1343 ((uint32_t)0x00080000) /* Write protection of Sector83 */ +#define OB_WRP2_Pages1344to1359 ((uint32_t)0x00100000) /* Write protection of Sector84 */ +#define OB_WRP2_Pages1360to1375 ((uint32_t)0x00200000) /* Write protection of Sector85 */ +#define OB_WRP2_Pages1376to1391 ((uint32_t)0x00400000) /* Write protection of Sector86 */ +#define OB_WRP2_Pages1392to1407 ((uint32_t)0x00800000) /* Write protection of Sector87 */ +#define OB_WRP2_Pages1408to1423 ((uint32_t)0x01000000) /* Write protection of Sector88 */ +#define OB_WRP2_Pages1424to1439 ((uint32_t)0x02000000) /* Write protection of Sector89 */ +#define OB_WRP2_Pages1440to1455 ((uint32_t)0x04000000) /* Write protection of Sector90 */ +#define OB_WRP2_Pages1456to1471 ((uint32_t)0x08000000) /* Write protection of Sector91 */ +#define OB_WRP2_Pages1472to1487 ((uint32_t)0x10000000) /* Write protection of Sector92 */ +#define OB_WRP2_Pages1488to1503 ((uint32_t)0x20000000) /* Write protection of Sector93 */ +#define OB_WRP2_Pages1504to1519 ((uint32_t)0x40000000) /* Write protection of Sector94 */ +#define OB_WRP2_Pages1520to1535 ((uint32_t)0x80000000) /* Write protection of Sector95 */ + +#define OB_WRP2_AllPages ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Sectors */ + +#define IS_OB_WRP(PAGE) (((PAGE) != 0x0000000)) + +/** + * @} + */ + + +/** @defgroup Selection_Protection_Mode + * @{ + */ +#define OB_PcROP_Enable ((uint16_t)0x0100) /*!< Disabled PcROP, nWPRi bits used for Write Protection on sector i */ +#define OB_PcROP_Disable ((uint16_t)0x0000) /*!< Enable PcROP, nWPRi bits used for PCRoP Protection on sector i */ +#define IS_OB_PCROP_SELECT(OB_PcROP) (((OB_PcROP) == OB_PcROP_Enable) || ((OB_PcROP) == OB_PcROP_Disable)) +/** + * @} + */ + + +/** @defgroup Option_Bytes_Read_Protection + * @{ + */ + +/** + * @brief Read Protection Level + */ +#define OB_RDP_Level_0 ((uint8_t)0xAA) +#define OB_RDP_Level_1 ((uint8_t)0xBB) +/*#define OB_RDP_Level_2 ((uint8_t)0xCC)*/ /* Warning: When enabling read protection level 2 + it's no more possible to go back to level 1 or 0 */ + +#define IS_OB_RDP(LEVEL) (((LEVEL) == OB_RDP_Level_0)||\ + ((LEVEL) == OB_RDP_Level_1))/*||\ + ((LEVEL) == OB_RDP_Level_2))*/ +/** + * @} + */ + +/** @defgroup Option_Bytes_IWatchdog + * @{ + */ + +#define OB_IWDG_SW ((uint8_t)0x10) /*!< Software WDG selected */ +#define OB_IWDG_HW ((uint8_t)0x00) /*!< Hardware WDG selected */ +#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW)) + +/** + * @} + */ + +/** @defgroup Option_Bytes_nRST_STOP + * @{ + */ + +#define OB_STOP_NoRST ((uint8_t)0x20) /*!< No reset generated when entering in STOP */ +#define OB_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP */ +#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST)) + +/** + * @} + */ + +/** @defgroup Option_Bytes_nRST_STDBY + * @{ + */ + +#define OB_STDBY_NoRST ((uint8_t)0x40) /*!< No reset generated when entering in STANDBY */ +#define OB_STDBY_RST ((uint8_t)0x00) /*!< Reset generated when entering in STANDBY */ +#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NoRST) || ((SOURCE) == OB_STDBY_RST)) + +/** + * @} + */ + +/** @defgroup Option_Bytes_BOOT + * @{ + */ + +#define OB_BOOT_BANK2 ((uint8_t)0x00) /*!< At startup, if boot pins are set in boot from user Flash position + and this parameter is selected the device will boot from Bank 2 + or Bank 1, depending on the activation of the bank */ +#define OB_BOOT_BANK1 ((uint8_t)0x80) /*!< At startup, if boot pins are set in boot from user Flash position + and this parameter is selected the device will boot from Bank1(Default) */ +#define IS_OB_BOOT_BANK(BANK) (((BANK) == OB_BOOT_BANK2) || ((BANK) == OB_BOOT_BANK1)) + +/** + * @} + */ + +/** @defgroup Option_Bytes_BOR_Level + * @{ + */ + +#define OB_BOR_OFF ((uint8_t)0x00) /*!< BOR is disabled at power down, the reset is asserted when the VDD + power supply reaches the PDR(Power Down Reset) threshold (1.5V) */ +#define OB_BOR_LEVEL1 ((uint8_t)0x08) /*!< BOR Reset threshold levels for 1.7V - 1.8V VDD power supply */ +#define OB_BOR_LEVEL2 ((uint8_t)0x09) /*!< BOR Reset threshold levels for 1.9V - 2.0V VDD power supply */ +#define OB_BOR_LEVEL3 ((uint8_t)0x0A) /*!< BOR Reset threshold levels for 2.3V - 2.4V VDD power supply */ +#define OB_BOR_LEVEL4 ((uint8_t)0x0B) /*!< BOR Reset threshold levels for 2.55V - 2.65V VDD power supply */ +#define OB_BOR_LEVEL5 ((uint8_t)0x0C) /*!< BOR Reset threshold levels for 2.8V - 2.9V VDD power supply */ + +#define IS_OB_BOR_LEVEL(LEVEL) (((LEVEL) == OB_BOR_OFF) || \ + ((LEVEL) == OB_BOR_LEVEL1) || \ + ((LEVEL) == OB_BOR_LEVEL2) || \ + ((LEVEL) == OB_BOR_LEVEL3) || \ + ((LEVEL) == OB_BOR_LEVEL4) || \ + ((LEVEL) == OB_BOR_LEVEL5)) + +/** + * @} + */ + +/** @defgroup FLASH_Flags + * @{ + */ + +#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */ +#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Programming flag */ +#define FLASH_FLAG_ENDHV FLASH_SR_ENHV /*!< FLASH End of High Voltage flag */ +#define FLASH_FLAG_READY FLASH_SR_READY /*!< FLASH Ready flag after low power mode */ +#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */ +#define FLASH_FLAG_PGAERR FLASH_SR_PGAERR /*!< FLASH Programming Alignment error flag */ +#define FLASH_FLAG_SIZERR FLASH_SR_SIZERR /*!< FLASH Size error flag */ +#define FLASH_FLAG_OPTVERR FLASH_SR_OPTVERR /*!< FLASH Option Validity error flag */ +#define FLASH_FLAG_OPTVERRUSR FLASH_SR_OPTVERRUSR /*!< FLASH Option User Validity error flag */ +#define FLASH_FLAG_RDERR FLASH_SR_RDERR /*!< FLASH Read protected error flag + (available only in STM32L1XX_MDP devices) */ + +#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFC0FD) == 0x00000000) && ((FLAG) != 0x00000000)) + +#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_EOP) || \ + ((FLAG) == FLASH_FLAG_ENDHV) || ((FLAG) == FLASH_FLAG_READY ) || \ + ((FLAG) == FLASH_FLAG_WRPERR) || ((FLAG) == FLASH_FLAG_PGAERR ) || \ + ((FLAG) == FLASH_FLAG_SIZERR) || ((FLAG) == FLASH_FLAG_OPTVERR) || \ + ((FLAG) == FLASH_FLAG_OPTVERRUSR) || ((FLAG) == FLASH_FLAG_RDERR)) +/** + * @} + */ + +/** @defgroup FLASH_Keys + * @{ + */ + +#define FLASH_PDKEY1 ((uint32_t)0x04152637) /*!< Flash power down key1 */ +#define FLASH_PDKEY2 ((uint32_t)0xFAFBFCFD) /*!< Flash power down key2: used with FLASH_PDKEY1 + to unlock the RUN_PD bit in FLASH_ACR */ + +#define FLASH_PEKEY1 ((uint32_t)0x89ABCDEF) /*!< Flash program erase key1 */ +#define FLASH_PEKEY2 ((uint32_t)0x02030405) /*!< Flash program erase key: used with FLASH_PEKEY2 + to unlock the write access to the FLASH_PECR register and + data EEPROM */ + +#define FLASH_PRGKEY1 ((uint32_t)0x8C9DAEBF) /*!< Flash program memory key1 */ +#define FLASH_PRGKEY2 ((uint32_t)0x13141516) /*!< Flash program memory key2: used with FLASH_PRGKEY2 + to unlock the program memory */ + +#define FLASH_OPTKEY1 ((uint32_t)0xFBEAD9C8) /*!< Flash option key1 */ +#define FLASH_OPTKEY2 ((uint32_t)0x24252627) /*!< Flash option key2: used with FLASH_OPTKEY1 to + unlock the write access to the option byte block */ +/** + * @} + */ + +/** @defgroup Timeout_definition + * @{ + */ +#define FLASH_ER_PRG_TIMEOUT ((uint32_t)0x8000) + +/** + * @} + */ + +/** @defgroup CMSIS_Legacy + * @{ + */ +#if defined ( __ICCARM__ ) +#define InterruptType_ACTLR_DISMCYCINT_Msk IntType_ACTLR_DISMCYCINT_Msk +#endif +/** + * @} + */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/** + * @brief FLASH memory functions that can be executed from FLASH. + */ +/* FLASH Interface configuration functions ************************************/ +void FLASH_SetLatency(uint32_t FLASH_Latency); +void FLASH_PrefetchBufferCmd(FunctionalState NewState); +void FLASH_ReadAccess64Cmd(FunctionalState NewState); +void FLASH_SLEEPPowerDownCmd(FunctionalState NewState); + +/* FLASH Memory Programming functions *****************************************/ +void FLASH_Unlock(void); +void FLASH_Lock(void); +FLASH_Status FLASH_ErasePage(uint32_t Page_Address); +FLASH_Status FLASH_FastProgramWord(uint32_t Address, uint32_t Data); + +/* DATA EEPROM Programming functions ******************************************/ +void DATA_EEPROM_Unlock(void); +void DATA_EEPROM_Lock(void); +void DATA_EEPROM_FixedTimeProgramCmd(FunctionalState NewState); +FLASH_Status DATA_EEPROM_EraseByte(uint32_t Address); +FLASH_Status DATA_EEPROM_EraseHalfWord(uint32_t Address); +FLASH_Status DATA_EEPROM_EraseWord(uint32_t Address); +FLASH_Status DATA_EEPROM_FastProgramByte(uint32_t Address, uint8_t Data); +FLASH_Status DATA_EEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data); +FLASH_Status DATA_EEPROM_FastProgramWord(uint32_t Address, uint32_t Data); +FLASH_Status DATA_EEPROM_ProgramByte(uint32_t Address, uint8_t Data); +FLASH_Status DATA_EEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data); +FLASH_Status DATA_EEPROM_ProgramWord(uint32_t Address, uint32_t Data); + +/* Option Bytes Programming functions *****************************************/ +void FLASH_OB_Unlock(void); +void FLASH_OB_Lock(void); +void FLASH_OB_Launch(void); +FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState); +FLASH_Status FLASH_OB_WRP1Config(uint32_t OB_WRP1, FunctionalState NewState); +FLASH_Status FLASH_OB_WRP2Config(uint32_t OB_WRP2, FunctionalState NewState); +FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP); +FLASH_Status FLASH_OB_PCROPConfig(uint32_t OB_WRP, FunctionalState NewState); +FLASH_Status FLASH_OB_PCROP1Config(uint32_t OB_WRP1, FunctionalState NewState); +FLASH_Status FLASH_OB_PCROPSelectionConfig(uint16_t OB_PcROP); +FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY); +FLASH_Status FLASH_OB_BORConfig(uint8_t OB_BOR); +FLASH_Status FLASH_OB_BootConfig(uint8_t OB_BOOT); +uint8_t FLASH_OB_GetUser(void); +uint32_t FLASH_OB_GetWRP(void); +uint32_t FLASH_OB_GetWRP1(void); +uint32_t FLASH_OB_GetWRP2(void); +FlagStatus FLASH_OB_GetRDP(void); +FlagStatus FLASH_OB_GetSPRMOD(void); +uint8_t FLASH_OB_GetBOR(void); + +/* Interrupts and flags management functions **********************************/ +void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); +FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG); +void FLASH_ClearFlag(uint32_t FLASH_FLAG); +FLASH_Status FLASH_GetStatus(void); +FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); + +/** + * @brief FLASH memory functions that should be executed from internal SRAM. + * These functions are defined inside the "stm32l1xx_flash_ramfunc.c" + * file. + */ +__RAM_FUNC FLASH_RUNPowerDownCmd(FunctionalState NewState); +__RAM_FUNC FLASH_EraseParallelPage(uint32_t Page_Address1, uint32_t Page_Address2); +__RAM_FUNC FLASH_ProgramHalfPage(uint32_t Address, uint32_t* pBuffer); +__RAM_FUNC FLASH_ProgramParallelHalfPage(uint32_t Address1, uint32_t* pBuffer1, uint32_t Address2, uint32_t* pBuffer2); +__RAM_FUNC DATA_EEPROM_EraseDoubleWord(uint32_t Address); +__RAM_FUNC DATA_EEPROM_ProgramDoubleWord(uint32_t Address, uint64_t Data); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_FLASH_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash_ramfunc.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash_ramfunc.c new file mode 100644 index 0000000000..161b521fcc --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_flash_ramfunc.c @@ -0,0 +1,553 @@ +/** + ****************************************************************************** + * @file stm32l1xx_flash_ramfunc.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides all the Flash firmware functions which should be + * executed from the internal SRAM. This file should be placed in + * internal SRAM. + * Other FLASH memory functions that can be used from the FLASH are + * defined in the "stm32l1xx_flash.c" file. +@verbatim + + *** ARM Compiler *** + -------------------- + [..] RAM functions are defined using the toolchain options. + Functions that are be executed in RAM should reside in a separate + source module. Using the 'Options for File' dialog you can simply change + the 'Code / Const' area of a module to a memory space in physical RAM. + Available memory areas are declared in the 'Target' tab of the + Options for Target' dialog. + + *** ICCARM Compiler *** + ----------------------- + [..] RAM functions are defined using a specific toolchain keyword "__ramfunc". + + *** GNU Compiler *** + -------------------- + [..] RAM functions are defined using a specific toolchain attribute + "__attribute__((section(".data")))". + + *** TASKING Compiler *** + ------------------------ + [..] RAM functions are defined using a specific toolchain pragma. This + pragma is defined inside this file. + +@endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_flash.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup FLASH + * @brief FLASH driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static __RAM_FUNC GetStatus(void); +static __RAM_FUNC WaitForLastOperation(uint32_t Timeout); + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup FLASH_Private_Functions + * @{ + */ + +/** @addtogroup FLASH_Group1 + * +@verbatim +@endverbatim + * @{ + */ +#if defined ( __TASKING__ ) +#pragma section_code_init on +#endif + +/** + * @brief Enable or disable the power down mode during RUN mode. + * @note This function can be used only when the user code is running from Internal SRAM. + * @param NewState: new state of the power down mode during RUN mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +__RAM_FUNC FLASH_RUNPowerDownCmd(FunctionalState NewState) +{ + FLASH_Status status = FLASH_COMPLETE; + + if (NewState != DISABLE) + { + /* Unlock the RUN_PD bit */ + FLASH->PDKEYR = FLASH_PDKEY1; + FLASH->PDKEYR = FLASH_PDKEY2; + + /* Set the RUN_PD bit in FLASH_ACR register to put Flash in power down mode */ + FLASH->ACR |= (uint32_t)FLASH_ACR_RUN_PD; + + if((FLASH->ACR & FLASH_ACR_RUN_PD) != FLASH_ACR_RUN_PD) + { + status = FLASH_ERROR_PROGRAM; + } + } + else + { + /* Clear the RUN_PD bit in FLASH_ACR register to put Flash in idle mode */ + FLASH->ACR &= (uint32_t)(~(uint32_t)FLASH_ACR_RUN_PD); + } + + /* Return the Write Status */ + return status; +} + +/** + * @} + */ + +/** @addtogroup FLASH_Group2 + * +@verbatim +@endverbatim + * @{ + */ + +/** + * @brief Erases a specified 2 page in program memory in parallel. + * @note This function can be used only for STM32L1XX_HD density devices. + * To correctly run this function, the FLASH_Unlock() function + * must be called before. + * Call the FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation). + * @param Page_Address1: The page address in program memory to be erased in + * the first Bank (BANK1). This parameter should be between 0x08000000 + * and 0x0802FF00. + * @param Page_Address2: The page address in program memory to be erased in + * the second Bank (BANK2). This parameter should be between 0x08030000 + * and 0x0805FF00. + * @note A Page is erased in the Program memory only if the address to load + * is the start address of a page (multiple of 256 bytes). + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_EraseParallelPage(uint32_t Page_Address1, uint32_t Page_Address2) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to erase the page */ + + /* Set the PARALLBANK bit */ + FLASH->PECR |= FLASH_PECR_PARALLBANK; + + /* Set the ERASE bit */ + FLASH->PECR |= FLASH_PECR_ERASE; + + /* Set PROG bit */ + FLASH->PECR |= FLASH_PECR_PROG; + + /* Write 00000000h to the first word of the first program page to erase */ + *(__IO uint32_t *)Page_Address1 = 0x00000000; + /* Write 00000000h to the first word of the second program page to erase */ + *(__IO uint32_t *)Page_Address2 = 0x00000000; + + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* If the erase operation is completed, disable the ERASE, PROG and PARALLBANK bits */ + FLASH->PECR &= (uint32_t)(~FLASH_PECR_PROG); + FLASH->PECR &= (uint32_t)(~FLASH_PECR_ERASE); + FLASH->PECR &= (uint32_t)(~FLASH_PECR_PARALLBANK); + } + /* Return the Erase Status */ + return status; +} + +/** + * @brief Programs a half page in program memory. + * @param Address: specifies the address to be written. + * @param pBuffer: pointer to the buffer containing the data to be written to + * the half page. + * @note To correctly run this function, the FLASH_Unlock() function + * must be called before. + * Call the FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation) + * @note Half page write is possible only from SRAM. + * @note If there are more than 32 words to write, after 32 words another + * Half Page programming operation starts and has to be finished. + * @note A half page is written to the program memory only if the first + * address to load is the start address of a half page (multiple of 128 + * bytes) and the 31 remaining words to load are in the same half page. + * @note During the Program memory half page write all read operations are + * forbidden (this includes DMA read operations and debugger read + * operations such as breakpoints, periodic updates, etc.). + * @note If a PGAERR is set during a Program memory half page write, the + * complete write operation is aborted. Software should then reset the + * FPRG and PROG/DATA bits and restart the write operation from the + * beginning. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +__RAM_FUNC FLASH_ProgramHalfPage(uint32_t Address, uint32_t* pBuffer) +{ + uint32_t count = 0; + + FLASH_Status status = FLASH_COMPLETE; + + /* Set the DISMCYCINT[0] bit in the Auxillary Control Register (0xE000E008) + This bit prevents the interruption of multicycle instructions and therefore + will increase the interrupt latency. of Cortex-M3. */ + SCnSCB->ACTLR |= SCnSCB_ACTLR_DISMCYCINT_Msk; + + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new + half page */ + FLASH->PECR |= FLASH_PECR_FPRG; + FLASH->PECR |= FLASH_PECR_PROG; + + /* Write one half page directly with 32 different words */ + while(count < 32) + { + *(__IO uint32_t*) (Address + (4 * count)) = *(pBuffer++); + count ++; + } + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* if the write operation is completed, disable the PROG and FPRG bits */ + FLASH->PECR &= (uint32_t)(~FLASH_PECR_PROG); + FLASH->PECR &= (uint32_t)(~FLASH_PECR_FPRG); + } + + SCnSCB->ACTLR &= ~SCnSCB_ACTLR_DISMCYCINT_Msk; + + /* Return the Write Status */ + return status; +} + +/** + * @brief Programs 2 half page in program memory in parallel. + * @param Address1: specifies the first address to be written in the first bank + * (BANK1). This parameter should be between 0x08000000 and 0x0802FF80. + * @param pBuffer1: pointer to the buffer containing the data to be written + * to the first half page in the first bank. + * @param Address2: specifies the second address to be written in the second bank + * (BANK2). This parameter should be between 0x08030000 and 0x0805FF80. + * @param pBuffer2: pointer to the buffer containing the data to be written + * to the second half page in the second bank. + * @note This function can be used only for STM32L1XX_HD density devices. + * @note To correctly run this function, the FLASH_Unlock() function + * must be called before. + * Call the FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation). + * @note Half page write is possible only from SRAM. + * @note If there are more than 32 words to write, after 32 words another + * Half Page programming operation starts and has to be finished. + * @note A half page is written to the program memory only if the first + * address to load is the start address of a half page (multiple of 128 + * bytes) and the 31 remaining words to load are in the same half page. + * @note During the Program memory half page write all read operations are + * forbidden (this includes DMA read operations and debugger read + * operations such as breakpoints, periodic updates, etc.). + * @note If a PGAERR is set during a Program memory half page write, the + * complete write operation is aborted. Software should then reset the + * FPRG and PROG/DATA bits and restart the write operation from the + * beginning. + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +__RAM_FUNC FLASH_ProgramParallelHalfPage(uint32_t Address1, uint32_t* pBuffer1, uint32_t Address2, uint32_t* pBuffer2) +{ + uint32_t count = 0; + + FLASH_Status status = FLASH_COMPLETE; + + /* Set the DISMCYCINT[0] bit in the Auxillary Control Register (0xE000E008) + This bit prevents the interruption of multicycle instructions and therefore + will increase the interrupt latency. of Cortex-M3. */ + SCnSCB->ACTLR |= SCnSCB_ACTLR_DISMCYCINT_Msk; + + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to program the new + half page */ + FLASH->PECR |= FLASH_PECR_PARALLBANK; + FLASH->PECR |= FLASH_PECR_FPRG; + FLASH->PECR |= FLASH_PECR_PROG; + + /* Write the first half page directly with 32 different words */ + while(count < 32) + { + *(__IO uint32_t*) (Address1 + (4 * count)) = *(pBuffer1++); + count ++; + } + count = 0; + /* Write the second half page directly with 32 different words */ + while(count < 32) + { + *(__IO uint32_t*) (Address2 + (4 * count)) = *(pBuffer2++); + count ++; + } + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* if the write operation is completed, disable the PROG, FPRG and PARALLBANK bits */ + FLASH->PECR &= (uint32_t)(~FLASH_PECR_PROG); + FLASH->PECR &= (uint32_t)(~FLASH_PECR_FPRG); + FLASH->PECR &= (uint32_t)(~FLASH_PECR_PARALLBANK); + } + + SCnSCB->ACTLR &= ~SCnSCB_ACTLR_DISMCYCINT_Msk; + + /* Return the Write Status */ + return status; +} + +/** + * @} + */ + +/** @addtogroup FLASH_Group3 + * +@verbatim +@endverbatim + * @{ + */ + +/** + * @brief Erase a double word in data memory. + * @param Address: specifies the address to be erased. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @note Data memory double word erase is possible only from SRAM. + * @note A double word is erased to the data memory only if the first address + * to load is the start address of a double word (multiple of 8 bytes). + * @note During the Data memory double word erase, all read operations are + * forbidden (this includes DMA read operations and debugger read + * operations such as breakpoints, periodic updates, etc.). + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ + +__RAM_FUNC DATA_EEPROM_EraseDoubleWord(uint32_t Address) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Set the DISMCYCINT[0] bit in the Auxillary Control Register (0xE000E008) + This bit prevents the interruption of multicycle instructions and therefore + will increase the interrupt latency. of Cortex-M3. */ + SCnSCB->ACTLR |= SCnSCB_ACTLR_DISMCYCINT_Msk; + + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to erase the next double word */ + /* Set the ERASE bit */ + FLASH->PECR |= FLASH_PECR_ERASE; + + /* Set DATA bit */ + FLASH->PECR |= FLASH_PECR_DATA; + + /* Write 00000000h to the 2 words to erase */ + *(__IO uint32_t *)Address = 0x00000000; + Address += 4; + *(__IO uint32_t *)Address = 0x00000000; + + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* If the erase operation is completed, disable the ERASE and DATA bits */ + FLASH->PECR &= (uint32_t)(~FLASH_PECR_ERASE); + FLASH->PECR &= (uint32_t)(~FLASH_PECR_DATA); + } + + SCnSCB->ACTLR &= ~SCnSCB_ACTLR_DISMCYCINT_Msk; + + /* Return the erase status */ + return status; +} + +/** + * @brief Write a double word in data memory without erase. + * @param Address: specifies the address to be written. + * @param Data: specifies the data to be written. + * @note To correctly run this function, the DATA_EEPROM_Unlock() function + * must be called before. + * Call the DATA_EEPROM_Lock() to he data EEPROM access + * and Flash program erase control register access(recommended to protect + * the DATA_EEPROM against possible unwanted operation). + * @note Data memory double word write is possible only from SRAM. + * @note A data memory double word is written to the data memory only if the + * first address to load is the start address of a double word (multiple + * of double word). + * @note During the Data memory double word write, all read operations are + * forbidden (this includes DMA read operations and debugger read + * operations such as breakpoints, periodic updates, etc.). + * @retval FLASH Status: The returned value can be: + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +__RAM_FUNC DATA_EEPROM_ProgramDoubleWord(uint32_t Address, uint64_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Set the DISMCYCINT[0] bit in the Auxillary Control Register (0xE000E008) + This bit prevents the interruption of multicycle instructions and therefore + will increase the interrupt latency. of Cortex-M3. */ + SCnSCB->ACTLR |= SCnSCB_ACTLR_DISMCYCINT_Msk; + + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + if(status == FLASH_COMPLETE) + { + /* If the previous operation is completed, proceed to program the new data*/ + FLASH->PECR |= FLASH_PECR_FPRG; + FLASH->PECR |= FLASH_PECR_DATA; + + /* Write the 2 words */ + *(__IO uint32_t *)Address = (uint32_t) Data; + Address += 4; + *(__IO uint32_t *)Address = (uint32_t) (Data >> 32); + + /* Wait for last operation to be completed */ + status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); + + /* If the write operation is completed, disable the FPRG and DATA bits */ + FLASH->PECR &= (uint32_t)(~FLASH_PECR_FPRG); + FLASH->PECR &= (uint32_t)(~FLASH_PECR_DATA); + } + + SCnSCB->ACTLR &= ~SCnSCB_ACTLR_DISMCYCINT_Msk; + + /* Return the Write Status */ + return status; +} + +/** + * @} + */ + +/** + * @brief Returns the FLASH Status. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_BUSY, + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP or FLASH_COMPLETE + */ +static __RAM_FUNC GetStatus(void) +{ + FLASH_Status FLASHstatus = FLASH_COMPLETE; + + if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) + { + FLASHstatus = FLASH_BUSY; + } + else + { + if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00) + { + FLASHstatus = FLASH_ERROR_WRP; + } + else + { + if((FLASH->SR & (uint32_t)0x1E00) != (uint32_t)0x00) + { + FLASHstatus = FLASH_ERROR_PROGRAM; + } + else + { + FLASHstatus = FLASH_COMPLETE; + } + } + } + /* Return the FLASH Status */ + return FLASHstatus; +} + +/** + * @brief Waits for a FLASH operation to complete or a TIMEOUT to occur. + * @param Timeout: FLASH programming Timeout + * @retval FLASH Status: The returned value can be: FLASH_BUSY, + * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or + * FLASH_TIMEOUT. + */ +static __RAM_FUNC WaitForLastOperation(uint32_t Timeout) +{ + __IO FLASH_Status status = FLASH_COMPLETE; + + /* Check for the FLASH Status */ + status = GetStatus(); + + /* Wait for a FLASH operation to complete or a TIMEOUT to occur */ + while((status == FLASH_BUSY) && (Timeout != 0x00)) + { + status = GetStatus(); + Timeout--; + } + + if(Timeout == 0x00 ) + { + status = FLASH_TIMEOUT; + } + /* Return the operation status */ + return status; +} + +#if defined ( __TASKING__ ) +#pragma section_code_init restore +#endif + +/** + * @} + */ + + /** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_fsmc.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_fsmc.c new file mode 100644 index 0000000000..04990269f2 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_fsmc.c @@ -0,0 +1,285 @@ +/** + ****************************************************************************** + * @file stm32l1xx_fsmc.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the FSMC peripheral: + * + Initialization + * + Interrupts and flags management + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_fsmc.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup FSMC + * @brief FSMC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup FSMC_Private_Functions + * @{ + */ + +/** @defgroup FSMC_Group1 NOR/SRAM Controller functions + * @brief NOR/SRAM Controller functions + * + @verbatim + ============================================================================== + ##### NOR-SRAM Controller functions ##### + ============================================================================== + [..] The following sequence should be followed to configure the FSMC to + interface with SRAM, PSRAM, NOR or OneNAND memory connected to the + NOR/SRAM Bank: + (#) Enable the clock for the FSMC and associated GPIOs using the following + functions: + (++)RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); + (++)RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOx, ENABLE); + (#) FSMC pins configuration + (++) Connect the involved FSMC pins to AF12 using the following function + GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC); + (++) Configure these FSMC pins in alternate function mode by calling the + function GPIO_Init(); + (#) Declare a FSMC_NORSRAMInitTypeDef structure, for example: + FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; and fill the + FSMC_NORSRAMInitStructure variable with the allowed values of the + structure member. + (#) Initialize the NOR/SRAM Controller by calling the function + FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); + (#) Then enable the NOR/SRAM Bank, for example: + FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE); + (#) At this stage you can read/write from/to the memory connected to the + NOR/SRAM Bank. + +@endverbatim + + * @{ + */ + +/** + * @brief Deinitializes the FSMC NOR/SRAM Banks registers to their default + * reset values. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 + * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 + * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 + * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 + * @retval None + */ +void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank) +{ + /* Check the parameter */ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); + + /* FSMC_Bank1_NORSRAM1 */ + if(FSMC_Bank == FSMC_Bank1_NORSRAM1) + { + FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030DB; + } + /* FSMC_Bank1_NORSRAM2, FSMC_Bank1_NORSRAM3 or FSMC_Bank1_NORSRAM4 */ + else + { + FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030D2; + } + FSMC_Bank1->BTCR[FSMC_Bank + 1] = 0x0FFFFFFF; + FSMC_Bank1E->BWTR[FSMC_Bank] = 0x0FFFFFFF; +} + +/** + * @brief Initializes the FSMC NOR/SRAM Banks according to the specified + * parameters in the FSMC_NORSRAMInitStruct. + * @param FSMC_NORSRAMInitStruct : pointer to a FSMC_NORSRAMInitTypeDef + * structure that contains the configuration information for + * the FSMC NOR/SRAM specified Banks. + * @retval None + */ +void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) +{ + /* Check the parameters */ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_NORSRAMInitStruct->FSMC_Bank)); + assert_param(IS_FSMC_MUX(FSMC_NORSRAMInitStruct->FSMC_DataAddressMux)); + assert_param(IS_FSMC_MEMORY(FSMC_NORSRAMInitStruct->FSMC_MemoryType)); + assert_param(IS_FSMC_MEMORY_WIDTH(FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth)); + assert_param(IS_FSMC_BURSTMODE(FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode)); + assert_param(IS_FSMC_ASYNWAIT(FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait)); + assert_param(IS_FSMC_WAIT_POLARITY(FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity)); + assert_param(IS_FSMC_WRAP_MODE(FSMC_NORSRAMInitStruct->FSMC_WrapMode)); + assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive)); + assert_param(IS_FSMC_WRITE_OPERATION(FSMC_NORSRAMInitStruct->FSMC_WriteOperation)); + assert_param(IS_FSMC_WAITE_SIGNAL(FSMC_NORSRAMInitStruct->FSMC_WaitSignal)); + assert_param(IS_FSMC_EXTENDED_MODE(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode)); + assert_param(IS_FSMC_WRITE_BURST(FSMC_NORSRAMInitStruct->FSMC_WriteBurst)); + assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime)); + assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime)); + assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime)); + assert_param(IS_FSMC_TURNAROUND_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration)); + assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision)); + assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency)); + assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode)); + + /* Bank1 NOR/SRAM control register configuration */ + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_DataAddressMux | + FSMC_NORSRAMInitStruct->FSMC_MemoryType | + FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth | + FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode | + FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait | + FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity | + FSMC_NORSRAMInitStruct->FSMC_WrapMode | + FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive | + FSMC_NORSRAMInitStruct->FSMC_WriteOperation | + FSMC_NORSRAMInitStruct->FSMC_WaitSignal | + FSMC_NORSRAMInitStruct->FSMC_ExtendedMode | + FSMC_NORSRAMInitStruct->FSMC_WriteBurst; + + if(FSMC_NORSRAMInitStruct->FSMC_MemoryType == FSMC_MemoryType_NOR) + { + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] |= (uint32_t)FSMC_BCR1_FACCEN; + } + + /* Bank1 NOR/SRAM timing register configuration */ + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank+1] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime << 4) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime << 8) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration << 16) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision << 20) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency << 24) | + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode; + + + /* Bank1 NOR/SRAM timing register for write configuration, if extended mode is used */ + if(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode == FSMC_ExtendedMode_Enable) + { + assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime)); + assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime)); + assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime)); + assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision)); + assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency)); + assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode)); + FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime << 4 )| + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime << 8) | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision << 20) | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency << 24) | + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode; + } + else + { + FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = 0x0FFFFFFF; + } +} + +/** + * @brief Fills each FSMC_NORSRAMInitStruct member with its default value. + * @param FSMC_NORSRAMInitStruct: pointer to a FSMC_NORSRAMInitTypeDef + * structure which will be initialized. + * @retval None + */ +void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) +{ + /* Reset NOR/SRAM Init structure parameters values */ + FSMC_NORSRAMInitStruct->FSMC_Bank = FSMC_Bank1_NORSRAM1; + FSMC_NORSRAMInitStruct->FSMC_DataAddressMux = FSMC_DataAddressMux_Enable; + FSMC_NORSRAMInitStruct->FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; + FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStruct->FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStruct->FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignal = FSMC_WaitSignal_Enable; + FSMC_NORSRAMInitStruct->FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime = 0xFF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime = 0xFF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; +} + +/** + * @brief Enables or disables the specified NOR/SRAM Memory Bank. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 + * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 + * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 + * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 + * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState) +{ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected NOR/SRAM Bank by setting the MBKEN bit in the BCRx register */ + FSMC_Bank1->BTCR[FSMC_Bank] |= FSMC_BCR1_MBKEN; + } + else + { + /* Disable the selected NOR/SRAM Bank by clearing the MBKEN bit in the BCRx register */ + FSMC_Bank1->BTCR[FSMC_Bank] &= (uint32_t)(~FSMC_BCR1_MBKEN); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_fsmc.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_fsmc.h new file mode 100644 index 0000000000..39d83cb412 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_fsmc.h @@ -0,0 +1,438 @@ +/** + ****************************************************************************** + * @file stm32l1xx_fsmc.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the FSMC firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_FSMC_H +#define __STM32L1xx_FSMC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup FSMC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief Timing parameters For NOR/SRAM Banks + */ + +typedef struct +{ + uint32_t FSMC_AddressSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address setup time. + This parameter can be a value between 0 and 0xF. + @note It is not used with synchronous NOR Flash memories. */ + + uint32_t FSMC_AddressHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address hold time. + This parameter can be a value between 0 and 0xF. + @note It is not used with synchronous NOR Flash memories.*/ + + uint32_t FSMC_DataSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data setup time. + This parameter can be a value between 0 and 0xFF. + @note It is used for SRAMs, ROMs and asynchronous multiplexed NOR Flash memories. */ + + uint32_t FSMC_BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure + the duration of the bus turnaround. + This parameter can be a value between 0 and 0xF. + @note It is only used for multiplexed NOR Flash memories. */ + + uint32_t FSMC_CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of HCLK cycles. + This parameter can be a value between 1 and 0xF. + @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM accesses. */ + + uint32_t FSMC_DataLatency; /*!< Defines the number of memory clock cycles to issue + to the memory before getting the first data. + The parameter value depends on the memory type as shown below: + - It must be set to 0 in case of a CRAM + - It is don't care in asynchronous NOR, SRAM or ROM accesses + - It may assume a value between 0 and 0xF in NOR Flash memories + with synchronous burst mode enable */ + + uint32_t FSMC_AccessMode; /*!< Specifies the asynchronous access mode. + This parameter can be a value of @ref FSMC_Access_Mode */ +}FSMC_NORSRAMTimingInitTypeDef; + +/** + * @brief FSMC NOR/SRAM Init structure definition + */ + +typedef struct +{ + uint32_t FSMC_Bank; /*!< Specifies the NOR/SRAM memory bank that will be used. + This parameter can be a value of @ref FSMC_NORSRAM_Bank */ + + uint32_t FSMC_DataAddressMux; /*!< Specifies whether the address and data values are + multiplexed on the databus or not. + This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */ + + uint32_t FSMC_MemoryType; /*!< Specifies the type of external memory attached to + the corresponding memory bank. + This parameter can be a value of @ref FSMC_Memory_Type */ + + uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be a value of @ref FSMC_Data_Width */ + + uint32_t FSMC_BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, + valid only with synchronous burst Flash memories. + This parameter can be a value of @ref FSMC_Burst_Access_Mode */ + + uint32_t FSMC_AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers, + valid only with asynchronous Flash memories. + This parameter can be a value of @ref FSMC_AsynchronousWait */ + + uint32_t FSMC_WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing + the Flash memory in burst mode. + This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */ + + uint32_t FSMC_WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash + memory, valid only when accessing Flash memories in burst mode. + This parameter can be a value of @ref FSMC_Wrap_Mode */ + + uint32_t FSMC_WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one + clock cycle before the wait state or during the wait state, + valid only when accessing memories in burst mode. + This parameter can be a value of @ref FSMC_Wait_Timing */ + + uint32_t FSMC_WriteOperation; /*!< Enables or disables the write operation in the selected bank by the FSMC. + This parameter can be a value of @ref FSMC_Write_Operation */ + + uint32_t FSMC_WaitSignal; /*!< Enables or disables the wait-state insertion via wait + signal, valid for Flash memory access in burst mode. + This parameter can be a value of @ref FSMC_Wait_Signal */ + + uint32_t FSMC_ExtendedMode; /*!< Enables or disables the extended mode. + This parameter can be a value of @ref FSMC_Extended_Mode */ + + uint32_t FSMC_WriteBurst; /*!< Enables or disables the write burst operation. + This parameter can be a value of @ref FSMC_Write_Burst */ + + FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the ExtendedMode is not used*/ + + FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct; /*!< Timing Parameters for write access if the ExtendedMode is used*/ +}FSMC_NORSRAMInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup FSMC_Exported_Constants + * @{ + */ + +/** @defgroup FSMC_NORSRAM_Bank + * @{ + */ +#define FSMC_Bank1_NORSRAM1 ((uint32_t)0x00000000) +#define FSMC_Bank1_NORSRAM2 ((uint32_t)0x00000002) +#define FSMC_Bank1_NORSRAM3 ((uint32_t)0x00000004) +#define FSMC_Bank1_NORSRAM4 ((uint32_t)0x00000006) + +#define IS_FSMC_NORSRAM_BANK(BANK) (((BANK) == FSMC_Bank1_NORSRAM1) || \ + ((BANK) == FSMC_Bank1_NORSRAM2) || \ + ((BANK) == FSMC_Bank1_NORSRAM3) || \ + ((BANK) == FSMC_Bank1_NORSRAM4)) +/** + * @} + */ + +/** @defgroup NOR_SRAM_Controller + * @{ + */ + +/** @defgroup FSMC_Data_Address_Bus_Multiplexing + * @{ + */ + +#define FSMC_DataAddressMux_Disable ((uint32_t)0x00000000) +#define FSMC_DataAddressMux_Enable ((uint32_t)0x00000002) +#define IS_FSMC_MUX(MUX) (((MUX) == FSMC_DataAddressMux_Disable) || \ + ((MUX) == FSMC_DataAddressMux_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Memory_Type + * @{ + */ + +#define FSMC_MemoryType_SRAM ((uint32_t)0x00000000) +#define FSMC_MemoryType_PSRAM ((uint32_t)0x00000004) +#define FSMC_MemoryType_NOR ((uint32_t)0x00000008) +#define IS_FSMC_MEMORY(MEMORY) (((MEMORY) == FSMC_MemoryType_SRAM) || \ + ((MEMORY) == FSMC_MemoryType_PSRAM)|| \ + ((MEMORY) == FSMC_MemoryType_NOR)) + +/** + * @} + */ + +/** @defgroup FSMC_Data_Width + * @{ + */ + +#define FSMC_MemoryDataWidth_8b ((uint32_t)0x00000000) +#define FSMC_MemoryDataWidth_16b ((uint32_t)0x00000010) +#define IS_FSMC_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_MemoryDataWidth_8b) || \ + ((WIDTH) == FSMC_MemoryDataWidth_16b)) + +/** + * @} + */ + +/** @defgroup FSMC_Burst_Access_Mode + * @{ + */ + +#define FSMC_BurstAccessMode_Disable ((uint32_t)0x00000000) +#define FSMC_BurstAccessMode_Enable ((uint32_t)0x00000100) +#define IS_FSMC_BURSTMODE(STATE) (((STATE) == FSMC_BurstAccessMode_Disable) || \ + ((STATE) == FSMC_BurstAccessMode_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_AsynchronousWait + * @{ + */ +#define FSMC_AsynchronousWait_Disable ((uint32_t)0x00000000) +#define FSMC_AsynchronousWait_Enable ((uint32_t)0x00008000) +#define IS_FSMC_ASYNWAIT(STATE) (((STATE) == FSMC_AsynchronousWait_Disable) || \ + ((STATE) == FSMC_AsynchronousWait_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Wait_Signal_Polarity + * @{ + */ + +#define FSMC_WaitSignalPolarity_Low ((uint32_t)0x00000000) +#define FSMC_WaitSignalPolarity_High ((uint32_t)0x00000200) +#define IS_FSMC_WAIT_POLARITY(POLARITY) (((POLARITY) == FSMC_WaitSignalPolarity_Low) || \ + ((POLARITY) == FSMC_WaitSignalPolarity_High)) + +/** + * @} + */ + +/** @defgroup FSMC_Wrap_Mode + * @{ + */ + +#define FSMC_WrapMode_Disable ((uint32_t)0x00000000) +#define FSMC_WrapMode_Enable ((uint32_t)0x00000400) +#define IS_FSMC_WRAP_MODE(MODE) (((MODE) == FSMC_WrapMode_Disable) || \ + ((MODE) == FSMC_WrapMode_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Wait_Timing + * @{ + */ + +#define FSMC_WaitSignalActive_BeforeWaitState ((uint32_t)0x00000000) +#define FSMC_WaitSignalActive_DuringWaitState ((uint32_t)0x00000800) +#define IS_FSMC_WAIT_SIGNAL_ACTIVE(ACTIVE) (((ACTIVE) == FSMC_WaitSignalActive_BeforeWaitState) || \ + ((ACTIVE) == FSMC_WaitSignalActive_DuringWaitState)) + +/** + * @} + */ + +/** @defgroup FSMC_Write_Operation + * @{ + */ + +#define FSMC_WriteOperation_Disable ((uint32_t)0x00000000) +#define FSMC_WriteOperation_Enable ((uint32_t)0x00001000) +#define IS_FSMC_WRITE_OPERATION(OPERATION) (((OPERATION) == FSMC_WriteOperation_Disable) || \ + ((OPERATION) == FSMC_WriteOperation_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Wait_Signal + * @{ + */ + +#define FSMC_WaitSignal_Disable ((uint32_t)0x00000000) +#define FSMC_WaitSignal_Enable ((uint32_t)0x00002000) +#define IS_FSMC_WAITE_SIGNAL(SIGNAL) (((SIGNAL) == FSMC_WaitSignal_Disable) || \ + ((SIGNAL) == FSMC_WaitSignal_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Extended_Mode + * @{ + */ + +#define FSMC_ExtendedMode_Disable ((uint32_t)0x00000000) +#define FSMC_ExtendedMode_Enable ((uint32_t)0x00004000) + +#define IS_FSMC_EXTENDED_MODE(MODE) (((MODE) == FSMC_ExtendedMode_Disable) || \ + ((MODE) == FSMC_ExtendedMode_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Write_Burst + * @{ + */ + +#define FSMC_WriteBurst_Disable ((uint32_t)0x00000000) +#define FSMC_WriteBurst_Enable ((uint32_t)0x00080000) +#define IS_FSMC_WRITE_BURST(BURST) (((BURST) == FSMC_WriteBurst_Disable) || \ + ((BURST) == FSMC_WriteBurst_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Address_Setup_Time + * @{ + */ + +#define IS_FSMC_ADDRESS_SETUP_TIME(TIME) ((TIME) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_Address_Hold_Time + * @{ + */ + +#define IS_FSMC_ADDRESS_HOLD_TIME(TIME) ((TIME) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_Data_Setup_Time + * @{ + */ + +#define IS_FSMC_DATASETUP_TIME(TIME) (((TIME) > 0) && ((TIME) <= 0xFF)) + +/** + * @} + */ + +/** @defgroup FSMC_Bus_Turn_around_Duration + * @{ + */ + +#define IS_FSMC_TURNAROUND_TIME(TIME) ((TIME) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_CLK_Division + * @{ + */ + +#define IS_FSMC_CLK_DIV(DIV) ((DIV) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_Data_Latency + * @{ + */ + +#define IS_FSMC_DATA_LATENCY(LATENCY) ((LATENCY) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_Access_Mode + * @{ + */ + +#define FSMC_AccessMode_A ((uint32_t)0x00000000) +#define FSMC_AccessMode_B ((uint32_t)0x10000000) +#define FSMC_AccessMode_C ((uint32_t)0x20000000) +#define FSMC_AccessMode_D ((uint32_t)0x30000000) +#define IS_FSMC_ACCESS_MODE(MODE) (((MODE) == FSMC_AccessMode_A) || \ + ((MODE) == FSMC_AccessMode_B) || \ + ((MODE) == FSMC_AccessMode_C) || \ + ((MODE) == FSMC_AccessMode_D)) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* NOR/SRAM Controller functions **********************************************/ +void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank); +void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); +void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); +void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_FSMC_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_gpio.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_gpio.c new file mode 100644 index 0000000000..6a306c6e51 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_gpio.c @@ -0,0 +1,557 @@ +/** + ****************************************************************************** + * @file stm32l1xx_gpio.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the GPIO peripheral: + * + Initialization and Configuration + * + GPIO Read and Write + * + GPIO Alternate functions configuration + * + * @verbatim + =========================================================================== + ##### How to use this driver ##### + =========================================================================== + [..] + (#) Enable the GPIO AHB clock using RCC_AHBPeriphClockCmd() + (#) Configure the GPIO pin(s) using GPIO_Init() + Four possible configuration are available for each pin: + (++) Input: Floating, Pull-up, Pull-down. + (++) Output: Push-Pull (Pull-up, Pull-down or no Pull) + Open Drain (Pull-up, Pull-down or no Pull). + In output mode, the speed is configurable: Very Low, Low, + Medium or High. + (++) Alternate Function: Push-Pull (Pull-up, Pull-down or no Pull) + Open Drain (Pull-up, Pull-down or no Pull). + (++) Analog: required mode when a pin is to be used as ADC channel, + DAC output or comparator input. + (#) Peripherals alternate function: + (++) For ADC, DAC and comparators, configure the desired pin in + analog mode using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN + (++) For other peripherals (TIM, USART...): + (+++) Connect the pin to the desired peripherals' Alternate + Function (AF) using GPIO_PinAFConfig() function. + (+++) Configure the desired pin in alternate function mode using + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF + (+++) Select the type, pull-up/pull-down and output speed via + GPIO_PuPd, GPIO_OType and GPIO_Speed members. + (+++) Call GPIO_Init() function. + (#) To get the level of a pin configured in input mode use GPIO_ReadInputDataBit() + (#) To set/reset the level of a pin configured in output mode use + GPIO_SetBits()/GPIO_ResetBits() + (#) During and just after reset, the alternate functions are not + active and the GPIO pins are configured in input floating mode + (except JTAG pins). + (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as + general-purpose (PC14 and PC15, respectively) when the LSE + oscillator is off. The LSE has priority over the GPIO function. + (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as + general-purpose PH0 and PH1, respectively, when the HSE + oscillator is off. The HSE has priority over the GPIO function. + @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_gpio.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup GPIO + * @brief GPIO driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup GPIO_Private_Functions + * @{ + */ + +/** @defgroup GPIO_Group1 Initialization and Configuration + * @brief Initialization and Configuration + * +@verbatim + =============================================================================== + ##### Initialization and Configuration ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the GPIOx peripheral registers to their default reset + * values. + * By default, The GPIO pins are configured in input floating mode + * (except JTAG pins). + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @retval None + */ +void GPIO_DeInit(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + if(GPIOx == GPIOA) + { + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, ENABLE); + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, DISABLE); + } + else if(GPIOx == GPIOB) + { + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, ENABLE); + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, DISABLE); + } + else if(GPIOx == GPIOC) + { + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, ENABLE); + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, DISABLE); + } + else if(GPIOx == GPIOD) + { + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, ENABLE); + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, DISABLE); + } + else if(GPIOx == GPIOE) + { + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOE, ENABLE); + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOE, DISABLE); + } + else if(GPIOx == GPIOF) + { + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOF, ENABLE); + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOF, DISABLE); + } + else if(GPIOx == GPIOG) + { + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOG, ENABLE); + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOG, DISABLE); + } + else + { + if(GPIOx == GPIOH) + { + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOH, ENABLE); + RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOH, DISABLE); + } + } +} + +/** + * @brief Initializes the GPIOx peripheral according to the specified + * parameters in the GPIO_InitStruct. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that + * contains the configuration information for the specified GPIO + * peripheral. + + * @retval None + */ +void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) +{ + uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); + assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); + assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd)); + + /* -------------------------Configure the port pins---------------- */ + /*-- GPIO Mode Configuration --*/ + for (pinpos = 0x00; pinpos < 0x10; pinpos++) + { + pos = ((uint32_t)0x01) << pinpos; + + /* Get the port pins position */ + currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; + + if (currentpin == pos) + { + GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2)); + + GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2)); + + if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF)) + { + /* Check Speed mode parameters */ + assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); + + /* Speed mode configuration */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2)); + GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2)); + + /*Check Output mode parameters */ + assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType)); + + /* Output mode configuration */ + GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ; + GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos)); + } + + /* Pull-up Pull down resistor configuration */ + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2)); + GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2)); + } + } +} + +/** + * @brief Fills each GPIO_InitStruct member with its default value. + * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStruct->GPIO_Speed = GPIO_Speed_400KHz; + GPIO_InitStruct->GPIO_OType = GPIO_OType_PP; + GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL; +} + +/** + * @brief Locks GPIO Pins configuration registers. + * The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, + * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. + * The configuration of the locked GPIO pins can no longer be modified + * until the next reset. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + __IO uint32_t tmp = 0x00010000; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + tmp |= GPIO_Pin; + /* Set LCKK bit */ + GPIOx->LCKR = tmp; + /* Reset LCKK bit */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKK bit */ + GPIOx->LCKR = tmp; + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; +} + +/** + * @} + */ + +/** @defgroup GPIO_Group2 GPIO Read and Write + * @brief GPIO Read and Write + * +@verbatim + =============================================================================== + ##### GPIO Read and Write ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Reads the specified input port pin. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to read. + * This parameter can be GPIO_Pin_x where x can be (0..15). + * @retval The input port pin value. + */ +uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint8_t bitstatus = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) + { + bitstatus = (uint8_t)Bit_SET; + } + else + { + bitstatus = (uint8_t)Bit_RESET; + } + return bitstatus; +} + +/** + * @brief Reads the specified GPIO input data port. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @retval GPIO input data port value. + */ +uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + return ((uint16_t)GPIOx->IDR); +} + +/** + * @brief Reads the specified output data port bit. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_Pin: Specifies the port bit to read. + * This parameter can be GPIO_Pin_x where x can be (0..15). + * @retval The output port pin value. + */ +uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint8_t bitstatus = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET) + { + bitstatus = (uint8_t)Bit_SET; + } + else + { + bitstatus = (uint8_t)Bit_RESET; + } + return bitstatus; +} + +/** + * @brief Reads the specified GPIO output data port. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @retval GPIO output data port value. + */ +uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + return ((uint16_t)GPIOx->ODR); +} + +/** + * @brief Sets the selected data port bits. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bits to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @note This functions uses GPIOx_BSRR register to allow atomic read/modify + * accesses. In this way, there is no risk of an IRQ occurring between + * the read and the modify access. + * @retval None + */ +void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->BSRRL = GPIO_Pin; +} + +/** + * @brief Clears the selected data port bits. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bits to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @note This functions uses GPIOx_BSRR register to allow atomic read/modify + * accesses. In this way, there is no risk of an IRQ occurring between + * the read and the modify access. + * @retval None + */ +void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->BSRRH = GPIO_Pin; +} + +/** + * @brief Sets or clears the selected data port bit. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_Pin_x where x can be (0..15). + * @param BitVal: specifies the value to be written to the selected bit. + * This parameter can be one of the BitAction enum values: + * @arg Bit_RESET: to clear the port pin + * @arg Bit_SET: to set the port pin + * @retval None + */ +void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_BIT_ACTION(BitVal)); + + if (BitVal != Bit_RESET) + { + GPIOx->BSRRL = GPIO_Pin; + } + else + { + GPIOx->BSRRH = GPIO_Pin ; + } +} + +/** + * @brief Writes data to the specified GPIO data port. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param PortVal: specifies the value to be written to the port output data + * register. + * @retval None + */ +void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + GPIOx->ODR = PortVal; +} + +/** + * @brief Toggles the specified GPIO pins.. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_Pin: Specifies the pins to be toggled. + * @retval None + */ +void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + GPIOx->ODR ^= GPIO_Pin; +} + +/** + * @} + */ + +/** @defgroup GPIO_Group3 GPIO Alternate functions configuration functions + * @brief GPIO Alternate functions configuration functions + * +@verbatim + =============================================================================== + ##### GPIO Alternate functions configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Changes the mapping of the specified pin. + * @param GPIOx: where x can be (A..H) to select the GPIO peripheral. + * @param GPIO_PinSource: specifies the pin for the Alternate function. + * This parameter can be GPIO_PinSourcex where x can be (0..15). + * @param GPIO_AFSelection: selects the pin to used as Alternat function. + * This parameter can be one of the following values: + * @arg GPIO_AF_RTC_50Hz: RTC 50/60 Hz synchronization + * @arg GPIO_AF_MCO: Microcontroller clock output + * @arg GPIO_AF_RTC_AF1: Time stamp, Tamper, Alarm A out, Alarm B out, + * 512 Hz clock output (with an LSE oscillator of 32.768 kHz) + * @arg GPIO_AF_WKUP: wakeup + * @arg GPIO_AF_SWJ: SWJ (SW and JTAG) + * @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset) + * @arg GPIO_AF_TIM2c: Connect TIM2 pins to AF1 + * @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2 + * @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2 + * @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2 + * @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3 + * @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3 + * @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3 + * @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4 + * @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4 + * @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5 + * @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5 + * @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6 + * @arg GPIO_AF_USART1: Connect USART1 pins to AF7 + * @arg GPIO_AF_USART2: Connect USART2 pins to AF7 + * @arg GPIO_AF_USART3: Connect USART3 pins to AF7 + * @arg GPIO_AF_UART4: Connect UART4 pins to AF8 + * @arg GPIO_AF_UART5: Connect UART5 pins to AF8 + * @arg GPIO_AF_USB: Connect USB pins to AF10 + * @arg GPIO_AF_LCD: Connect LCD pins to AF11 + * @arg GPIO_AF_FSMC: Connect FSMC pins to AF12 + * @arg GPIO_AF_SDIO: Connect SDIO pins to AF12 + * @arg GPIO_AF_RI: Connect RI pins to AF14 + * @arg GPIO_AF_EVENTOUT: Cortex-M3 EVENTOUT signal + * @note The pin should already been configured in Alternate Function mode(AF) + * using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF + * @note Please refer to the Alternate function mapping table in the device + * datasheet for the detailed mapping of the system and peripherals' + * alternate function I/O pins. + * @note EVENTOUT is not mapped on PH0, PH1 and PH2. + * @retval None + */ +void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) +{ + uint32_t temp = 0x00; + uint32_t temp_2 = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); + assert_param(IS_GPIO_AF(GPIO_AF)); + + temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; + GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; + temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp; + GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_gpio.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_gpio.h new file mode 100644 index 0000000000..478f9fea22 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_gpio.h @@ -0,0 +1,391 @@ +/** + ****************************************************************************** + * @file stm32l1xx_gpio.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the GPIO + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_GPIO_H +#define __STM32L1xx_GPIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ + ((PERIPH) == GPIOB) || \ + ((PERIPH) == GPIOC) || \ + ((PERIPH) == GPIOD) || \ + ((PERIPH) == GPIOE) || \ + ((PERIPH) == GPIOH) || \ + ((PERIPH) == GPIOF) || \ + ((PERIPH) == GPIOG)) + +/** @defgroup Configuration_Mode_enumeration + * @{ + */ +typedef enum +{ + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ + GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ + GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ +}GPIOMode_TypeDef; +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ + ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) +/** + * @} + */ + +/** @defgroup Output_type_enumeration + * @{ + */ +typedef enum +{ GPIO_OType_PP = 0x00, + GPIO_OType_OD = 0x01 +}GPIOOType_TypeDef; +#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) + +/** + * @} + */ + +/** @defgroup Output_Maximum_frequency_enumeration + * @{ + */ +typedef enum +{ + GPIO_Speed_400KHz = 0x00, /*!< Very Low Speed */ + GPIO_Speed_2MHz = 0x01, /*!< Low Speed */ + GPIO_Speed_10MHz = 0x02, /*!< Medium Speed */ + GPIO_Speed_40MHz = 0x03 /*!< High Speed */ +}GPIOSpeed_TypeDef; +#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_400KHz) || ((SPEED) == GPIO_Speed_2MHz) || \ + ((SPEED) == GPIO_Speed_10MHz)|| ((SPEED) == GPIO_Speed_40MHz)) +/** + * @} + */ + +/** @defgroup Configuration_Pull-Up_Pull-Down_enumeration + * @{ + */ +typedef enum +{ GPIO_PuPd_NOPULL = 0x00, + GPIO_PuPd_UP = 0x01, + GPIO_PuPd_DOWN = 0x02 +}GPIOPuPd_TypeDef; +#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ + ((PUPD) == GPIO_PuPd_DOWN)) +/** + * @} + */ + +/** @defgroup Bit_SET_and_Bit_RESET_enumeration + * @{ + */ +typedef enum +{ Bit_RESET = 0, + Bit_SET +}BitAction; +#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) + +/** + * @} + */ + +/** + * @brief GPIO Init structure definition + */ +typedef struct +{ + uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins_define */ + + GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIOMode_TypeDef */ + + GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIOSpeed_TypeDef */ + + GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref GPIOOType_TypeDef */ + + GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref GPIOPuPd_TypeDef */ +}GPIO_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Constants + * @{ + */ + +/** @defgroup GPIO_pins_define + * @{ + */ +#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ +#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ +#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ +#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ +#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ +#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ +#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ +#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ +#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ +#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ +#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ +#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ +#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ +#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ +#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ +#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */ +#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */ + +#define IS_GPIO_PIN(PIN) ((PIN) != (uint16_t)0x00) +#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ + ((PIN) == GPIO_Pin_1) || \ + ((PIN) == GPIO_Pin_2) || \ + ((PIN) == GPIO_Pin_3) || \ + ((PIN) == GPIO_Pin_4) || \ + ((PIN) == GPIO_Pin_5) || \ + ((PIN) == GPIO_Pin_6) || \ + ((PIN) == GPIO_Pin_7) || \ + ((PIN) == GPIO_Pin_8) || \ + ((PIN) == GPIO_Pin_9) || \ + ((PIN) == GPIO_Pin_10) || \ + ((PIN) == GPIO_Pin_11) || \ + ((PIN) == GPIO_Pin_12) || \ + ((PIN) == GPIO_Pin_13) || \ + ((PIN) == GPIO_Pin_14) || \ + ((PIN) == GPIO_Pin_15)) +/** + * @} + */ + +/** @defgroup GPIO_Pin_sources + * @{ + */ +#define GPIO_PinSource0 ((uint8_t)0x00) +#define GPIO_PinSource1 ((uint8_t)0x01) +#define GPIO_PinSource2 ((uint8_t)0x02) +#define GPIO_PinSource3 ((uint8_t)0x03) +#define GPIO_PinSource4 ((uint8_t)0x04) +#define GPIO_PinSource5 ((uint8_t)0x05) +#define GPIO_PinSource6 ((uint8_t)0x06) +#define GPIO_PinSource7 ((uint8_t)0x07) +#define GPIO_PinSource8 ((uint8_t)0x08) +#define GPIO_PinSource9 ((uint8_t)0x09) +#define GPIO_PinSource10 ((uint8_t)0x0A) +#define GPIO_PinSource11 ((uint8_t)0x0B) +#define GPIO_PinSource12 ((uint8_t)0x0C) +#define GPIO_PinSource13 ((uint8_t)0x0D) +#define GPIO_PinSource14 ((uint8_t)0x0E) +#define GPIO_PinSource15 ((uint8_t)0x0F) + +#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ + ((PINSOURCE) == GPIO_PinSource1) || \ + ((PINSOURCE) == GPIO_PinSource2) || \ + ((PINSOURCE) == GPIO_PinSource3) || \ + ((PINSOURCE) == GPIO_PinSource4) || \ + ((PINSOURCE) == GPIO_PinSource5) || \ + ((PINSOURCE) == GPIO_PinSource6) || \ + ((PINSOURCE) == GPIO_PinSource7) || \ + ((PINSOURCE) == GPIO_PinSource8) || \ + ((PINSOURCE) == GPIO_PinSource9) || \ + ((PINSOURCE) == GPIO_PinSource10) || \ + ((PINSOURCE) == GPIO_PinSource11) || \ + ((PINSOURCE) == GPIO_PinSource12) || \ + ((PINSOURCE) == GPIO_PinSource13) || \ + ((PINSOURCE) == GPIO_PinSource14) || \ + ((PINSOURCE) == GPIO_PinSource15)) +/** + * @} + */ + +/** @defgroup GPIO_Alternat_function_selection_define + * @{ + */ + +/** + * @brief AF 0 selection + */ +#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /*!< RTC 50/60 Hz Alternate Function mapping */ +#define GPIO_AF_MCO ((uint8_t)0x00) /*!< MCO Alternate Function mapping */ +#define GPIO_AF_RTC_AF1 ((uint8_t)0x00) /*!< RTC_AF1 Alternate Function mapping */ +#define GPIO_AF_WKUP ((uint8_t)0x00) /*!< Wakeup (WKUP1, WKUP2 and WKUP3) Alternate Function mapping */ +#define GPIO_AF_SWJ ((uint8_t)0x00) /*!< SWJ (SW and JTAG) Alternate Function mapping */ +#define GPIO_AF_TRACE ((uint8_t)0x00) /*!< TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF_TIM2 ((uint8_t)0x01) /*!< TIM2 Alternate Function mapping */ +/** + * @brief AF 2 selection + */ +#define GPIO_AF_TIM3 ((uint8_t)0x02) /*!< TIM3 Alternate Function mapping */ +#define GPIO_AF_TIM4 ((uint8_t)0x02) /*!< TIM4 Alternate Function mapping */ +#define GPIO_AF_TIM5 ((uint8_t)0x02) /*!< TIM5 Alternate Function mapping */ +/** + * @brief AF 3 selection + */ +#define GPIO_AF_TIM9 ((uint8_t)0x03) /*!< TIM9 Alternate Function mapping */ +#define GPIO_AF_TIM10 ((uint8_t)0x03) /*!< TIM10 Alternate Function mapping */ +#define GPIO_AF_TIM11 ((uint8_t)0x03) /*!< TIM11 Alternate Function mapping */ +/** + * @brief AF 4 selection + */ +#define GPIO_AF_I2C1 ((uint8_t)0x04) /*!< I2C1 Alternate Function mapping */ +#define GPIO_AF_I2C2 ((uint8_t)0x04) /*!< I2C2 Alternate Function mapping */ +/** + * @brief AF 5 selection + */ +#define GPIO_AF_SPI1 ((uint8_t)0x05) /*!< SPI1 Alternate Function mapping */ +#define GPIO_AF_SPI2 ((uint8_t)0x05) /*!< SPI2 Alternate Function mapping */ +/** + * @brief AF 6 selection + */ +#define GPIO_AF_SPI3 ((uint8_t)0x06) /*!< SPI3 Alternate Function mapping */ +/** + * @brief AF 7 selection + */ +#define GPIO_AF_USART1 ((uint8_t)0x07) /*!< USART1 Alternate Function mapping */ +#define GPIO_AF_USART2 ((uint8_t)0x07) /*!< USART2 Alternate Function mapping */ +#define GPIO_AF_USART3 ((uint8_t)0x07) /*!< USART3 Alternate Function mapping */ +/** + * @brief AF 8 selection + */ +#define GPIO_AF_UART4 ((uint8_t)0x08) /*!< UART4 Alternate Function mapping */ +#define GPIO_AF_UART5 ((uint8_t)0x08) /*!< UART5 Alternate Function mapping */ +/** + * @brief AF 10 selection + */ +#define GPIO_AF_USB ((uint8_t)0xA) /*!< USB Full speed device Alternate Function mapping */ +/** + * @brief AF 11 selection + */ +#define GPIO_AF_LCD ((uint8_t)0x0B) /*!< LCD Alternate Function mapping */ +/** + * @brief AF 12 selection + */ +#define GPIO_AF_FSMC ((uint8_t)0x0C) /*!< FSMC Alternate Function mapping */ +#define GPIO_AF_SDIO ((uint8_t)0x0C) /*!< SDIO Alternate Function mapping */ +/** + * @brief AF 14 selection + */ +#define GPIO_AF_RI ((uint8_t)0x0E) /*!< RI Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /*!< EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_MCO) || \ + ((AF) == GPIO_AF_RTC_AF1) || ((AF) == GPIO_AF_WKUP) || \ + ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ + ((AF) == GPIO_AF_TIM2) || ((AF)== GPIO_AF_TIM3) || \ + ((AF) == GPIO_AF_TIM4) || ((AF)== GPIO_AF_TIM9) || \ + ((AF) == GPIO_AF_TIM10) || ((AF)== GPIO_AF_TIM11) || \ + ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ + ((AF) == GPIO_AF_SPI1) || ((AF) == GPIO_AF_SPI2) || \ + ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ + ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_USB) || \ + ((AF) == GPIO_AF_LCD) || ((AF) == GPIO_AF_RI) || \ + ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_SPI3) || \ + ((AF) == GPIO_AF_UART4) || ((AF) == GPIO_AF_UART5) || \ + ((AF) == GPIO_AF_FSMC) || ((AF) == GPIO_AF_SDIO) || \ + ((AF) == GPIO_AF_EVENTOUT)) + +/** + * @} + */ + +/** @defgroup GPIO_Legacy + * @{ + */ + +#define GPIO_Mode_AIN GPIO_Mode_AN + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the GPIO configuration to the default reset state ****/ +void GPIO_DeInit(GPIO_TypeDef* GPIOx); + +/* Initialization and Configuration functions *********************************/ +void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); +void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); +void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + +/* GPIO Read and Write functions **********************************************/ +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); +void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + +/* GPIO Alternate functions configuration functions ***************************/ +void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_GPIO_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_i2c.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_i2c.c new file mode 100644 index 0000000000..0d66d17d23 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_i2c.c @@ -0,0 +1,1364 @@ +/** + ****************************************************************************** + * @file stm32l1xx_i2c.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Inter-integrated circuit (I2C) + * + Initialization and Configuration + * + Data transfers + * + PEC management + * + DMA transfers management + * + Interrupts, events and flags management + * + * @verbatim + * + * ============================================================================ + * ##### How to use this driver ##### + * ============================================================================ + [..] + (#) Enable peripheral clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2Cx, ENABLE) + function for I2C1 or I2C2. + (#) Enable SDA, SCL and SMBA (when used) GPIO clocks using + RCC_AHBPeriphClockCmd() function. + (#) Peripherals alternate function: + (++) Connect the pin to the desired peripherals' Alternate + Function (AF) using GPIO_PinAFConfig() function. + (++) Configure the desired pin in alternate function by: + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF + (++) Select the type, pull-up/pull-down and output speed via + GPIO_PuPd, GPIO_OType and GPIO_Speed members + (++) Call GPIO_Init() function. + (#) Program the Mode, duty cycle , Own address, Ack, Speed and Acknowledged + Address using the I2C_Init() function. + (#) Optionally you can enable/configure the following parameters without + re-initialization (i.e there is no need to call again I2C_Init() function): + (++) Enable the acknowledge feature using I2C_AcknowledgeConfig() function. + (++) Enable the dual addressing mode using I2C_DualAddressCmd() function. + (++) Enable the general call using the I2C_GeneralCallCmd() function. + (++) Enable the clock stretching using I2C_StretchClockCmd() function. + (++) Enable the fast mode duty cycle using the I2C_FastModeDutyCycleConfig() + function. + (++) Enable the PEC Calculation using I2C_CalculatePEC() function. + (++) For SMBus Mode: + (+++) Enable the Address Resolution Protocol (ARP) using I2C_ARPCmd() function. + (+++) Configure the SMBusAlert pin using I2C_SMBusAlertConfig() function. + (#) Enable the NVIC and the corresponding interrupt using the function + I2C_ITConfig() if you need to use interrupt mode. + (#) When using the DMA mode + (++) Configure the DMA using DMA_Init() function. + (++) Active the needed channel Request using I2C_DMACmd() or + I2C_DMALastTransferCmd() function. + (#) Enable the I2C using the I2C_Cmd() function. + (#) Enable the DMA using the DMA_Cmd() function when using DMA mode in the + transfers. + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_i2c.h" +#include "stm32l1xx_rcc.h" + + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup I2C + * @brief I2C driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +#define CR1_CLEAR_MASK ((uint16_t)0xFBF5) /*I2C_ClockSpeed)); + assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode)); + assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle)); + assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); + assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack)); + assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress)); + +/*---------------------------- I2Cx CR2 Configuration ------------------------*/ + /* Get the I2Cx CR2 value */ + tmpreg = I2Cx->CR2; + /* Clear frequency FREQ[5:0] bits */ + tmpreg &= (uint16_t)~((uint16_t)I2C_CR2_FREQ); + /* Get pclk1 frequency value */ + RCC_GetClocksFreq(&rcc_clocks); + pclk1 = rcc_clocks.PCLK1_Frequency; + /* Set frequency bits depending on pclk1 value */ + freqrange = (uint16_t)(pclk1 / 1000000); + tmpreg |= freqrange; + /* Write to I2Cx CR2 */ + I2Cx->CR2 = tmpreg; + +/*---------------------------- I2Cx CCR Configuration ------------------------*/ + /* Disable the selected I2C peripheral to configure TRISE */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE); + /* Reset tmpreg value */ + /* Clear F/S, DUTY and CCR[11:0] bits */ + tmpreg = 0; + + /* Configure speed in standard mode */ + if (I2C_InitStruct->I2C_ClockSpeed <= 100000) + { + /* Standard mode speed calculate */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1)); + /* Test if CCR value is under 0x4*/ + if (result < 0x04) + { + /* Set minimum allowed value */ + result = 0x04; + } + /* Set speed value for standard mode */ + tmpreg |= result; + /* Set Maximum Rise Time for standard mode */ + I2Cx->TRISE = freqrange + 1; + } + /* Configure speed in fast mode */ + /* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral + input clock) must be a multiple of 10 MHz */ + else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/ + { + if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2) + { + /* Fast mode speed calculate: Tlow/Thigh = 2 */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3)); + } + else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/ + { + /* Fast mode speed calculate: Tlow/Thigh = 16/9 */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25)); + /* Set DUTY bit */ + result |= I2C_DutyCycle_16_9; + } + + /* Test if CCR value is under 0x1*/ + if ((result & I2C_CCR_CCR) == 0) + { + /* Set minimum allowed value */ + result |= (uint16_t)0x0001; + } + /* Set speed value and set F/S bit for fast mode */ + tmpreg |= (uint16_t)(result | I2C_CCR_FS); + /* Set Maximum Rise Time for fast mode */ + I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); + } + + /* Write to I2Cx CCR */ + I2Cx->CCR = tmpreg; + /* Enable the selected I2C peripheral */ + I2Cx->CR1 |= I2C_CR1_PE; + +/*---------------------------- I2Cx CR1 Configuration ------------------------*/ + /* Get the I2Cx CR1 value */ + tmpreg = I2Cx->CR1; + /* Clear ACK, SMBTYPE and SMBUS bits */ + tmpreg &= CR1_CLEAR_MASK; + /* Configure I2Cx: mode and acknowledgement */ + /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */ + /* Set ACK bit according to I2C_Ack value */ + tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack); + /* Write to I2Cx CR1 */ + I2Cx->CR1 = tmpreg; + +/*---------------------------- I2Cx OAR1 Configuration -----------------------*/ + /* Set I2Cx Own Address1 and acknowledged address */ + I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1); +} + +/** + * @brief Fills each I2C_InitStruct member with its default value. + * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) +{ +/*---------------- Reset I2C init structure parameters values ----------------*/ + /* initialize the I2C_ClockSpeed member */ + I2C_InitStruct->I2C_ClockSpeed = 5000; + /* Initialize the I2C_Mode member */ + I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; + /* Initialize the I2C_DutyCycle member */ + I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2; + /* Initialize the I2C_OwnAddress1 member */ + I2C_InitStruct->I2C_OwnAddress1 = 0; + /* Initialize the I2C_Ack member */ + I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; + /* Initialize the I2C_AcknowledgedAddress member */ + I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; +} + +/** + * @brief Enables or disables the specified I2C peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2Cx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C peripheral */ + I2Cx->CR1 |= I2C_CR1_PE; + } + else + { + /* Disable the selected I2C peripheral */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE); + } +} + +/** + * @brief Generates I2Cx communication START condition. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C START condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Generate a START condition */ + I2Cx->CR1 |= I2C_CR1_START; + } + else + { + /* Disable the START condition generation */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_START); + } +} + +/** + * @brief Generates I2Cx communication STOP condition. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C STOP condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Generate a STOP condition */ + I2Cx->CR1 |= I2C_CR1_STOP; + } + else + { + /* Disable the STOP condition generation */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_STOP); + } +} + +/** + * @brief Enables or disables the specified I2C acknowledge feature. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C Acknowledgement. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the acknowledgement */ + I2Cx->CR1 |= I2C_CR1_ACK; + } + else + { + /* Disable the acknowledgement */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK); + } +} + +/** + * @brief Configures the specified I2C own address2. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param Address: specifies the 7bit I2C own address2. + * @retval None. + */ +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address) +{ + uint16_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Get the old register value */ + tmpreg = I2Cx->OAR2; + + /* Reset I2Cx Own address2 bit [7:1] */ + tmpreg &= (uint16_t)~((uint16_t)I2C_OAR2_ADD2); + + /* Set I2Cx Own address2 */ + tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE); + + /* Store the new register value */ + I2Cx->OAR2 = tmpreg; +} + +/** + * @brief Enables or disables the specified I2C dual addressing mode. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C dual addressing mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable dual addressing mode */ + I2Cx->OAR2 |= I2C_OAR2_ENDUAL; + } + else + { + /* Disable dual addressing mode */ + I2Cx->OAR2 &= (uint16_t)~((uint16_t)I2C_OAR2_ENDUAL); + } +} + +/** + * @brief Enables or disables the specified I2C general call feature. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C General call. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable generall call */ + I2Cx->CR1 |= I2C_CR1_ENGC; + } + else + { + /* Disable generall call */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENGC); + } +} + +/** + * @brief Enables or disables the specified I2C software reset. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C software reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Peripheral under reset */ + I2Cx->CR1 |= I2C_CR1_SWRST; + } + else + { + /* Peripheral not under reset */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_SWRST); + } +} + +/** + * @brief Drives the SMBusAlert pin high or low for the specified I2C. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_SMBusAlert: specifies SMBAlert pin level. + * This parameter can be one of the following values: + * @arg I2C_SMBusAlert_Low: SMBAlert pin driven low + * @arg I2C_SMBusAlert_High: SMBAlert pin driven high + * @retval None + */ +void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert)); + if (I2C_SMBusAlert == I2C_SMBusAlert_Low) + { + /* Drive the SMBusAlert pin Low */ + I2Cx->CR1 |= I2C_SMBusAlert_Low; + } + else + { + /* Drive the SMBusAlert pin High */ + I2Cx->CR1 &= I2C_SMBusAlert_High; + } +} + +/** + * @brief Enables or disables the specified I2C ARP. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2Cx ARP. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C ARP */ + I2Cx->CR1 |= I2C_CR1_ENARP; + } + else + { + /* Disable the selected I2C ARP */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENARP); + } +} + +/** + * @brief Enables or disables the specified I2C Clock stretching. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2Cx Clock stretching. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState == DISABLE) + { + /* Enable the selected I2C Clock stretching */ + I2Cx->CR1 |= I2C_CR1_NOSTRETCH; + } + else + { + /* Disable the selected I2C Clock stretching */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_NOSTRETCH); + } +} + +/** + * @brief Selects the specified I2C fast mode duty cycle. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_DutyCycle: specifies the fast mode duty cycle. + * This parameter can be one of the following values: + * @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2 + * @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9 + * @retval None + */ +void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle)); + if (I2C_DutyCycle != I2C_DutyCycle_16_9) + { + /* I2C fast mode Tlow/Thigh=2 */ + I2Cx->CCR &= I2C_DutyCycle_2; + } + else + { + /* I2C fast mode Tlow/Thigh=16/9 */ + I2Cx->CCR |= I2C_DutyCycle_16_9; + } +} + +/** + * @brief Transmits the address byte to select the slave device. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param Address: specifies the slave address which will be transmitted. + * @param I2C_Direction: specifies whether the I2C device will be a + * Transmitter or a Receiver. This parameter can be one of the following values: + * @arg I2C_Direction_Transmitter: Transmitter mode + * @arg I2C_Direction_Receiver: Receiver mode + * @retval None. + */ +void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DIRECTION(I2C_Direction)); + /* Test on the direction to set/reset the read/write bit */ + if (I2C_Direction != I2C_Direction_Transmitter) + { + /* Set the address bit0 for read */ + Address |= I2C_OAR1_ADD0; + } + else + { + /* Reset the address bit0 for write */ + Address &= (uint8_t)~((uint8_t)I2C_OAR1_ADD0); + } + /* Send the address */ + I2Cx->DR = Address; +} + +/** + * @} + */ + +/** @defgroup I2C_Group2 Data transfers functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### Data transfers functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Sends a data byte through the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param Data: Byte to be transmitted. + * @retval None + */ +void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Write in the DR register the data to be sent */ + I2Cx->DR = Data; +} + +/** + * @brief Returns the most recent received data by the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @retval The value of the received data. + */ +uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Return the data in the DR register */ + return (uint8_t)I2Cx->DR; +} + +/** + * @brief Selects the specified I2C NACK position in master receiver mode. + * This function is useful in I2C Master Receiver mode when the number + * of data to be received is equal to 2. In this case, this function + * should be called (with parameter I2C_NACKPosition_Next) before data + * reception starts,as described in the 2-byte reception procedure + * recommended in Reference Manual in Section: Master receiver. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_NACKPosition: specifies the NACK position. + * This parameter can be one of the following values: + * @arg I2C_NACKPosition_Next: indicates that the next byte will be the last + * received byte. + * @arg I2C_NACKPosition_Current: indicates that current byte is the last + * received byte. + * @note This function configures the same bit (POS) as I2C_PECPositionConfig() + * but is intended to be used in I2C mode while I2C_PECPositionConfig() + * is intended to used in SMBUS mode. + * + * @retval None + */ +void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_NACK_POSITION(I2C_NACKPosition)); + + /* Check the input parameter */ + if (I2C_NACKPosition == I2C_NACKPosition_Next) + { + /* Next byte in shift register is the last received byte */ + I2Cx->CR1 |= I2C_NACKPosition_Next; + } + else + { + /* Current byte in shift register is the last received byte */ + I2Cx->CR1 &= I2C_NACKPosition_Current; + } +} + +/** + * @} + */ + +/** @defgroup I2C_Group3 PEC management functions + * @brief PEC management functions + * +@verbatim + =============================================================================== + ##### PEC management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified I2C PEC transfer. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C PEC transmission. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C PEC transmission */ + I2Cx->CR1 |= I2C_CR1_PEC; + } + else + { + /* Disable the selected I2C PEC transmission */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PEC); + } +} + +/** + * @brief Selects the specified I2C PEC position. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_PECPosition: specifies the PEC position. + * This parameter can be one of the following values: + * @arg I2C_PECPosition_Next: indicates that the next byte is PEC + * @arg I2C_PECPosition_Current: indicates that current byte is PEC + * @note This function configures the same bit (POS) as I2C_NACKPositionConfig() + * but is intended to be used in SMBUS mode while I2C_NACKPositionConfig() + * is intended to used in I2C mode. + * @retval None + */ +void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition)); + if (I2C_PECPosition == I2C_PECPosition_Next) + { + /* Next byte in shift register is PEC */ + I2Cx->CR1 |= I2C_PECPosition_Next; + } + else + { + /* Current byte in shift register is PEC */ + I2Cx->CR1 &= I2C_PECPosition_Current; + } +} + +/** + * @brief Enables or disables the PEC value calculation of the transferred bytes. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2Cx PEC value calculation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C PEC calculation */ + I2Cx->CR1 |= I2C_CR1_ENPEC; + } + else + { + /* Disable the selected I2C PEC calculation */ + I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENPEC); + } +} + +/** + * @brief Returns the PEC value for the specified I2C. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @retval The PEC value. + */ +uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Return the selected I2C PEC value */ + return ((I2Cx->SR2) >> 8); +} + +/** + * @} + */ + +/** @defgroup I2C_Group4 DMA transfers management functions + * @brief DMA transfers management functions + * +@verbatim + =============================================================================== + ##### DMA transfers management functions ##### + =============================================================================== + [..] This section provides functions allowing to configure the I2C DMA channels + requests. +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified I2C DMA requests. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C DMA transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C DMA requests */ + I2Cx->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Disable the selected I2C DMA requests */ + I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_DMAEN); + } +} + +/** + * @brief Specifies that the next DMA transfer is the last one. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C DMA last transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Next DMA transfer is the last transfer */ + I2Cx->CR2 |= I2C_CR2_LAST; + } + else + { + /* Next DMA transfer is not the last transfer */ + I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_LAST); + } +} + +/** + * @} + */ + +/** @defgroup I2C_Group5 Interrupts events and flags management functions + * @brief Interrupts, events and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts, events and flags management functions ##### + =============================================================================== + [..] This section provides functions allowing to configure the I2C Interrupts + sources and check or clear the flags or pending bits status. + The user should identify which mode will be used in his application to manage + the communication: Polling mode, Interrupt mode or DMA mode. + + + ##### I2C State Monitoring Functions ##### + =============================================================================== + [..]This I2C driver provides three different ways for I2C state monitoring + depending on the application requirements and constraints: + + + ***. Basic state monitoring (Using I2C_CheckEvent() function) *** + ----------------------------------------------------------------- + [..]It compares the status registers (SR1 and SR2) content to a given event + (can be the combination of one or more flags). + It returns SUCCESS if the current status includes the given flags + and returns ERROR if one or more flags are missing in the current status. + + (+) When to use + (++) This function is suitable for most applications as well as for + startup activity since the events are fully described in the product + reference manual (RM0038). + (++) It is also suitable for users who need to define their own events. + (+) Limitations + (++) If an error occurs (ie. error flags are set besides to the monitored + flags), the I2C_CheckEvent() function may return SUCCESS despite + the communication hold or corrupted real state. + In this case, it is advised to use error interrupts to monitor + the error events and handle them in the interrupt IRQ handler. + -@@- For error management, it is advised to use the following functions: + (+@@) I2C_ITConfig() to configure and enable the error interrupts + (I2C_IT_ERR). + (+@@) I2Cx_ER_IRQHandler() which is called when the error interrupt occurs. + Where x is the peripheral instance (I2C1, I2C2 ...). + (+@@) I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the + I2Cx_ER_IRQHandler() function in order to determine which error occurred. + (+@@) I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() + and/or I2C_GenerateStop() in order to clear the error flag and source + and return to correct communication status. + + *** Advanced state monitoring (Using the function I2C_GetLastEvent()) *** + ------------------------------------------------------------------------- + [..] Using the function I2C_GetLastEvent() which returns the image of both status + registers in a single word (uint32_t) (Status Register 2 value is shifted left + by 16 bits and concatenated to Status Register 1). + + (+) When to use + (++) This function is suitable for the same applications above but it + allows to overcome the mentioned limitation of I2C_GetFlagStatus() + function. + (++) The returned value could be compared to events already defined in + the library (stm32l1xx_i2c.h) or to custom values defined by user. + This function is suitable when multiple flags are monitored at the + same time. + (++) At the opposite of I2C_CheckEvent() function, this function allows + user to choose when an event is accepted (when all events flags are + set and no other flags are set or just when the needed flags are set + like I2C_CheckEvent() function. + + (+) Limitations + (++) User may need to define his own events. + (++) Same remark concerning the error management is applicable for this + function if user decides to check only regular communication flags + (and ignores error flags). + + + *** Flag-based state monitoring (Using the function I2C_GetFlagStatus()) *** + ---------------------------------------------------------------------------- + [..] Using the function I2C_GetFlagStatus() which simply returns the status of + one single flag (ie. I2C_FLAG_RXNE ...). + (+) When to use + (++) This function could be used for specific applications or in debug + phase. + (++) It is suitable when only one flag checking is needed (most I2C + events are monitored through multiple flags). + (+) Limitations: + (++) When calling this function, the Status register is accessed. + Some flags are cleared when the status register is accessed. + So checking the status of one Flag, may clear other ones. + (++) Function may need to be called twice or more in order to monitor + one single event. + + [..] For detailed description of Events, please refer to section I2C_Events in + stm32l1xx_i2c.h file. + +@endverbatim + * @{ + */ + +/** + * @brief Reads the specified I2C register and returns its value. + * @param I2C_Register: specifies the register to read. + * This parameter can be one of the following values: + * @arg I2C_Register_CR1: CR1 register. + * @arg I2C_Register_CR2: CR2 register. + * @arg I2C_Register_OAR1: OAR1 register. + * @arg I2C_Register_OAR2: OAR2 register. + * @arg I2C_Register_DR: DR register. + * @arg I2C_Register_SR1: SR1 register. + * @arg I2C_Register_SR2: SR2 register. + * @arg I2C_Register_CCR: CCR register. + * @arg I2C_Register_TRISE: TRISE register. + * @retval The value of the read register. + */ +uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_REGISTER(I2C_Register)); + + tmp = (uint32_t) I2Cx; + tmp += I2C_Register; + + /* Return the selected register value */ + return (*(__IO uint16_t *) tmp); +} + +/** + * @brief Enables or disables the specified I2C interrupts. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg I2C_IT_BUF: Buffer interrupt mask + * @arg I2C_IT_EVT: Event interrupt mask + * @arg I2C_IT_ERR: Error interrupt mask + * @param NewState: new state of the specified I2C interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2C_CONFIG_IT(I2C_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C interrupts */ + I2Cx->CR2 |= I2C_IT; + } + else + { + /* Disable the selected I2C interrupts */ + I2Cx->CR2 &= (uint16_t)~I2C_IT; + } +} + +/* + =============================================================================== + 1. Basic state monitoring + =============================================================================== + */ + +/** + * @brief Checks whether the last I2Cx Event is equal to the one passed + * as parameter. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_EVENT: specifies the event to be checked. + * This parameter can be one of the following values: + * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: EV1 + * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED: EV2 + * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF): EV2 + * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL): EV2 + * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED: EV3 + * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF): EV3 + * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL): EV3 + * @arg I2C_EVENT_SLAVE_ACK_FAILURE: EV3_2 + * @arg I2C_EVENT_SLAVE_STOP_DETECTED: EV4 + * @arg I2C_EVENT_MASTER_MODE_SELECT: EV5 + * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: EV6 + * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: EV6 + * @arg I2C_EVENT_MASTER_BYTE_RECEIVED: EV7 + * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING: EV8 + * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED: EV8_2 + * @arg I2C_EVENT_MASTER_MODE_ADDRESS10: EV9 + * @note For detailed description of Events, please refer to section + * I2C_Events in stm32l1xx_i2c.h file. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Last event is equal to the I2C_EVENT + * - ERROR: Last event is different from the I2C_EVENT + */ +ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) +{ + uint32_t lastevent = 0; + uint32_t flag1 = 0, flag2 = 0; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_EVENT(I2C_EVENT)); + + /* Read the I2Cx status register */ + flag1 = I2Cx->SR1; + flag2 = I2Cx->SR2; + flag2 = flag2 << 16; + + /* Get the last event value from I2C status register */ + lastevent = (flag1 | flag2) & FLAG_MASK; + + /* Check whether the last event contains the I2C_EVENT */ + if ((lastevent & I2C_EVENT) == I2C_EVENT) + { + /* SUCCESS: last event is equal to I2C_EVENT */ + status = SUCCESS; + } + else + { + /* ERROR: last event is different from I2C_EVENT */ + status = ERROR; + } + /* Return status */ + return status; +} + +/* + =============================================================================== + 2. Advanced state monitoring + =============================================================================== + */ + +/** + * @brief Returns the last I2Cx Event. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * + * @note For detailed description of Events, please refer to section + * I2C_Events in stm32l1xx_i2c.h file. + * + * @retval The last event + */ +uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx) +{ + uint32_t lastevent = 0; + uint32_t flag1 = 0, flag2 = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Read the I2Cx status register */ + flag1 = I2Cx->SR1; + flag2 = I2Cx->SR2; + flag2 = flag2 << 16; + + /* Get the last event value from I2C status register */ + lastevent = (flag1 | flag2) & FLAG_MASK; + + /* Return status */ + return lastevent; +} + +/* + =============================================================================== + 3. Flag-based state monitoring + =============================================================================== + */ + +/** + * @brief Checks whether the specified I2C flag is set or not. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2C_FLAG_DUALF: Dual flag (Slave mode) + * @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode) + * @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode) + * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode) + * @arg I2C_FLAG_TRA: Transmitter/Receiver flag + * @arg I2C_FLAG_BUSY: Bus busy flag + * @arg I2C_FLAG_MSL: Master/Slave flag + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * @arg I2C_FLAG_TXE: Data register empty flag (Transmitter) + * @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag + * @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode) + * @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode) + * @arg I2C_FLAG_BTF: Byte transfer finished flag + * @arg I2C_FLAG_ADDR: Address sent flag (Master mode) "ADSL" + * Address matched flag (Slave mode)"ENDAD" + * @arg I2C_FLAG_SB: Start bit flag (Master mode) + * @retval The new state of I2C_FLAG (SET or RESET). + */ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) +{ + FlagStatus bitstatus = RESET; + __IO uint32_t i2creg = 0, i2cxbase = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); + + /* Get the I2Cx peripheral base address */ + i2cxbase = (uint32_t)I2Cx; + + /* Read flag register index */ + i2creg = I2C_FLAG >> 28; + + /* Get bit[23:0] of the flag */ + I2C_FLAG &= FLAG_MASK; + + if(i2creg != 0) + { + /* Get the I2Cx SR1 register address */ + i2cxbase += 0x14; + } + else + { + /* Flag in I2Cx SR2 Register */ + I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); + /* Get the I2Cx SR2 register address */ + i2cxbase += 0x18; + } + + if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) + { + /* I2C_FLAG is set */ + bitstatus = SET; + } + else + { + /* I2C_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the I2C_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the I2Cx's pending flags. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * + + *@note STOPF (STOP detection) is cleared by software sequence: a read operation + * to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation + * to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). + *@note ADD10 (10-bit header sent) is cleared by software sequence: a read + * operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the + * second byte of the address in DR register. + *@note BTF (Byte Transfer Finished) is cleared by software sequence: a read + * operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a + * read/write to I2C_DR register (I2C_SendData()). + *@note ADDR (Address sent) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to + * I2C_SR2 register ((void)(I2Cx->SR2)). + *@note SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1 + * register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR + * register (I2C_SendData()). + * @retval None + */ +void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) +{ + uint32_t flagpos = 0; + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG)); + /* Get the I2C flag position */ + flagpos = I2C_FLAG & FLAG_MASK; + /* Clear the selected I2C flag */ + I2Cx->SR1 = (uint16_t)~flagpos; +} + +/** + * @brief Checks whether the specified I2C interrupt has occurred or not. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_IT: specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_SMBALERT: SMBus Alert flag + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_IT_PECERR: PEC error in reception flag + * @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_IT_AF: Acknowledge failure flag + * @arg I2C_IT_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_IT_BERR: Bus error flag + * @arg I2C_IT_TXE: Data register empty flag (Transmitter) + * @arg I2C_IT_RXNE: Data register not empty (Receiver) flag + * @arg I2C_IT_STOPF: Stop detection flag (Slave mode) + * @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode) + * @arg I2C_IT_BTF: Byte transfer finished flag + * @arg I2C_IT_ADDR: Address sent flag (Master mode) "ADSL" + * Address matched flag (Slave mode)"ENDAD" + * @arg I2C_IT_SB: Start bit flag (Master mode) + * @retval The new state of I2C_IT (SET or RESET). + */ +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_IT(I2C_IT)); + + /* Check if the interrupt source is enabled or not */ + enablestatus = (uint32_t)(((I2C_IT & ITEN_MASK) >> 16) & (I2Cx->CR2)) ; + + /* Get bit[23:0] of the flag */ + I2C_IT &= FLAG_MASK; + + /* Check the status of the specified I2C flag */ + if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus) + { + /* I2C_IT is set */ + bitstatus = SET; + } + else + { + /* I2C_IT is reset */ + bitstatus = RESET; + } + /* Return the I2C_IT status */ + return bitstatus; +} + +/** + * @brief Clears the I2Cx's interrupt pending bits. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg I2C_IT_SMBALERT: SMBus Alert interrupt + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt + * @arg I2C_IT_PECERR: PEC error in reception interrupt + * @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode) + * @arg I2C_IT_AF: Acknowledge failure interrupt + * @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode) + * @arg I2C_IT_BERR: Bus error interrupt + * + + * @note STOPF (STOP detection) is cleared by software sequence: a read operation + * to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to + * I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). + * @note ADD10 (10-bit header sent) is cleared by software sequence: a read + * operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second + * byte of the address in I2C_DR register. + * @note BTF (Byte Transfer Finished) is cleared by software sequence: a read + * operation to I2C_SR1 register (I2C_GetITStatus()) followed by a + * read/write to I2C_DR register (I2C_SendData()). + * @note ADDR (Address sent) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to + * I2C_SR2 register ((void)(I2Cx->SR2)). + * @note SB (Start Bit) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to + * I2C_DR register (I2C_SendData()). + * @retval None + */ +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT) +{ + uint32_t flagpos = 0; + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_IT(I2C_IT)); + /* Get the I2C flag position */ + flagpos = I2C_IT & FLAG_MASK; + /* Clear the selected I2C flag */ + I2Cx->SR1 = (uint16_t)~flagpos; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_i2c.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_i2c.h new file mode 100644 index 0000000000..8b52a09406 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_i2c.h @@ -0,0 +1,703 @@ +/** + ****************************************************************************** + * @file stm32l1xx_i2c.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the I2C firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_I2C_H +#define __STM32L1xx_I2C_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief I2C Init structure definition + */ + +typedef struct +{ + uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. + This parameter must be set to a value lower than 400kHz */ + + uint16_t I2C_Mode; /*!< Specifies the I2C mode. + This parameter can be a value of @ref I2C_mode */ + + uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle. + This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ + + uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement. + This parameter can be a value of @ref I2C_acknowledgement */ + + uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged. + This parameter can be a value of @ref I2C_acknowledged_address */ +}I2C_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + + +/** @defgroup I2C_Exported_Constants + * @{ + */ + +#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \ + ((PERIPH) == I2C2)) +/** @defgroup I2C_mode + * @{ + */ + +#define I2C_Mode_I2C ((uint16_t)0x0000) +#define I2C_Mode_SMBusDevice ((uint16_t)0x0002) +#define I2C_Mode_SMBusHost ((uint16_t)0x000A) +#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \ + ((MODE) == I2C_Mode_SMBusDevice) || \ + ((MODE) == I2C_Mode_SMBusHost)) +/** + * @} + */ + +/** @defgroup I2C_duty_cycle_in_fast_mode + * @{ + */ + +#define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */ +#define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */ +#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \ + ((CYCLE) == I2C_DutyCycle_2)) +/** + * @} + */ + +/** @defgroup I2C_acknowledgement + * @{ + */ + +#define I2C_Ack_Enable ((uint16_t)0x0400) +#define I2C_Ack_Disable ((uint16_t)0x0000) +#define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \ + ((STATE) == I2C_Ack_Disable)) +/** + * @} + */ + +/** @defgroup I2C_transfer_direction + * @{ + */ + +#define I2C_Direction_Transmitter ((uint8_t)0x00) +#define I2C_Direction_Receiver ((uint8_t)0x01) +#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \ + ((DIRECTION) == I2C_Direction_Receiver)) +/** + * @} + */ + +/** @defgroup I2C_acknowledged_address + * @{ + */ + +#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000) +#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000) +#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \ + ((ADDRESS) == I2C_AcknowledgedAddress_10bit)) +/** + * @} + */ + +/** @defgroup I2C_registers + * @{ + */ + +#define I2C_Register_CR1 ((uint8_t)0x00) +#define I2C_Register_CR2 ((uint8_t)0x04) +#define I2C_Register_OAR1 ((uint8_t)0x08) +#define I2C_Register_OAR2 ((uint8_t)0x0C) +#define I2C_Register_DR ((uint8_t)0x10) +#define I2C_Register_SR1 ((uint8_t)0x14) +#define I2C_Register_SR2 ((uint8_t)0x18) +#define I2C_Register_CCR ((uint8_t)0x1C) +#define I2C_Register_TRISE ((uint8_t)0x20) +#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \ + ((REGISTER) == I2C_Register_CR2) || \ + ((REGISTER) == I2C_Register_OAR1) || \ + ((REGISTER) == I2C_Register_OAR2) || \ + ((REGISTER) == I2C_Register_DR) || \ + ((REGISTER) == I2C_Register_SR1) || \ + ((REGISTER) == I2C_Register_SR2) || \ + ((REGISTER) == I2C_Register_CCR) || \ + ((REGISTER) == I2C_Register_TRISE)) +/** + * @} + */ + +/** @defgroup I2C_SMBus_alert_pin_level + * @{ + */ + +#define I2C_SMBusAlert_Low ((uint16_t)0x2000) +#define I2C_SMBusAlert_High ((uint16_t)0xDFFF) +#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \ + ((ALERT) == I2C_SMBusAlert_High)) +/** + * @} + */ + +/** @defgroup I2C_PEC_position + * @{ + */ + +#define I2C_PECPosition_Next ((uint16_t)0x0800) +#define I2C_PECPosition_Current ((uint16_t)0xF7FF) +#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \ + ((POSITION) == I2C_PECPosition_Current)) +/** + * @} + */ + +/** @defgroup I2C_NACK_position + * @{ + */ + +#define I2C_NACKPosition_Next ((uint16_t)0x0800) +#define I2C_NACKPosition_Current ((uint16_t)0xF7FF) +#define IS_I2C_NACK_POSITION(POSITION) (((POSITION) == I2C_NACKPosition_Next) || \ + ((POSITION) == I2C_NACKPosition_Current)) +/** + * @} + */ + +/** @defgroup I2C_interrupts_definition + * @{ + */ + +#define I2C_IT_BUF ((uint16_t)0x0400) +#define I2C_IT_EVT ((uint16_t)0x0200) +#define I2C_IT_ERR ((uint16_t)0x0100) +#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00)) +/** + * @} + */ + +/** @defgroup I2C_interrupts_definition + * @{ + */ + +#define I2C_IT_SMBALERT ((uint32_t)0x01008000) +#define I2C_IT_TIMEOUT ((uint32_t)0x01004000) +#define I2C_IT_PECERR ((uint32_t)0x01001000) +#define I2C_IT_OVR ((uint32_t)0x01000800) +#define I2C_IT_AF ((uint32_t)0x01000400) +#define I2C_IT_ARLO ((uint32_t)0x01000200) +#define I2C_IT_BERR ((uint32_t)0x01000100) +#define I2C_IT_TXE ((uint32_t)0x06000080) +#define I2C_IT_RXNE ((uint32_t)0x06000040) +#define I2C_IT_STOPF ((uint32_t)0x02000010) +#define I2C_IT_ADD10 ((uint32_t)0x02000008) +#define I2C_IT_BTF ((uint32_t)0x02000004) +#define I2C_IT_ADDR ((uint32_t)0x02000002) +#define I2C_IT_SB ((uint32_t)0x02000001) + +#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00)) + +#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \ + ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \ + ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \ + ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \ + ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \ + ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \ + ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB)) +/** + * @} + */ + +/** @defgroup I2C_flags_definition + * @{ + */ + +/** + * @brief SR2 register flags + */ + +#define I2C_FLAG_DUALF ((uint32_t)0x00800000) +#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000) +#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000) +#define I2C_FLAG_GENCALL ((uint32_t)0x00100000) +#define I2C_FLAG_TRA ((uint32_t)0x00040000) +#define I2C_FLAG_BUSY ((uint32_t)0x00020000) +#define I2C_FLAG_MSL ((uint32_t)0x00010000) + +/** + * @brief SR1 register flags + */ + +#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000) +#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000) +#define I2C_FLAG_PECERR ((uint32_t)0x10001000) +#define I2C_FLAG_OVR ((uint32_t)0x10000800) +#define I2C_FLAG_AF ((uint32_t)0x10000400) +#define I2C_FLAG_ARLO ((uint32_t)0x10000200) +#define I2C_FLAG_BERR ((uint32_t)0x10000100) +#define I2C_FLAG_TXE ((uint32_t)0x10000080) +#define I2C_FLAG_RXNE ((uint32_t)0x10000040) +#define I2C_FLAG_STOPF ((uint32_t)0x10000010) +#define I2C_FLAG_ADD10 ((uint32_t)0x10000008) +#define I2C_FLAG_BTF ((uint32_t)0x10000004) +#define I2C_FLAG_ADDR ((uint32_t)0x10000002) +#define I2C_FLAG_SB ((uint32_t)0x10000001) + +#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00)) + +#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \ + ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \ + ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \ + ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \ + ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \ + ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \ + ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \ + ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \ + ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \ + ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \ + ((FLAG) == I2C_FLAG_SB)) +/** + * @} + */ + +/** @defgroup I2C_Events + * @{ + */ + +/** + =============================================================================== + I2C Master Events (Events grouped in order of communication) + =============================================================================== + */ + +/** + * @brief Communication start + * + * After sending the START condition (I2C_GenerateSTART() function) the master + * has to wait for this event. It means that the Start condition has been correctly + * released on the I2C bus (the bus is free, no other devices is communicating). + * + */ +/* --EV5 */ +#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ + +/** + * @brief Address Acknowledge + * + * After checking on EV5 (start condition correctly released on the bus), the + * master sends the address of the slave(s) with which it will communicate + * (I2C_Send7bitAddress() function, it also determines the direction of the communication: + * Master transmitter or Receiver). Then the master has to wait that a slave acknowledges + * his address. If an acknowledge is sent on the bus, one of the following events will + * be set: + * + * 1) In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED + * event is set. + * + * 2) In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED + * is set + * + * 3) In case of 10-Bit addressing mode, the master (just after generating the START + * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData() + * function). Then master should wait on EV9. It means that the 10-bit addressing + * header has been correctly sent on the bus. Then master should send the second part of + * the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master + * should wait for event EV6. + * + */ + +/* --EV6 */ +#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ +#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ +/* --EV9 */ +#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */ + +/** + * @brief Communication events + * + * If a communication is established (START condition generated and slave address + * acknowledged) then the master has to check on one of the following events for + * communication procedures: + * + * 1) Master Receiver mode: The master has to wait on the event EV7 then to read + * the data received from the slave (I2C_ReceiveData() function). + * + * 2) Master Transmitter mode: The master has to send data (I2C_SendData() + * function) then to wait on event EV8 or EV8_2. + * These two events are similar: + * - EV8 means that the data has been written in the data register and is + * being shifted out. + * - EV8_2 means that the data has been physically shifted out and output + * on the bus. + * In most cases, using EV8 is sufficient for the application. + * Using EV8_2 leads to a slower communication but ensure more reliable test. + * EV8_2 is also more suitable than EV8 for testing on the last data transmission + * (before Stop condition generation). + * + * @note In case the user software does not guarantee that this event EV7 is + * managed before the current byte end of transfer, then user may check on EV7 + * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)). + * In this case the communication may be slower. + * + */ + +/* Master RECEIVER mode -----------------------------*/ +/* --EV7 */ +#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */ + +/* Master TRANSMITTER mode --------------------------*/ +/* --EV8 */ +#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */ +/* --EV8_2 */ +#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ + + +/** + =============================================================================== + I2C Slave Events (Events grouped in order of communication) + =============================================================================== + */ + + +/** + * @brief Communication start events + * + * Wait on one of these events at the start of the communication. It means that + * the I2C peripheral detected a Start condition on the bus (generated by master + * device) followed by the peripheral address. The peripheral generates an ACK + * condition on the bus (if the acknowledge feature is enabled through function + * I2C_AcknowledgeConfig()) and the events listed above are set : + * + * 1) In normal case (only one address managed by the slave), when the address + * sent by the master matches the own address of the peripheral (configured by + * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set + * (where XXX could be TRANSMITTER or RECEIVER). + * + * 2) In case the address sent by the master matches the second address of the + * peripheral (configured by the function I2C_OwnAddress2Config() and enabled + * by the function I2C_DualAddressCmd()) the events I2C_EVENT_SLAVE_XXX_SECONDADDRESS_MATCHED + * (where XXX could be TRANSMITTER or RECEIVER) are set. + * + * 3) In case the address sent by the master is General Call (address 0x00) and + * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd()) + * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED. + * + */ + +/* --EV1 (all the events below are variants of EV1) */ +/* 1) Case of One Single Address managed by the slave */ +#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */ +#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */ + +/* 2) Case of Dual address managed by the slave */ +#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */ +#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */ + +/* 3) Case of General Call enabled for the slave */ +#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */ + +/** + * @brief Communication events + * + * Wait on one of these events when EV1 has already been checked and: + * + * - Slave RECEIVER mode: + * - EV2: When the application is expecting a data byte to be received. + * - EV4: When the application is expecting the end of the communication: master + * sends a stop condition and data transmission is stopped. + * + * - Slave Transmitter mode: + * - EV3: When a byte has been transmitted by the slave and the application is expecting + * the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and + * I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be + * used when the user software doesn't guarantee the EV3 is managed before the + * current byte end of transfer. + * - EV3_2: When the master sends a NACK in order to tell slave that data transmission + * shall end (before sending the STOP condition). In this case slave has to stop sending + * data bytes and expect a Stop condition on the bus. + * + * @note In case the user software does not guarantee that the event EV2 is + * managed before the current byte end of transfer, then user may check on EV2 + * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)). + * In this case the communication may be slower. + * + */ + +/* Slave RECEIVER mode --------------------------*/ +/* --EV2 */ +#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */ +/* --EV4 */ +#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */ + +/* Slave TRANSMITTER mode -----------------------*/ +/* --EV3 */ +#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */ +#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */ +/* --EV3_2 */ +#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */ + +/* + =============================================================================== + End of Events Description + =============================================================================== + */ + +#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \ + ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \ + ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \ + ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \ + ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \ + ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE)) +/** + * @} + */ + +/** @defgroup I2C_own_address1 + * @{ + */ + +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF) +/** + * @} + */ + +/** @defgroup I2C_clock_speed + * @{ + */ + +#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the I2C configuration to the default reset state *****/ +void I2C_DeInit(I2C_TypeDef* I2Cx); + +/* Initialization and Configuration functions *********************************/ +void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct); +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address); +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert); +void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle); +void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction); + +/* Data transfers functions ***************************************************/ +void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); +uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); +void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition); + +/* PEC management functions ***************************************************/ +void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition); +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState); +uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx); + +/* DMA transfers management functions *****************************************/ +void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); + + +/* Interrupts, events and flags management functions **************************/ +uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register); +void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState); + +/* + + =============================================================================== + I2C State Monitoring Functions + =============================================================================== + This I2C driver provides three different ways for I2C state monitoring + depending on the application requirements and constraints: + + + 1. Basic state monitoring (Using I2C_CheckEvent() function) + ----------------------------------------------------------- + It compares the status registers (SR1 and SR2) content to a given event + (can be the combination of one or more flags). + It returns SUCCESS if the current status includes the given flags + and returns ERROR if one or more flags are missing in the current status. + + - When to use + - This function is suitable for most applications as well as for startup + activity since the events are fully described in the product reference + manual (RM0038). + - It is also suitable for users who need to define their own events. + + - Limitations + - If an error occurs (ie. error flags are set besides to the monitored + flags), the I2C_CheckEvent() function may return SUCCESS despite + the communication hold or corrupted real state. + In this case, it is advised to use error interrupts to monitor + the error events and handle them in the interrupt IRQ handler. + + Note + For error management, it is advised to use the following functions: + - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). + - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs. + Where x is the peripheral instance (I2C1, I2C2 ...) + - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the + I2Cx_ER_IRQHandler() function in order to determine which error occurred. + - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() + and/or I2C_GenerateStop() in order to clear the error flag and source + and return to correct communciation status. + + + 2. Advanced state monitoring (Using the function I2C_GetLastEvent()) + -------------------------------------------------------------------- + Using the function I2C_GetLastEvent() which returns the image of both status + registers in a single word (uint32_t) (Status Register 2 value is shifted left + by 16 bits and concatenated to Status Register 1). + + - When to use + - This function is suitable for the same applications above but it + allows to overcome the mentioned limitation of I2C_GetFlagStatus() + function. + - The returned value could be compared to events already defined in + the library (stm32l1xx_i2c.h) or to custom values defined by user. + This function is suitable when multiple flags are monitored at the + same time. + - At the opposite of I2C_CheckEvent() function, this function allows + user to choose when an event is accepted (when all events flags are + set and no other flags are set or just when the needed flags are set + like I2C_CheckEvent() function. + + - Limitations + - User may need to define his own events. + - Same remark concerning the error management is applicable for this + function if user decides to check only regular communication flags + (and ignores error flags). + + + 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus()) + ----------------------------------------------------------------------- + + Using the function I2C_GetFlagStatus() which simply returns the status of + one single flag (ie. I2C_FLAG_RXNE ...). + + - When to use + - This function could be used for specific applications or in debug + phase. + - It is suitable when only one flag checking is needed (most I2C + events are monitored through multiple flags). + - Limitations: + - When calling this function, the Status register is accessed. + Some flags are cleared when the status register is accessed. + So checking the status of one Flag, may clear other ones. + - Function may need to be called twice or more in order to monitor + one single event. + + For detailed description of Events, please refer to section I2C_Events in + stm32l1xx_i2c.h file. + +*/ + +/* + =============================================================================== + 1. Basic state monitoring + =============================================================================== + */ +ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT); +/* + =============================================================================== + 2. Advanced state monitoring + =============================================================================== + */ +uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx); +/* + =============================================================================== + 3. Flag-based state monitoring + =============================================================================== + */ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); + + +void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT); +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_I2C_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_iwdg.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_iwdg.c new file mode 100644 index 0000000000..d6fe0226cb --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_iwdg.c @@ -0,0 +1,266 @@ +/** + ****************************************************************************** + * @file stm32l1xx_iwdg.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Independent watchdog (IWDG) peripheral: + * + Prescaler and Counter configuration + * + IWDG activation + * + Flag management + * + * @verbatim + * + ============================================================================== + ##### IWDG features ##### + ============================================================================== + [..] The IWDG can be started by either software or hardware (configurable + through option byte). + + [..] The IWDG is clocked by its own dedicated low-speed clock (LSI) and + thus stays active even if the main clock fails. + Once the IWDG is started, the LSI is forced ON and cannot be disabled + (LSI cannot be disabled too), and the counter starts counting down from + the reset value of 0xFFF. When it reaches the end of count value (0x000) + a system reset is generated. + The IWDG counter should be reloaded at regular intervals to prevent + an MCU reset. + + [..] The IWDG is implemented in the VDD voltage domain that is still functional + in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY). + + [..] IWDGRST flag in RCC_CSR register can be used to inform when a IWDG + reset occurs. + + [..] Min-max timeout value @37KHz (LSI): ~108us / ~28.3s + The IWDG timeout may vary due to LSI frequency dispersion. STM32L1xx + devices provide the capability to measure the LSI frequency (LSI clock + connected internally to TIM10 CH1 input capture). The measured value + can be used to have an IWDG timeout with an acceptable accuracy. + For more information, please refer to the STM32L1xx Reference manual. + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable write access to IWDG_PR and IWDG_RLR registers using + IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable) function. + (#) Configure the IWDG prescaler using IWDG_SetPrescaler() function. + + (#) Configure the IWDG counter value using IWDG_SetReload() function. + This value will be loaded in the IWDG counter each time the counter + is reloaded, then the IWDG will start counting down from this value. + + (#) Start the IWDG using IWDG_Enable() function, when the IWDG is used + in software mode (no need to enable the LSI, it will be enabled + by hardware). + + (#) Then the application program must reload the IWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + IWDG_ReloadCounter() function. + + @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_iwdg.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup IWDG + * @brief IWDG driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* ---------------------- IWDG registers bit mask ----------------------------*/ +/* KR register bit mask */ +#define KR_KEY_RELOAD ((uint16_t)0xAAAA) +#define KR_KEY_ENABLE ((uint16_t)0xCCCC) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup IWDG_Private_Functions + * @{ + */ + +/** @defgroup IWDG_Group1 Prescaler and Counter configuration functions + * @brief Prescaler and Counter configuration functions + * +@verbatim + ============================================================================== + ##### Prescaler and Counter configuration functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers. + * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers. + * This parameter can be one of the following values: + * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers + * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers + * @retval None + */ +void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess) +{ + /* Check the parameters */ + assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess)); + IWDG->KR = IWDG_WriteAccess; +} + +/** + * @brief Sets IWDG Prescaler value. + * @param IWDG_Prescaler: specifies the IWDG Prescaler value. + * This parameter can be one of the following values: + * @arg IWDG_Prescaler_4: IWDG prescaler set to 4 + * @arg IWDG_Prescaler_8: IWDG prescaler set to 8 + * @arg IWDG_Prescaler_16: IWDG prescaler set to 16 + * @arg IWDG_Prescaler_32: IWDG prescaler set to 32 + * @arg IWDG_Prescaler_64: IWDG prescaler set to 64 + * @arg IWDG_Prescaler_128: IWDG prescaler set to 128 + * @arg IWDG_Prescaler_256: IWDG prescaler set to 256 + * @retval None + */ +void IWDG_SetPrescaler(uint8_t IWDG_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler)); + IWDG->PR = IWDG_Prescaler; +} + +/** + * @brief Sets IWDG Reload value. + * @param Reload: specifies the IWDG Reload value. + * This parameter must be a number between 0 and 0x0FFF. + * @retval None + */ +void IWDG_SetReload(uint16_t Reload) +{ + /* Check the parameters */ + assert_param(IS_IWDG_RELOAD(Reload)); + IWDG->RLR = Reload; +} + +/** + * @brief Reloads IWDG counter with value defined in the reload register + * (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param None + * @retval None + */ +void IWDG_ReloadCounter(void) +{ + IWDG->KR = KR_KEY_RELOAD; +} + +/** + * @} + */ + +/** @defgroup IWDG_Group2 IWDG activation function + * @brief IWDG activation function + * +@verbatim + ============================================================================== + ##### IWDG activation function ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param None. + * @retval None. + */ +void IWDG_Enable(void) +{ + IWDG->KR = KR_KEY_ENABLE; +} + +/** + * @} + */ + +/** @defgroup IWDG_Group3 Flag management function + * @brief Flag management function + * +@verbatim + =============================================================================== + ##### Flag management function ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Checks whether the specified IWDG flag is set or not. + * @param IWDG_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg IWDG_FLAG_PVU: Prescaler Value Update on going + * @arg IWDG_FLAG_RVU: Reload Value Update on going + * @retval The new state of IWDG_FLAG (SET or RESET). + */ +FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_IWDG_FLAG(IWDG_FLAG)); + if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_iwdg.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_iwdg.h new file mode 100644 index 0000000000..c05617a73b --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_iwdg.h @@ -0,0 +1,134 @@ +/** + ****************************************************************************** + * @file stm32l1xx_iwdg.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the IWDG + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_IWDG_H +#define __STM32L1xx_IWDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup IWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup IWDG_Exported_Constants + * @{ + */ + +/** @defgroup IWDG_WriteAccess + * @{ + */ + +#define IWDG_WriteAccess_Enable ((uint16_t)0x5555) +#define IWDG_WriteAccess_Disable ((uint16_t)0x0000) +#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ + ((ACCESS) == IWDG_WriteAccess_Disable)) +/** + * @} + */ + +/** @defgroup IWDG_prescaler + * @{ + */ + +#define IWDG_Prescaler_4 ((uint8_t)0x00) +#define IWDG_Prescaler_8 ((uint8_t)0x01) +#define IWDG_Prescaler_16 ((uint8_t)0x02) +#define IWDG_Prescaler_32 ((uint8_t)0x03) +#define IWDG_Prescaler_64 ((uint8_t)0x04) +#define IWDG_Prescaler_128 ((uint8_t)0x05) +#define IWDG_Prescaler_256 ((uint8_t)0x06) +#define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ + ((PRESCALER) == IWDG_Prescaler_8) || \ + ((PRESCALER) == IWDG_Prescaler_16) || \ + ((PRESCALER) == IWDG_Prescaler_32) || \ + ((PRESCALER) == IWDG_Prescaler_64) || \ + ((PRESCALER) == IWDG_Prescaler_128)|| \ + ((PRESCALER) == IWDG_Prescaler_256)) +/** + * @} + */ + +/** @defgroup IWDG_Flag + * @{ + */ + +#define IWDG_FLAG_PVU ((uint16_t)0x0001) +#define IWDG_FLAG_RVU ((uint16_t)0x0002) +#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU)) +#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Prescaler and Counter configuration functions ******************************/ +void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); +void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); +void IWDG_SetReload(uint16_t Reload); +void IWDG_ReloadCounter(void); + +/* IWDG activation function ***************************************************/ +void IWDG_Enable(void); + +/* Flag management function ***************************************************/ +FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_IWDG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_lcd.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_lcd.c new file mode 100644 index 0000000000..f3ab0d2901 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_lcd.c @@ -0,0 +1,640 @@ +/** + ****************************************************************************** + * @file stm32l1xx_lcd.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the LCD controller (LCD) peripheral: + * + Initialization and configuration + * + LCD RAM memory write + * + Interrupts and flags management + * + * @verbatim + + =============================================================================== + ##### LCD Clock ##### + =============================================================================== + [..] LCDCLK is the same as RTCCLK. + [..] To configure the RTCCLK/LCDCLK, proceed as follows: + (+) Enable the Power Controller (PWR) APB1 interface clock using the + RCC_APB1PeriphClockCmd() function. + (+) Enable access to RTC domain using the PWR_RTCAccessCmd() function. + (+) Select the RTC clock source using the RCC_RTCCLKConfig() function. + + [..] The frequency generator allows you to achieve various LCD frame rates + starting from an LCD input clock frequency (LCDCLK) which can vary + from 32 kHz up to 1 MHz. + + ##### LCD and low power modes ##### + =============================================================================== + [..] The LCD still active during STOP mode. + + ##### How to use this driver ##### + =============================================================================== + [..] + (#) Enable LCD clock using + RCC_APB1PeriphClockCmd(RCC_APB1Periph_LCD, ENABLE) function. + (#) Configure the LCD prescaler, divider, duty, bias and voltage source + using LCD_Init() function. + (#) Optionally you can enable/configure: + (++) LCD High Drive using the LCD_HighDriveCmd() function. + (++) LCD COM/SEG Mux using the LCD_MuxSegmentCmd() function. + (++) LCD Pulse ON Duration using the LCD_PulseOnDurationConfig() function. + (++) LCD Dead Time using the LCD_DeadTimeConfig() function + (++) The LCD Blink mode and frequency using the LCD_BlinkConfig() function. + (++) The LCD Contrast using the LCD_ContrastConfig() function. + (#) Call the LCD_WaitForSynchro() function to wait for LCD_FCR register + synchronization. + (#) Call the LCD_Cmd() to enable the LCD controller. + (#) Wait until the LCD Controller status is enabled and the step-up + converter is ready using the LCD_GetFlagStatus() and + LCD_FLAG_ENS and LCD_FLAG_RDY flags. + (#) Write to the LCD RAM memory using the LCD_Write() function. + (#) Request an update display using the LCD_UpdateDisplayRequest() + function. + (#) Wait until the update display is finished by checking the UDD + flag status using the LCD_GetFlagStatus(LCD_FLAG_UDD). + + @endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_lcd.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup LCD + * @brief LCD driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* ------------ LCD registers bit address in the alias region --------------- */ +#define LCD_OFFSET (LCD_BASE - PERIPH_BASE) + +/* --- CR Register ---*/ + +/* Alias word address of LCDEN bit */ +#define CR_OFFSET (LCD_OFFSET + 0x00) +#define LCDEN_BitNumber 0x00 +#define CR_LCDEN_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (LCDEN_BitNumber * 4)) + +/* Alias word address of MUX_SEG bit */ +#define MUX_SEG_BitNumber 0x07 +#define CR_MUX_SEG_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (MUX_SEG_BitNumber * 4)) + + +/* --- FCR Register ---*/ + +/* Alias word address of HD bit */ +#define FCR_OFFSET (LCD_OFFSET + 0x04) +#define HD_BitNumber 0x00 +#define FCR_HD_BB (PERIPH_BB_BASE + (FCR_OFFSET * 32) + (HD_BitNumber * 4)) + +/* --- SR Register ---*/ + +/* Alias word address of UDR bit */ +#define SR_OFFSET (LCD_OFFSET + 0x08) +#define UDR_BitNumber 0x02 +#define SR_UDR_BB (PERIPH_BB_BASE + (SR_OFFSET * 32) + (UDR_BitNumber * 4)) + +#define FCR_MASK ((uint32_t)0xFC03FFFF) /* LCD FCR Mask */ +#define CR_MASK ((uint32_t)0xFFFFFF81) /* LCD CR Mask */ +#define PON_MASK ((uint32_t)0xFFFFFF8F) /* LCD PON Mask */ +#define DEAD_MASK ((uint32_t)0xFFFFFC7F) /* LCD DEAD Mask */ +#define BLINK_MASK ((uint32_t)0xFFFC1FFF) /* LCD BLINK Mask */ +#define CONTRAST_MASK ((uint32_t)0xFFFFE3FF) /* LCD CONTRAST Mask */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup LCD_Private_Functions + * @{ + */ + +/** @defgroup LCD_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the LCD peripheral registers to their default reset + * values. + * @param None + * @retval None + */ +void LCD_DeInit(void) +{ + /* Enable LCD reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_LCD, ENABLE); + /* Release LCD from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_LCD, DISABLE); +} + +/** + * @brief Initializes the LCD peripheral according to the specified parameters + * in the LCD_InitStruct. + * @note This function can be used only when the LCD is disabled. + * @param LCD_InitStruct: pointer to a LCD_InitTypeDef structure that contains + * the configuration information for the specified LCD peripheral. + * @retval None + */ +void LCD_Init(LCD_InitTypeDef* LCD_InitStruct) +{ + /* Check function parameters */ + assert_param(IS_LCD_PRESCALER(LCD_InitStruct->LCD_Prescaler)); + assert_param(IS_LCD_DIVIDER(LCD_InitStruct->LCD_Divider)); + assert_param(IS_LCD_DUTY(LCD_InitStruct->LCD_Duty)); + assert_param(IS_LCD_BIAS(LCD_InitStruct->LCD_Bias)); + assert_param(IS_LCD_VOLTAGE_SOURCE(LCD_InitStruct->LCD_VoltageSource)); + + LCD->FCR &= (uint32_t)FCR_MASK; + LCD->FCR |= (uint32_t)(LCD_InitStruct->LCD_Prescaler | LCD_InitStruct->LCD_Divider); + + LCD_WaitForSynchro(); + + LCD->CR &= (uint32_t)CR_MASK; + LCD->CR |= (uint32_t)(LCD_InitStruct->LCD_Duty | LCD_InitStruct->LCD_Bias | \ + LCD_InitStruct->LCD_VoltageSource); + +} + +/** + * @brief Fills each LCD_InitStruct member with its default value. + * @param LCD_InitStruct: pointer to a LCD_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void LCD_StructInit(LCD_InitTypeDef* LCD_InitStruct) +{ +/*--------------- Reset LCD init structure parameters values -----------------*/ + LCD_InitStruct->LCD_Prescaler = LCD_Prescaler_1; /*!< Initialize the LCD_Prescaler member */ + + LCD_InitStruct->LCD_Divider = LCD_Divider_16; /*!< Initialize the LCD_Divider member */ + + LCD_InitStruct->LCD_Duty = LCD_Duty_Static; /*!< Initialize the LCD_Duty member */ + + LCD_InitStruct->LCD_Bias = LCD_Bias_1_4; /*!< Initialize the LCD_Bias member */ + + LCD_InitStruct->LCD_VoltageSource = LCD_VoltageSource_Internal; /*!< Initialize the LCD_VoltageSource member */ +} + +/** + * @brief Enables or disables the LCD Controller. + * @param NewState: new state of the LCD peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void LCD_Cmd(FunctionalState NewState) +{ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_LCDEN_BB = (uint32_t)NewState; +} + +/** + * @brief Waits until the LCD FCR register is synchronized in the LCDCLK domain. + * This function must be called after any write operation to LCD_FCR register. + * @param None + * @retval None + */ +void LCD_WaitForSynchro(void) +{ + /* Loop until FCRSF flag is set */ + while ((LCD->SR & LCD_FLAG_FCRSF) == (uint32_t)RESET) + { + } +} + +/** + * @brief Enables or disables the low resistance divider. Displays with high + * internal resistance may need a longer drive time to achieve + * satisfactory contrast. This function is useful in this case if some + * additional power consumption can be tolerated. + * @note When this mode is enabled, the PulseOn Duration (PON) have to be + * programmed to 1/CK_PS (LCD_PulseOnDuration_1). + * @param NewState: new state of the low resistance divider. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void LCD_HighDriveCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) FCR_HD_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the Mux Segment. + * @note This function can be used only when the LCD is disabled. + * @param NewState: new state of the Mux Segment. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void LCD_MuxSegmentCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_MUX_SEG_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the LCD pulses on duration. + * @param LCD_PulseOnDuration: specifies the LCD pulse on duration in terms of + * CK_PS (prescaled LCD clock period) pulses. + * This parameter can be one of the following values: + * @arg LCD_PulseOnDuration_0: 0 pulse + * @arg LCD_PulseOnDuration_1: Pulse ON duration = 1/CK_PS + * @arg LCD_PulseOnDuration_2: Pulse ON duration = 2/CK_PS + * @arg LCD_PulseOnDuration_3: Pulse ON duration = 3/CK_PS + * @arg LCD_PulseOnDuration_4: Pulse ON duration = 4/CK_PS + * @arg LCD_PulseOnDuration_5: Pulse ON duration = 5/CK_PS + * @arg LCD_PulseOnDuration_6: Pulse ON duration = 6/CK_PS + * @arg LCD_PulseOnDuration_7: Pulse ON duration = 7/CK_PS + * @retval None + */ +void LCD_PulseOnDurationConfig(uint32_t LCD_PulseOnDuration) +{ + /* Check the parameters */ + assert_param(IS_LCD_PULSE_ON_DURATION(LCD_PulseOnDuration)); + + LCD->FCR &= (uint32_t)PON_MASK; + LCD->FCR |= (uint32_t)(LCD_PulseOnDuration); +} + +/** + * @brief Configures the LCD dead time. + * @param LCD_DeadTime: specifies the LCD dead time. + * This parameter can be one of the following values: + * @arg LCD_DeadTime_0: No dead Time + * @arg LCD_DeadTime_1: One Phase between different couple of Frame + * @arg LCD_DeadTime_2: Two Phase between different couple of Frame + * @arg LCD_DeadTime_3: Three Phase between different couple of Frame + * @arg LCD_DeadTime_4: Four Phase between different couple of Frame + * @arg LCD_DeadTime_5: Five Phase between different couple of Frame + * @arg LCD_DeadTime_6: Six Phase between different couple of Frame + * @arg LCD_DeadTime_7: Seven Phase between different couple of Frame + * @retval None + */ +void LCD_DeadTimeConfig(uint32_t LCD_DeadTime) +{ + /* Check the parameters */ + assert_param(IS_LCD_DEAD_TIME(LCD_DeadTime)); + + LCD->FCR &= (uint32_t)DEAD_MASK; + LCD->FCR |= (uint32_t)(LCD_DeadTime); +} + +/** + * @brief Configures the LCD Blink mode and Blink frequency. + * @param LCD_BlinkMode: specifies the LCD blink mode. + * This parameter can be one of the following values: + * @arg LCD_BlinkMode_Off: Blink disabled + * @arg LCD_BlinkMode_SEG0_COM0: Blink enabled on SEG[0], COM[0] (1 pixel) + * @arg LCD_BlinkMode_SEG0_AllCOM: Blink enabled on SEG[0], all COM (up to 8 + * pixels according to the programmed duty) + * @arg LCD_BlinkMode_AllSEG_AllCOM: Blink enabled on all SEG and all COM + * (all pixels) + * @param LCD_BlinkFrequency: specifies the LCD blink frequency. + * This parameter can be one of the following values: + * @arg LCD_BlinkFrequency_Div8: The Blink frequency = fLcd/8 + * @arg LCD_BlinkFrequency_Div16: The Blink frequency = fLcd/16 + * @arg LCD_BlinkFrequency_Div32: The Blink frequency = fLcd/32 + * @arg LCD_BlinkFrequency_Div64: The Blink frequency = fLcd/64 + * @arg LCD_BlinkFrequency_Div128: The Blink frequency = fLcd/128 + * @arg LCD_BlinkFrequency_Div256: The Blink frequency = fLcd/256 + * @arg LCD_BlinkFrequency_Div512: The Blink frequency = fLcd/512 + * @arg LCD_BlinkFrequency_Div1024: The Blink frequency = fLcd/1024 + * @retval None + */ +void LCD_BlinkConfig(uint32_t LCD_BlinkMode, uint32_t LCD_BlinkFrequency) +{ + /* Check the parameters */ + assert_param(IS_LCD_BLINK_MODE(LCD_BlinkMode)); + assert_param(IS_LCD_BLINK_FREQUENCY(LCD_BlinkFrequency)); + + LCD->FCR &= (uint32_t)BLINK_MASK; + LCD->FCR |= (uint32_t)(LCD_BlinkMode | LCD_BlinkFrequency); +} + +/** + * @brief Configures the LCD Contrast. + * @param LCD_Contrast: specifies the LCD Contrast. + * This parameter can be one of the following values: + * @arg LCD_Contrast_Level_0: Maximum Voltage = 2.60V + * @arg LCD_Contrast_Level_1: Maximum Voltage = 2.73V + * @arg LCD_Contrast_Level_2: Maximum Voltage = 2.86V + * @arg LCD_Contrast_Level_3: Maximum Voltage = 2.99V + * @arg LCD_Contrast_Level_4: Maximum Voltage = 3.12V + * @arg LCD_Contrast_Level_5: Maximum Voltage = 3.25V + * @arg LCD_Contrast_Level_6: Maximum Voltage = 3.38V + * @arg LCD_Contrast_Level_7: Maximum Voltage = 3.51V + * @retval None + */ +void LCD_ContrastConfig(uint32_t LCD_Contrast) +{ + /* Check the parameters */ + assert_param(IS_LCD_CONTRAST(LCD_Contrast)); + + LCD->FCR &= (uint32_t)CONTRAST_MASK; + LCD->FCR |= (uint32_t)(LCD_Contrast); +} + +/** + * @} + */ + +/** @defgroup LCD_Group2 LCD RAM memory write functions + * @brief LCD RAM memory write functions + * +@verbatim + =============================================================================== + ##### LCD RAM memory write functions ##### + =============================================================================== + [..] Using its double buffer memory the LCD controller ensures the coherency + of the displayed information without having to use interrupts to control + LCD_RAM modification. + + [..] The application software can access the first buffer level (LCD_RAM) through + the APB interface. Once it has modified the LCD_RAM, it sets the UDR flag + in the LCD_SR register using the LCD_UpdateDisplayRequest() function. + + [..] This UDR flag (update display request) requests the updated information + to be moved into the second buffer level (LCD_DISPLAY). + + [..] This operation is done synchronously with the frame (at the beginning of + the next frame), until the update is completed, the LCD_RAM is write + protected and the UDR flag stays high. + + [..] Once the update is completed another flag (UDD - Update Display Done) is + set and generates an interrupt if the UDDIE bit in the LCD_FCR register + is set. + + [..] The time it takes to update LCD_DISPLAY is, in the worst case, one odd + and one even frame. + + [..] The update will not occur (UDR = 1 and UDD = 0) until the display is + enabled (LCDEN = 1). + +@endverbatim + * @{ + */ + +/** + * @brief Writes a word in the specific LCD RAM. + * @param LCD_RAMRegister: specifies the LCD Contrast. + * This parameter can be one of the following values: + * @arg LCD_RAMRegister_0: LCD RAM Register 0 + * @arg LCD_RAMRegister_1: LCD RAM Register 1 + * @arg LCD_RAMRegister_2: LCD RAM Register 2 + * @arg LCD_RAMRegister_3: LCD RAM Register 3 + * @arg LCD_RAMRegister_4: LCD RAM Register 4 + * @arg LCD_RAMRegister_5: LCD RAM Register 5 + * @arg LCD_RAMRegister_6: LCD RAM Register 6 + * @arg LCD_RAMRegister_7: LCD RAM Register 7 + * @arg LCD_RAMRegister_8: LCD RAM Register 8 + * @arg LCD_RAMRegister_9: LCD RAM Register 9 + * @arg LCD_RAMRegister_10: LCD RAM Register 10 + * @arg LCD_RAMRegister_11: LCD RAM Register 11 + * @arg LCD_RAMRegister_12: LCD RAM Register 12 + * @arg LCD_RAMRegister_13: LCD RAM Register 13 + * @arg LCD_RAMRegister_14: LCD RAM Register 14 + * @arg LCD_RAMRegister_15: LCD RAM Register 15 + * @param LCD_Data: specifies LCD Data Value to be written. + * @retval None + */ +void LCD_Write(uint32_t LCD_RAMRegister, uint32_t LCD_Data) +{ + /* Check the parameters */ + assert_param(IS_LCD_RAM_REGISTER(LCD_RAMRegister)); + + /* Copy data bytes to RAM register */ + LCD->RAM[LCD_RAMRegister] = (uint32_t)LCD_Data; +} + +/** + * @brief Enables the Update Display Request. + * @note Each time software modifies the LCD_RAM it must set the UDR bit to + * transfer the updated data to the second level buffer. + * The UDR bit stays set until the end of the update and during this + * time the LCD_RAM is write protected. + * @note When the display is disabled, the update is performed for all + * LCD_DISPLAY locations. + * When the display is enabled, the update is performed only for locations + * for which commons are active (depending on DUTY). For example if + * DUTY = 1/2, only the LCD_DISPLAY of COM0 and COM1 will be updated. + * @param None + * @retval None + */ +void LCD_UpdateDisplayRequest(void) +{ + *(__IO uint32_t *) SR_UDR_BB = (uint32_t)0x01; +} + +/** + * @} + */ + +/** @defgroup LCD_Group3 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified LCD interrupts. + * @param LCD_IT: specifies the LCD interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg LCD_IT_SOF: Start of Frame Interrupt + * @arg LCD_IT_UDD: Update Display Done Interrupt + * @param NewState: new state of the specified LCD interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void LCD_ITConfig(uint32_t LCD_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_LCD_IT(LCD_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + LCD->FCR |= LCD_IT; + } + else + { + LCD->FCR &= (uint32_t)~LCD_IT; + } +} + +/** + * @brief Checks whether the specified LCD flag is set or not. + * @param LCD_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg LCD_FLAG_ENS: LCD Enabled flag. It indicates the LCD controller status. + * @note The ENS bit is set immediately when the LCDEN bit in the LCD_CR + * goes from 0 to 1. On deactivation it reflects the real status of + * LCD so it becomes 0 at the end of the last displayed frame. + * @arg LCD_FLAG_SOF: Start of Frame flag. This flag is set by hardware at + * the beginning of a new frame, at the same time as the display data is + * updated. + * @arg LCD_FLAG_UDR: Update Display Request flag. + * @arg LCD_FLAG_UDD: Update Display Done flag. + * @arg LCD_FLAG_RDY: Step_up converter Ready flag. It indicates the status + * of the step-up converter. + * @arg LCD_FLAG_FCRSF: LCD Frame Control Register Synchronization Flag. + * This flag is set by hardware each time the LCD_FCR register is updated + * in the LCDCLK domain. + * @retval The new state of LCD_FLAG (SET or RESET). + */ +FlagStatus LCD_GetFlagStatus(uint32_t LCD_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_LCD_GET_FLAG(LCD_FLAG)); + + if ((LCD->SR & LCD_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the LCD's pending flags. + * @param LCD_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg LCD_FLAG_SOF: Start of Frame Interrupt + * @arg LCD_FLAG_UDD: Update Display Done Interrupt + * @retval None + */ +void LCD_ClearFlag(uint32_t LCD_FLAG) +{ + /* Check the parameters */ + assert_param(IS_LCD_CLEAR_FLAG(LCD_FLAG)); + + /* Clear the corresponding LCD flag */ + LCD->CLR = (uint32_t)LCD_FLAG; +} + +/** + * @brief Checks whether the specified RTC interrupt has occurred or not. + * @param LCD_IT: specifies the LCD interrupts sources to check. + * This parameter can be one of the following values: + * @arg LCD_IT_SOF: Start of Frame Interrupt + * @arg LCD_IT_UDD: Update Display Done Interrupt. + * @note If the device is in STOP mode (PCLK not provided) UDD will not + * generate an interrupt even if UDDIE = 1. + * If the display is not enabled the UDD interrupt will never occur. + * @retval The new state of the LCD_IT (SET or RESET). + */ +ITStatus LCD_GetITStatus(uint32_t LCD_IT) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_LCD_GET_IT(LCD_IT)); + + if ((LCD->SR & LCD_IT) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + if (((LCD->FCR & LCD_IT) != (uint16_t)RESET) && (bitstatus != (uint32_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the LCD's interrupt pending bits. + * @param LCD_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg LCD_IT_SOF: Start of Frame Interrupt + * @arg LCD_IT_UDD: Update Display Done Interrupt + * @retval None + */ +void LCD_ClearITPendingBit(uint32_t LCD_IT) +{ + /* Check the parameters */ + assert_param(IS_LCD_IT(LCD_IT)); + + /* Clear the corresponding LCD pending bit */ + LCD->CLR = (uint32_t)LCD_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_lcd.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_lcd.h new file mode 100644 index 0000000000..73601b6b4e --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_lcd.h @@ -0,0 +1,452 @@ +/** + ****************************************************************************** + * @file stm32l1xx_lcd.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the LCD firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_LCD_H +#define __STM32L1xx_LCD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup LCD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief LCD Init structure definition + */ + +typedef struct +{ + uint32_t LCD_Prescaler; /*!< Configures the LCD Prescaler. + This parameter can be one value of @ref LCD_Prescaler */ + uint32_t LCD_Divider; /*!< Configures the LCD Divider. + This parameter can be one value of @ref LCD_Divider */ + uint32_t LCD_Duty; /*!< Configures the LCD Duty. + This parameter can be one value of @ref LCD_Duty */ + uint32_t LCD_Bias; /*!< Configures the LCD Bias. + This parameter can be one value of @ref LCD_Bias */ + uint32_t LCD_VoltageSource; /*!< Selects the LCD Voltage source. + This parameter can be one value of @ref LCD_Voltage_Source */ +}LCD_InitTypeDef; + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup LCD_Exported_Constants + * @{ + */ + +/** @defgroup LCD_Prescaler + * @{ + */ + +#define LCD_Prescaler_1 ((uint32_t)0x00000000) /*!< CLKPS = LCDCLK */ +#define LCD_Prescaler_2 ((uint32_t)0x00400000) /*!< CLKPS = LCDCLK/2 */ +#define LCD_Prescaler_4 ((uint32_t)0x00800000) /*!< CLKPS = LCDCLK/4 */ +#define LCD_Prescaler_8 ((uint32_t)0x00C00000) /*!< CLKPS = LCDCLK/8 */ +#define LCD_Prescaler_16 ((uint32_t)0x01000000) /*!< CLKPS = LCDCLK/16 */ +#define LCD_Prescaler_32 ((uint32_t)0x01400000) /*!< CLKPS = LCDCLK/32 */ +#define LCD_Prescaler_64 ((uint32_t)0x01800000) /*!< CLKPS = LCDCLK/64 */ +#define LCD_Prescaler_128 ((uint32_t)0x01C00000) /*!< CLKPS = LCDCLK/128 */ +#define LCD_Prescaler_256 ((uint32_t)0x02000000) /*!< CLKPS = LCDCLK/256 */ +#define LCD_Prescaler_512 ((uint32_t)0x02400000) /*!< CLKPS = LCDCLK/512 */ +#define LCD_Prescaler_1024 ((uint32_t)0x02800000) /*!< CLKPS = LCDCLK/1024 */ +#define LCD_Prescaler_2048 ((uint32_t)0x02C00000) /*!< CLKPS = LCDCLK/2048 */ +#define LCD_Prescaler_4096 ((uint32_t)0x03000000) /*!< CLKPS = LCDCLK/4096 */ +#define LCD_Prescaler_8192 ((uint32_t)0x03400000) /*!< CLKPS = LCDCLK/8192 */ +#define LCD_Prescaler_16384 ((uint32_t)0x03800000) /*!< CLKPS = LCDCLK/16384 */ +#define LCD_Prescaler_32768 ((uint32_t)0x03C00000) /*!< CLKPS = LCDCLK/32768 */ + +#define IS_LCD_PRESCALER(PRESCALER) (((PRESCALER) == LCD_Prescaler_1) || \ + ((PRESCALER) == LCD_Prescaler_2) || \ + ((PRESCALER) == LCD_Prescaler_4) || \ + ((PRESCALER) == LCD_Prescaler_8) || \ + ((PRESCALER) == LCD_Prescaler_16) || \ + ((PRESCALER) == LCD_Prescaler_32) || \ + ((PRESCALER) == LCD_Prescaler_64) || \ + ((PRESCALER) == LCD_Prescaler_128) || \ + ((PRESCALER) == LCD_Prescaler_256) || \ + ((PRESCALER) == LCD_Prescaler_512) || \ + ((PRESCALER) == LCD_Prescaler_1024) || \ + ((PRESCALER) == LCD_Prescaler_2048) || \ + ((PRESCALER) == LCD_Prescaler_4096) || \ + ((PRESCALER) == LCD_Prescaler_8192) || \ + ((PRESCALER) == LCD_Prescaler_16384) || \ + ((PRESCALER) == LCD_Prescaler_32768)) + +/** + * @} + */ + +/** @defgroup LCD_Divider + * @{ + */ + +#define LCD_Divider_16 ((uint32_t)0x00000000) /*!< LCD frequency = CLKPS/16 */ +#define LCD_Divider_17 ((uint32_t)0x00040000) /*!< LCD frequency = CLKPS/17 */ +#define LCD_Divider_18 ((uint32_t)0x00080000) /*!< LCD frequency = CLKPS/18 */ +#define LCD_Divider_19 ((uint32_t)0x000C0000) /*!< LCD frequency = CLKPS/19 */ +#define LCD_Divider_20 ((uint32_t)0x00100000) /*!< LCD frequency = CLKPS/20 */ +#define LCD_Divider_21 ((uint32_t)0x00140000) /*!< LCD frequency = CLKPS/21 */ +#define LCD_Divider_22 ((uint32_t)0x00180000) /*!< LCD frequency = CLKPS/22 */ +#define LCD_Divider_23 ((uint32_t)0x001C0000) /*!< LCD frequency = CLKPS/23 */ +#define LCD_Divider_24 ((uint32_t)0x00200000) /*!< LCD frequency = CLKPS/24 */ +#define LCD_Divider_25 ((uint32_t)0x00240000) /*!< LCD frequency = CLKPS/25 */ +#define LCD_Divider_26 ((uint32_t)0x00280000) /*!< LCD frequency = CLKPS/26 */ +#define LCD_Divider_27 ((uint32_t)0x002C0000) /*!< LCD frequency = CLKPS/27 */ +#define LCD_Divider_28 ((uint32_t)0x00300000) /*!< LCD frequency = CLKPS/28 */ +#define LCD_Divider_29 ((uint32_t)0x00340000) /*!< LCD frequency = CLKPS/29 */ +#define LCD_Divider_30 ((uint32_t)0x00380000) /*!< LCD frequency = CLKPS/30 */ +#define LCD_Divider_31 ((uint32_t)0x003C0000) /*!< LCD frequency = CLKPS/31 */ + +#define IS_LCD_DIVIDER(DIVIDER) (((DIVIDER) == LCD_Divider_16) || \ + ((DIVIDER) == LCD_Divider_17) || \ + ((DIVIDER) == LCD_Divider_18) || \ + ((DIVIDER) == LCD_Divider_19) || \ + ((DIVIDER) == LCD_Divider_20) || \ + ((DIVIDER) == LCD_Divider_21) || \ + ((DIVIDER) == LCD_Divider_22) || \ + ((DIVIDER) == LCD_Divider_23) || \ + ((DIVIDER) == LCD_Divider_24) || \ + ((DIVIDER) == LCD_Divider_25) || \ + ((DIVIDER) == LCD_Divider_26) || \ + ((DIVIDER) == LCD_Divider_27) || \ + ((DIVIDER) == LCD_Divider_28) || \ + ((DIVIDER) == LCD_Divider_29) || \ + ((DIVIDER) == LCD_Divider_30) || \ + ((DIVIDER) == LCD_Divider_31)) + +/** + * @} + */ + + +/** @defgroup LCD_Duty + * @{ + */ + +#define LCD_Duty_Static ((uint32_t)0x00000000) /*!< Static duty */ +#define LCD_Duty_1_2 ((uint32_t)0x00000004) /*!< 1/2 duty */ +#define LCD_Duty_1_3 ((uint32_t)0x00000008) /*!< 1/3 duty */ +#define LCD_Duty_1_4 ((uint32_t)0x0000000C) /*!< 1/4 duty */ +#define LCD_Duty_1_8 ((uint32_t)0x00000010) /*!< 1/4 duty */ + +#define IS_LCD_DUTY(DUTY) (((DUTY) == LCD_Duty_Static) || \ + ((DUTY) == LCD_Duty_1_2) || \ + ((DUTY) == LCD_Duty_1_3) || \ + ((DUTY) == LCD_Duty_1_4) || \ + ((DUTY) == LCD_Duty_1_8)) + +/** + * @} + */ + + +/** @defgroup LCD_Bias + * @{ + */ + +#define LCD_Bias_1_4 ((uint32_t)0x00000000) /*!< 1/4 Bias */ +#define LCD_Bias_1_2 LCD_CR_BIAS_0 /*!< 1/2 Bias */ +#define LCD_Bias_1_3 LCD_CR_BIAS_1 /*!< 1/3 Bias */ + +#define IS_LCD_BIAS(BIAS) (((BIAS) == LCD_Bias_1_4) || \ + ((BIAS) == LCD_Bias_1_2) || \ + ((BIAS) == LCD_Bias_1_3)) +/** + * @} + */ + +/** @defgroup LCD_Voltage_Source + * @{ + */ + +#define LCD_VoltageSource_Internal ((uint32_t)0x00000000) /*!< Internal voltage source for the LCD */ +#define LCD_VoltageSource_External LCD_CR_VSEL /*!< External voltage source for the LCD */ + +#define IS_LCD_VOLTAGE_SOURCE(SOURCE) (((SOURCE) == LCD_VoltageSource_Internal) || \ + ((SOURCE) == LCD_VoltageSource_External)) + +/** + * @} + */ + +/** @defgroup LCD_Interrupts + * @{ + */ +#define LCD_IT_SOF LCD_FCR_SOFIE +#define LCD_IT_UDD LCD_FCR_UDDIE + +#define IS_LCD_IT(IT) ((((IT) & (uint32_t)0xFFFFFFF5) == 0x00) && ((IT) != 0x00)) + +#define IS_LCD_GET_IT(IT) (((IT) == LCD_IT_SOF) || ((IT) == LCD_IT_UDD)) + +/** + * @} + */ + +/** @defgroup LCD_PulseOnDuration + * @{ + */ + +#define LCD_PulseOnDuration_0 ((uint32_t)0x00000000) /*!< Pulse ON duration = 0 pulse */ +#define LCD_PulseOnDuration_1 ((uint32_t)0x00000010) /*!< Pulse ON duration = 1/CK_PS */ +#define LCD_PulseOnDuration_2 ((uint32_t)0x00000020) /*!< Pulse ON duration = 2/CK_PS */ +#define LCD_PulseOnDuration_3 ((uint32_t)0x00000030) /*!< Pulse ON duration = 3/CK_PS */ +#define LCD_PulseOnDuration_4 ((uint32_t)0x00000040) /*!< Pulse ON duration = 4/CK_PS */ +#define LCD_PulseOnDuration_5 ((uint32_t)0x00000050) /*!< Pulse ON duration = 5/CK_PS */ +#define LCD_PulseOnDuration_6 ((uint32_t)0x00000060) /*!< Pulse ON duration = 6/CK_PS */ +#define LCD_PulseOnDuration_7 ((uint32_t)0x00000070) /*!< Pulse ON duration = 7/CK_PS */ + +#define IS_LCD_PULSE_ON_DURATION(DURATION) (((DURATION) == LCD_PulseOnDuration_0) || \ + ((DURATION) == LCD_PulseOnDuration_1) || \ + ((DURATION) == LCD_PulseOnDuration_2) || \ + ((DURATION) == LCD_PulseOnDuration_3) || \ + ((DURATION) == LCD_PulseOnDuration_4) || \ + ((DURATION) == LCD_PulseOnDuration_5) || \ + ((DURATION) == LCD_PulseOnDuration_6) || \ + ((DURATION) == LCD_PulseOnDuration_7)) +/** + * @} + */ + + +/** @defgroup LCD_DeadTime + * @{ + */ + +#define LCD_DeadTime_0 ((uint32_t)0x00000000) /*!< No dead Time */ +#define LCD_DeadTime_1 ((uint32_t)0x00000080) /*!< One Phase between different couple of Frame */ +#define LCD_DeadTime_2 ((uint32_t)0x00000100) /*!< Two Phase between different couple of Frame */ +#define LCD_DeadTime_3 ((uint32_t)0x00000180) /*!< Three Phase between different couple of Frame */ +#define LCD_DeadTime_4 ((uint32_t)0x00000200) /*!< Four Phase between different couple of Frame */ +#define LCD_DeadTime_5 ((uint32_t)0x00000280) /*!< Five Phase between different couple of Frame */ +#define LCD_DeadTime_6 ((uint32_t)0x00000300) /*!< Six Phase between different couple of Frame */ +#define LCD_DeadTime_7 ((uint32_t)0x00000380) /*!< Seven Phase between different couple of Frame */ + +#define IS_LCD_DEAD_TIME(TIME) (((TIME) == LCD_DeadTime_0) || \ + ((TIME) == LCD_DeadTime_1) || \ + ((TIME) == LCD_DeadTime_2) || \ + ((TIME) == LCD_DeadTime_3) || \ + ((TIME) == LCD_DeadTime_4) || \ + ((TIME) == LCD_DeadTime_5) || \ + ((TIME) == LCD_DeadTime_6) || \ + ((TIME) == LCD_DeadTime_7)) +/** + * @} + */ + +/** @defgroup LCD_BlinkMode + * @{ + */ + +#define LCD_BlinkMode_Off ((uint32_t)0x00000000) /*!< Blink disabled */ +#define LCD_BlinkMode_SEG0_COM0 ((uint32_t)0x00010000) /*!< Blink enabled on SEG[0], COM[0] (1 pixel) */ +#define LCD_BlinkMode_SEG0_AllCOM ((uint32_t)0x00020000) /*!< Blink enabled on SEG[0], all COM (up to + 8 pixels according to the programmed duty) */ +#define LCD_BlinkMode_AllSEG_AllCOM ((uint32_t)0x00030000) /*!< Blink enabled on all SEG and all COM (all pixels) */ + +#define IS_LCD_BLINK_MODE(MODE) (((MODE) == LCD_BlinkMode_Off) || \ + ((MODE) == LCD_BlinkMode_SEG0_COM0) || \ + ((MODE) == LCD_BlinkMode_SEG0_AllCOM) || \ + ((MODE) == LCD_BlinkMode_AllSEG_AllCOM)) +/** + * @} + */ + +/** @defgroup LCD_BlinkFrequency + * @{ + */ + +#define LCD_BlinkFrequency_Div8 ((uint32_t)0x00000000) /*!< The Blink frequency = fLCD/8 */ +#define LCD_BlinkFrequency_Div16 ((uint32_t)0x00002000) /*!< The Blink frequency = fLCD/16 */ +#define LCD_BlinkFrequency_Div32 ((uint32_t)0x00004000) /*!< The Blink frequency = fLCD/32 */ +#define LCD_BlinkFrequency_Div64 ((uint32_t)0x00006000) /*!< The Blink frequency = fLCD/64 */ +#define LCD_BlinkFrequency_Div128 ((uint32_t)0x00008000) /*!< The Blink frequency = fLCD/128 */ +#define LCD_BlinkFrequency_Div256 ((uint32_t)0x0000A000) /*!< The Blink frequency = fLCD/256 */ +#define LCD_BlinkFrequency_Div512 ((uint32_t)0x0000C000) /*!< The Blink frequency = fLCD/512 */ +#define LCD_BlinkFrequency_Div1024 ((uint32_t)0x0000E000) /*!< The Blink frequency = fLCD/1024 */ + +#define IS_LCD_BLINK_FREQUENCY(FREQUENCY) (((FREQUENCY) == LCD_BlinkFrequency_Div8) || \ + ((FREQUENCY) == LCD_BlinkFrequency_Div16) || \ + ((FREQUENCY) == LCD_BlinkFrequency_Div32) || \ + ((FREQUENCY) == LCD_BlinkFrequency_Div64) || \ + ((FREQUENCY) == LCD_BlinkFrequency_Div128) || \ + ((FREQUENCY) == LCD_BlinkFrequency_Div256) || \ + ((FREQUENCY) == LCD_BlinkFrequency_Div512) || \ + ((FREQUENCY) == LCD_BlinkFrequency_Div1024)) +/** + * @} + */ + +/** @defgroup LCD_Contrast + * @{ + */ + +#define LCD_Contrast_Level_0 ((uint32_t)0x00000000) /*!< Maximum Voltage = 2.60V */ +#define LCD_Contrast_Level_1 ((uint32_t)0x00000400) /*!< Maximum Voltage = 2.73V */ +#define LCD_Contrast_Level_2 ((uint32_t)0x00000800) /*!< Maximum Voltage = 2.86V */ +#define LCD_Contrast_Level_3 ((uint32_t)0x00000C00) /*!< Maximum Voltage = 2.99V */ +#define LCD_Contrast_Level_4 ((uint32_t)0x00001000) /*!< Maximum Voltage = 3.12V */ +#define LCD_Contrast_Level_5 ((uint32_t)0x00001400) /*!< Maximum Voltage = 3.25V */ +#define LCD_Contrast_Level_6 ((uint32_t)0x00001800) /*!< Maximum Voltage = 3.38V */ +#define LCD_Contrast_Level_7 ((uint32_t)0x00001C00) /*!< Maximum Voltage = 3.51V */ + +#define IS_LCD_CONTRAST(CONTRAST) (((CONTRAST) == LCD_Contrast_Level_0) || \ + ((CONTRAST) == LCD_Contrast_Level_1) || \ + ((CONTRAST) == LCD_Contrast_Level_2) || \ + ((CONTRAST) == LCD_Contrast_Level_3) || \ + ((CONTRAST) == LCD_Contrast_Level_4) || \ + ((CONTRAST) == LCD_Contrast_Level_5) || \ + ((CONTRAST) == LCD_Contrast_Level_6) || \ + ((CONTRAST) == LCD_Contrast_Level_7)) +/** + * @} + */ + +/** @defgroup LCD_Flag + * @{ + */ + +#define LCD_FLAG_ENS LCD_SR_ENS +#define LCD_FLAG_SOF LCD_SR_SOF +#define LCD_FLAG_UDR LCD_SR_UDR +#define LCD_FLAG_UDD LCD_SR_UDD +#define LCD_FLAG_RDY LCD_SR_RDY +#define LCD_FLAG_FCRSF LCD_SR_FCRSR + +#define IS_LCD_GET_FLAG(FLAG) (((FLAG) == LCD_FLAG_ENS) || ((FLAG) == LCD_FLAG_SOF) || \ + ((FLAG) == LCD_FLAG_UDR) || ((FLAG) == LCD_FLAG_UDD) || \ + ((FLAG) == LCD_FLAG_RDY) || ((FLAG) == LCD_FLAG_FCRSF)) + +#define IS_LCD_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFF5) == 0x00) && ((FLAG) != 0x00)) +/** + * @} + */ + +/** @defgroup LCD_RAMRegister + * @{ + */ + +#define LCD_RAMRegister_0 ((uint32_t)0x00000000) /*!< LCD RAM Register 0 */ +#define LCD_RAMRegister_1 ((uint32_t)0x00000001) /*!< LCD RAM Register 1 */ +#define LCD_RAMRegister_2 ((uint32_t)0x00000002) /*!< LCD RAM Register 2 */ +#define LCD_RAMRegister_3 ((uint32_t)0x00000003) /*!< LCD RAM Register 3 */ +#define LCD_RAMRegister_4 ((uint32_t)0x00000004) /*!< LCD RAM Register 4 */ +#define LCD_RAMRegister_5 ((uint32_t)0x00000005) /*!< LCD RAM Register 5 */ +#define LCD_RAMRegister_6 ((uint32_t)0x00000006) /*!< LCD RAM Register 6 */ +#define LCD_RAMRegister_7 ((uint32_t)0x00000007) /*!< LCD RAM Register 7 */ +#define LCD_RAMRegister_8 ((uint32_t)0x00000008) /*!< LCD RAM Register 8 */ +#define LCD_RAMRegister_9 ((uint32_t)0x00000009) /*!< LCD RAM Register 9 */ +#define LCD_RAMRegister_10 ((uint32_t)0x0000000A) /*!< LCD RAM Register 10 */ +#define LCD_RAMRegister_11 ((uint32_t)0x0000000B) /*!< LCD RAM Register 11 */ +#define LCD_RAMRegister_12 ((uint32_t)0x0000000C) /*!< LCD RAM Register 12 */ +#define LCD_RAMRegister_13 ((uint32_t)0x0000000D) /*!< LCD RAM Register 13 */ +#define LCD_RAMRegister_14 ((uint32_t)0x0000000E) /*!< LCD RAM Register 14 */ +#define LCD_RAMRegister_15 ((uint32_t)0x0000000F) /*!< LCD RAM Register 15 */ + +#define IS_LCD_RAM_REGISTER(REGISTER) (((REGISTER) == LCD_RAMRegister_0) || \ + ((REGISTER) == LCD_RAMRegister_1) || \ + ((REGISTER) == LCD_RAMRegister_2) || \ + ((REGISTER) == LCD_RAMRegister_3) || \ + ((REGISTER) == LCD_RAMRegister_4) || \ + ((REGISTER) == LCD_RAMRegister_5) || \ + ((REGISTER) == LCD_RAMRegister_6) || \ + ((REGISTER) == LCD_RAMRegister_7) || \ + ((REGISTER) == LCD_RAMRegister_8) || \ + ((REGISTER) == LCD_RAMRegister_9) || \ + ((REGISTER) == LCD_RAMRegister_10) || \ + ((REGISTER) == LCD_RAMRegister_11) || \ + ((REGISTER) == LCD_RAMRegister_12) || \ + ((REGISTER) == LCD_RAMRegister_13) || \ + ((REGISTER) == LCD_RAMRegister_14) || \ + ((REGISTER) == LCD_RAMRegister_15)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the LCD configuration to the default reset state *****/ +void LCD_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void LCD_Init(LCD_InitTypeDef* LCD_InitStruct); +void LCD_StructInit(LCD_InitTypeDef* LCD_InitStruct); +void LCD_Cmd(FunctionalState NewState); +void LCD_WaitForSynchro(void); +void LCD_HighDriveCmd(FunctionalState NewState); +void LCD_MuxSegmentCmd(FunctionalState NewState); +void LCD_PulseOnDurationConfig(uint32_t LCD_PulseOnDuration); +void LCD_DeadTimeConfig(uint32_t LCD_DeadTime); +void LCD_BlinkConfig(uint32_t LCD_BlinkMode, uint32_t LCD_BlinkFrequency); +void LCD_ContrastConfig(uint32_t LCD_Contrast); + +/* LCD RAM memory write functions *********************************************/ +void LCD_Write(uint32_t LCD_RAMRegister, uint32_t LCD_Data); +void LCD_UpdateDisplayRequest(void); + +/* Interrupts and flags management functions **********************************/ +void LCD_ITConfig(uint32_t LCD_IT, FunctionalState NewState); +FlagStatus LCD_GetFlagStatus(uint32_t LCD_FLAG); +void LCD_ClearFlag(uint32_t LCD_FLAG); +ITStatus LCD_GetITStatus(uint32_t LCD_IT); +void LCD_ClearITPendingBit(uint32_t LCD_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_LCD_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_opamp.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_opamp.c new file mode 100644 index 0000000000..d5cd5ee875 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_opamp.c @@ -0,0 +1,557 @@ +/** + ****************************************************************************** + * @file stm32l1xx_opamp.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the operational amplifiers (opamp) peripheral: + * + Initialization and configuration + * + Calibration management + * + * @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] The device integrates three independent rail-to-rail operational amplifiers + OPAMP1, OPAMP2 and OPAMP3: + (+) Internal connections to the ADC. + (+) Internal connections to the DAC. + (+) Internal connection to COMP1 (only OPAMP3). + (+) Internal connection for unity gain (voltage follower) configuration. + (+) Calibration capability. + (+) Selectable gain-bandwidth (2MHz in normal mode, 500KHz in low power mode). + [..] + (#) COMP AHB clock must be enabled to get write access + to OPAMP registers using + (#) RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE) + + (#) Configure the corresponding GPIO to OPAMPx INP, OPAMPx_INN (if used) + and OPAMPx_OUT in analog mode. + + (#) Configure (close/open) the OPAMP switches using OPAMP_SwitchCmd() + + (#) Enable the OPAMP peripheral using OPAMP_Cmd() + + -@- In order to use OPAMP outputs as ADC inputs, the opamps must be enabled + and the ADC must use the OPAMP output channel number: + (+@) OPAMP1 output is connected to ADC channel 3. + (+@) OPAMP2 output is connected to ADC channel 8. + (+@) OPAMP3 output is connected to ADC channel 13 (SW1 switch must be closed). + + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_opamp.h" + + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup OPAMP + * @brief OPAMP driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup OPAMP_Private_Functions + * @{ + */ + +/** @defgroup OPAMP_Group1 Initialization and configuration + * @brief Initialization and configuration + * +@verbatim + =============================================================================== + ##### Initialization and configuration ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitialize the OPAMPs register to its default reset value. + * @note At startup, OTR and LPOTR registers are set to factory programmed values. + * @param None. + * @retval None. + */ +void OPAMP_DeInit(void) +{ + /*!< Set OPAMP_CSR register to reset value */ + OPAMP->CSR = 0x00010101; + /*!< Set OPAMP_OTR register to reset value */ + OPAMP->OTR = (uint32_t)(* (uint32_t*)FLASH_R_BASE + 0x00000038); + /*!< Set OPAMP_LPOTR register to reset value */ + OPAMP->LPOTR = (uint32_t)(* (uint32_t*)FLASH_R_BASE + 0x0000003C); +} + +/** + * @brief Close or Open the OPAMP switches. + * @param OPAMP_OPAMPxSwitchy: selects the OPAMPx switch. + * This parameter can be any combinations of the following values: + * @arg OPAMP_OPAMP1Switch3: used to connect internally OPAMP1 output to + * OPAMP1 negative input (internal follower) + * @arg OPAMP_OPAMP1Switch4: used to connect PA2 to OPAMP1 negative input + * @arg OPAMP_OPAMP1Switch5: used to connect PA1 to OPAMP1 positive input + * @arg OPAMP_OPAMP1Switch6: used to connect DAC_OUT1 to OPAMP1 positive input + * @arg OPAMP_OPAMP1SwitchANA: used to meet 1 nA input leakage + * @arg OPAMP_OPAMP2Switch3: used to connect internally OPAMP2 output to + * OPAMP2 negative input (internal follower) + * @arg OPAMP_OPAMP2Switch4: used to connect PA7 to OPAMP2 negative input + * @arg OPAMP_OPAMP2Switch5: used to connect PA6 to OPAMP2 positive input + * @arg OPAMP_OPAMP2Switch6: used to connect DAC_OUT1 to OPAMP2 positive input + * @arg OPAMP_OPAMP2Switch7: used to connect DAC_OUT2 to OPAMP2 positive input + * @arg OPAMP_OPAMP2SwitchANA: used to meet 1 nA input leakage + * @arg OPAMP_OPAMP3Switch3: used to connect internally OPAMP3 output to + * OPAMP3 negative input (internal follower) + * @arg OPAMP_OPAMP3Switch4: used to connect PC2 to OPAMP3 negative input + * @arg OPAMP_OPAMP3Switch5: used to connect PC1 to OPAMP3 positive input + * @arg OPAMP_OPAMP3Switch6: used to connect DAC_OUT1 to OPAMP3 positive input + * @arg OPAMP_OPAMP3SwitchANA: used to meet 1 nA input leakage on negative input + * + * @param NewState: New state of the OPAMP switch. + * This parameter can be: + * ENABLE to close the OPAMP switch + * or DISABLE to open the OPAMP switch + * @note OPAMP_OPAMP2Switch6 and OPAMP_OPAMP2Switch7 mustn't be closed together. + * @retval None + */ +void OPAMP_SwitchCmd(uint32_t OPAMP_OPAMPxSwitchy, FunctionalState NewState) +{ + /* Check the parameter */ + assert_param(IS_OPAMP_SWITCH(OPAMP_OPAMPxSwitchy)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Close the selected switches */ + OPAMP->CSR |= (uint32_t) OPAMP_OPAMPxSwitchy; + } + else + { + /* Open the selected switches */ + OPAMP->CSR &= (~(uint32_t)OPAMP_OPAMPxSwitchy); + } +} + +/** + * @brief Enable or disable the OPAMP peripheral. + * @param OPAMP_Selection: the selected OPAMP. + * This parameter can be one of the following values: + * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected + * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected + * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected + * @param NewState: new state of the selected OPAMP peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void OPAMP_Cmd(uint32_t OPAMP_Selection, FunctionalState NewState) +{ + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected OPAMP */ + OPAMP->CSR &= (~(uint32_t) OPAMP_Selection); + } + else + { + /* Disable the selected OPAMP */ + OPAMP->CSR |= (uint32_t) OPAMP_Selection; + } +} + +/** + * @brief Enable or disable the low power mode for OPAMP peripheral. + * @param OPAMP_Selection: the selected OPAMP. + * This parameter can be one of the following values: + * @arg OPAMP_Selection_OPAMP1: OPAMP1 selected + * @arg OPAMP_Selection_OPAMP2: OPAMP2 selected + * @arg OPAMP_Selection_OPAMP3: OPAMP3 selected + * @param NewState: new low power state of the selected OPAMP peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void OPAMP_LowPowerCmd(uint32_t OPAMP_Selection, FunctionalState NewState) +{ + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the selected OPAMP in low power mode */ + OPAMP->CSR |= (uint32_t) (OPAMP_Selection << 7); + } + else + { + /* Disable the low power mode for the selected OPAMP */ + OPAMP->CSR &= (~(uint32_t) (OPAMP_Selection << 7)); + } +} + +/** + * @brief Select the OPAMP power range. + * @note The OPAMP power range selection must be performed while OPAMPs are powered down. + * @param OPAMP_Range: the selected OPAMP power range. + * This parameter can be one of the following values: + * @arg OPAMP_PowerRange_Low: Low power range is selected (VDDA is lower than 2.4V). + * @arg OPAMP_PowerRange_High: High power range is selected (VDDA is higher than 2.4V). + * @retval None + */ +void OPAMP_PowerRangeSelect(uint32_t OPAMP_PowerRange) +{ + /* Check the parameter */ + assert_param(IS_OPAMP_RANGE(OPAMP_PowerRange)); + + /* Reset the OPAMP range bit */ + OPAMP->CSR &= (~(uint32_t) (OPAMP_CSR_AOP_RANGE)); + + /* Select the OPAMP power range */ + OPAMP->CSR |= OPAMP_PowerRange; +} + +/** + * @} + */ + +/** @defgroup OPAMP_Group2 Calibration functions + * @brief Calibration functions + * +@verbatim + =============================================================================== + ##### Calibration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Select the trimming mode. + * @param OffsetTrimming: the selected offset trimming mode. + * This parameter can be one of the following values: + * @arg OffsetTrimming_Factory: factory trimming values are used for offset + * calibration. + * @arg OffsetTrimming_User: user trimming values are used for offset + * calibration. + * @note When OffsetTrimming_User is selected, use OPAMP_OffsetTrimConfig() + * function or OPAMP_OffsetTrimLowPowerConfig() function to adjust + * trimming value. + * @retval None + */ +void OPAMP_OffsetTrimmingModeSelect(uint32_t OPAMP_Trimming) +{ + /* Check the parameter */ + assert_param(IS_OPAMP_TRIMMING(OPAMP_Trimming)); + + /* Reset the OPAMP_OTR range bit */ + OPAMP->CSR &= (~(uint32_t) (OPAMP_OTR_OT_USER)); + + /* Select the OPAMP offset trimming */ + OPAMP->CSR |= OPAMP_Trimming; + +} + +/** + * @brief Configure the trimming value of OPAMPs in normal mode. + * @param OPAMP_Selection: the selected OPAMP. + * This parameter can be one of the following values: + * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected to configure the trimming value. + * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected to configure the trimming value. + * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected to configure the trimming value. + * @param OPAMP_Input: the selected OPAMP input. + * This parameter can be one of the following values: + * @arg OPAMP_Input_NMOS: NMOS input is selected to configure the trimming value. + * @arg OPAMP_Input_PMOS: PMOS input is selected to configure the trimming value. + * @param OPAMP_TrimValue: the trimming value. This parameter can be any value lower + * or equal to 0x0000001F. + * @retval None + */ +void OPAMP_OffsetTrimConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue) +{ + uint32_t tmpreg = 0; + + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection)); + assert_param(IS_OPAMP_INPUT(OPAMP_Input)); + assert_param(IS_OPAMP_TRIMMINGVALUE(OPAMP_TrimValue)); + + /* Get the OPAMP_OTR value */ + tmpreg = OPAMP->OTR; + + if(OPAMP_Selection == OPAMP_Selection_OPAMP1) + { + /* Reset the OPAMP inputs selection */ + tmpreg &= (uint32_t)~(OPAMP_CSR_OPA1CAL_L | OPAMP_CSR_OPA1CAL_H); + /* Select the OPAMP input */ + tmpreg |= OPAMP_Input; + + if(OPAMP_Input == OPAMP_Input_PMOS) + { + /* Reset the trimming value corresponding to OPAMP1 PMOS input */ + tmpreg &= (0xFFFFFFE0); + /* Set the new trimming value corresponding to OPAMP1 PMOS input */ + tmpreg |= (OPAMP_TrimValue); + } + else + { + /* Reset the trimming value corresponding to OPAMP1 NMOS input */ + tmpreg &= (0xFFFFFC1F); + /* Set the new trimming value corresponding to OPAMP1 NMOS input */ + tmpreg |= (OPAMP_TrimValue<<5); + } + } + else if (OPAMP_Selection == OPAMP_Selection_OPAMP2) + { + /* Reset the OPAMP inputs selection */ + tmpreg &= (uint32_t)~(OPAMP_CSR_OPA2CAL_L | OPAMP_CSR_OPA2CAL_H); + /* Select the OPAMP input */ + tmpreg |= (uint32_t)(OPAMP_Input<<8); + + if(OPAMP_Input == OPAMP_Input_PMOS) + { + /* Reset the trimming value corresponding to OPAMP2 PMOS input */ + tmpreg &= (0xFFFF83FF); + /* Set the new trimming value corresponding to OPAMP2 PMOS input */ + tmpreg |= (OPAMP_TrimValue<<10); + } + else + { + /* Reset the trimming value corresponding to OPAMP2 NMOS input */ + tmpreg &= (0xFFF07FFF); + /* Set the new trimming value corresponding to OPAMP2 NMOS input */ + tmpreg |= (OPAMP_TrimValue<<15); + } + } + else + { + /* Reset the OPAMP inputs selection */ + tmpreg &= (uint32_t)~(OPAMP_CSR_OPA3CAL_L | OPAMP_CSR_OPA3CAL_H); + /* Select the OPAMP input */ + tmpreg |= (uint32_t)(OPAMP_Input<<16); + + if(OPAMP_Input == OPAMP_Input_PMOS) + { + /* Reset the trimming value corresponding to OPAMP3 PMOS input */ + tmpreg &= (0xFE0FFFFF); + /* Set the new trimming value corresponding to OPAMP3 PMOS input */ + tmpreg |= (OPAMP_TrimValue<<20); + } + else + { + /* Reset the trimming value corresponding to OPAMP3 NMOS input */ + tmpreg &= (0xC1FFFFFF); + /* Set the new trimming value corresponding to OPAMP3 NMOS input */ + tmpreg |= (OPAMP_TrimValue<<25); + } + } + + /* Set the OPAMP_OTR register */ + OPAMP->OTR = tmpreg; +} + +/** + * @brief Configure the trimming value of OPAMPs in low power mode. + * @param OPAMP_Selection: the selected OPAMP. + * This parameter can be one of the following values: + * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected to configure the trimming value. + * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected to configure the trimming value. + * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected to configure the trimming value. + * @param OPAMP_Input: the selected OPAMP input. + * This parameter can be one of the following values: + * @arg OPAMP_Input_NMOS: NMOS input is selected to configure the trimming value. + * @arg OPAMP_Input_PMOS: PMOS input is selected to configure the trimming value. + * @param OPAMP_TrimValue: the trimming value. + * This parameter can be any value lower or equal to 0x0000001F. + * @retval None + */ +void OPAMP_OffsetTrimLowPowerConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue) +{ + uint32_t tmpreg = 0; + + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection)); + assert_param(IS_OPAMP_INPUT(OPAMP_Input)); + assert_param(IS_OPAMP_TRIMMINGVALUE(OPAMP_TrimValue)); + + /* Get the OPAMP_LPOTR value */ + tmpreg = OPAMP->LPOTR; + + if(OPAMP_Selection == OPAMP_Selection_OPAMP1) + { + /* Reset the OPAMP inputs selection */ + tmpreg &= (uint32_t)~(OPAMP_CSR_OPA1CAL_L | OPAMP_CSR_OPA1CAL_H); + /* Select the OPAMP input */ + tmpreg |= OPAMP_Input; + + if(OPAMP_Input == OPAMP_Input_PMOS) + { + /* Reset the trimming value corresponding to OPAMP1 PMOS input */ + tmpreg &= (0xFFFFFFE0); + /* Set the new trimming value corresponding to OPAMP1 PMOS input */ + tmpreg |= (OPAMP_TrimValue); + } + else + { + /* Reset the trimming value corresponding to OPAMP1 NMOS input */ + tmpreg &= (0xFFFFFC1F); + /* Set the new trimming value corresponding to OPAMP1 NMOS input */ + tmpreg |= (OPAMP_TrimValue<<5); + } + } + else if (OPAMP_Selection == OPAMP_Selection_OPAMP2) + { + /* Reset the OPAMP inputs selection */ + tmpreg &= (uint32_t)~(OPAMP_CSR_OPA2CAL_L | OPAMP_CSR_OPA2CAL_H); + /* Select the OPAMP input */ + tmpreg |= (uint32_t)(OPAMP_Input<<8); + + if(OPAMP_Input == OPAMP_Input_PMOS) + { + /* Reset the trimming value corresponding to OPAMP2 PMOS input */ + tmpreg &= (0xFFFF83FF); + /* Set the new trimming value corresponding to OPAMP2 PMOS input */ + tmpreg |= (OPAMP_TrimValue<<10); + } + else + { + /* Reset the trimming value corresponding to OPAMP2 NMOS input */ + tmpreg &= (0xFFF07FFF); + /* Set the new trimming value corresponding to OPAMP2 NMOS input */ + tmpreg |= (OPAMP_TrimValue<<15); + } + } + else + { + /* Reset the OPAMP inputs selection */ + tmpreg &= (uint32_t)~(OPAMP_CSR_OPA3CAL_L | OPAMP_CSR_OPA3CAL_H); + /* Select the OPAMP input */ + tmpreg |= (uint32_t)(OPAMP_Input<<16); + + if(OPAMP_Input == OPAMP_Input_PMOS) + { + /* Reset the trimming value corresponding to OPAMP3 PMOS input */ + tmpreg &= (0xFE0FFFFF); + /* Set the new trimming value corresponding to OPAMP3 PMOS input */ + tmpreg |= (OPAMP_TrimValue<<20); + } + else + { + /* Reset the trimming value corresponding to OPAMP3 NMOS input */ + tmpreg &= (0xC1FFFFFF); + /* Set the new trimming value corresponding to OPAMP3 NMOS input */ + tmpreg |= (OPAMP_TrimValue<<25); + } + } + + /* Set the OPAMP_LPOTR register */ + OPAMP->LPOTR = tmpreg; +} + +/** + * @brief Checks whether the specified OPAMP calibration flag is set or not. + * @note User should wait until calibration flag change the value when changing + * the trimming value. + * @param OPAMP_Selection: the selected OPAMP. + * This parameter can be one of the following values: + * @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected. + * @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected. + * @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected. + * @retval The new state of the OPAMP calibration flag (SET or RESET). + */ +FlagStatus OPAMP_GetFlagStatus(uint32_t OPAMP_Selection) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection)); + + /* Get the CSR register value */ + tmpreg = OPAMP->CSR; + + /* Check if OPAMP1 is selected */ + if(OPAMP_Selection == OPAMP_Selection_OPAMP1) + { + /* Check OPAMP1 CAL bit status */ + if ((tmpreg & OPAMP_CSR_OPA1CALOUT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + /* Check if OPAMP2 is selected */ + else if(OPAMP_Selection == OPAMP_Selection_OPAMP2) + { + /* Check OPAMP2 CAL bit status */ + if ((tmpreg & OPAMP_CSR_OPA2CALOUT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + else + { + /* Check OPAMP3 CAL bit status */ + if ((tmpreg & OPAMP_CSR_OPA3CALOUT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_opamp.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_opamp.h new file mode 100644 index 0000000000..1bff60c866 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_opamp.h @@ -0,0 +1,187 @@ +/** + ****************************************************************************** + * @file stm32l1xx_opamp.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the operational + * amplifiers (opamp) firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_OPAMP_H +#define __STM32L1xx_OPAMP_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup OPAMP + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup OPAMP_Exported_Constants + * @{ + */ + +/** @defgroup OPAMP_Selection + * @{ + */ + +#define OPAMP_Selection_OPAMP1 OPAMP_CSR_OPA1PD +#define OPAMP_Selection_OPAMP2 OPAMP_CSR_OPA2PD +#define OPAMP_Selection_OPAMP3 OPAMP_CSR_OPA3PD + +#define IS_OPAMP_ALL_PERIPH(PERIPH) (((PERIPH) == OPAMP_Selection_OPAMP1) || \ + ((PERIPH) == OPAMP_Selection_OPAMP2) || \ + ((PERIPH) == OPAMP_Selection_OPAMP3)) + +/** + * @} + */ + +/** @defgroup OPAMP_Switches + * @{ + */ + +/* OPAMP1 Switches */ +#define OPAMP_OPAMP1Switch3 OPAMP_CSR_S3SEL1 /*!< OPAMP1 Switch 3 */ +#define OPAMP_OPAMP1Switch4 OPAMP_CSR_S4SEL1 /*!< OPAMP1 Switch 4 */ +#define OPAMP_OPAMP1Switch5 OPAMP_CSR_S5SEL1 /*!< OPAMP1 Switch 5 */ +#define OPAMP_OPAMP1Switch6 OPAMP_CSR_S6SEL1 /*!< OPAMP1 Switch 6 */ +#define OPAMP_OPAMP1SwitchANA OPAMP_CSR_ANAWSEL1 /*!< OPAMP1 Switch ANA */ + +/* OPAMP2 Switches */ +#define OPAMP_OPAMP2Switch3 OPAMP_CSR_S3SEL2 /*!< OPAMP2 Switch 3 */ +#define OPAMP_OPAMP2Switch4 OPAMP_CSR_S4SEL2 /*!< OPAMP2 Switch 4 */ +#define OPAMP_OPAMP2Switch5 OPAMP_CSR_S5SEL2 /*!< OPAMP2 Switch 5 */ +#define OPAMP_OPAMP2Switch6 OPAMP_CSR_S6SEL2 /*!< OPAMP2 Switch 6 */ +#define OPAMP_OPAMP2Switch7 OPAMP_CSR_S7SEL2 /*!< OPAMP2 Switch 7 */ +#define OPAMP_OPAMP2SwitchANA OPAMP_CSR_ANAWSEL2 /*!< OPAMP2 Switch ANA */ + +/* OPAMP3 Switches */ +#define OPAMP_OPAMP3Switch3 OPAMP_CSR_S3SEL3 /*!< OPAMP3 Switch 3 */ +#define OPAMP_OPAMP3Switch4 OPAMP_CSR_S4SEL3 /*!< OPAMP3 Switch 4 */ +#define OPAMP_OPAMP3Switch5 OPAMP_CSR_S5SEL3 /*!< OPAMP3 Switch 5 */ +#define OPAMP_OPAMP3Switch6 OPAMP_CSR_S6SEL3 /*!< OPAMP3 Switch 6 */ +#define OPAMP_OPAMP3SwitchANA OPAMP_CSR_ANAWSEL3 /*!< OPAMP3 Switch ANA */ + +#define IS_OPAMP_SWITCH(SWITCH) ((((SWITCH) & (uint32_t)0xF0E1E1E1) == 0x00) && ((SWITCH) != 0x00)) + +/** + * @} + */ + +/** @defgroup OPAMP_Trimming + * @{ + */ + +#define OPAMP_Trimming_Factory ((uint32_t)0x00000000) /*!< Factory trimming */ +#define OPAMP_Trimming_User OPAMP_OTR_OT_USER /*!< User trimming */ + +#define IS_OPAMP_TRIMMING(TRIMMING) (((TRIMMING) == OPAMP_Trimming_Factory) || \ + ((TRIMMING) == OPAMP_Trimming_User)) + +/** + * @} + */ + +/** @defgroup OPAMP_Input + * @{ + */ + +#define OPAMP_Input_NMOS OPAMP_CSR_OPA1CAL_H /*!< NMOS input */ +#define OPAMP_Input_PMOS OPAMP_CSR_OPA1CAL_L /*!< PMOS input */ + +#define IS_OPAMP_INPUT(INPUT) (((INPUT) == OPAMP_Input_NMOS) || \ + ((INPUT) == OPAMP_Input_PMOS)) + +/** + * @} + */ + +/** @defgroup OPAMP_TrimValue + * @{ + */ + +#define IS_OPAMP_TRIMMINGVALUE(VALUE) ((VALUE) <= 0x0000001F) /*!< Trimming value */ + +/** + * @} + */ + +/** @defgroup OPAMP_PowerRange + * @{ + */ + +#define OPAMP_PowerRange_Low ((uint32_t)0x00000000) /*!< Low power range is selected (VDDA is lower than 2.4V) */ +#define OPAMP_PowerRange_High OPAMP_CSR_AOP_RANGE /*!< High power range is selected (VDDA is higher than 2.4V) */ + +#define IS_OPAMP_RANGE(RANGE) (((RANGE) == OPAMP_PowerRange_Low) || \ + ((RANGE) == OPAMP_PowerRange_High)) + +/** + * @} + */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Initialization and Configuration functions *********************************/ +void OPAMP_DeInit(void); +void OPAMP_SwitchCmd(uint32_t OPAMP_OPAMPxSwitchy, FunctionalState NewState); +void OPAMP_Cmd(uint32_t OPAMP_Selection, FunctionalState NewState); +void OPAMP_LowPowerCmd(uint32_t OPAMP_Selection, FunctionalState NewState); +void OPAMP_PowerRangeSelect(uint32_t OPAMP_PowerRange); + +/* Calibration functions ******************************************************/ +void OPAMP_OffsetTrimmingModeSelect(uint32_t OPAMP_Trimming); +void OPAMP_OffsetTrimConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue); +void OPAMP_OffsetTrimLowPowerConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue); +FlagStatus OPAMP_GetFlagStatus(uint32_t OPAMP_Selection); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_OPAMP_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_pwr.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_pwr.c new file mode 100644 index 0000000000..ce6f04753f --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_pwr.c @@ -0,0 +1,833 @@ +/** + ****************************************************************************** + * @file stm32l1xx_pwr.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Power Controller (PWR) peripheral: + * + RTC Domain Access + * + PVD configuration + * + WakeUp pins configuration + * + Ultra Low Power mode configuration + * + Voltage Scaling configuration + * + Low Power modes configuration + * + Flags management + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_pwr.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup PWR + * @brief PWR driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* --------- PWR registers bit address in the alias region ---------- */ +#define PWR_OFFSET (PWR_BASE - PERIPH_BASE) + +/* --- CR Register ---*/ + +/* Alias word address of DBP bit */ +#define CR_OFFSET (PWR_OFFSET + 0x00) +#define DBP_BitNumber 0x08 +#define CR_DBP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (DBP_BitNumber * 4)) + +/* Alias word address of PVDE bit */ +#define PVDE_BitNumber 0x04 +#define CR_PVDE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PVDE_BitNumber * 4)) + +/* Alias word address of ULP bit */ +#define ULP_BitNumber 0x09 +#define CR_ULP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (ULP_BitNumber * 4)) + +/* Alias word address of FWU bit */ +#define FWU_BitNumber 0x0A +#define CR_FWU_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (FWU_BitNumber * 4)) + +/* --- CSR Register ---*/ + +/* Alias word address of EWUP bit */ +#define CSR_OFFSET (PWR_OFFSET + 0x04) +#define EWUP_BitNumber 0x08 +#define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4)) + +/* ------------------ PWR registers bit mask ------------------------ */ + +/* CR register bit mask */ +#define CR_DS_MASK ((uint32_t)0xFFFFFFFC) +#define CR_PLS_MASK ((uint32_t)0xFFFFFF1F) +#define CR_VOS_MASK ((uint32_t)0xFFFFE7FF) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup PWR_Private_Functions + * @{ + */ + +/** @defgroup PWR_Group1 RTC Domain Access function + * @brief RTC Domain Access function + * +@verbatim + ============================================================================== + ##### RTC Domain Access function ##### + ============================================================================== + + [..] After reset, the RTC Registers (RCC CSR Register, RTC registers and RTC backup + registers) are protected against possible stray write accesses. + [..] To enable access to RTC domain use the PWR_RTCAccessCmd(ENABLE) function. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the PWR peripheral registers to their default reset values. + * @note Before calling this function, the VOS[1:0] bits should be configured + * to "10" and the system frequency has to be configured accordingly. + * To configure the VOS[1:0] bits, use the PWR_VoltageScalingConfig() + * function. + * @note ULP and FWU bits are not reset by this function. + * @param None + * @retval None + */ +void PWR_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE); +} + +/** + * @brief Enables or disables access to the RTC and backup registers. + * @note If the HSE divided by 2, 4, 8 or 16 is used as the RTC clock, the + * RTC Domain Access should be kept enabled. + * @param NewState: new state of the access to the RTC and backup registers. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_RTCAccessCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup PWR_Group2 PVD configuration functions + * @brief PVD configuration functions + * +@verbatim + ============================================================================== + ##### PVD configuration functions ##### + ============================================================================== + [..] + (+) The PVD is used to monitor the VDD power supply by comparing it to a threshold + selected by the PVD Level (PLS[2:0] bits in the PWR_CR). + (+) The PVD can use an external input analog voltage (PVD_IN) which is compared + internally to VREFINT. The PVD_IN (PB7) has to be configured in Analog mode + when PWR_PVDLevel_7 is selected (PLS[2:0] = 111). + (+) A PVDO flag is available to indicate if VDD/VDDA is higher or lower than the + PVD threshold. This event is internally connected to the EXTI line16 + and can generate an interrupt if enabled through the EXTI registers. + (+) The PVD is stopped in Standby mode. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). + * @param PWR_PVDLevel: specifies the PVD detection level. + * This parameter can be one of the following values: + * @arg PWR_PVDLevel_0: PVD detection level set to 1.9V. + * @arg PWR_PVDLevel_1: PVD detection level set to 2.1V. + * @arg PWR_PVDLevel_2: PVD detection level set to 2.3V. + * @arg PWR_PVDLevel_3: PVD detection level set to 2.5V. + * @arg PWR_PVDLevel_4: PVD detection level set to 2.7V. + * @arg PWR_PVDLevel_5: PVD detection level set to 2.9V. + * @arg PWR_PVDLevel_6: PVD detection level set to 3.1V. + * @arg PWR_PVDLevel_7: External input analog voltage (Compare internally to VREFINT). + * @retval None + */ +void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel)); + + tmpreg = PWR->CR; + + /* Clear PLS[7:5] bits */ + tmpreg &= CR_PLS_MASK; + + /* Set PLS[7:5] bits according to PWR_PVDLevel value */ + tmpreg |= PWR_PVDLevel; + + /* Store the new value */ + PWR->CR = tmpreg; +} + +/** + * @brief Enables or disables the Power Voltage Detector(PVD). + * @param NewState: new state of the PVD. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_PVDCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup PWR_Group3 WakeUp pins configuration functions + * @brief WakeUp pins configuration functions + * +@verbatim + ============================================================================== + ##### WakeUp pin configuration functions ##### + ============================================================================== + + (+) WakeUp pins are used to wakeup the system from Standby mode. These pins are + forced in input pull down configuration and are active on rising edges. + (+) There are three WakeUp pins: WakeUp Pin 1 on PA.00, WakeUp Pin 2 on PC.13 and + WakeUp Pin 3 on PE.06. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the WakeUp Pin functionality. + * @param PWR_WakeUpPin: specifies the WakeUpPin. + * This parameter can be: PWR_WakeUpPin_1, PWR_WakeUpPin_2 or PWR_WakeUpPin_3. + * @param NewState: new state of the WakeUp Pin functionality. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_WakeUpPinCmd(uint32_t PWR_WakeUpPin, FunctionalState NewState) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_PWR_WAKEUP_PIN(PWR_WakeUpPin)); + + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + tmp = CSR_EWUP_BB + PWR_WakeUpPin; + + *(__IO uint32_t *) (tmp) = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup PWR_Group4 Ultra Low Power mode configuration functions + * @brief Ultra Low Power mode configuration functions + * +@verbatim + ============================================================================== + ##### Ultra Low Power mode configuration functions ##### + ============================================================================== + [..] + (+) The internal voltage reference consumption is not negligible, in particular + in Stop and Standby mode. To reduce power consumption, use the PWR_UltraLowPowerCmd() + function (ULP bit (Ultra low power) in the PWR_CR register) to disable the + internal voltage reference. However, in this case, when exiting from the + Stop/Standby mode, the functions managed through the internal voltage reference + are not reliable during the internal voltage reference startup time (up to 3 ms). + To reduce the wakeup time, the device can exit from Stop/Standby mode without + waiting for the internal voltage reference startup time. This is performed + by using the PWR_FastWakeUpCmd() function (setting the FWU bit (Fast + wakeup) in the PWR_CR register) before entering Stop/Standby mode. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the Fast WakeUp from Ultra Low Power mode. + * @param NewState: new state of the Fast WakeUp functionality. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_FastWakeUpCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_FWU_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the Ultra Low Power mode. + * @param NewState: new state of the Ultra Low Power mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_UltraLowPowerCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_ULP_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup PWR_Group5 Voltage Scaling configuration functions + * @brief Voltage Scaling configuration functions + * +@verbatim + ============================================================================== + ##### Voltage Scaling configuration functions ##### + ============================================================================== + + (+) The dynamic voltage scaling is a power management technique which consists in + increasing or decreasing the voltage used for the digital peripherals (VCORE), + according to the circumstances. + + [..] Depending on the device voltage range, the maximum frequency and FLASH wait + state should be adapted accordingly: + [..] + +------------------------------------------------------------------+ + | Wait states | HCLK clock frequency (MHz) | + | |------------------------------------------------| + | (Latency) | voltage range | voltage range | + | | 1.65 V - 3.6 V | 2.0 V - 3.6 V | + | |----------------|---------------|---------------| + | | Range 3 | Range 2 | Range 1 | + | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V | + |---------------- |----------------|---------------|---------------| + | 0WS(1CPU cycle) |0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 | + |-----------------|----------------|---------------|---------------| + | 1WS(2CPU cycle) |2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32| + |-----------------|----------------|---------------|---------------| + | CPU Performance | Low | Medium | High | + |-----__----------|----------------|---------------|---------------| + |Power Performance| High | Medium | Low | + +------------------------------------------------------------------+ + + (+) To modify the Product voltage range, user application has to: + (++) Check VDD to identify which ranges are allowed (see table above). + (++) Check the PWR_FLAG_VOSF (Voltage Scaling update ongoing) using the PWR_GetFlagStatus() + function and wait until it is reset. + (++) Configure the Voltage range using the PWR_VoltageScalingConfig() function. + + (+) When VCORE range 1 is selected and VDD drops below 2.0 V, the application must + reconfigure the system: + (++) Detect that VDD drops below 2.0 V using the PVD Level 1. + (++) Adapt the clock frequency to the voltage range that will be selected at next step. + (++) Select the required voltage range. + (++) When VCORE range 2 or range 3 is selected and VDD drops below 2.0 V, no system + reconfiguration is required. + + (+) When VDD is above 2.0 V, any of the 3 voltage ranges can be selected. + (++) When the voltage range is above the targeted voltage range (e.g. from range + 1 to 2). + (++) Adapt the clock frequency to the lower voltage range that will be selected + at next step. + (++) Select the required voltage range. + (++) When the voltage range is below the targeted voltage range (e.g. from range + 3 to 1). + (++) Select the required voltage range. + (++) Tune the clock frequency if needed. + + (+) When VDD is below 2.0 V, only range 2 and 3 can be selected: + (++) From range 2 to range 3. + (+++) Adapt the clock frequency to voltage range 3. + (+++) Select voltage range 3. + (++) From range 3 to range 2. + (+++) Select the voltage range 2. + (+++) Tune the clock frequency if needed. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the voltage scaling range. + * @note During voltage scaling configuration, the system clock is stopped + * until the regulator is stabilized (VOSF = 0). This must be taken + * into account during application developement, in case a critical + * reaction time to interrupt is needed, and depending on peripheral + * used (timer, communication,...). + * + * @param PWR_VoltageScaling: specifies the voltage scaling range. + * This parameter can be: + * @arg PWR_VoltageScaling_Range1: Voltage Scaling Range 1 (VCORE = 1.8V). + * @arg PWR_VoltageScaling_Range2: Voltage Scaling Range 2 (VCORE = 1.5V). + * @arg PWR_VoltageScaling_Range3: Voltage Scaling Range 3 (VCORE = 1.2V) + * @retval None + */ +void PWR_VoltageScalingConfig(uint32_t PWR_VoltageScaling) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(PWR_VoltageScaling)); + + tmp = PWR->CR; + + tmp &= CR_VOS_MASK; + tmp |= PWR_VoltageScaling; + + PWR->CR = tmp & 0xFFFFFFF3; + +} + +/** + * @} + */ + +/** @defgroup PWR_Group6 Low Power modes configuration functions + * @brief Low Power modes configuration functions + * +@verbatim + ============================================================================== + ##### Low Power modes configuration functions ##### + ============================================================================== + + [..] The devices feature five low-power modes: + (+) Low power run mode: regulator in low power mode, limited clock frequency, + limited number of peripherals running. + (+) Sleep mode: Cortex-M3 core stopped, peripherals kept running. + (+) Low power sleep mode: Cortex-M3 core stopped, limited clock frequency, + limited number of peripherals running, regulator in low power mode. + (+) Stop mode: all clocks are stopped, regulator running, regulator in low power mode. + (+) Standby mode: VCORE domain powered off. + + *** Low power run mode (LP run) *** + =================================== + [..] + (+) Entry: + (++) Decrease the system frequency. + (++) The regulator is forced in low power mode using the PWR_EnterLowPowerRunMode() + function. + (+) Exit: + (++) The regulator is forced in Main regulator mode sing the PWR_EnterLowPowerRunMode() + function. + (++) Increase the system frequency if needed. + + *** Sleep mode *** + ================== + [..] + (+) Entry: + (++) The Sleep mode is entered by using the PWR_EnterSleepMode(PWR_Regulator_ON,) + function with regulator ON. + (+) Exit: + (++) Any peripheral interrupt acknowledged by the nested vectored interrupt + controller (NVIC) can wake up the device from Sleep mode. + + *** Low power sleep mode (LP sleep) *** + ======================================= + [..] + (+) Entry: + (++) The Flash memory must be switched off by using the FLASH_SLEEPPowerDownCmd() + function. + (++) Decrease the system frequency. + (++) The regulator is forced in low power mode and the WFI or WFE instructions + are executed using the PWR_EnterSleepMode(PWR_Regulator_LowPower,) function + with regulator in LowPower. + (+) Exit: + (++) Any peripheral interrupt acknowledged by the nested vectored interrupt + controller (NVIC) can wake up the device from Sleep LP mode. + + *** Stop mode *** + ================= + [..] In Stop mode, all clocks in the VCORE domain are stopped, the PLL, the MSI, + the HSI and the HSE RC oscillators are disabled. Internal SRAM and register + contents are preserved. + The voltage regulator can be configured either in normal or low-power mode. + To minimize the consumption In Stop mode, VREFINT, the BOR, PVD, and temperature + sensor can be switched off before entering the Stop mode. They can be switched + on again by software after exiting the Stop mode using the PWR_UltraLowPowerCmd() + function. + + (+) Entry: + (++) The Stop mode is entered using the PWR_EnterSTOPMode(PWR_Regulator_LowPower,) + function with regulator in LowPower or with Regulator ON. + (+) Exit: + (++) Any EXTI Line (Internal or External) configured in Interrupt/Event mode. + + *** Standby mode *** + ==================== + [..] The Standby mode allows to achieve the lowest power consumption. It is based + on the Cortex-M3 deepsleep mode, with the voltage regulator disabled. + The VCORE domain is consequently powered off. The PLL, the MSI, the HSI + oscillator and the HSE oscillator are also switched off. SRAM and register + contents are lost except for the RTC registers, RTC backup registers and + Standby circuitry. + + [..] The voltage regulator is OFF. + + [..] To minimize the consumption In Standby mode, VREFINT, the BOR, PVD, and temperature + sensor can be switched off before entering the Standby mode. They can be switched + on again by software after exiting the Standby mode using the PWR_UltraLowPowerCmd() + function. + + (+) Entry: + (++) The Standby mode is entered using the PWR_EnterSTANDBYMode() function. + (+) Exit: + (++) WKUP pin rising edge, RTC alarm (Alarm A and Alarm B), RTC wakeup, + tamper event, time-stamp event, external reset in NRST pin, IWDG reset. + + *** Auto-wakeup (AWU) from low-power mode *** + ============================================= + [..]The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC + Wakeup event, a tamper event, a time-stamp event, or a comparator event, + without depending on an external interrupt (Auto-wakeup mode). + + (+) RTC auto-wakeup (AWU) from the Stop mode + (++) To wake up from the Stop mode with an RTC alarm event, it is necessary to: + (+++) Configure the EXTI Line 17 to be sensitive to rising edges (Interrupt + or Event modes) using the EXTI_Init() function. + (+++) Enable the RTC Alarm Interrupt using the RTC_ITConfig() function + (+++) Configure the RTC to generate the RTC alarm using the RTC_SetAlarm() + and RTC_AlarmCmd() functions. + (++) To wake up from the Stop mode with an RTC Tamper or time stamp event, it + is necessary to: + (+++) Configure the EXTI Line 19 to be sensitive to rising edges (Interrupt + or Event modes) using the EXTI_Init() function. + (+++) Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig() + function. + (+++) Configure the RTC to detect the tamper or time stamp event using the + RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd() + functions. + (++) To wake up from the Stop mode with an RTC WakeUp event, it is necessary to: + (+++) Configure the EXTI Line 20 to be sensitive to rising edges (Interrupt + or Event modes) using the EXTI_Init() function. + (+++) Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function. + (+++) Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(), + RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. + + (+) RTC auto-wakeup (AWU) from the Standby mode + (++) To wake up from the Standby mode with an RTC alarm event, it is necessary to: + (+++) Enable the RTC Alarm Interrupt using the RTC_ITConfig() function. + (+++) Configure the RTC to generate the RTC alarm using the RTC_SetAlarm() + and RTC_AlarmCmd() functions. + (++) To wake up from the Standby mode with an RTC Tamper or time stamp event, it + is necessary to: + (+++) Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig() + function. + (+++) Configure the RTC to detect the tamper or time stamp event using the + RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd() + functions. + (++) To wake up from the Standby mode with an RTC WakeUp event, it is necessary to: + (+++) Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function + (+++) Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(), + RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. + + (+) Comparator auto-wakeup (AWU) from the Stop mode + (++) To wake up from the Stop mode with an comparator 1 or comparator 2 wakeup + event, it is necessary to: + (+++) Configure the EXTI Line 21 for comparator 1 or EXTI Line 22 for comparator 2 + to be sensitive to to the selected edges (falling, rising or falling + and rising) (Interrupt or Event modes) using the EXTI_Init() function. + (+++) Configure the comparator to generate the event. + +@endverbatim + * @{ + */ + +/** + * @brief Enters/Exits the Low Power Run mode. + * @note Low power run mode can only be entered when VCORE is in range 2. + * In addition, the dynamic voltage scaling must not be used when Low + * power run mode is selected. Only Stop and Sleep modes with regulator + * configured in Low power mode is allowed when Low power run mode is + * selected. + * @note In Low power run mode, all I/O pins keep the same state as in Run mode. + * @param NewState: new state of the Low Power Run mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_EnterLowPowerRunMode(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + PWR->CR |= PWR_CR_LPSDSR; + PWR->CR |= PWR_CR_LPRUN; + } + else + { + PWR->CR &= (uint32_t)~((uint32_t)PWR_CR_LPRUN); + PWR->CR &= (uint32_t)~((uint32_t)PWR_CR_LPSDSR); + } +} + +/** + * @brief Enters Sleep mode. + * @note In Sleep mode, all I/O pins keep the same state as in Run mode. + * @param PWR_Regulator: specifies the regulator state in Sleep mode. + * This parameter can be one of the following values: + * @arg PWR_Regulator_ON: Sleep mode with regulator ON + * @arg PWR_Regulator_LowPower: Sleep mode with regulator in low power mode + * @note Low power sleep mode can only be entered when VCORE is in range 2. + * @note When the voltage regulator operates in low power mode, an additional + * startup delay is incurred when waking up from Low power sleep mode. + * @param PWR_SLEEPEntry: specifies if SLEEP mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_SLEEPEntry_WFI: enter SLEEP mode with WFI instruction + * @arg PWR_SLEEPEntry_WFE: enter SLEEP mode with WFE instruction + * @retval None + */ +void PWR_EnterSleepMode(uint32_t PWR_Regulator, uint8_t PWR_SLEEPEntry) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(PWR_Regulator)); + + assert_param(IS_PWR_SLEEP_ENTRY(PWR_SLEEPEntry)); + + /* Select the regulator state in Sleep mode ---------------------------------*/ + tmpreg = PWR->CR; + + /* Clear PDDS and LPDSR bits */ + tmpreg &= CR_DS_MASK; + + /* Set LPDSR bit according to PWR_Regulator value */ + tmpreg |= PWR_Regulator; + + /* Store the new value */ + PWR->CR = tmpreg; + + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); + + /* Select SLEEP mode entry -------------------------------------------------*/ + if(PWR_SLEEPEntry == PWR_SLEEPEntry_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __WFE(); + } +} + +/** + * @brief Enters STOP mode. + * @note In Stop mode, all I/O pins keep the same state as in Run mode. + * @note When exiting Stop mode by issuing an interrupt or a wakeup event, + * the MSI RC oscillator is selected as system clock. + * @note When the voltage regulator operates in low power mode, an additional + * startup delay is incurred when waking up from Stop mode. + * By keeping the internal regulator ON during Stop mode, the consumption + * is higher although the startup time is reduced. + * @param PWR_Regulator: specifies the regulator state in STOP mode. + * This parameter can be one of the following values: + * @arg PWR_Regulator_ON: STOP mode with regulator ON. + * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode. + * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction. + * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction. + * @retval None + */ +void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(PWR_Regulator)); + assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); + + /* Select the regulator state in STOP mode ---------------------------------*/ + tmpreg = PWR->CR; + /* Clear PDDS and LPDSR bits */ + tmpreg &= CR_DS_MASK; + + /* Set LPDSR bit according to PWR_Regulator value */ + tmpreg |= PWR_Regulator; + + /* Store the new value */ + PWR->CR = tmpreg; + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP; + + /* Select STOP mode entry --------------------------------------------------*/ + if(PWR_STOPEntry == PWR_STOPEntry_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __WFE(); + } + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); +} + +/** + * @brief Enters STANDBY mode. + * @note In Standby mode, all I/O pins are high impedance except for: + * Reset pad (still available) + * RTC_AF1 pin (PC13) if configured for Wakeup pin 2 (WKUP2), tamper, + * time-stamp, RTC Alarm out, or RTC clock calibration out. + * WKUP pin 1 (PA0) and WKUP pin 3 (PE6), if enabled. + * @param None + * @retval None + */ +void PWR_EnterSTANDBYMode(void) +{ + /* Clear Wakeup flag */ + PWR->CR |= PWR_CR_CWUF; + + /* Select STANDBY mode */ + PWR->CR |= PWR_CR_PDDS; + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP; + +/* This option is used to ensure that store operations are completed */ +#if defined ( __CC_ARM ) + __force_stores(); +#endif + /* Request Wait For Interrupt */ + __WFI(); +} + +/** + * @} + */ + +/** @defgroup PWR_Group7 Flags management functions + * @brief Flags management functions + * +@verbatim + ============================================================================== + ##### Flags management functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Checks whether the specified PWR flag is set or not. + * @param PWR_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event + * was received from the WKUP pin or from the RTC alarm (Alarm A or Alarm B), + * RTC Tamper event, RTC TimeStamp event or RTC Wakeup. + * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was + * resumed from StandBy mode. + * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled + * by the PWR_PVDCmd() function. + * @arg PWR_FLAG_VREFINTRDY: Internal Voltage Reference Ready flag. This + * flag indicates the state of the internal voltage reference, VREFINT. + * @arg PWR_FLAG_VOS: Voltage Scaling select flag. A delay is required for + * the internal regulator to be ready after the voltage range is changed. + * The VOSF flag indicates that the regulator has reached the voltage level + * defined with bits VOS[1:0] of PWR_CR register. + * @arg PWR_FLAG_REGLP: Regulator LP flag. This flag is set by hardware + * when the MCU is in Low power run mode. + * When the MCU exits from Low power run mode, this flag stays SET until + * the regulator is ready in main mode. A polling on this flag is + * recommended to wait for the regulator main mode. + * This flag is RESET by hardware when the regulator is ready. + * @retval The new state of PWR_FLAG (SET or RESET). + */ +FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_PWR_GET_FLAG(PWR_FLAG)); + + if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the PWR's pending flags. + * @param PWR_FLAG: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag + * @arg PWR_FLAG_SB: StandBy flag + * @retval None + */ +void PWR_ClearFlag(uint32_t PWR_FLAG) +{ + /* Check the parameters */ + assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG)); + + PWR->CR |= PWR_FLAG << 2; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_pwr.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_pwr.h new file mode 100644 index 0000000000..fb1ed50412 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_pwr.h @@ -0,0 +1,213 @@ +/** + ****************************************************************************** + * @file stm32l1xx_pwr.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the PWR firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_PWR_H +#define __STM32L1xx_PWR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup PWR + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Constants + * @{ + */ + +/** @defgroup PWR_PVD_detection_level + * @{ + */ + +#define PWR_PVDLevel_0 PWR_CR_PLS_LEV0 +#define PWR_PVDLevel_1 PWR_CR_PLS_LEV1 +#define PWR_PVDLevel_2 PWR_CR_PLS_LEV2 +#define PWR_PVDLevel_3 PWR_CR_PLS_LEV3 +#define PWR_PVDLevel_4 PWR_CR_PLS_LEV4 +#define PWR_PVDLevel_5 PWR_CR_PLS_LEV5 +#define PWR_PVDLevel_6 PWR_CR_PLS_LEV6 +#define PWR_PVDLevel_7 PWR_CR_PLS_LEV7 /* External input analog voltage + (Compare internally to VREFINT) */ +#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_0) || ((LEVEL) == PWR_PVDLevel_1)|| \ + ((LEVEL) == PWR_PVDLevel_2) || ((LEVEL) == PWR_PVDLevel_3)|| \ + ((LEVEL) == PWR_PVDLevel_4) || ((LEVEL) == PWR_PVDLevel_5)|| \ + ((LEVEL) == PWR_PVDLevel_6) || ((LEVEL) == PWR_PVDLevel_7)) +/** + * @} + */ + +/** @defgroup PWR_WakeUp_Pins + * @{ + */ + +#define PWR_WakeUpPin_1 ((uint32_t)0x00000000) +#define PWR_WakeUpPin_2 ((uint32_t)0x00000004) +#define PWR_WakeUpPin_3 ((uint32_t)0x00000008) +#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WakeUpPin_1) || \ + ((PIN) == PWR_WakeUpPin_2) || \ + ((PIN) == PWR_WakeUpPin_3)) +/** + * @} + */ + + +/** @defgroup PWR_Voltage_Scaling_Ranges + * @{ + */ + +#define PWR_VoltageScaling_Range1 PWR_CR_VOS_0 +#define PWR_VoltageScaling_Range2 PWR_CR_VOS_1 +#define PWR_VoltageScaling_Range3 PWR_CR_VOS + +#define IS_PWR_VOLTAGE_SCALING_RANGE(RANGE) (((RANGE) == PWR_VoltageScaling_Range1) || \ + ((RANGE) == PWR_VoltageScaling_Range2) || \ + ((RANGE) == PWR_VoltageScaling_Range3)) +/** + * @} + */ + +/** @defgroup PWR_Regulator_state_is_Sleep_STOP_mode + * @{ + */ + +#define PWR_Regulator_ON ((uint32_t)0x00000000) +#define PWR_Regulator_LowPower PWR_CR_LPSDSR +#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ + ((REGULATOR) == PWR_Regulator_LowPower)) +/** + * @} + */ + +/** @defgroup PWR_SLEEP_mode_entry + * @{ + */ + +#define PWR_SLEEPEntry_WFI ((uint8_t)0x01) +#define PWR_SLEEPEntry_WFE ((uint8_t)0x02) +#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPEntry_WFI) || ((ENTRY) == PWR_SLEEPEntry_WFE)) + +/** + * @} + */ + +/** @defgroup PWR_STOP_mode_entry + * @{ + */ + +#define PWR_STOPEntry_WFI ((uint8_t)0x01) +#define PWR_STOPEntry_WFE ((uint8_t)0x02) +#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) + +/** + * @} + */ + +/** @defgroup PWR_Flag + * @{ + */ + +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF +#define PWR_FLAG_PVDO PWR_CSR_PVDO +#define PWR_FLAG_VREFINTRDY PWR_CSR_VREFINTRDYF +#define PWR_FLAG_VOS PWR_CSR_VOSF +#define PWR_FLAG_REGLP PWR_CSR_REGLPF + +#define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ + ((FLAG) == PWR_FLAG_PVDO) || ((FLAG) == PWR_FLAG_VREFINTRDY) || \ + ((FLAG) == PWR_FLAG_VOS) || ((FLAG) == PWR_FLAG_REGLP)) + +#define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the PWR configuration to the default reset state ******/ +void PWR_DeInit(void); + +/* RTC Domain Access function *************************************************/ +void PWR_RTCAccessCmd(FunctionalState NewState); + +/* PVD configuration functions ************************************************/ +void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); +void PWR_PVDCmd(FunctionalState NewState); + +/* WakeUp pins configuration functions ****************************************/ +void PWR_WakeUpPinCmd(uint32_t PWR_WakeUpPin, FunctionalState NewState); + +/* Ultra Low Power mode configuration functions *******************************/ +void PWR_FastWakeUpCmd(FunctionalState NewState); +void PWR_UltraLowPowerCmd(FunctionalState NewState); + +/* Voltage Scaling configuration functions ************************************/ +void PWR_VoltageScalingConfig(uint32_t PWR_VoltageScaling); + +/* Low Power modes configuration functions ************************************/ +void PWR_EnterLowPowerRunMode(FunctionalState NewState); +void PWR_EnterSleepMode(uint32_t PWR_Regulator, uint8_t PWR_SLEEPEntry); +void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); +void PWR_EnterSTANDBYMode(void); + +/* Flags management functions *************************************************/ +FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); +void PWR_ClearFlag(uint32_t PWR_FLAG); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_PWR_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rcc.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rcc.c new file mode 100644 index 0000000000..6218025f9f --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rcc.c @@ -0,0 +1,1642 @@ +/** + ****************************************************************************** + * @file stm32l1xx_rcc.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Reset and clock control (RCC) peripheral: + * + Internal/external clocks, PLL, CSS and MCO configuration + * + System, AHB and APB busses clocks configuration + * + Peripheral clocks configuration + * + Interrupts and flags management + * + @verbatim + + =============================================================================== + ##### RCC specific features ##### + =============================================================================== + [..] After reset the device is running from MSI (2 MHz) with Flash 0 WS, + all peripherals are off except internal SRAM, Flash and JTAG. + (#) There is no prescaler on High speed (AHB) and Low speed (APB) busses; + all peripherals mapped on these busses are running at MSI speed. + (#) The clock for all peripherals is switched off, except the SRAM and + FLASH. + (#) All GPIOs are in input floating state, except the JTAG pins which + are assigned to be used for debug purpose. + [..] Once the device started from reset, the user application has to: + (#) Configure the clock source to be used to drive the System clock + (if the application needs higher frequency/performance) + (#) Configure the System clock frequency and Flash settings + (#) Configure the AHB and APB busses prescalers + (#) Enable the clock for the peripheral(s) to be used + (#) Configure the clock source(s) for peripherals whose clocks are not + derived from the System clock (ADC, RTC/LCD and IWDG) + + @endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup RCC + * @brief RCC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ------------ RCC registers bit address in the alias region ----------- */ +#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) + +/* --- CR Register ---*/ + +/* Alias word address of HSION bit */ +#define CR_OFFSET (RCC_OFFSET + 0x00) +#define HSION_BitNumber 0x00 +#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4)) + +/* Alias word address of MSION bit */ +#define MSION_BitNumber 0x08 +#define CR_MSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (MSION_BitNumber * 4)) + +/* Alias word address of PLLON bit */ +#define PLLON_BitNumber 0x18 +#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4)) + +/* Alias word address of CSSON bit */ +#define CSSON_BitNumber 0x1C +#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4)) + +/* --- CSR Register ---*/ + +/* Alias word address of LSION bit */ +#define CSR_OFFSET (RCC_OFFSET + 0x34) +#define LSION_BitNumber 0x00 +#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4)) + +/* Alias word address of LSECSSON bit */ +#define LSECSSON_BitNumber 0x0B +#define CSR_LSECSSON_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSECSSON_BitNumber * 4)) + +/* Alias word address of RTCEN bit */ +#define RTCEN_BitNumber 0x16 +#define CSR_RTCEN_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (RTCEN_BitNumber * 4)) + +/* Alias word address of RTCRST bit */ +#define RTCRST_BitNumber 0x17 +#define CSR_RTCRST_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (RTCRST_BitNumber * 4)) + + +/* ---------------------- RCC registers mask -------------------------------- */ +/* RCC Flag Mask */ +#define FLAG_MASK ((uint8_t)0x1F) + +/* CR register byte 3 (Bits[23:16]) base address */ +#define CR_BYTE3_ADDRESS ((uint32_t)0x40023802) + +/* ICSCR register byte 4 (Bits[31:24]) base address */ +#define ICSCR_BYTE4_ADDRESS ((uint32_t)0x40023807) + +/* CFGR register byte 3 (Bits[23:16]) base address */ +#define CFGR_BYTE3_ADDRESS ((uint32_t)0x4002380A) + +/* CFGR register byte 4 (Bits[31:24]) base address */ +#define CFGR_BYTE4_ADDRESS ((uint32_t)0x4002380B) + +/* CIR register byte 2 (Bits[15:8]) base address */ +#define CIR_BYTE2_ADDRESS ((uint32_t)0x4002380D) + +/* CIR register byte 3 (Bits[23:16]) base address */ +#define CIR_BYTE3_ADDRESS ((uint32_t)0x4002380E) + +/* CSR register byte 2 (Bits[15:8]) base address */ +#define CSR_BYTE2_ADDRESS ((uint32_t)0x40023835) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +static __I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; +static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RCC_Private_Functions + * @{ + */ + +/** @defgroup RCC_Group1 Internal and external clocks, PLL, CSS and MCO configuration functions + * @brief Internal and external clocks, PLL, CSS and MCO configuration functions + * +@verbatim + =============================================================================== + ##### Internal-external clocks, PLL, CSS and MCO configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to configure the internal/external + clocks, PLL, CSS and MCO. + (#) HSI (high-speed internal), 16 MHz factory-trimmed RC used directly + or through the PLL as System clock source. + (#) MSI (multi-speed internal), multispeed low power RC + (65.536 KHz to 4.194 MHz) MHz used as System clock source. + (#) LSI (low-speed internal), 37 KHz low consumption RC used as IWDG + and/or RTC clock source. + (#) HSE (high-speed external), 1 to 24 MHz crystal oscillator used + directly or through the PLL as System clock source. Can be used + also as RTC clock source. + (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source. + (#) PLL (clocked by HSI or HSE), for System clock and USB (48 MHz). + (#) CSS (Clock security system), once enable and if a HSE clock failure + occurs (HSE used directly or through PLL as System clock source), + the System clock is automatically switched to MSI and an interrupt + is generated if enabled. + The interrupt is linked to the Cortex-M3 NMI (Non-Maskable Interrupt) + exception vector. + (#) MCO (microcontroller clock output), used to output SYSCLK, HSI, MSI, + HSE, PLL, LSI or LSE clock (through a configurable prescaler) on + PA8 pin. + +@endverbatim + * @{ + */ + +/** + * @brief Resets the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * @note MSI ON and used as system clock source (MSI range is not modified + * by this function, it keep the value configured by user application) + * @note HSI, HSE and PLL OFF + * @note AHB, APB1 and APB2 prescaler set to 1. + * @note CSS and MCO OFF + * @note All interrupts disabled + * @note However, this function doesn't modify the configuration of the + * @note Peripheral clocks + * @note LSI, LSE and RTC clocks + * @param None + * @retval None + */ +void RCC_DeInit(void) +{ + + /* Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100; + + /* Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t)0x88FFC00C; + + /* Reset HSION, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xEEFEFFFE; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; +} + +/** + * @brief Configures the External High Speed oscillator (HSE). + * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application + * software should wait on HSERDY flag to be set indicating that HSE clock + * is stable and can be used to clock the PLL and/or system clock. + * @note HSE state can not be changed if it is used directly or through the + * PLL as system clock. In this case, you have to select another source + * of the system clock then change the HSE state (ex. disable it). + * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. + * @note This function reset the CSSON bit, so if the Clock security system(CSS) + * was previously enabled you have to enable it again after calling this + * function. + * @param RCC_HSE: specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after + * 6 HSE oscillator clock cycles. + * @arg RCC_HSE_ON: turn ON the HSE oscillator + * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock + * @retval None + */ +void RCC_HSEConfig(uint8_t RCC_HSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_HSE)); + + /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ + *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE_OFF; + + /* Set the new HSE configuration -------------------------------------------*/ + *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE; + +} + +/** + * @brief Waits for HSE start-up. + * @note This functions waits on HSERDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * HSE_STARTUP_TIMEOUT in stm32l1xx.h file. You can tailor it depending + * on the HSE crystal used in your application. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: HSE oscillator is stable and ready to use + * - ERROR: HSE oscillator not yet ready + */ +ErrorStatus RCC_WaitForHSEStartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus HSEStatus = RESET; + + /* Wait till HSE is ready and if timeout is reached exit */ + do + { + HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY); + StartUpCounter++; + } while((StartUpCounter != HSE_STARTUP_TIMEOUT) && (HSEStatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Adjusts the Internal Multi Speed oscillator (MSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal MSI RC. + * Refer to the Application Note AN3300 for more details on how to + * calibrate the MSI. + * @param MSICalibrationValue: specifies the MSI calibration trimming value. + * This parameter must be a number between 0 and 0xFF. + * @retval None + */ +void RCC_AdjustMSICalibrationValue(uint8_t MSICalibrationValue) +{ + + /* Check the parameters */ + assert_param(IS_RCC_MSI_CALIBRATION_VALUE(MSICalibrationValue)); + + *(__IO uint8_t *) ICSCR_BYTE4_ADDRESS = MSICalibrationValue; +} + +/** + * @brief Configures the Internal Multi Speed oscillator (MSI) clock range. + * @note After restart from Reset or wakeup from STANDBY, the MSI clock is + * around 2.097 MHz. The MSI clock does not change after wake-up from + * STOP mode. + * @note The MSI clock range can be modified on the fly. + * @param RCC_MSIRange: specifies the MSI Clock range. + * This parameter must be one of the following values: + * @arg RCC_MSIRange_0: MSI clock is around 65.536 KHz + * @arg RCC_MSIRange_1: MSI clock is around 131.072 KHz + * @arg RCC_MSIRange_2: MSI clock is around 262.144 KHz + * @arg RCC_MSIRange_3: MSI clock is around 524.288 KHz + * @arg RCC_MSIRange_4: MSI clock is around 1.048 MHz + * @arg RCC_MSIRange_5: MSI clock is around 2.097 MHz (default after Reset or wake-up from STANDBY) + * @arg RCC_MSIRange_6: MSI clock is around 4.194 MHz + * + * @retval None + */ +void RCC_MSIRangeConfig(uint32_t RCC_MSIRange) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_MSIRange)); + + tmpreg = RCC->ICSCR; + + /* Clear MSIRANGE[2:0] bits */ + tmpreg &= ~RCC_ICSCR_MSIRANGE; + + /* Set the MSIRANGE[2:0] bits according to RCC_MSIRange value */ + tmpreg |= (uint32_t)RCC_MSIRange; + + /* Store the new value */ + RCC->ICSCR = tmpreg; +} + +/** + * @brief Enables or disables the Internal Multi Speed oscillator (MSI). + * @note The MSI is stopped by hardware when entering STOP and STANDBY modes. + * It is used (enabled by hardware) as system clock source after + * startup from Reset, wakeup from STOP and STANDBY mode, or in case + * of failure of the HSE used directly or indirectly as system clock + * (if the Clock Security System CSS is enabled). + * @note MSI can not be stopped if it is used as system clock source. + * In this case, you have to select another source of the system + * clock then stop the MSI. + * @note After enabling the MSI, the application software should wait on + * MSIRDY flag to be set indicating that MSI clock is stable and can + * be used as system clock source. + * @param NewState: new state of the MSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the MSI is stopped, MSIRDY flag goes low after 6 MSI oscillator + * clock cycles. + * @retval None + */ +void RCC_MSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_MSION_BB = (uint32_t)NewState; +} + +/** + * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI RC. + * Refer to the Application Note AN3300 for more details on how to + * calibrate the HSI. + * @param HSICalibrationValue: specifies the HSI calibration trimming value. + * This parameter must be a number between 0 and 0x1F. + * @retval None + */ +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_HSI_CALIBRATION_VALUE(HSICalibrationValue)); + + tmpreg = RCC->ICSCR; + + /* Clear HSITRIM[4:0] bits */ + tmpreg &= ~RCC_ICSCR_HSITRIM; + + /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ + tmpreg |= (uint32_t)HSICalibrationValue << 8; + + /* Store the new value */ + RCC->ICSCR = tmpreg; +} + +/** + * @brief Enables or disables the Internal High Speed oscillator (HSI). + * @note After enabling the HSI, the application software should wait on + * HSIRDY flag to be set indicating that HSI clock is stable and can + * be used to clock the PLL and/or system clock. + * @note HSI can not be stopped if it is used directly or through the PLL + * as system clock. In this case, you have to select another source + * of the system clock then stop the HSI. + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * @param NewState: new state of the HSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + * @retval None + */ +void RCC_HSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the External Low Speed oscillator (LSE). + * @note As the LSE is in the RTC domain and write access is denied to this + * domain after reset, you have to enable write access using + * PWR_RTCAccessCmd(ENABLE) function before to configure the LSE + * (to be done once after reset). + * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_Bypass), the application + * software should wait on LSERDY flag to be set indicating that LSE clock + * is stable and can be used to clock the RTC. + * @param RCC_LSE: specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after + * 6 LSE oscillator clock cycles. + * @arg RCC_LSE_ON: turn ON the LSE oscillator + * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock + * @retval None + */ +void RCC_LSEConfig(uint8_t RCC_LSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_LSE)); + + /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ + *(__IO uint8_t *) CSR_BYTE2_ADDRESS = RCC_LSE_OFF; + + /* Set the new LSE configuration -------------------------------------------*/ + *(__IO uint8_t *) CSR_BYTE2_ADDRESS = RCC_LSE; +} + +/** + * @brief Enables or disables the Internal Low Speed oscillator (LSI). + * @note After enabling the LSI, the application software should wait on + * LSIRDY flag to be set indicating that LSI clock is stable and can + * be used to clock the IWDG and/or the RTC. + * @note LSI can not be disabled if the IWDG is running. + * @param NewState: new state of the LSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator + * clock cycles. + * @retval None + */ +void RCC_LSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the PLL clock source and multiplication factor. + * @note This function must be used only when the PLL is disabled. + * + * @param RCC_PLLSource: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLLSource_HSI: HSI oscillator clock selected as PLL clock source + * @arg RCC_PLLSource_HSE: HSE oscillator clock selected as PLL clock source + * @note The minimum input clock frequency for PLL is 2 MHz (when using HSE as + * PLL source). + * + * @param RCC_PLLMul: specifies the PLL multiplication factor, which drive the PLLVCO clock + * This parameter can be: + * @arg RCC_PLLMul_3: PLL clock source multiplied by 3 + * @arg RCC_PLLMul_4: PLL clock source multiplied by 4 + * @arg RCC_PLLMul_6: PLL clock source multiplied by 6 + * @arg RCC_PLLMul_8: PLL clock source multiplied by 8 + * @arg RCC_PLLMul_12: PLL clock source multiplied by 12 + * @arg RCC_PLLMul_16: PLL clock source multiplied by 16 + * @arg RCC_PLLMul_24: PLL clock source multiplied by 24 + * @arg RCC_PLLMul_32: PLL clock source multiplied by 32 + * @arg RCC_PLLMul_48: PLL clock source multiplied by 48 + * @note The application software must set correctly the PLL multiplication + * factor to avoid exceeding: + * - 96 MHz as PLLVCO when the product is in range 1 + * - 48 MHz as PLLVCO when the product is in range 2 + * - 24 MHz when the product is in range 3 + * @note When using the USB the PLLVCO should be 96MHz + * + * @param RCC_PLLDiv: specifies the PLL division factor. + * This parameter can be: + * @arg RCC_PLLDiv_2: PLL Clock output divided by 2 + * @arg RCC_PLLDiv_3: PLL Clock output divided by 3 + * @arg RCC_PLLDiv_4: PLL Clock output divided by 4 + * @note The application software must set correctly the output division to avoid + * exceeding 32 MHz as SYSCLK. + * + * @retval None + */ +void RCC_PLLConfig(uint8_t RCC_PLLSource, uint8_t RCC_PLLMul, uint8_t RCC_PLLDiv) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource)); + assert_param(IS_RCC_PLL_MUL(RCC_PLLMul)); + assert_param(IS_RCC_PLL_DIV(RCC_PLLDiv)); + + *(__IO uint8_t *) CFGR_BYTE3_ADDRESS = (uint8_t)(RCC_PLLSource | ((uint8_t)(RCC_PLLMul | (uint8_t)(RCC_PLLDiv)))); +} + +/** + * @brief Enables or disables the PLL. + * @note After enabling the PLL, the application software should wait on + * PLLRDY flag to be set indicating that PLL clock is stable and can + * be used as system clock source. + * @note The PLL can not be disabled if it is used as system clock source + * @note The PLL is disabled by hardware when entering STOP and STANDBY modes. + * @param NewState: new state of the PLL. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLLCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the Clock Security System. + * @note If a failure is detected on the HSE oscillator clock, this oscillator + * is automatically disabled and an interrupt is generated to inform the + * software about the failure (Clock Security System Interrupt, CSSI), + * allowing the MCU to perform rescue operations. The CSSI is linked to + * the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector. + * @param NewState: new state of the Clock Security System. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ClockSecuritySystemCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the LSE Clock Security System. + * @param NewState: new state of the Clock Security System. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_LSEClockSecuritySystemCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CSR_LSECSSON_BB = (uint32_t)NewState; +} + +/** + * @brief Selects the clock source to output on MCO pin (PA8). + * @note PA8 should be configured in alternate function mode. + * @param RCC_MCOSource: specifies the clock source to output. + * This parameter can be one of the following values: + * @arg RCC_MCOSource_NoClock: No clock selected + * @arg RCC_MCOSource_SYSCLK: System clock selected + * @arg RCC_MCOSource_HSI: HSI oscillator clock selected + * @arg RCC_MCOSource_MSI: MSI oscillator clock selected + * @arg RCC_MCOSource_HSE: HSE oscillator clock selected + * @arg RCC_MCOSource_PLLCLK: PLL clock selected + * @arg RCC_MCOSource_LSI: LSI clock selected + * @arg RCC_MCOSource_LSE: LSE clock selected + * @param RCC_MCODiv: specifies the MCO prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCODiv_1: no division applied to MCO clock + * @arg RCC_MCODiv_2: division by 2 applied to MCO clock + * @arg RCC_MCODiv_4: division by 4 applied to MCO clock + * @arg RCC_MCODiv_8: division by 8 applied to MCO clock + * @arg RCC_MCODiv_16: division by 16 applied to MCO clock + * @retval None + */ +void RCC_MCOConfig(uint8_t RCC_MCOSource, uint8_t RCC_MCODiv) +{ + /* Check the parameters */ + assert_param(IS_RCC_MCO_SOURCE(RCC_MCOSource)); + assert_param(IS_RCC_MCO_DIV(RCC_MCODiv)); + + /* Select MCO clock source and prescaler */ + *(__IO uint8_t *) CFGR_BYTE4_ADDRESS = RCC_MCOSource | RCC_MCODiv; +} + +/** + * @} + */ + +/** @defgroup RCC_Group2 System AHB and APB busses clocks configuration functions + * @brief System, AHB and APB busses clocks configuration functions + * +@verbatim + =============================================================================== + ##### System, AHB and APB busses clocks configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to configure the System, AHB, + APB1 and APB2 busses clocks. + (#) Several clock sources can be used to drive the System clock (SYSCLK): + MSI, HSI, HSE and PLL. + The AHB clock (HCLK) is derived from System clock through configurable + prescaler and used to clock the CPU, memory and peripherals mapped + on AHB bus (DMA and GPIO).APB1 (PCLK1) and APB2 (PCLK2) clocks are + derived from AHB clock through configurable prescalers and used to + clock the peripherals mapped on these busses. You can use + "RCC_GetClocksFreq()" function to retrieve the frequencies of these + clocks. + + -@- All the peripheral clocks are derived from the System clock (SYSCLK) + except: + (+@) The USB 48 MHz clock which is derived from the PLL VCO clock. + (+@) The ADC clock which is always the HSI clock. A divider by 1, 2 + or 4 allows to adapt the clock frequency to the device operating + conditions. + (+@) The RTC/LCD clock which is derived from the LSE, LSI or 1 MHz + HSE_RTC (HSE divided by a programmable prescaler). + The System clock (SYSCLK) frequency must be higher or equal to + the RTC/LCD clock frequency. + (+@) IWDG clock which is always the LSI clock. + + (#) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 32 MHz. + Depending on the device voltage range, the maximum frequency should + be adapted accordingly: + + +----------------------------------------------------------------+ + | Wait states | HCLK clock frequency (MHz) | + | |------------------------------------------------| + | (Latency) | voltage range | voltage range | + | | 1.65 V - 3.6 V | 2.0 V - 3.6 V | + | |----------------|---------------|---------------| + | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V | + |-------------- |----------------|---------------|---------------| + |0WS(1CPU cycle)|0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 | + |---------------|----------------|---------------|---------------| + |1WS(2CPU cycle)|2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32| + +----------------------------------------------------------------+ + + (#) After reset, the System clock source is the MSI (2 MHz) with 0 WS, + Flash 32-bit access is enabled and prefetch is disabled. + [..] It is recommended to use the following software sequences to tune the + number of wait states needed to access the Flash memory with the CPU + frequency (HCLK). + (+) Increasing the CPU frequency (in the same voltage range) + (+) Program the Flash 64-bit access, using "FLASH_ReadAccess64Cmd(ENABLE)" + function + (+) Check that 64-bit access is taken into account by reading FLASH_ACR + (+) Program Flash WS to 1, using "FLASH_SetLatency(FLASH_Latency_1)" + function + (+) Check that the new number of WS is taken into account by reading + FLASH_ACR + (+) Modify the CPU clock source, using "RCC_SYSCLKConfig()" function + (+) If needed, modify the CPU clock prescaler by using "RCC_HCLKConfig()" + function + (+) Check that the new CPU clock source is taken into account by reading + the clock source status, using "RCC_GetSYSCLKSource()" function + (+) Decreasing the CPU frequency (in the same voltage range) + (+) Modify the CPU clock source, using "RCC_SYSCLKConfig()" function + (+) If needed, modify the CPU clock prescaler by using "RCC_HCLKConfig()" + function + (+) Check that the new CPU clock source is taken into account by reading + the clock source status, using "RCC_GetSYSCLKSource()" function + (+) Program the new number of WS, using "FLASH_SetLatency()" function + (+) Check that the new number of WS is taken into account by reading + FLASH_ACR + (+) Enable the Flash 32-bit access, using "FLASH_ReadAccess64Cmd(DISABLE)" + function + (+) Check that 32-bit access is taken into account by reading FLASH_ACR + +@endverbatim + * @{ + */ + +/** + * @brief Configures the system clock (SYSCLK). + * @note The MSI is used (enabled by hardware) as system clock source after + * startup from Reset, wake-up from STOP and STANDBY mode, or in case + * of failure of the HSE used directly or indirectly as system clock + * (if the Clock Security System CSS is enabled). + * @note A switch from one clock source to another occurs only if the target + * clock source is ready (clock stable after startup delay or PLL locked). + * If a clock source which is not yet ready is selected, the switch will + * occur when the clock source will be ready. + * You can use RCC_GetSYSCLKSource() function to know which clock is + * currently used as system clock source. + * @param RCC_SYSCLKSource: specifies the clock source used as system clock source + * This parameter can be one of the following values: + * @arg RCC_SYSCLKSource_MSI: MSI selected as system clock source + * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock source + * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock source + * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock source + * @retval None + */ +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource)); + + tmpreg = RCC->CFGR; + + /* Clear SW[1:0] bits */ + tmpreg &= ~RCC_CFGR_SW; + + /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ + tmpreg |= RCC_SYSCLKSource; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Returns the clock source used as system clock. + * @param None + * @retval The clock source used as system clock. The returned value can be one + * of the following values: + * - 0x00: MSI used as system clock + * - 0x04: HSI used as system clock + * - 0x08: HSE used as system clock + * - 0x0C: PLL used as system clock + */ +uint8_t RCC_GetSYSCLKSource(void) +{ + return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS)); +} + +/** + * @brief Configures the AHB clock (HCLK). + * @note Depending on the device voltage range, the software has to set correctly + * these bits to ensure that the system frequency does not exceed the + * maximum allowed frequency (for more details refer to section above + * "CPU, AHB and APB busses clocks configuration functions") + * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from + * the system clock (SYSCLK). + * This parameter can be one of the following values: + * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK + * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2 + * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4 + * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8 + * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16 + * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64 + * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128 + * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256 + * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512 + * @retval None + */ +void RCC_HCLKConfig(uint32_t RCC_SYSCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_HCLK(RCC_SYSCLK)); + + tmpreg = RCC->CFGR; + + /* Clear HPRE[3:0] bits */ + tmpreg &= ~RCC_CFGR_HPRE; + + /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ + tmpreg |= RCC_SYSCLK; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the Low Speed APB clock (PCLK1). + * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_Div1: APB1 clock = HCLK + * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2 + * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4 + * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8 + * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16 + * @retval None + */ +void RCC_PCLK1Config(uint32_t RCC_HCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK)); + + tmpreg = RCC->CFGR; + + /* Clear PPRE1[2:0] bits */ + tmpreg &= ~RCC_CFGR_PPRE1; + + /* Set PPRE1[2:0] bits according to RCC_HCLK value */ + tmpreg |= RCC_HCLK; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the High Speed APB clock (PCLK2). + * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_Div1: APB2 clock = HCLK + * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2 + * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4 + * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8 + * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16 + * @retval None + */ +void RCC_PCLK2Config(uint32_t RCC_HCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK)); + + tmpreg = RCC->CFGR; + + /* Clear PPRE2[2:0] bits */ + tmpreg &= ~RCC_CFGR_PPRE2; + + /* Set PPRE2[2:0] bits according to RCC_HCLK value */ + tmpreg |= RCC_HCLK << 3; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Returns the frequencies of the System, AHB and APB busses clocks. + * @note The frequency returned by this function is not the real frequency + * in the chip. It is calculated based on the predefined constant and + * the source selected by RCC_SYSCLKConfig(): + * + * @note If SYSCLK source is MSI, function returns values based on MSI + * Value as defined by the MSI range, refer to RCC_MSIRangeConfig() + * + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * + * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) + * + * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature, refer to RCC_AdjustHSICalibrationValue(). + * + * (**) HSE_VALUE is a constant defined in stm32l1xx.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * return wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold + * the clocks frequencies. + * + * @note This function can be used by the user application to compute the + * baudrate for the communication peripherals or configure other parameters. + * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function + * must be called to update the structure's field. Otherwise, any + * configuration based on this function will be incorrect. + * + * @retval None + */ +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) +{ + uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, presc = 0, msirange = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* MSI used as system clock */ + msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13; + RCC_Clocks->SYSCLK_Frequency = (32768 * (1 << (msirange + 1))); + break; + case 0x04: /* HSI used as system clock */ + RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; + break; + case 0x08: /* HSE used as system clock */ + RCC_Clocks->SYSCLK_Frequency = HSE_VALUE; + break; + case 0x0C: /* PLL used as system clock */ + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; + plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; + pllmul = PLLMulTable[(pllmul >> 18)]; + plldiv = (plldiv >> 22) + 1; + + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + + if (pllsource == 0x00) + { + /* HSI oscillator clock selected as PLL clock source */ + RCC_Clocks->SYSCLK_Frequency = (((HSI_VALUE) * pllmul) / plldiv); + } + else + { + /* HSE selected as PLL clock source */ + RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE) * pllmul) / plldiv); + } + break; + default: /* MSI used as system clock */ + msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13; + RCC_Clocks->SYSCLK_Frequency = (32768 * (1 << (msirange + 1))); + break; + } + /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/ + /* Get HCLK prescaler */ + tmp = RCC->CFGR & RCC_CFGR_HPRE; + tmp = tmp >> 4; + presc = APBAHBPrescTable[tmp]; + /* HCLK clock frequency */ + RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc; + + /* Get PCLK1 prescaler */ + tmp = RCC->CFGR & RCC_CFGR_PPRE1; + tmp = tmp >> 8; + presc = APBAHBPrescTable[tmp]; + /* PCLK1 clock frequency */ + RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc; + + /* Get PCLK2 prescaler */ + tmp = RCC->CFGR & RCC_CFGR_PPRE2; + tmp = tmp >> 11; + presc = APBAHBPrescTable[tmp]; + /* PCLK2 clock frequency */ + RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc; +} + +/** + * @} + */ + +/** @defgroup RCC_Group3 Peripheral clocks configuration functions + * @brief Peripheral clocks configuration functions + * +@verbatim + =============================================================================== + ##### Peripheral clocks configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to configure the Peripheral clocks. + (#) The RTC/LCD clock which is derived from the LSE, LSI or 1 MHz HSE_RTC + (HSE divided by a programmable prescaler). + (#) After restart from Reset or wakeup from STANDBY, all peripherals are + off except internal SRAM, Flash and JTAG. Before to start using a + peripheral you have to enable its interface clock. You can do this + using RCC_AHBPeriphClockCmd(), RCC_APB2PeriphClockCmd() and + RCC_APB1PeriphClockCmd() functions. + + (#) To reset the peripherals configuration (to the default state after + device reset) you can use RCC_AHBPeriphResetCmd(), + RCC_APB2PeriphResetCmd() and RCC_APB1PeriphResetCmd() functions. + (#) To further reduce power consumption in SLEEP mode the peripheral + clocks can be disabled prior to executing the WFI or WFE instructions. + You can do this using RCC_AHBPeriphClockLPModeCmd(), + RCC_APB2PeriphClockLPModeCmd() and RCC_APB1PeriphClockLPModeCmd() + functions. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the RTC and LCD clock (RTCCLK / LCDCLK). + * @note As the RTC clock configuration bits are in the RTC domain and write + * access is denied to this domain after reset, you have to enable write + * access using PWR_RTCAccessCmd(ENABLE) function before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it can't be changed unless the RTC + * is reset using RCC_RTCResetCmd function, or by a Power On Reset (POR) + * @note The RTC clock (RTCCLK) is used also to clock the LCD (LCDCLK). + * + * @param RCC_RTCCLKSource: specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock + * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock + * @arg RCC_RTCCLKSource_HSE_Div2: HSE divided by 2 selected as RTC clock + * @arg RCC_RTCCLKSource_HSE_Div4: HSE divided by 4 selected as RTC clock + * @arg RCC_RTCCLKSource_HSE_Div8: HSE divided by 8 selected as RTC clock + * @arg RCC_RTCCLKSource_HSE_Div16: HSE divided by 16 selected as RTC clock + * + * @note If the LSE or LSI is used as RTC clock source, the RTC continues to + * work in STOP and STANDBY modes, and can be used as wakeup source. + * However, when the HSE clock is used as RTC clock source, the RTC + * cannot be used in STOP and STANDBY modes. + * + * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as + * RTC clock source). + * + * @retval None + */ +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource)); + + if ((RCC_RTCCLKSource & RCC_CSR_RTCSEL_HSE) == RCC_CSR_RTCSEL_HSE) + { + /* If HSE is selected as RTC clock source, configure HSE division factor for RTC clock */ + tmpreg = RCC->CR; + + /* Clear RTCPRE[1:0] bits */ + tmpreg &= ~RCC_CR_RTCPRE; + + /* Configure HSE division factor for RTC clock */ + tmpreg |= (RCC_RTCCLKSource & RCC_CR_RTCPRE); + + /* Store the new value */ + RCC->CR = tmpreg; + } + + RCC->CSR &= ~RCC_CSR_RTCSEL; + + /* Select the RTC clock source */ + RCC->CSR |= (RCC_RTCCLKSource & RCC_CSR_RTCSEL); +} + +/** + * @brief Enables or disables the RTC clock. + * @note This function must be used only after the RTC clock source was selected + * using the RCC_RTCCLKConfig function. + * @param NewState: new state of the RTC clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_RTCCLKCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CSR_RTCEN_BB = (uint32_t)NewState; +} + +/** + * @brief Forces or releases the RTC peripheral and associated resources reset. + * @note This function resets the RTC peripheral, RTC clock source selection + * (in RCC_CSR) and the backup registers. + * @param NewState: new state of the RTC reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_RTCResetCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CSR_RTCRST_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the AHB peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHBPeriph_GPIOA: GPIOA clock + * @arg RCC_AHBPeriph_GPIOB: GPIOB clock + * @arg RCC_AHBPeriph_GPIOC: GPIOC clock + * @arg RCC_AHBPeriph_GPIOD: GPIOD clock + * @arg RCC_AHBPeriph_GPIOE: GPIOE clock + * @arg RCC_AHBPeriph_GPIOH: GPIOH clock + * @arg RCC_AHBPeriph_GPIOF: GPIOF clock + * @arg RCC_AHBPeriph_GPIOG: GPIOG clock + * @arg RCC_AHBPeriph_CRC: CRC clock + * @arg RCC_AHBPeriph_FLITF: (has effect only when the Flash memory is in power down mode) + * @arg RCC_AHBPeriph_DMA1: DMA1 clock + * @arg RCC_AHBPeriph_DMA2: DMA2 clock + * @arg RCC_AHBPeriph_AES: AES clock + * @arg RCC_AHBPeriph_FSMC: FSMC clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHBENR |= RCC_AHBPeriph; + } + else + { + RCC->AHBENR &= ~RCC_AHBPeriph; + } +} + +/** + * @brief Enables or disables the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_SYSCFG: SYSCFG APB2 Clock. + * @arg RCC_APB2Periph_TIM9: TIM9 APB2 Clock. + * @arg RCC_APB2Periph_TIM10: TIM10 APB2 Clock. + * @arg RCC_APB2Periph_TIM11: TIM11 APB2 Clock. + * @arg RCC_APB2Periph_ADC1: ADC1 APB2 Clock. + * @arg RCC_APB2Periph_SDIO: SDIO APB2 Clock. + * @arg RCC_APB2Periph_SPI1: SPI1 APB2 Clock. + * @arg RCC_APB2Periph_USART1: USART1 APB2 Clock. + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB2ENR |= RCC_APB2Periph; + } + else + { + RCC->APB2ENR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Enables or disables the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_LCD: LCD clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_USB: USB clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @arg RCC_APB1Periph_COMP COMP clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB1ENR |= RCC_APB1Periph; + } + else + { + RCC->APB1ENR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Forces or releases AHB peripheral reset. + * @param RCC_AHBPeriph: specifies the AHB peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHBPeriph_GPIOA: GPIOA clock + * @arg RCC_AHBPeriph_GPIOB: GPIOB clock + * @arg RCC_AHBPeriph_GPIOC: GPIOC clock + * @arg RCC_AHBPeriph_GPIOD: GPIOD clock + * @arg RCC_AHBPeriph_GPIOE: GPIOE clock + * @arg RCC_AHBPeriph_GPIOH: GPIOH clock + * @arg RCC_AHBPeriph_GPIOF: GPIOF clock + * @arg RCC_AHBPeriph_GPIOG: GPIOG clock + * @arg RCC_AHBPeriph_CRC: CRC clock + * @arg RCC_AHBPeriph_FLITF: (has effect only when the Flash memory is in power down mode) + * @arg RCC_AHBPeriph_DMA1: DMA1 clock + * @arg RCC_AHBPeriph_DMA2: DMA2 clock + * @arg RCC_AHBPeriph_AES: AES clock + * @arg RCC_AHBPeriph_FSMC: FSMC clock + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHBRSTR |= RCC_AHBPeriph; + } + else + { + RCC->AHBRSTR &= ~RCC_AHBPeriph; + } +} + +/** + * @brief Forces or releases High Speed APB (APB2) peripheral reset. + * @param RCC_APB2Periph: specifies the APB2 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @arg RCC_APB2Periph_ADC1: ADC1 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB2RSTR |= RCC_APB2Periph; + } + else + { + RCC->APB2RSTR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Forces or releases Low Speed APB (APB1) peripheral reset. + * @param RCC_APB1Periph: specifies the APB1 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_LCD: LCD clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_USB: USB clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @arg RCC_APB1Periph_COMP + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB1RSTR |= RCC_APB1Periph; + } + else + { + RCC->APB1RSTR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Enables or disables the AHB peripheral clock during SLEEP mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * - After wakeup from SLEEP mode, the peripheral clock is enabled again. + * - By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHBPeriph_GPIOA: GPIOA clock + * @arg RCC_AHBPeriph_GPIOB: GPIOB clock + * @arg RCC_AHBPeriph_GPIOC: GPIOC clock + * @arg RCC_AHBPeriph_GPIOD: GPIOD clock + * @arg RCC_AHBPeriph_GPIOE: GPIOE clock + * @arg RCC_AHBPeriph_GPIOH: GPIOH clock + * @arg RCC_AHBPeriph_GPIOF: GPIOF clock + * @arg RCC_AHBPeriph_GPIOG: GPIOG clock + * @arg RCC_AHBPeriph_CRC: CRC clock + * @arg RCC_AHBPeriph_FLITF: (has effect only when the Flash memory is in power down mode) + * @arg RCC_AHBPeriph_SRAM: SRAM clock + * @arg RCC_AHBPeriph_DMA1: DMA1 clock + * @arg RCC_AHBPeriph_DMA2: DMA2 clock + * @arg RCC_AHBPeriph_AES: AES clock + * @arg RCC_AHBPeriph_FSMC: FSMC clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHBPeriphClockLPModeCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB_LPMODE_PERIPH(RCC_AHBPeriph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHBLPENR |= RCC_AHBPeriph; + } + else + { + RCC->AHBLPENR &= ~RCC_AHBPeriph; + } +} + +/** + * @brief Enables or disables the APB2 peripheral clock during SLEEP mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @arg RCC_APB2Periph_ADC1: ADC1 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB2LPENR |= RCC_APB2Periph; + } + else + { + RCC->APB2LPENR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Enables or disables the APB1 peripheral clock during SLEEP mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_LCD: LCD clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_USB: USB clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @arg RCC_APB1Periph_COMP: COMP clock + * @param NewState: new state + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB1LPENR |= RCC_APB1Periph; + } + else + { + RCC->APB1LPENR &= ~RCC_APB1Periph; + } +} + +/** + * @} + */ + +/** @defgroup RCC_Group4 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified RCC interrupts. + * @note The CSS interrupt doesn't have an enable bit; once the CSS is enabled + * and if the HSE clock fails, the CSS interrupt occurs and an NMI is + * automatically generated. The NMI will be executed indefinitely, and + * since NMI has higher priority than any other IRQ (and main program) + * the application will be stacked in the NMI ISR unless the CSS interrupt + * pending bit is cleared. + * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * @arg RCC_IT_MSIRDY: MSI ready interrupt + * @arg RCC_IT_LSECSS: LSE CSS interrupt + * @param NewState: new state of the specified RCC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_IT(RCC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Perform Byte access to RCC_CIR[12:8] bits to enable the selected interrupts */ + *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT; + } + else + { + /* Perform Byte access to RCC_CIR[12:8] bits to disable the selected interrupts */ + *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT; + } +} + +/** + * @brief Checks whether the specified RCC flag is set or not. + * @param RCC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready + * @arg RCC_FLAG_MSIRDY: MSI oscillator clock ready + * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready + * @arg RCC_FLAG_PLLRDY: PLL clock ready + * @arg RCC_FLAG_LSECSS: LSE oscillator clock CSS detected + * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready + * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready + * @arg RCC_FLAG_OBLRST: Option Byte Loader (OBL) reset + * @arg RCC_FLAG_PINRST: Pin reset + * @arg RCC_FLAG_PORRST: POR/PDR reset + * @arg RCC_FLAG_SFTRST: Software reset + * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset + * @arg RCC_FLAG_WWDGRST: Window Watchdog reset + * @arg RCC_FLAG_LPWRRST: Low Power reset + * @retval The new state of RCC_FLAG (SET or RESET). + */ +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) +{ + uint32_t tmp = 0; + uint32_t statusreg = 0; + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_FLAG(RCC_FLAG)); + + /* Get the RCC register index */ + tmp = RCC_FLAG >> 5; + + if (tmp == 1) /* The flag to check is in CR register */ + { + statusreg = RCC->CR; + } + else /* The flag to check is in CSR register (tmp == 2) */ + { + statusreg = RCC->CSR; + } + + /* Get the flag position */ + tmp = RCC_FLAG & FLAG_MASK; + + if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the RCC reset flags. + * The reset flags are: RCC_FLAG_OBLRST, RCC_FLAG_PINRST, RCC_FLAG_PORRST, + * RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST. + * @param None + * @retval None + */ +void RCC_ClearFlag(void) +{ + /* Set RMVF bit to clear the reset flags */ + RCC->CSR |= RCC_CSR_RMVF; +} + +/** + * @brief Checks whether the specified RCC interrupt has occurred or not. + * @param RCC_IT: specifies the RCC interrupt source to check. + * This parameter can be one of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * @arg RCC_IT_MSIRDY: MSI ready interrupt + * @arg RCC_IT_LSECSS: LSE CSS interrupt + * @arg RCC_IT_CSS: Clock Security System interrupt + * @retval The new state of RCC_IT (SET or RESET). + */ +ITStatus RCC_GetITStatus(uint8_t RCC_IT) +{ + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_RCC_GET_IT(RCC_IT)); + + /* Check the status of the specified RCC interrupt */ + if ((RCC->CIR & RCC_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the RCC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the RCC's interrupt pending bits. + * @param RCC_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * @arg RCC_IT_MSIRDY: MSI ready interrupt + * @arg RCC_IT_LSECSS: LSE CSS interrupt + * @arg RCC_IT_CSS: Clock Security System interrupt + * @retval None + */ +void RCC_ClearITPendingBit(uint8_t RCC_IT) +{ + /* Check the parameters */ + assert_param(IS_RCC_CLEAR_IT(RCC_IT)); + + /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt + pending bits */ + *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rcc.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rcc.h new file mode 100644 index 0000000000..7f85fa8455 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rcc.h @@ -0,0 +1,488 @@ +/** + ****************************************************************************** + * @file stm32l1xx_rcc.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the RCC + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_RCC_H +#define __STM32L1xx_RCC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +typedef struct +{ + uint32_t SYSCLK_Frequency; + uint32_t HCLK_Frequency; + uint32_t PCLK1_Frequency; + uint32_t PCLK2_Frequency; +}RCC_ClocksTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Constants + * @{ + */ + +/** @defgroup RCC_HSE_configuration + * @{ + */ + +#define RCC_HSE_OFF ((uint8_t)0x00) +#define RCC_HSE_ON ((uint8_t)0x01) +#define RCC_HSE_Bypass ((uint8_t)0x05) +#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \ + ((HSE) == RCC_HSE_Bypass)) + +/** + * @} + */ + +/** @defgroup RCC_MSI_Clock_Range + * @{ + */ + +#define RCC_MSIRange_0 RCC_ICSCR_MSIRANGE_0 /*!< MSI = 65.536 KHz */ +#define RCC_MSIRange_1 RCC_ICSCR_MSIRANGE_1 /*!< MSI = 131.072 KHz */ +#define RCC_MSIRange_2 RCC_ICSCR_MSIRANGE_2 /*!< MSI = 262.144 KHz */ +#define RCC_MSIRange_3 RCC_ICSCR_MSIRANGE_3 /*!< MSI = 524.288 KHz */ +#define RCC_MSIRange_4 RCC_ICSCR_MSIRANGE_4 /*!< MSI = 1.048 MHz */ +#define RCC_MSIRange_5 RCC_ICSCR_MSIRANGE_5 /*!< MSI = 2.097 MHz */ +#define RCC_MSIRange_6 RCC_ICSCR_MSIRANGE_6 /*!< MSI = 4.194 MHz */ + +#define IS_RCC_MSI_CLOCK_RANGE(RANGE) (((RANGE) == RCC_MSIRange_0) || \ + ((RANGE) == RCC_MSIRange_1) || \ + ((RANGE) == RCC_MSIRange_2) || \ + ((RANGE) == RCC_MSIRange_3) || \ + ((RANGE) == RCC_MSIRange_4) || \ + ((RANGE) == RCC_MSIRange_5) || \ + ((RANGE) == RCC_MSIRange_6)) + +/** + * @} + */ + +/** @defgroup RCC_PLL_Clock_Source + * @{ + */ + +#define RCC_PLLSource_HSI ((uint8_t)0x00) +#define RCC_PLLSource_HSE ((uint8_t)0x01) + +#define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI) || \ + ((SOURCE) == RCC_PLLSource_HSE)) +/** + * @} + */ + +/** @defgroup RCC_PLL_Multiplication_Factor + * @{ + */ + +#define RCC_PLLMul_3 ((uint8_t)0x00) +#define RCC_PLLMul_4 ((uint8_t)0x04) +#define RCC_PLLMul_6 ((uint8_t)0x08) +#define RCC_PLLMul_8 ((uint8_t)0x0C) +#define RCC_PLLMul_12 ((uint8_t)0x10) +#define RCC_PLLMul_16 ((uint8_t)0x14) +#define RCC_PLLMul_24 ((uint8_t)0x18) +#define RCC_PLLMul_32 ((uint8_t)0x1C) +#define RCC_PLLMul_48 ((uint8_t)0x20) + + +#define IS_RCC_PLL_MUL(MUL) (((MUL) == RCC_PLLMul_3) || ((MUL) == RCC_PLLMul_4) || \ + ((MUL) == RCC_PLLMul_6) || ((MUL) == RCC_PLLMul_8) || \ + ((MUL) == RCC_PLLMul_12) || ((MUL) == RCC_PLLMul_16) || \ + ((MUL) == RCC_PLLMul_24) || ((MUL) == RCC_PLLMul_32) || \ + ((MUL) == RCC_PLLMul_48)) +/** + * @} + */ + +/** @defgroup RCC_PLL_Divider_Factor + * @{ + */ + +#define RCC_PLLDiv_2 ((uint8_t)0x40) +#define RCC_PLLDiv_3 ((uint8_t)0x80) +#define RCC_PLLDiv_4 ((uint8_t)0xC0) + + +#define IS_RCC_PLL_DIV(DIV) (((DIV) == RCC_PLLDiv_2) || ((DIV) == RCC_PLLDiv_3) || \ + ((DIV) == RCC_PLLDiv_4)) +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source + * @{ + */ + +#define RCC_SYSCLKSource_MSI RCC_CFGR_SW_MSI +#define RCC_SYSCLKSource_HSI RCC_CFGR_SW_HSI +#define RCC_SYSCLKSource_HSE RCC_CFGR_SW_HSE +#define RCC_SYSCLKSource_PLLCLK RCC_CFGR_SW_PLL +#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_MSI) || \ + ((SOURCE) == RCC_SYSCLKSource_HSI) || \ + ((SOURCE) == RCC_SYSCLKSource_HSE) || \ + ((SOURCE) == RCC_SYSCLKSource_PLLCLK)) +/** + * @} + */ + +/** @defgroup RCC_AHB_Clock_Source + * @{ + */ + +#define RCC_SYSCLK_Div1 RCC_CFGR_HPRE_DIV1 +#define RCC_SYSCLK_Div2 RCC_CFGR_HPRE_DIV2 +#define RCC_SYSCLK_Div4 RCC_CFGR_HPRE_DIV4 +#define RCC_SYSCLK_Div8 RCC_CFGR_HPRE_DIV8 +#define RCC_SYSCLK_Div16 RCC_CFGR_HPRE_DIV16 +#define RCC_SYSCLK_Div64 RCC_CFGR_HPRE_DIV64 +#define RCC_SYSCLK_Div128 RCC_CFGR_HPRE_DIV128 +#define RCC_SYSCLK_Div256 RCC_CFGR_HPRE_DIV256 +#define RCC_SYSCLK_Div512 RCC_CFGR_HPRE_DIV512 +#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \ + ((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \ + ((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \ + ((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \ + ((HCLK) == RCC_SYSCLK_Div512)) +/** + * @} + */ + +/** @defgroup RCC_APB1_APB2_Clock_Source + * @{ + */ + +#define RCC_HCLK_Div1 RCC_CFGR_PPRE1_DIV1 +#define RCC_HCLK_Div2 RCC_CFGR_PPRE1_DIV2 +#define RCC_HCLK_Div4 RCC_CFGR_PPRE1_DIV4 +#define RCC_HCLK_Div8 RCC_CFGR_PPRE1_DIV8 +#define RCC_HCLK_Div16 RCC_CFGR_PPRE1_DIV16 +#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \ + ((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \ + ((PCLK) == RCC_HCLK_Div16)) +/** + * @} + */ + + +/** @defgroup RCC_Interrupt_Source + * @{ + */ + +#define RCC_IT_LSIRDY ((uint8_t)0x01) +#define RCC_IT_LSERDY ((uint8_t)0x02) +#define RCC_IT_HSIRDY ((uint8_t)0x04) +#define RCC_IT_HSERDY ((uint8_t)0x08) +#define RCC_IT_PLLRDY ((uint8_t)0x10) +#define RCC_IT_MSIRDY ((uint8_t)0x20) +#define RCC_IT_LSECSS ((uint8_t)0x40) +#define RCC_IT_CSS ((uint8_t)0x80) + +#define IS_RCC_IT(IT) ((((IT) & (uint8_t)0x80) == 0x00) && ((IT) != 0x00)) + +#define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ + ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ + ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_MSIRDY) || \ + ((IT) == RCC_IT_CSS) || ((IT) == RCC_IT_LSECSS)) + +#define IS_RCC_CLEAR_IT(IT) ((((IT) & (uint8_t)0x00) == 0x00) && ((IT) != 0x00)) + +/** + * @} + */ + +/** @defgroup RCC_LSE_Configuration + * @{ + */ + +#define RCC_LSE_OFF ((uint8_t)0x00) +#define RCC_LSE_ON ((uint8_t)0x01) +#define RCC_LSE_Bypass ((uint8_t)0x05) +#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ + ((LSE) == RCC_LSE_Bypass)) +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_Source + * @{ + */ + +#define RCC_RTCCLKSource_LSE RCC_CSR_RTCSEL_LSE +#define RCC_RTCCLKSource_LSI RCC_CSR_RTCSEL_LSI +#define RCC_RTCCLKSource_HSE_Div2 RCC_CSR_RTCSEL_HSE +#define RCC_RTCCLKSource_HSE_Div4 ((uint32_t)RCC_CSR_RTCSEL_HSE | RCC_CR_RTCPRE_0) +#define RCC_RTCCLKSource_HSE_Div8 ((uint32_t)RCC_CSR_RTCSEL_HSE | RCC_CR_RTCPRE_1) +#define RCC_RTCCLKSource_HSE_Div16 ((uint32_t)RCC_CSR_RTCSEL_HSE | RCC_CR_RTCPRE) +#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \ + ((SOURCE) == RCC_RTCCLKSource_LSI) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div2) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div4) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div8) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div16)) +/** + * @} + */ + +/** @defgroup RCC_AHB_Peripherals + * @{ + */ + +#define RCC_AHBPeriph_GPIOA RCC_AHBENR_GPIOAEN +#define RCC_AHBPeriph_GPIOB RCC_AHBENR_GPIOBEN +#define RCC_AHBPeriph_GPIOC RCC_AHBENR_GPIOCEN +#define RCC_AHBPeriph_GPIOD RCC_AHBENR_GPIODEN +#define RCC_AHBPeriph_GPIOE RCC_AHBENR_GPIOEEN +#define RCC_AHBPeriph_GPIOH RCC_AHBENR_GPIOHEN +#define RCC_AHBPeriph_GPIOF RCC_AHBENR_GPIOFEN +#define RCC_AHBPeriph_GPIOG RCC_AHBENR_GPIOGEN +#define RCC_AHBPeriph_CRC RCC_AHBENR_CRCEN +#define RCC_AHBPeriph_FLITF RCC_AHBENR_FLITFEN +#define RCC_AHBPeriph_SRAM RCC_AHBLPENR_SRAMLPEN +#define RCC_AHBPeriph_DMA1 RCC_AHBENR_DMA1EN +#define RCC_AHBPeriph_DMA2 RCC_AHBENR_DMA2EN +#define RCC_AHBPeriph_AES RCC_AHBENR_AESEN +#define RCC_AHBPeriph_FSMC RCC_AHBENR_FSMCEN + +#define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xB4FF6F00) == 0x00) && ((PERIPH) != 0x00)) +#define IS_RCC_AHB_LPMODE_PERIPH(PERIPH) ((((PERIPH) & 0xB4FF6F00) == 0x00) && ((PERIPH) != 0x00)) + +/** + * @} + */ + +/** @defgroup RCC_APB2_Peripherals + * @{ + */ + +#define RCC_APB2Periph_SYSCFG RCC_APB2ENR_SYSCFGEN +#define RCC_APB2Periph_TIM9 RCC_APB2ENR_TIM9EN +#define RCC_APB2Periph_TIM10 RCC_APB2ENR_TIM10EN +#define RCC_APB2Periph_TIM11 RCC_APB2ENR_TIM11EN +#define RCC_APB2Periph_ADC1 RCC_APB2ENR_ADC1EN +#define RCC_APB2Periph_SDIO RCC_APB2ENR_SDIOEN +#define RCC_APB2Periph_SPI1 RCC_APB2ENR_SPI1EN +#define RCC_APB2Periph_USART1 RCC_APB2ENR_USART1EN + +#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFA5E2) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup RCC_APB1_Peripherals + * @{ + */ + +#define RCC_APB1Periph_TIM2 RCC_APB1ENR_TIM2EN +#define RCC_APB1Periph_TIM3 RCC_APB1ENR_TIM3EN +#define RCC_APB1Periph_TIM4 RCC_APB1ENR_TIM4EN +#define RCC_APB1Periph_TIM5 RCC_APB1ENR_TIM5EN +#define RCC_APB1Periph_TIM6 RCC_APB1ENR_TIM6EN +#define RCC_APB1Periph_TIM7 RCC_APB1ENR_TIM7EN +#define RCC_APB1Periph_LCD RCC_APB1ENR_LCDEN +#define RCC_APB1Periph_WWDG RCC_APB1ENR_WWDGEN +#define RCC_APB1Periph_SPI2 RCC_APB1ENR_SPI2EN +#define RCC_APB1Periph_SPI3 RCC_APB1ENR_SPI3EN +#define RCC_APB1Periph_USART2 RCC_APB1ENR_USART2EN +#define RCC_APB1Periph_USART3 RCC_APB1ENR_USART3EN +#define RCC_APB1Periph_UART4 RCC_APB1ENR_UART4EN +#define RCC_APB1Periph_UART5 RCC_APB1ENR_UART5EN +#define RCC_APB1Periph_I2C1 RCC_APB1ENR_I2C1EN +#define RCC_APB1Periph_I2C2 RCC_APB1ENR_I2C2EN +#define RCC_APB1Periph_USB RCC_APB1ENR_USBEN +#define RCC_APB1Periph_PWR RCC_APB1ENR_PWREN +#define RCC_APB1Periph_DAC RCC_APB1ENR_DACEN +#define RCC_APB1Periph_COMP RCC_APB1ENR_COMPEN + + +#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x4F0135C0) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup RCC_MCO_Clock_Source + * @{ + */ + +#define RCC_MCOSource_NoClock ((uint8_t)0x00) +#define RCC_MCOSource_SYSCLK ((uint8_t)0x01) +#define RCC_MCOSource_HSI ((uint8_t)0x02) +#define RCC_MCOSource_MSI ((uint8_t)0x03) +#define RCC_MCOSource_HSE ((uint8_t)0x04) +#define RCC_MCOSource_PLLCLK ((uint8_t)0x05) +#define RCC_MCOSource_LSI ((uint8_t)0x06) +#define RCC_MCOSource_LSE ((uint8_t)0x07) + +#define IS_RCC_MCO_SOURCE(SOURCE) (((SOURCE) == RCC_MCOSource_NoClock) || ((SOURCE) == RCC_MCOSource_SYSCLK) || \ + ((SOURCE) == RCC_MCOSource_HSI) || ((SOURCE) == RCC_MCOSource_MSI) || \ + ((SOURCE) == RCC_MCOSource_HSE) || ((SOURCE) == RCC_MCOSource_PLLCLK) || \ + ((SOURCE) == RCC_MCOSource_LSI) || ((SOURCE) == RCC_MCOSource_LSE)) +/** + * @} + */ + +/** @defgroup RCC_MCO_Output_Divider + * @{ + */ + +#define RCC_MCODiv_1 ((uint8_t)0x00) +#define RCC_MCODiv_2 ((uint8_t)0x10) +#define RCC_MCODiv_4 ((uint8_t)0x20) +#define RCC_MCODiv_8 ((uint8_t)0x30) +#define RCC_MCODiv_16 ((uint8_t)0x40) + +#define IS_RCC_MCO_DIV(DIV) (((DIV) == RCC_MCODiv_1) || ((DIV) == RCC_MCODiv_2) || \ + ((DIV) == RCC_MCODiv_4) || ((DIV) == RCC_MCODiv_8) || \ + ((DIV) == RCC_MCODiv_16)) +/** + * @} + */ + +/** @defgroup RCC_Flag + * @{ + */ + +#define RCC_FLAG_HSIRDY ((uint8_t)0x21) +#define RCC_FLAG_MSIRDY ((uint8_t)0x29) +#define RCC_FLAG_HSERDY ((uint8_t)0x31) +#define RCC_FLAG_PLLRDY ((uint8_t)0x39) +#define RCC_FLAG_LSERDY ((uint8_t)0x49) +#define RCC_FLAG_LSECSS ((uint8_t)0x4A) +#define RCC_FLAG_LSIRDY ((uint8_t)0x41) +#define RCC_FLAG_OBLRST ((uint8_t)0x59) +#define RCC_FLAG_PINRST ((uint8_t)0x5A) +#define RCC_FLAG_PORRST ((uint8_t)0x5B) +#define RCC_FLAG_SFTRST ((uint8_t)0x5C) +#define RCC_FLAG_IWDGRST ((uint8_t)0x5D) +#define RCC_FLAG_WWDGRST ((uint8_t)0x5E) +#define RCC_FLAG_LPWRRST ((uint8_t)0x5F) + +#define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ + ((FLAG) == RCC_FLAG_MSIRDY) || ((FLAG) == RCC_FLAG_PLLRDY) || \ + ((FLAG) == RCC_FLAG_LSERDY) || ((FLAG) == RCC_FLAG_LSIRDY) || \ + ((FLAG) == RCC_FLAG_PINRST) || ((FLAG) == RCC_FLAG_PORRST) || \ + ((FLAG) == RCC_FLAG_SFTRST) || ((FLAG) == RCC_FLAG_IWDGRST)|| \ + ((FLAG) == RCC_FLAG_WWDGRST)|| ((FLAG) == RCC_FLAG_LPWRRST)|| \ + ((FLAG) == RCC_FLAG_WWDGRST)|| ((FLAG) == RCC_FLAG_LSECSS)) + +#define IS_RCC_HSI_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F) +#define IS_RCC_MSI_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x3F) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the RCC clock configuration to the default reset state */ +void RCC_DeInit(void); + +/* Internal/external clocks, PLL, CSS and MCO configuration functions *********/ +void RCC_HSEConfig(uint8_t RCC_HSE); +ErrorStatus RCC_WaitForHSEStartUp(void); +void RCC_MSIRangeConfig(uint32_t RCC_MSIRange); +void RCC_AdjustMSICalibrationValue(uint8_t MSICalibrationValue); +void RCC_MSICmd(FunctionalState NewState); +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); +void RCC_HSICmd(FunctionalState NewState); +void RCC_LSEConfig(uint8_t RCC_LSE); +void RCC_LSICmd(FunctionalState NewState); +void RCC_PLLConfig(uint8_t RCC_PLLSource, uint8_t RCC_PLLMul, uint8_t RCC_PLLDiv); +void RCC_PLLCmd(FunctionalState NewState); +void RCC_ClockSecuritySystemCmd(FunctionalState NewState); +void RCC_LSEClockSecuritySystemCmd(FunctionalState NewState); +void RCC_MCOConfig(uint8_t RCC_MCOSource, uint8_t RCC_MCODiv); + +/* System, AHB and APB busses clocks configuration functions ******************/ +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); +uint8_t RCC_GetSYSCLKSource(void); +void RCC_HCLKConfig(uint32_t RCC_SYSCLK); +void RCC_PCLK1Config(uint32_t RCC_HCLK); +void RCC_PCLK2Config(uint32_t RCC_HCLK); +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); + +/* Peripheral clocks configuration functions **********************************/ +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); +void RCC_RTCCLKCmd(FunctionalState NewState); +void RCC_RTCResetCmd(FunctionalState NewState); + +void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); + +void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); + +void RCC_AHBPeriphClockLPModeCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); +void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); +void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); +void RCC_ClearFlag(void); +ITStatus RCC_GetITStatus(uint8_t RCC_IT); +void RCC_ClearITPendingBit(uint8_t RCC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_RCC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rtc.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rtc.c new file mode 100644 index 0000000000..d853c3aeec --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rtc.c @@ -0,0 +1,2675 @@ +/** + ****************************************************************************** + * @file stm32l1xx_rtc.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Real-Time Clock (RTC) peripheral: + * + Initialization + * + Calendar (Time and Date) configuration + * + Alarms (Alarm A and Alarm B) configuration + * + WakeUp Timer configuration + * + Daylight Saving configuration + * + Output pin Configuration + * + Coarse digital Calibration configuration + * + Smooth digital Calibration configuration + * + TimeStamp configuration + * + Tampers configuration + * + Backup Data Registers configuration + * + Output Type Config configuration + * + Shift control synchronisation + * + Interrupts and flags management + * + @verbatim + + =============================================================================== + ##### RTC Domain Reset ##### + =============================================================================== + [..] After power-on reset, the RTC domain (RTC clock source configuration, + RTC registers and RTC Backup data registers) is reset. You can also + reset this domain by software using the RCC_RTCResetCmd() function. + + ##### RTC Operating Condition ##### + =============================================================================== + [..] As long as the supply voltage remains in the operating range, + the RTC never stops, regardless of the device status (Run mode, + low power modes or under reset). + + ##### RTC Domain Access ##### + =============================================================================== + [..] After reset, the RTC domain (RTC clock source configuration, + RTC registers and RTC Backup data registers) are protected against + possible stray write accesses. + [..] To enable access to the RTC Domain and RTC registers, proceed as follows: + (+) Enable the Power Controller (PWR) APB1 interface clock using the + RCC_APB1PeriphClockCmd() function. + (+) Enable access to RTC domain using the PWR_RTCAccessCmd() function. + (+) Select the RTC clock source using the RCC_RTCCLKConfig() function. + (+) Enable RTC Clock using the RCC_RTCCLKCmd() function. + + ##### How to use this driver ##### + =============================================================================== + [..] + (+) Enable the RTC domain access (see description in the section above) + (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and + RTC hour format using the RTC_Init() function. + ***Time and Date configuration *** + ================================== + [..] + (+) To configure the RTC Calendar (Time and Date) use the RTC_SetTime() + and RTC_SetDate() functions. + (+) To read the RTC Calendar, use the RTC_GetTime() and RTC_GetDate() + functions. + (+) To read the RTC subsecond, use the RTC_GetSubSecond() function. + (+) Use the RTC_DayLightSavingConfig() function to add or sub one + hour to the RTC Calendar. + + ***Alarm configuration *** + ========================== + [..] + (+) To configure the RTC Alarm use the RTC_SetAlarm() function. + (+) Enable the selected RTC Alarm using the RTC_AlarmCmd() function + (+) To read the RTC Alarm, use the RTC_GetAlarm() function. + (+) To read the RTC alarm SubSecond, use the RTC_GetAlarmSubSecond() function. + + ***RTC Wakeup configuration *** + =============================== + [..] + (+) Configure the RTC Wakeup Clock source use the RTC_WakeUpClockConfig() + function. + (+) Configure the RTC WakeUp Counter using the RTC_SetWakeUpCounter() + function. + (+) Enable the RTC WakeUp using the RTC_WakeUpCmd() function + (+) To read the RTC WakeUp Counter register, use the RTC_GetWakeUpCounter() + function. + + ***Outputs configuration *** + ============================ + [..] The RTC has 2 different outputs: + (+) AFO_ALARM: this output is used to manage the RTC Alarm A, Alarm B + and WaKeUp signals. + To output the selected RTC signal on RTC_AF1 pin, use the + RTC_OutputConfig() function. + (+) AFO_CALIB: this output is 512Hz signal or 1Hz. + To output the RTC Clock on RTC_AF1 pin, use the RTC_CalibOutputCmd() + function. + + ***Smooth digital Calibration configuration *** + =============================================== + [..] + (+) Configure the RTC Original Digital Calibration Value and the corresponding + calibration cycle period (32s,16s and 8s) using the RTC_SmoothCalibConfig() + function. + + ***Coarse digital Calibration configuration *** + =============================================== + [..] + (+) Configure the RTC Coarse Calibration Value and the corresponding + sign using the RTC_CoarseCalibConfig() function. + (+) Enable the RTC Coarse Calibration using the RTC_CoarseCalibCmd() + function. + + ***TimeStamp configuration *** + ============================== + [..] + (+) Configure the RTC_AF1 trigger and enables the RTC TimeStamp + using the RTC_TimeStampCmd() function. + (+) To read the RTC TimeStamp Time and Date register, use the + RTC_GetTimeStamp() function. + (+) To read the RTC TimeStamp SubSecond register, use the + RTC_GetTimeStampSubSecond() function. + + ***Tamper configuration *** + =========================== + [..] + (+) Configure the Tamper filter count using RTC_TamperFilterConfig() + function. + (+) Configure the RTC Tamper trigger Edge or Level according to the Tamper + filter (if equal to 0 Edge else Level) value using the RTC_TamperConfig() + function. + (+) Configure the Tamper sampling frequency using RTC_TamperSamplingFreqConfig() + function. + (+) Configure the Tamper precharge or discharge duration using + RTC_TamperPinsPrechargeDuration() function. + (+) Enable the Tamper Pull-UP using RTC_TamperPullUpDisableCmd() function. + (+) Enable the RTC Tamper using the RTC_TamperCmd() function. + (+) Enable the Time stamp on Tamper detection event using + RTC_TSOnTamperDetecCmd() function. + + ***Backup Data Registers configuration *** + ========================================== + [..] + (+) To write to the RTC Backup Data registers, use the RTC_WriteBackupRegister() + function. + (+) To read the RTC Backup Data registers, use the RTC_ReadBackupRegister() + function. + + ##### RTC and low power modes ##### + =============================================================================== + [..] The MCU can be woken up from a low power mode by an RTC alternate + function. + [..] The RTC alternate functions are the RTC alarms (Alarm A and Alarm B), + RTC wakeup, RTC tamper event detection and RTC time stamp event detection. + These RTC alternate functions can wake up the system from the Stop + and Standby lowpower modes. + The system can also wake up from low power modes without depending + on an external interrupt (Auto-wakeup mode), by using the RTC alarm + or the RTC wakeup events. + [..] The RTC provides a programmable time base for waking up from the + Stop or Standby mode at regular intervals. + Wakeup from STOP and Standby modes is possible only when the RTC + clock source is LSE or LSI. + + ##### Selection of RTC_AF1 alternate functions ##### + =============================================================================== + [..] The RTC_AF1 pin (PC13) can be used for the following purposes: + (+) Wakeup pin 2 (WKUP2) using the PWR_WakeUpPinCmd() function. + (+) AFO_ALARM output. + (+) AFO_CALIB output. + (+) AFI_TAMPER. + (+) AFI_TIMESTAMP. + + +------------------------------------------------------------------------------------------+ + | Pin |AFO_ALARM |AFO_CALIB |AFI_TAMPER |AFI_TIMESTAMP | WKUP2 |ALARMOUTTYPE | + | configuration | ENABLED | ENABLED | ENABLED | ENABLED |ENABLED | AFO_ALARM | + | and function | | | | | |Configuration | + |-----------------|----------|----------|-----------|--------------|--------|--------------| + | Alarm out | | | | | Don't | | + | output OD | 1 | 0 |Don't care | Don't care | care | 0 | + |-----------------|----------|----------|-----------|--------------|--------|--------------| + | Alarm out | | | | | Don't | | + | output PP | 1 | 0 |Don't care | Don't care | care | 1 | + |-----------------|----------|----------|-----------|--------------|--------|--------------| + | Calibration out | | | | | Don't | | + | output PP | 0 | 1 |Don't care | Don't care | care | Don't care | + |-----------------|----------|----------|-----------|--------------|--------|--------------| + | TAMPER input | | | | | Don't | | + | floating | 0 | 0 | 1 | 0 | care | Don't care | + |-----------------|----------|----------|-----------|--------------|--------|--------------| + | TIMESTAMP and | | | | | Don't | | + | TAMPER input | 0 | 0 | 1 | 1 | care | Don't care | + | floating | | | | | | | + |-----------------|----------|----------|-----------|--------------|--------|--------------| + | TIMESTAMP input | | | | | Don't | | + | floating | 0 | 0 | 0 | 1 | care | Don't care | + |-----------------|----------|----------|-----------|--------------|--------|--------------| + | Wakeup Pin 2 | 0 | 0 | 0 | 0 | 1 | Don't care | + |-----------------|----------|----------|-----------|--------------|--------|--------------| + | Standard GPIO | 0 | 0 | 0 | 0 | 0 | Don't care | + +------------------------------------------------------------------------------------------+ + + @endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_rtc.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup RTC + * @brief RTC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* Masks Definition */ +#define RTC_TR_RESERVED_MASK ((uint32_t)0x007F7F7F) +#define RTC_DR_RESERVED_MASK ((uint32_t)0x00FFFF3F) +#define RTC_INIT_MASK ((uint32_t)0xFFFFFFFF) +#define RTC_RSF_MASK ((uint32_t)0xFFFFFF5F) +#define RTC_FLAGS_MASK ((uint32_t)(RTC_FLAG_TSOVF | RTC_FLAG_TSF | RTC_FLAG_WUTF | \ + RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_INITF | \ + RTC_FLAG_RSF | RTC_FLAG_INITS | RTC_FLAG_WUTWF | \ + RTC_FLAG_ALRBWF | RTC_FLAG_ALRAWF | RTC_FLAG_TAMP1F | \ + RTC_FLAG_TAMP2F | RTC_FLAG_TAMP3F | RTC_FLAG_RECALPF | \ + RTC_FLAG_SHPF)) + +#define INITMODE_TIMEOUT ((uint32_t) 0x00002000) +#define SYNCHRO_TIMEOUT ((uint32_t) 0x00008000) +#define RECALPF_TIMEOUT ((uint32_t) 0x00001000) +#define SHPF_TIMEOUT ((uint32_t) 0x00002000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static uint8_t RTC_ByteToBcd2(uint8_t Value); +static uint8_t RTC_Bcd2ToByte(uint8_t Value); + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RTC_Private_Functions + * @{ + */ + +/** @defgroup RTC_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to initialize and configure the + RTC Prescaler (Synchronous and Asynchronous), RTC Hour format, disable + RTC registers Write protection, enter and exit the RTC initialization mode, + RTC registers synchronization check and reference clock detection enable. + (#) The RTC Prescaler is programmed to generate the RTC 1Hz time base. + It is split into 2 programmable prescalers to minimize power consumption. + (++) A 7-bit asynchronous prescaler and A 13-bit synchronous prescaler. + (++) When both prescalers are used, it is recommended to configure the + asynchronous prescaler to a high value to minimize consumption. + (#) All RTC registers are Write protected. Writing to the RTC registers + is enabled by writing a key into the Write Protection register, RTC_WPR. + (#) To Configure the RTC Calendar, user application should enter + initialization mode. In this mode, the calendar counter is stopped + and its value can be updated. When the initialization sequence is + complete, the calendar restarts counting after 4 RTCCLK cycles. + (#) To read the calendar through the shadow registers after Calendar + initialization, calendar update or after wakeup from low power modes + the software must first clear the RSF flag. The software must then + wait until it is set again before reading the calendar, which means + that the calendar registers have been correctly copied into the + RTC_TR and RTC_DR shadow registers.The RTC_WaitForSynchro() function + implements the above software sequence (RSF clear and RSF check). + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the RTC registers to their default reset values. + * @note This function doesn't reset the RTC Clock source and RTC Backup Data + * registers. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are deinitialized + * - ERROR: RTC registers are not deinitialized + */ +ErrorStatus RTC_DeInit(void) +{ + __IO uint32_t wutcounter = 0x00; + uint32_t wutwfstatus = 0x00; + ErrorStatus status = ERROR; + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Reset TR, DR and CR registers */ + RTC->TR = (uint32_t)0x00000000; + RTC->DR = (uint32_t)0x00002101; + + /* Reset All CR bits except CR[2:0] */ + RTC->CR &= (uint32_t)0x00000007; + + /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ + do + { + wutwfstatus = RTC->ISR & RTC_ISR_WUTWF; + wutcounter++; + } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_WUTWF) == RESET) + { + status = ERROR; + } + else + { + /* Reset all RTC CR register bits */ + RTC->CR &= (uint32_t)0x00000000; + RTC->WUTR = (uint32_t)0x0000FFFF; + RTC->PRER = (uint32_t)0x007F00FF; + RTC->CALIBR = (uint32_t)0x00000000; + RTC->ALRMAR = (uint32_t)0x00000000; + RTC->ALRMBR = (uint32_t)0x00000000; + RTC->SHIFTR = (uint32_t)0x00000000; + RTC->CALR = (uint32_t)0x00000000; + RTC->ALRMASSR = (uint32_t)0x00000000; + RTC->ALRMBSSR = (uint32_t)0x00000000; + + /* Reset ISR register and exit initialization mode */ + RTC->ISR = (uint32_t)0x00000000; + + /* Reset Tamper and alternate functions configuration register */ + RTC->TAFCR = 0x00000000; + + /* Wait till the RTC RSF flag is set */ + if (RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Initializes the RTC registers according to the specified parameters + * in RTC_InitStruct. + * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure that contains + * the configuration information for the RTC peripheral. + * @note The RTC Prescaler register is write protected and can be written in + * initialization mode only. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are initialized + * - ERROR: RTC registers are not initialized + */ +ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_HOUR_FORMAT(RTC_InitStruct->RTC_HourFormat)); + assert_param(IS_RTC_ASYNCH_PREDIV(RTC_InitStruct->RTC_AsynchPrediv)); + assert_param(IS_RTC_SYNCH_PREDIV(RTC_InitStruct->RTC_SynchPrediv)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Clear RTC CR FMT Bit */ + RTC->CR &= ((uint32_t)~(RTC_CR_FMT)); + /* Set RTC_CR register */ + RTC->CR |= ((uint32_t)(RTC_InitStruct->RTC_HourFormat)); + + /* Configure the RTC PRER */ + RTC->PRER = (uint32_t)(RTC_InitStruct->RTC_SynchPrediv); + RTC->PRER |= (uint32_t)(RTC_InitStruct->RTC_AsynchPrediv << 16); + + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + status = SUCCESS; + } + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Fills each RTC_InitStruct member with its default value. + * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure which will be + * initialized. + * @retval None + */ +void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct) +{ + /* Initialize the RTC_HourFormat member */ + RTC_InitStruct->RTC_HourFormat = RTC_HourFormat_24; + + /* Initialize the RTC_AsynchPrediv member */ + RTC_InitStruct->RTC_AsynchPrediv = (uint32_t)0x7F; + + /* Initialize the RTC_SynchPrediv member */ + RTC_InitStruct->RTC_SynchPrediv = (uint32_t)0xFF; +} + +/** + * @brief Enables or disables the RTC registers write protection. + * @note All the RTC registers are write protected except for RTC_ISR[13:8], + * RTC_TAFCR and RTC_BKPxR. + * @note Writing a wrong key reactivates the write protection. + * @note The protection mechanism is not affected by system reset. + * @param NewState: new state of the write protection. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_WriteProtectionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + } + else + { + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + } +} + +/** + * @brief Enters the RTC Initialization mode. + * @note The RTC Initialization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) before calling this function. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC is in Init mode + * - ERROR: RTC is not in Init mode + */ +ErrorStatus RTC_EnterInitMode(void) +{ + __IO uint32_t initcounter = 0x00; + ErrorStatus status = ERROR; + uint32_t initstatus = 0x00; + + /* Check if the Initialization mode is set */ + if ((RTC->ISR & RTC_ISR_INITF) == (uint32_t)RESET) + { + /* Set the Initialization mode */ + RTC->ISR = (uint32_t)RTC_INIT_MASK; + + /* Wait till RTC is in INIT state and if Time out is reached exit */ + do + { + initstatus = RTC->ISR & RTC_ISR_INITF; + initcounter++; + } while((initcounter != INITMODE_TIMEOUT) && (initstatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_INITF) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + } + else + { + status = SUCCESS; + } + + return (status); +} + +/** + * @brief Exits the RTC Initialization mode. + * @note When the initialization sequence is complete, the calendar restarts + * counting after 4 RTCCLK cycles. + * @note The RTC Initialization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) before calling this function. + * @param None + * @retval None + */ +void RTC_ExitInitMode(void) +{ + /* Exit Initialization mode */ + RTC->ISR &= (uint32_t)~RTC_ISR_INIT; +} + +/** + * @brief Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * @note The RTC Resynchronization mode is write protected, use the + * RTC_WriteProtectionCmd(DISABLE) before calling this function. + * @note To read the calendar through the shadow registers after Calendar + * initialization, calendar update or after wakeup from low power modes + * the software must first clear the RSF flag. + * The software must then wait until it is set again before reading + * the calendar, which means that the calendar registers have been + * correctly copied into the RTC_TR and RTC_DR shadow registers. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are synchronised + * - ERROR: RTC registers are not synchronised + */ +ErrorStatus RTC_WaitForSynchro(void) +{ + __IO uint32_t synchrocounter = 0; + ErrorStatus status = ERROR; + uint32_t synchrostatus = 0x00; + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear RSF flag */ + RTC->ISR &= (uint32_t)RTC_RSF_MASK; + + /* Wait the registers to be synchronised */ + do + { + synchrostatus = RTC->ISR & RTC_ISR_RSF; + synchrocounter++; + } while((synchrocounter != SYNCHRO_TIMEOUT) && (synchrostatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_RSF) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return (status); +} + +/** + * @brief Enables or disables the RTC reference clock detection. + * @param NewState: new state of the RTC reference clock. + * This parameter can be: ENABLE or DISABLE. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC reference clock detection is enabled + * - ERROR: RTC reference clock detection is disabled + */ +ErrorStatus RTC_RefClockCmd(FunctionalState NewState) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + if (NewState != DISABLE) + { + /* Enable the RTC reference clock detection */ + RTC->CR |= RTC_CR_REFCKON; + } + else + { + /* Disable the RTC reference clock detection */ + RTC->CR &= ~RTC_CR_REFCKON; + } + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + status = SUCCESS; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Enables or Disables the Bypass Shadow feature. + * @note When the Bypass Shadow is enabled the calendar value are taken + * directly from the Calendar counter. + * @param NewState: new state of the Bypass Shadow feature. + * This parameter can be: ENABLE or DISABLE. + * @retval None +*/ +void RTC_BypassShadowCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + if (NewState != DISABLE) + { + /* Set the BYPSHAD bit */ + RTC->CR |= (uint8_t)RTC_CR_BYPSHAD; + } + else + { + /* Reset the BYPSHAD bit */ + RTC->CR &= (uint8_t)~RTC_CR_BYPSHAD; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @} + */ + +/** @defgroup RTC_Group2 Time and Date configuration functions + * @brief Time and Date configuration functions + * +@verbatim + =============================================================================== + ##### Time and Date configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to program and read the RTC + Calendar (Time and Date). + +@endverbatim + * @{ + */ + +/** + * @brief Set the RTC current time. + * @param RTC_Format: specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format. + * @arg RTC_Format_BCD: BCD data format. + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that contains + * the time configuration information for the RTC. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Time register is configured + * - ERROR: RTC Time register is not configured + */ +ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) +{ + uint32_t tmpreg = 0; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + if (RTC_Format == RTC_Format_BIN) + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + assert_param(IS_RTC_HOUR12(RTC_TimeStruct->RTC_Hours)); + assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); + } + else + { + RTC_TimeStruct->RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_TimeStruct->RTC_Hours)); + } + assert_param(IS_RTC_MINUTES(RTC_TimeStruct->RTC_Minutes)); + assert_param(IS_RTC_SECONDS(RTC_TimeStruct->RTC_Seconds)); + } + else + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + tmpreg = RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); + } + else + { + RTC_TimeStruct->RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours))); + } + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds))); + } + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + tmpreg = (((uint32_t)(RTC_TimeStruct->RTC_Hours) << 16) | \ + ((uint32_t)(RTC_TimeStruct->RTC_Minutes) << 8) | \ + ((uint32_t)RTC_TimeStruct->RTC_Seconds) | \ + ((uint32_t)(RTC_TimeStruct->RTC_H12) << 16)); + } + else + { + tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Seconds)) | \ + (((uint32_t)RTC_TimeStruct->RTC_H12) << 16)); + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Set the RTC_TR register */ + RTC->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK); + + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if ((RTC->CR & RTC_CR_BYPSHAD) == RESET) + { + if (RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else + { + status = SUCCESS; + } + + } + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Fills each RTC_TimeStruct member with its default value + * (Time = 00h:00min:00sec). + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure which will be + * initialized. + * @retval None + */ +void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct) +{ + /* Time = 00h:00min:00sec */ + RTC_TimeStruct->RTC_H12 = RTC_H12_AM; + RTC_TimeStruct->RTC_Hours = 0; + RTC_TimeStruct->RTC_Minutes = 0; + RTC_TimeStruct->RTC_Seconds = 0; +} + +/** + * @brief Get the RTC current Time. + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format. + * @arg RTC_Format_BCD: BCD data format. + * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that will + * contain the returned current time configuration. + * @retval None + */ +void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the RTC_TR register */ + tmpreg = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + RTC_TimeStruct->RTC_Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); + RTC_TimeStruct->RTC_Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); + RTC_TimeStruct->RTC_Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); + RTC_TimeStruct->RTC_H12 = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); + + /* Check the input parameters format */ + if (RTC_Format == RTC_Format_BIN) + { + /* Convert the structure parameters to Binary format */ + RTC_TimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); + RTC_TimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes); + RTC_TimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds); + } +} + +/** + * @brief Gets the RTC current Calendar Subseconds value. + * @note This function freeze the Time and Date registers after reading the + * SSR register. + * @param None + * @retval RTC current Calendar Subseconds value. + */ +uint32_t RTC_GetSubSecond(void) +{ + uint32_t tmpreg = 0; + + /* Get subseconds values from the correspondent registers*/ + tmpreg = (uint32_t)(RTC->SSR); + + /* Read DR register to unfroze calendar registers */ + (void) (RTC->DR); + + return (tmpreg); +} + +/** + * @brief Set the RTC current date. + * @param RTC_Format: specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format. + * @arg RTC_Format_BCD: BCD data format. + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains + * the date configuration information for the RTC. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Date register is configured + * - ERROR: RTC Date register is not configured + */ +ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) +{ + uint32_t tmpreg = 0; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + if ((RTC_Format == RTC_Format_BIN) && ((RTC_DateStruct->RTC_Month & 0x10) == 0x10)) + { + RTC_DateStruct->RTC_Month = (RTC_DateStruct->RTC_Month & (uint32_t)~(0x10)) + 0x0A; + } + if (RTC_Format == RTC_Format_BIN) + { + assert_param(IS_RTC_YEAR(RTC_DateStruct->RTC_Year)); + assert_param(IS_RTC_MONTH(RTC_DateStruct->RTC_Month)); + assert_param(IS_RTC_DATE(RTC_DateStruct->RTC_Date)); + } + else + { + assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year))); + tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); + assert_param(IS_RTC_MONTH(tmpreg)); + tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); + assert_param(IS_RTC_DATE(tmpreg)); + } + assert_param(IS_RTC_WEEKDAY(RTC_DateStruct->RTC_WeekDay)); + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + tmpreg = ((((uint32_t)RTC_DateStruct->RTC_Year) << 16) | \ + (((uint32_t)RTC_DateStruct->RTC_Month) << 8) | \ + ((uint32_t)RTC_DateStruct->RTC_Date) | \ + (((uint32_t)RTC_DateStruct->RTC_WeekDay) << 13)); + } + else + { + tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Year) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Month) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Date)) | \ + ((uint32_t)RTC_DateStruct->RTC_WeekDay << 13)); + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Set the RTC_DR register */ + RTC->DR = (uint32_t)(tmpreg & RTC_DR_RESERVED_MASK); + + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if ((RTC->CR & RTC_CR_BYPSHAD) == RESET) + { + if (RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else + { + status = SUCCESS; + } + } + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Fills each RTC_DateStruct member with its default value + * (Monday, January 01 xx00). + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure which will be + * initialized. + * @retval None + */ +void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct) +{ + /* Monday, January 01 xx00 */ + RTC_DateStruct->RTC_WeekDay = RTC_Weekday_Monday; + RTC_DateStruct->RTC_Date = 1; + RTC_DateStruct->RTC_Month = RTC_Month_January; + RTC_DateStruct->RTC_Year = 0; +} + +/** + * @brief Get the RTC current date. + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format. + * @arg RTC_Format_BCD: BCD data format. + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that will + * contain the returned current date configuration. + * @retval None + */ +void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the RTC_TR register */ + tmpreg = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + RTC_DateStruct->RTC_Year = (uint8_t)((tmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); + RTC_DateStruct->RTC_Month = (uint8_t)((tmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); + RTC_DateStruct->RTC_Date = (uint8_t)(tmpreg & (RTC_DR_DT | RTC_DR_DU)); + RTC_DateStruct->RTC_WeekDay = (uint8_t)((tmpreg & (RTC_DR_WDU)) >> 13); + + /* Check the input parameters format */ + if (RTC_Format == RTC_Format_BIN) + { + /* Convert the structure parameters to Binary format */ + RTC_DateStruct->RTC_Year = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year); + RTC_DateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); + RTC_DateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); + } +} + +/** + * @} + */ + +/** @defgroup RTC_Group3 Alarms configuration functions + * @brief Alarms (Alarm A and Alarm B) configuration functions + * +@verbatim + =============================================================================== + ##### Alarms (Alarm A and Alarm B) configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to program and read the RTC + Alarms. + +@endverbatim + * @{ + */ + +/** + * @brief Set the specified RTC Alarm. + * @note The Alarm register can only be written when the corresponding Alarm + * is disabled (Use the RTC_AlarmCmd(DISABLE)). + * @param RTC_Format: specifies the format of the returned parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format. + * @arg RTC_Format_BCD: BCD data format. + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A. + * @arg RTC_Alarm_B: to select Alarm B. + * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that + * contains the alarm configuration parameters. + * @retval None + */ +void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + assert_param(IS_RTC_ALARM(RTC_Alarm)); + assert_param(IS_ALARM_MASK(RTC_AlarmStruct->RTC_AlarmMask)); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel)); + + if (RTC_Format == RTC_Format_BIN) + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + assert_param(IS_RTC_HOUR12(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); + assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); + } + else + { + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); + } + assert_param(IS_RTC_MINUTES(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes)); + assert_param(IS_RTC_SECONDS(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)); + + if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); + } + else + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); + } + } + else + { + if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours); + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); + } + else + { + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours))); + } + + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds))); + + if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) + { + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg)); + } + else + { + tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg)); + } + } + + /* Check the input parameters format */ + if (RTC_Format != RTC_Format_BIN) + { + tmpreg = (((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); + } + else + { + tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)) | \ + ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ + ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Alarm register */ + if (RTC_Alarm == RTC_Alarm_A) + { + RTC->ALRMAR = (uint32_t)tmpreg; + } + else + { + RTC->ALRMBR = (uint32_t)tmpreg; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Fills each RTC_AlarmStruct member with its default value + * (Time = 00h:00mn:00sec / Date = 1st day of the month/Mask = + * all fields are masked). + * @param RTC_AlarmStruct: pointer to a @ref RTC_AlarmTypeDef structure which + * will be initialized. + * @retval None + */ +void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + /* Alarm Time Settings : Time = 00h:00mn:00sec */ + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = RTC_H12_AM; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = 0; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = 0; + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = 0; + + /* Alarm Date Settings : Date = 1st day of the month */ + RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; + RTC_AlarmStruct->RTC_AlarmDateWeekDay = 1; + + /* Alarm Masks Settings : Mask = all fields are not masked */ + RTC_AlarmStruct->RTC_AlarmMask = RTC_AlarmMask_None; +} + +/** + * @brief Get the RTC Alarm value and masks. + * @param RTC_Format: specifies the format of the output parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format. + * @arg RTC_Format_BCD: BCD data format. + * @param RTC_Alarm: specifies the alarm to be read. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A. + * @arg RTC_Alarm_B: to select Alarm B. + * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that will + * contains the output alarm configuration values. + * @retval None + */ +void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + assert_param(IS_RTC_ALARM(RTC_Alarm)); + + /* Get the RTC_ALRMxR register */ + if (RTC_Alarm == RTC_Alarm_A) + { + tmpreg = (uint32_t)(RTC->ALRMAR); + } + else + { + tmpreg = (uint32_t)(RTC->ALRMBR); + } + + /* Fill the structure with the read parameters */ + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = (uint32_t)((tmpreg & (RTC_ALRMAR_HT | \ + RTC_ALRMAR_HU)) >> 16); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = (uint32_t)((tmpreg & (RTC_ALRMAR_MNT | \ + RTC_ALRMAR_MNU)) >> 8); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = (uint32_t)(tmpreg & (RTC_ALRMAR_ST | \ + RTC_ALRMAR_SU)); + RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = (uint32_t)((tmpreg & RTC_ALRMAR_PM) >> 16); + RTC_AlarmStruct->RTC_AlarmDateWeekDay = (uint32_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24); + RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL); + RTC_AlarmStruct->RTC_AlarmMask = (uint32_t)(tmpreg & RTC_AlarmMask_All); + + if (RTC_Format == RTC_Format_BIN) + { + RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ + RTC_AlarmTime.RTC_Hours); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ + RTC_AlarmTime.RTC_Minutes); + RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ + RTC_AlarmTime.RTC_Seconds); + RTC_AlarmStruct->RTC_AlarmDateWeekDay = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); + } +} + +/** + * @brief Enables or disables the specified RTC Alarm. + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be any combination of the following values: + * @arg RTC_Alarm_A: to select Alarm A. + * @arg RTC_Alarm_B: to select Alarm B. + * @param NewState: new state of the specified alarm. + * This parameter can be: ENABLE or DISABLE. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Alarm is enabled/disabled + * - ERROR: RTC Alarm is not enabled/disabled + */ +ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState) +{ + __IO uint32_t alarmcounter = 0x00; + uint32_t alarmstatus = 0x00; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_CMD_ALARM(RTC_Alarm)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Alarm state */ + if (NewState != DISABLE) + { + RTC->CR |= (uint32_t)RTC_Alarm; + + status = SUCCESS; + } + else + { + /* Disable the Alarm in RTC_CR register */ + RTC->CR &= (uint32_t)~RTC_Alarm; + + /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */ + do + { + alarmstatus = RTC->ISR & (RTC_Alarm >> 8); + alarmcounter++; + } while((alarmcounter != INITMODE_TIMEOUT) && (alarmstatus == 0x00)); + + if ((RTC->ISR & (RTC_Alarm >> 8)) == RESET) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Configure the RTC AlarmA/B Subseconds value and mask.* + * @note This function is performed only when the Alarm is disabled. + * @param RTC_Alarm: specifies the alarm to be configured. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A. + * @arg RTC_Alarm_B: to select Alarm B. + * @param RTC_AlarmSubSecondValue: specifies the Subseconds value. + * This parameter can be a value from 0 to 0x00007FFF. + * @param RTC_AlarmSubSecondMask: specifies the Subseconds Mask. + * This parameter can be any combination of the following values: + * @arg RTC_AlarmSubSecondMask_All: All Alarm SS fields are masked. + * There is no comparison on sub seconds for Alarm. + * @arg RTC_AlarmSubSecondMask_SS14_1: SS[14:1] are don't care in Alarm comparison. + * Only SS[0] is compared + * @arg RTC_AlarmSubSecondMask_SS14_2: SS[14:2] are don't care in Alarm comparison. + * Only SS[1:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_3: SS[14:3] are don't care in Alarm comparison. + * Only SS[2:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_4: SS[14:4] are don't care in Alarm comparison. + * Only SS[3:0] are compared + * @arg RTC_AlarmSubSecondMask_SS14_5: SS[14:5] are don't care in Alarm comparison. + * Only SS[4:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14_6: SS[14:6] are don't care in Alarm comparison. + * Only SS[5:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14_7: SS[14:7] are don't care in Alarm comparison. + * Only SS[6:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14_8: SS[14:8] are don't care in Alarm comparison. + * Only SS[7:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14_9: SS[14:9] are don't care in Alarm comparison. + * Only SS[8:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14_10: SS[14:10] are don't care in Alarm comparison. + * Only SS[9:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14_11: SS[14:11] are don't care in Alarm comparison. + * Only SS[10:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14_12: SS[14:12] are don't care in Alarm comparison. + * Only SS[11:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14_13: SS[14:13] are don't care in Alarm comparison. + * Only SS[12:0] are compared. + * @arg RTC_AlarmSubSecondMask_SS14: SS[14] is don't care in Alarm comparison. + * Only SS[13:0] are compared. + * @arg RTC_AlarmSubSecondMask_None: SS[14:0] are compared and must match + * to activate alarm. + * @retval None + */ +void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_ALARM(RTC_Alarm)); + assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(RTC_AlarmSubSecondValue)); + assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(RTC_AlarmSubSecondMask)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Alarm A or Alarm B SubSecond registers */ + tmpreg = (uint32_t) (uint32_t)(RTC_AlarmSubSecondValue) | (uint32_t)(RTC_AlarmSubSecondMask); + + if (RTC_Alarm == RTC_Alarm_A) + { + /* Configure the AlarmA SubSecond register */ + RTC->ALRMASSR = tmpreg; + } + else + { + /* Configure the Alarm B SubSecond register */ + RTC->ALRMBSSR = tmpreg; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + +} + +/** + * @brief Gets the RTC Alarm Subseconds value. + * @param RTC_Alarm: specifies the alarm to be read. + * This parameter can be one of the following values: + * @arg RTC_Alarm_A: to select Alarm A. + * @arg RTC_Alarm_B: to select Alarm B. + * @param None + * @retval RTC Alarm Subseconds value. + */ +uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm) +{ + uint32_t tmpreg = 0; + + /* Get the RTC_ALRMxR register */ + if (RTC_Alarm == RTC_Alarm_A) + { + tmpreg = (uint32_t)((RTC->ALRMASSR) & RTC_ALRMASSR_SS); + } + else + { + tmpreg = (uint32_t)((RTC->ALRMBSSR) & RTC_ALRMBSSR_SS); + } + + return (tmpreg); +} + +/** + * @} + */ + +/** @defgroup RTC_Group4 WakeUp Timer configuration functions + * @brief WakeUp Timer configuration functions + * +@verbatim + =============================================================================== + ##### WakeUp Timer configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to program and read the RTC WakeUp. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the RTC Wakeup clock source. + * @note The WakeUp Clock source can only be changed when the RTC WakeUp + * is disabled (Use the RTC_WakeUpCmd(DISABLE)). + * @param RTC_WakeUpClock: Wakeup Clock source. + * This parameter can be one of the following values: + * @arg RTC_WakeUpClock_RTCCLK_Div16: RTC Wakeup Counter Clock = RTCCLK/16. + * @arg RTC_WakeUpClock_RTCCLK_Div8: RTC Wakeup Counter Clock = RTCCLK/8. + * @arg RTC_WakeUpClock_RTCCLK_Div4: RTC Wakeup Counter Clock = RTCCLK/4. + * @arg RTC_WakeUpClock_RTCCLK_Div2: RTC Wakeup Counter Clock = RTCCLK/2. + * @arg RTC_WakeUpClock_CK_SPRE_16bits: RTC Wakeup Counter Clock = CK_SPRE. + * @arg RTC_WakeUpClock_CK_SPRE_17bits: RTC Wakeup Counter Clock = CK_SPRE. + * @retval None + */ +void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock) +{ + /* Check the parameters */ + assert_param(IS_RTC_WAKEUP_CLOCK(RTC_WakeUpClock)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear the Wakeup Timer clock source bits in CR register */ + RTC->CR &= (uint32_t)~RTC_CR_WUCKSEL; + + /* Configure the clock source */ + RTC->CR |= (uint32_t)RTC_WakeUpClock; + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Configures the RTC Wakeup counter. + * @note The RTC WakeUp counter can only be written when the RTC WakeUp. + * is disabled (Use the RTC_WakeUpCmd(DISABLE)). + * @param RTC_WakeUpCounter: specifies the WakeUp counter. + * This parameter can be a value from 0x0000 to 0xFFFF. + * @retval None + */ +void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter) +{ + /* Check the parameters */ + assert_param(IS_RTC_WAKEUP_COUNTER(RTC_WakeUpCounter)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Wakeup Timer counter */ + RTC->WUTR = (uint32_t)RTC_WakeUpCounter; + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Returns the RTC WakeUp timer counter value. + * @param None + * @retval The RTC WakeUp Counter value. + */ +uint32_t RTC_GetWakeUpCounter(void) +{ + /* Get the counter value */ + return ((uint32_t)(RTC->WUTR & RTC_WUTR_WUT)); +} + +/** + * @brief Enables or Disables the RTC WakeUp timer. + * @param NewState: new state of the WakeUp timer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +ErrorStatus RTC_WakeUpCmd(FunctionalState NewState) +{ + __IO uint32_t wutcounter = 0x00; + uint32_t wutwfstatus = 0x00; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + if (NewState != DISABLE) + { + /* Enable the Wakeup Timer */ + RTC->CR |= (uint32_t)RTC_CR_WUTE; + status = SUCCESS; + } + else + { + /* Disable the Wakeup Timer */ + RTC->CR &= (uint32_t)~RTC_CR_WUTE; + /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ + do + { + wutwfstatus = RTC->ISR & RTC_ISR_WUTWF; + wutcounter++; + } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00)); + + if ((RTC->ISR & RTC_ISR_WUTWF) == RESET) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @} + */ + +/** @defgroup RTC_Group5 Daylight Saving configuration functions + * @brief Daylight Saving configuration functions + * +@verbatim + =============================================================================== + ##### Daylight Saving configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to configure the RTC DayLight Saving. + +@endverbatim + * @{ + */ + +/** + * @brief Adds or substract one hour from the current time. + * @param RTC_DayLightSaveOperation: the value of hour adjustment. + * This parameter can be one of the following values: + * @arg RTC_DayLightSaving_SUB1H: Substract one hour (winter time). + * @arg RTC_DayLightSaving_ADD1H: Add one hour (summer time). + * @param RTC_StoreOperation: Specifies the value to be written in the BCK bit + * in CR register to store the operation. + * This parameter can be one of the following values: + * @arg RTC_StoreOperation_Reset: BCK Bit Reset. + * @arg RTC_StoreOperation_Set: BCK Bit Set. + * @retval None + */ +void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation) +{ + /* Check the parameters */ + assert_param(IS_RTC_DAYLIGHT_SAVING(RTC_DayLightSaving)); + assert_param(IS_RTC_STORE_OPERATION(RTC_StoreOperation)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear the bits to be configured */ + RTC->CR &= (uint32_t)~(RTC_CR_BCK); + + /* Configure the RTC_CR register */ + RTC->CR |= (uint32_t)(RTC_DayLightSaving | RTC_StoreOperation); + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Returns the RTC Day Light Saving stored operation. + * @param None + * @retval RTC Day Light Saving stored operation. + * - RTC_StoreOperation_Reset + * - RTC_StoreOperation_Set + */ +uint32_t RTC_GetStoreOperation(void) +{ + return (RTC->CR & RTC_CR_BCK); +} + +/** + * @} + */ + +/** @defgroup RTC_Group6 Output pin Configuration function + * @brief Output pin Configuration function + * +@verbatim + =============================================================================== + ##### Output pin Configuration function ##### + =============================================================================== + [..] This section provide functions allowing to configure the RTC Output source. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the RTC output source (AFO_ALARM). + * @param RTC_Output: Specifies which signal will be routed to the RTC output. + * This parameter can be one of the following values: + * @arg RTC_Output_Disable: No output selected + * @arg RTC_Output_AlarmA: signal of AlarmA mapped to output. + * @arg RTC_Output_AlarmB: signal of AlarmB mapped to output. + * @arg RTC_Output_WakeUp: signal of WakeUp mapped to output. + * @param RTC_OutputPolarity: Specifies the polarity of the output signal. + * This parameter can be one of the following: + * @arg RTC_OutputPolarity_High: The output pin is high when the + * ALRAF/ALRBF/WUTF is high (depending on OSEL). + * @arg RTC_OutputPolarity_Low: The output pin is low when the + * ALRAF/ALRBF/WUTF is high (depending on OSEL). + * @retval None + */ +void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity) +{ + /* Check the parameters */ + assert_param(IS_RTC_OUTPUT(RTC_Output)); + assert_param(IS_RTC_OUTPUT_POL(RTC_OutputPolarity)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Clear the bits to be configured */ + RTC->CR &= (uint32_t)~(RTC_CR_OSEL | RTC_CR_POL); + + /* Configure the output selection and polarity */ + RTC->CR |= (uint32_t)(RTC_Output | RTC_OutputPolarity); + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @} + */ + +/** @defgroup RTC_Group7 Coarse and Smooth Calibrations configuration functions + * @brief Coarse and Smooth Calibrations configuration functions + * +@verbatim + =============================================================================== + ##### Coarse and Smooth Calibrations configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the Coarse Calibration parameters. + * @param RTC_CalibSign: specifies the sign of the calibration value. + * This parameter can be one of the following values: + * @arg RTC_CalibSign_Positive: The value sign is positive. + * @arg RTC_CalibSign_Negative: The value sign is negative. + * @param Value: value of calibration expressed in ppm (coded on 5 bits) + * This value should be between 0 and 63 when using negative sign + * with a 2-ppm step. + * This value should be between 0 and 126 when using positive sign + * with a 4-ppm step. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Coarse calibration are initialized + * - ERROR: RTC Coarse calibration are not initialized + */ +ErrorStatus RTC_CoarseCalibConfig(uint32_t RTC_CalibSign, uint32_t Value) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_CALIB_SIGN(RTC_CalibSign)); + assert_param(IS_RTC_CALIB_VALUE(Value)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + /* Set the coarse calibration value */ + RTC->CALIBR = (uint32_t)(RTC_CalibSign | Value); + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + status = SUCCESS; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** +* @brief Enables or disables the Coarse calibration process. + * @param NewState: new state of the Coarse calibration. + * This parameter can be: ENABLE or DISABLE. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Coarse calibration are enabled/disabled + * - ERROR: RTC Coarse calibration are not enabled/disabled + */ +ErrorStatus RTC_CoarseCalibCmd(FunctionalState NewState) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Set Initialization mode */ + if (RTC_EnterInitMode() == ERROR) + { + status = ERROR; + } + else + { + if (NewState != DISABLE) + { + /* Enable the Coarse Calibration */ + RTC->CR |= (uint32_t)RTC_CR_DCE; + } + else + { + /* Disable the Coarse Calibration */ + RTC->CR &= (uint32_t)~RTC_CR_DCE; + } + /* Exit Initialization mode */ + RTC_ExitInitMode(); + + status = SUCCESS; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return status; +} + +/** + * @brief Enables or disables the RTC clock to be output through the relative + * pin. + * @param NewState: new state of the coarse calibration Output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_CalibOutputCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + if (NewState != DISABLE) + { + /* Enable the RTC clock output */ + RTC->CR |= (uint32_t)RTC_CR_COE; + } + else + { + /* Disable the RTC clock output */ + RTC->CR &= (uint32_t)~RTC_CR_COE; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + * @param RTC_CalibOutput : Select the Calibration output Selection . + * This parameter can be one of the following values: + * @arg RTC_CalibOutput_512Hz: A signal has a regular waveform at 512Hz. + * @arg RTC_CalibOutput_1Hz: A signal has a regular waveform at 1Hz. + * @retval None +*/ +void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput) +{ + /* Check the parameters */ + assert_param(IS_RTC_CALIB_OUTPUT(RTC_CalibOutput)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /*clear flags before config*/ + RTC->CR &= (uint32_t)~(RTC_CR_COSEL); + + /* Configure the RTC_CR register */ + RTC->CR |= (uint32_t)RTC_CalibOutput; + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Configures the Smooth Calibration Settings. + * @param RTC_SmoothCalibPeriod: Select the Smooth Calibration Period. + * This parameter can be can be one of the following values: + * @arg RTC_SmoothCalibPeriod_32sec: The smooth calibration periode is 32s. + * @arg RTC_SmoothCalibPeriod_16sec: The smooth calibration periode is 16s. + * @arg RTC_SmoothCalibPeriod_8sec: The smooth calibartion periode is 8s. + * @param RTC_SmoothCalibPlusPulses: Select to Set or reset the CALP bit. + * This parameter can be one of the following values: + * @arg RTC_SmoothCalibPlusPulses_Set: Add one RTCCLK puls every 2**11 pulses. + * @arg RTC_SmoothCalibPlusPulses_Reset: No RTCCLK pulses are added. + * @param RTC_SmouthCalibMinusPulsesValue: Select the value of CALM[8:0] bits. + * This parameter can be one any value from 0 to 0x000001FF. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Calib registers are configured + * - ERROR: RTC Calib registers are not configured +*/ +ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod, + uint32_t RTC_SmoothCalibPlusPulses, + uint32_t RTC_SmouthCalibMinusPulsesValue) +{ + ErrorStatus status = ERROR; + uint32_t recalpfcount = 0; + + /* Check the parameters */ + assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(RTC_SmoothCalibPeriod)); + assert_param(IS_RTC_SMOOTH_CALIB_PLUS(RTC_SmoothCalibPlusPulses)); + assert_param(IS_RTC_SMOOTH_CALIB_MINUS(RTC_SmouthCalibMinusPulsesValue)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* check if a calibration is pending*/ + if ((RTC->ISR & RTC_ISR_RECALPF) != RESET) + { + /* wait until the Calibration is completed*/ + while (((RTC->ISR & RTC_ISR_RECALPF) != RESET) && (recalpfcount != RECALPF_TIMEOUT)) + { + recalpfcount++; + } + } + + /* check if the calibration pending is completed or if there is no calibration operation at all*/ + if ((RTC->ISR & RTC_ISR_RECALPF) == RESET) + { + /* Configure the Smooth calibration settings */ + RTC->CALR = (uint32_t)((uint32_t)RTC_SmoothCalibPeriod | (uint32_t)RTC_SmoothCalibPlusPulses | (uint32_t)RTC_SmouthCalibMinusPulsesValue); + + status = SUCCESS; + } + else + { + status = ERROR; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return (ErrorStatus)(status); +} + +/** + * @} + */ + + +/** @defgroup RTC_Group8 TimeStamp configuration functions + * @brief TimeStamp configuration functions + * +@verbatim + =============================================================================== + ##### TimeStamp configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or Disables the RTC TimeStamp functionality with the + * specified time stamp pin stimulating edge. + * @param RTC_TimeStampEdge: Specifies the pin edge on which the TimeStamp is + * activated. + * This parameter can be one of the following: + * @arg RTC_TimeStampEdge_Rising: the Time stamp event occurs on the rising + * edge of the related pin. + * @arg RTC_TimeStampEdge_Falling: the Time stamp event occurs on the + * falling edge of the related pin. + * @param NewState: new state of the TimeStamp. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_TIMESTAMP_EDGE(RTC_TimeStampEdge)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Get the RTC_CR register and clear the bits to be configured */ + tmpreg = (uint32_t)(RTC->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE)); + + /* Get the new configuration */ + if (NewState != DISABLE) + { + tmpreg |= (uint32_t)(RTC_TimeStampEdge | RTC_CR_TSE); + } + else + { + tmpreg |= (uint32_t)(RTC_TimeStampEdge); + } + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Configure the Time Stamp TSEDGE and Enable bits */ + RTC->CR = (uint32_t)tmpreg; + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Get the RTC TimeStamp value and masks. + * @param RTC_Format: specifies the format of the output parameters. + * This parameter can be one of the following values: + * @arg RTC_Format_BIN: Binary data format + * @arg RTC_Format_BCD: BCD data format + * @param RTC_StampTimeStruct: pointer to a RTC_TimeTypeDef structure that will + * contains the TimeStamp time values. + * @param RTC_StampDateStruct: pointer to a RTC_DateTypeDef structure that will + * contains the TimeStamp date values. + * @retval None + */ +void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, + RTC_DateTypeDef* RTC_StampDateStruct) +{ + uint32_t tmptime = 0, tmpdate = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(RTC_Format)); + + /* Get the TimeStamp time and date registers values */ + tmptime = (uint32_t)(RTC->TSTR & RTC_TR_RESERVED_MASK); + tmpdate = (uint32_t)(RTC->TSDR & RTC_DR_RESERVED_MASK); + + /* Fill the Time structure fields with the read parameters */ + RTC_StampTimeStruct->RTC_Hours = (uint8_t)((tmptime & (RTC_TR_HT | RTC_TR_HU)) >> 16); + RTC_StampTimeStruct->RTC_Minutes = (uint8_t)((tmptime & (RTC_TR_MNT | RTC_TR_MNU)) >> 8); + RTC_StampTimeStruct->RTC_Seconds = (uint8_t)(tmptime & (RTC_TR_ST | RTC_TR_SU)); + RTC_StampTimeStruct->RTC_H12 = (uint8_t)((tmptime & (RTC_TR_PM)) >> 16); + + /* Fill the Date structure fields with the read parameters */ + RTC_StampDateStruct->RTC_Year = 0; + RTC_StampDateStruct->RTC_Month = (uint8_t)((tmpdate & (RTC_DR_MT | RTC_DR_MU)) >> 8); + RTC_StampDateStruct->RTC_Date = (uint8_t)(tmpdate & (RTC_DR_DT | RTC_DR_DU)); + RTC_StampDateStruct->RTC_WeekDay = (uint8_t)((tmpdate & (RTC_DR_WDU)) >> 13); + + /* Check the input parameters format */ + if (RTC_Format == RTC_Format_BIN) + { + /* Convert the Time structure parameters to Binary format */ + RTC_StampTimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Hours); + RTC_StampTimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Minutes); + RTC_StampTimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Seconds); + + /* Convert the Date structure parameters to Binary format */ + RTC_StampDateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Month); + RTC_StampDateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Date); + RTC_StampDateStruct->RTC_WeekDay = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_WeekDay); + } +} + +/** + * @brief Get the RTC timestamp Subseconds value. + * @param None + * @retval RTC current timestamp Subseconds value. + */ +uint32_t RTC_GetTimeStampSubSecond(void) +{ + /* Get timestamp subseconds values from the correspondent registers */ + return (uint32_t)(RTC->TSSSR); +} + +/** + * @} + */ + +/** @defgroup RTC_Group9 Tampers configuration functions + * @brief Tampers configuration functions + * +@verbatim + =============================================================================== + ##### Tampers configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the select Tamper pin edge. + * @param RTC_Tamper: Selected tamper pin. + * This parameter can be any combination of the following values: + * @arg RTC_Tamper_1: Select Tamper 1. + * @arg RTC_Tamper_2: Select Tamper 2. + * @arg RTC_Tamper_3: Select Tamper 3. + * @param RTC_TamperTrigger: Specifies the trigger on the tamper pin that + * stimulates tamper event. + * This parameter can be one of the following values: + * @arg RTC_TamperTrigger_RisingEdge: Rising Edge of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_FallingEdge: Falling Edge of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_LowLevel: Low Level of the tamper pin causes tamper event. + * @arg RTC_TamperTrigger_HighLevel: High Level of the tamper pin causes tamper event. + * @retval None + */ +void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(RTC_Tamper)); + assert_param(IS_RTC_TAMPER_TRIGGER(RTC_TamperTrigger)); + + /* Check if the active level for Tamper is rising edge (Low level)*/ + if (RTC_TamperTrigger == RTC_TamperTrigger_RisingEdge) + { + /* Configure the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)((uint32_t)~(RTC_Tamper << 1)); + } + else + { + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)(RTC_Tamper << 1); + } +} + +/** + * @brief Enables or Disables the Tamper detection. + * @param RTC_Tamper: Selected tamper pin. + * This parameter can be any combination of the following values: + * @arg RTC_Tamper_1: Select Tamper 1. + * @arg RTC_Tamper_2: Select Tamper 2. + * @arg RTC_Tamper_3: Select Tamper 3. + * @param NewState: new state of the tamper pin. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(RTC_Tamper)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected Tamper pin */ + RTC->TAFCR |= (uint32_t)RTC_Tamper; + } + else + { + /* Disable the selected Tamper pin */ + RTC->TAFCR &= (uint32_t)~RTC_Tamper; + } +} + +/** + * @brief Configures the Tampers Filter. + * @param RTC_TamperFilter: Specifies the tampers filter. + * This parameter can be one of the following values: + * @arg RTC_TamperFilter_Disable: Tamper filter is disabled. + * @arg RTC_TamperFilter_2Sample: Tamper is activated after 2 consecutive + * samples at the active level. + * @arg RTC_TamperFilter_4Sample: Tamper is activated after 4 consecutive + * samples at the active level. + * @arg RTC_TamperFilter_8Sample: Tamper is activated after 8 consecutive + * samples at the active level. + * @retval None + */ +void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_FILTER(RTC_TamperFilter)); + + /* Clear TAMPFLT[1:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFLT); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperFilter; +} + +/** + * @brief Configures the Tampers Sampling Frequency. + * @param RTC_TamperSamplingFreq: Specifies the tampers Sampling Frequency. + * This parameter can be one of the following values: + * @arg RTC_TamperSamplingFreq_RTCCLK_Div32768: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 32768 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div16384: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 16384 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div8192: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 8192 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div4096: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 4096 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div2048: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 2048 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div1024: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 1024 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div512: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 512 + * @arg RTC_TamperSamplingFreq_RTCCLK_Div256: Each of the tamper inputs are sampled + * with a frequency = RTCCLK / 256 + * @retval None + */ +void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(RTC_TamperSamplingFreq)); + + /* Clear TAMPFREQ[2:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFREQ); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperSamplingFreq; +} + +/** + * @brief Configures the Tampers Pins input Precharge Duration. + * @param RTC_TamperPrechargeDuration: Specifies the Tampers Pins input + * Precharge Duration. + * This parameter can be one of the following values: + * @arg RTC_TamperPrechargeDuration_1RTCCLK: Tamper pins are pre-charged before sampling during 1 RTCCLK cycle. + * @arg RTC_TamperPrechargeDuration_2RTCCLK: Tamper pins are pre-charged before sampling during 2 RTCCLK cycle. + * @arg RTC_TamperPrechargeDuration_4RTCCLK: Tamper pins are pre-charged before sampling during 4 RTCCLK cycle. + * @arg RTC_TamperPrechargeDuration_8RTCCLK: Tamper pins are pre-charged before sampling during 8 RTCCLK cycle. + * @retval None + */ +void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration) +{ + /* Check the parameters */ + assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(RTC_TamperPrechargeDuration)); + + /* Clear TAMPPRCH[1:0] bits in the RTC_TAFCR register */ + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPPRCH); + + /* Configure the RTC_TAFCR register */ + RTC->TAFCR |= (uint32_t)RTC_TamperPrechargeDuration; +} + +/** + * @brief Enables or Disables the TimeStamp on Tamper Detection Event. + * @note The timestamp is valid even the TSE bit in tamper control register + * is reset. + * @param NewState: new state of the timestamp on tamper event. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Save timestamp on tamper detection event */ + RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPTS; + } + else + { + /* Tamper detection does not cause a timestamp to be saved */ + RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPTS; + } +} + +/** + * @brief Enables or Disables the Precharge of Tamper pin. + * @param NewState: new state of tamper pull up. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_TamperPullUpCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable precharge of the selected Tamper pin */ + RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPPUDIS; + } + else + { + /* Disable precharge of the selected Tamper pin */ + RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPPUDIS; + } +} + +/** + * @} + */ + +/** @defgroup RTC_Group10 Backup Data Registers configuration functions + * @brief Backup Data Registers configuration functions + * +@verbatim + =============================================================================== + ##### Backup Data Registers configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Writes a data in a specified RTC Backup data register. + * @param RTC_BKP_DR: RTC Backup data Register number. + * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to + * specify the register. + * @param Data: Data to be written in the specified RTC Backup data register. + * @retval None + */ +void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_RTC_BKP(RTC_BKP_DR)); + + tmp = RTC_BASE + 0x50; + tmp += (RTC_BKP_DR * 4); + + /* Write the specified register */ + *(__IO uint32_t *)tmp = (uint32_t)Data; +} + +/** + * @brief Reads data from the specified RTC Backup data Register. + * @param RTC_BKP_DR: RTC Backup data Register number. + * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to + * specify the register. + * @retval None + */ +uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_RTC_BKP(RTC_BKP_DR)); + + tmp = RTC_BASE + 0x50; + tmp += (RTC_BKP_DR * 4); + + /* Read the specified register */ + return (*(__IO uint32_t *)tmp); +} + +/** + * @} + */ + +/** @defgroup RTC_Group11 Output Type Config configuration functions + * @brief Output Type Config configuration functions + * +@verbatim + =============================================================================== + ##### Output Type Config configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the RTC Output Pin mode. + * @param RTC_OutputType: specifies the RTC Output (PC13) pin mode. + * This parameter can be one of the following values: + * @arg RTC_OutputType_OpenDrain: RTC Output (PC13) is configured in + * Open Drain mode. + * @arg RTC_OutputType_PushPull: RTC Output (PC13) is configured in + * Push Pull mode. + * @retval None + */ +void RTC_OutputTypeConfig(uint32_t RTC_OutputType) +{ + /* Check the parameters */ + assert_param(IS_RTC_OUTPUT_TYPE(RTC_OutputType)); + + RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_ALARMOUTTYPE); + RTC->TAFCR |= (uint32_t)(RTC_OutputType); +} + +/** + * @} + */ + +/** @defgroup RTC_Group12 Shift control synchronisation functions + * @brief Shift control synchronisation functions + * +@verbatim + =============================================================================== + ##### Shift control synchronisation functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the Synchronization Shift Control Settings. + * @note When REFCKON is set, firmware must not write to Shift control register + * @param RTC_ShiftAdd1S : Select to add or not 1 second to the time Calendar. + * This parameter can be one of the following values : + * @arg RTC_ShiftAdd1S_Set: Add one second to the clock calendar. + * @arg RTC_ShiftAdd1S_Reset: No effect. + * @param RTC_ShiftSubFS: Select the number of Second Fractions to Substitute. + * This parameter can be one any value from 0 to 0x7FFF. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Shift registers are configured + * - ERROR: RTC Shift registers are not configured +*/ +ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS) +{ + ErrorStatus status = ERROR; + uint32_t shpfcount = 0; + + /* Check the parameters */ + assert_param(IS_RTC_SHIFT_ADD1S(RTC_ShiftAdd1S)); + assert_param(IS_RTC_SHIFT_SUBFS(RTC_ShiftSubFS)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + /* Check if a Shift is pending*/ + if ((RTC->ISR & RTC_ISR_SHPF) != RESET) + { + /* Wait until the shift is completed*/ + while (((RTC->ISR & RTC_ISR_SHPF) != RESET) && (shpfcount != SHPF_TIMEOUT)) + { + shpfcount++; + } + } + + /* Check if the Shift pending is completed or if there is no Shift operation at all*/ + if ((RTC->ISR & RTC_ISR_SHPF) == RESET) + { + /* check if the reference clock detection is disabled */ + if((RTC->CR & RTC_CR_REFCKON) == RESET) + { + /* Configure the Shift settings */ + RTC->SHIFTR = (uint32_t)(uint32_t)(RTC_ShiftSubFS) | (uint32_t)(RTC_ShiftAdd1S); + + if(RTC_WaitForSynchro() == ERROR) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else + { + status = ERROR; + } + } + else + { + status = ERROR; + } + + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; + + return (ErrorStatus)(status); +} + +/** + * @} + */ + +/** @defgroup RTC_Group13 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + [..] All RTC interrupts are connected to the EXTI controller. + (+) To enable the RTC Alarm interrupt, the following sequence is required: + (+) Configure and enable the EXTI Line 17 in interrupt mode and select + the rising edge sensitivity using the EXTI_Init() function. + (+) Configure and enable the RTC_Alarm IRQ channel in the NVIC using + the NVIC_Init() function. + (+) Configure the RTC to generate RTC alarms (Alarm A and/or Alarm B) + using the RTC_SetAlarm() and RTC_AlarmCmd() functions. + + (+) To enable the RTC Wakeup interrupt, the following sequence is required: + (+) Configure and enable the EXTI Line 20 in interrupt mode and select + the rising edge sensitivity using the EXTI_Init() function. + (+) Configure and enable the RTC_WKUP IRQ channel in the NVIC using the + NVIC_Init() function. + (+) Configure the RTC to generate the RTC wakeup timer event using the + RTC_WakeUpClockConfig(), RTC_SetWakeUpCounter() and RTC_WakeUpCmd() + functions. + + (+) To enable the RTC Tamper interrupt, the following sequence is required: + (+) Configure and enable the EXTI Line 19 in interrupt mode and select + the rising edge sensitivity using the EXTI_Init() function. + (+) Configure and enable the TAMP_STAMP IRQ channel in the NVIC using + the NVIC_Init() function. + (+) Configure the RTC to detect the RTC tamper event using the + RTC_TamperTriggerConfig() and RTC_TamperCmd() functions. + + (+) To enable the RTC TimeStamp interrupt, the following sequence is + required: + (+) Configure and enable the EXTI Line 19 in interrupt mode and select + the rising edge sensitivity using the EXTI_Init() function. + (+) Configure and enable the TAMP_STAMP IRQ channel in the NVIC using + the NVIC_Init() function. + (+) Configure the RTC to detect the RTC time-stamp event using the + RTC_TimeStampCmd() functions. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified RTC interrupts. + * @param RTC_IT: specifies the RTC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_IT_TS: Time Stamp interrupt mask. + * @arg RTC_IT_WUT: WakeUp Timer interrupt mask. + * @arg RTC_IT_ALRB: Alarm B interrupt mask. + * @arg RTC_IT_ALRA: Alarm A interrupt mask. + * @arg RTC_IT_TAMP: Tamper event interrupt mask. + * @param NewState: new state of the specified RTC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_CONFIG_IT(RTC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* Disable the write protection for RTC registers */ + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + if (NewState != DISABLE) + { + /* Configure the Interrupts in the RTC_CR register */ + RTC->CR |= (uint32_t)(RTC_IT & ~RTC_TAFCR_TAMPIE); + /* Configure the Tamper Interrupt in the RTC_TAFCR */ + RTC->TAFCR |= (uint32_t)(RTC_IT & RTC_TAFCR_TAMPIE); + } + else + { + /* Configure the Interrupts in the RTC_CR register */ + RTC->CR &= (uint32_t)~(RTC_IT & (uint32_t)~RTC_TAFCR_TAMPIE); + /* Configure the Tamper Interrupt in the RTC_TAFCR */ + RTC->TAFCR &= (uint32_t)~(RTC_IT & RTC_TAFCR_TAMPIE); + } + /* Enable the write protection for RTC registers */ + RTC->WPR = 0xFF; +} + +/** + * @brief Checks whether the specified RTC flag is set or not. + * @param RTC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RTC_FLAG_RECALPF: RECALPF event flag. + * @arg RTC_FLAG_TAMP3F: Tamper 3 event flag. + * @arg RTC_FLAG_TAMP2F: Tamper 2 event flag. + * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag. + * @arg RTC_FLAG_TSOVF: Time Stamp OverFlow flag. + * @arg RTC_FLAG_TSF: Time Stamp event flag. + * @arg RTC_FLAG_WUTF: WakeUp Timer flag. + * @arg RTC_FLAG_ALRBF: Alarm B flag. + * @arg RTC_FLAG_ALRAF: Alarm A flag. + * @arg RTC_FLAG_INITF: Initialization mode flag. + * @arg RTC_FLAG_RSF: Registers Synchronized flag. + * @arg RTC_FLAG_INITS: Registers Configured flag. + * @argRTC_FLAG_SHPF: Shift operation pending flag. + * @arg RTC_FLAG_WUTWF: WakeUp Timer Write flag. + * @arg RTC_FLAG_ALRBWF: Alarm B Write flag. + * @arg RTC_FLAG_ALRAWF: Alarm A write flag. + * @retval The new state of RTC_FLAG (SET or RESET). + */ +FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_GET_FLAG(RTC_FLAG)); + + /* Get all the flags */ + tmpreg = (uint32_t)(RTC->ISR & RTC_FLAGS_MASK); + + /* Return the status of the flag */ + if ((tmpreg & RTC_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the RTC's pending flags. + * @param RTC_FLAG: specifies the RTC flag to clear. + * This parameter can be any combination of the following values: + * @arg RTC_FLAG_TAMP3F: Tamper 3 event flag. + * @arg RTC_FLAG_TAMP2F: Tamper 2 event flag. + * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag. + * @arg RTC_FLAG_TSOVF: Time Stamp Overflow flag. + * @arg RTC_FLAG_TSF: Time Stamp event flag. + * @arg RTC_FLAG_WUTF: WakeUp Timer flag. + * @arg RTC_FLAG_ALRBF: Alarm B flag. + * @arg RTC_FLAG_ALRAF: Alarm A flag. + * @arg RTC_FLAG_RSF: Registers Synchronized flag. + * @retval None + */ +void RTC_ClearFlag(uint32_t RTC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_RTC_CLEAR_FLAG(RTC_FLAG)); + + /* Clear the Flags in the RTC_ISR register */ + RTC->ISR = (uint32_t)((uint32_t)(~((RTC_FLAG | RTC_ISR_INIT)& 0x0001FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT))); +} + +/** + * @brief Checks whether the specified RTC interrupt has occurred or not. + * @param RTC_IT: specifies the RTC interrupt source to check. + * This parameter can be one of the following values: + * @arg RTC_IT_TS: Time Stamp interrupt. + * @arg RTC_IT_WUT: WakeUp Timer interrupt. + * @arg RTC_IT_ALRB: Alarm B interrupt. + * @arg RTC_IT_ALRA: Alarm A interrupt. + * @arg RTC_IT_TAMP1: Tamper1 event interrupt. + * @arg RTC_IT_TAMP2: Tamper2 event interrupt. + * @arg RTC_IT_TAMP3: Tamper3 event interrupt. + * @retval The new state of RTC_IT (SET or RESET). + */ +ITStatus RTC_GetITStatus(uint32_t RTC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t tmpreg = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_RTC_GET_IT(RTC_IT)); + + /* Get the TAMPER Interrupt enable bit and pending bit */ + tmpreg = (uint32_t)(RTC->TAFCR & (RTC_TAFCR_TAMPIE)); + + /* Get the Interrupt enable Status */ + enablestatus = (uint32_t)((RTC->CR & RTC_IT) | (tmpreg & ((RTC_IT >> (RTC_IT >> 18)) >> 15))); + + /* Get the Interrupt pending bit */ + tmpreg = (uint32_t)((RTC->ISR & (uint32_t)(RTC_IT >> 4))); + + /* Get the status of the Interrupt */ + if ((enablestatus != (uint32_t)RESET) && ((tmpreg & 0x0000FFFF) != (uint32_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the RTC's interrupt pending bits. + * @param RTC_IT: specifies the RTC interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RTC_IT_TS: Time Stamp interrupt + * @arg RTC_IT_WUT: WakeUp Timer interrupt + * @arg RTC_IT_ALRB: Alarm B interrupt + * @arg RTC_IT_ALRA: Alarm A interrupt + * @arg RTC_IT_TAMP1: Tamper1 event interrupt + * @arg RTC_IT_TAMP2: Tamper2 event interrupt + * @arg RTC_IT_TAMP3: Tamper3 event interrupt + * @retval None + */ +void RTC_ClearITPendingBit(uint32_t RTC_IT) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_CLEAR_IT(RTC_IT)); + + /* Get the RTC_ISR Interrupt pending bits mask */ + tmpreg = (uint32_t)(RTC_IT >> 4); + + /* Clear the interrupt pending bits in the RTC_ISR register */ + RTC->ISR = (uint32_t)((uint32_t)(~((tmpreg | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT))); +} + +/** + * @} + */ + +/** + * @brief Converts a 2 digit decimal to BCD format. + * @param Value: Byte to be converted. + * @retval Converted byte + */ +static uint8_t RTC_ByteToBcd2(uint8_t Value) +{ + uint8_t bcdhigh = 0; + + while (Value >= 10) + { + bcdhigh++; + Value -= 10; + } + + return ((uint8_t)(bcdhigh << 4) | Value); +} + +/** + * @brief Convert from 2 digit BCD to Binary. + * @param Value: BCD value to be converted. + * @retval Converted word + */ +static uint8_t RTC_Bcd2ToByte(uint8_t Value) +{ + uint8_t tmp = 0; + tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10; + return (tmp + (Value & (uint8_t)0x0F)); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rtc.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rtc.h new file mode 100644 index 0000000000..b1a3c86fbf --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_rtc.h @@ -0,0 +1,896 @@ +/** + ****************************************************************************** + * @file stm32l1xx_rtc.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the RTC firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_RTC_H +#define __STM32L1xx_RTC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup RTC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief RTC Init structures definition + */ +typedef struct +{ + uint32_t RTC_HourFormat; /*!< Specifies the RTC Hour Format. + This parameter can be a value of @ref RTC_Hour_Formats */ + + uint32_t RTC_AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value. + This parameter must be set to a value lower than 0x7F */ + + uint32_t RTC_SynchPrediv; /*!< Specifies the RTC Synchronous Predivider value. + This parameter must be set to a value lower than 0x7FFF */ +}RTC_InitTypeDef; + +/** + * @brief RTC Time structure definition + */ +typedef struct +{ + uint8_t RTC_Hours; /*!< Specifies the RTC Time Hour. + This parameter must be set to a value in the 0-12 range + if the RTC_HourFormat_12 is selected or 0-23 range if + the RTC_HourFormat_24 is selected. */ + + uint8_t RTC_Minutes; /*!< Specifies the RTC Time Minutes. + This parameter must be set to a value in the 0-59 range. */ + + uint8_t RTC_Seconds; /*!< Specifies the RTC Time Seconds. + This parameter must be set to a value in the 0-59 range. */ + + uint8_t RTC_H12; /*!< Specifies the RTC AM/PM Time. + This parameter can be a value of @ref RTC_AM_PM_Definitions */ +}RTC_TimeTypeDef; + +/** + * @brief RTC Date structure definition + */ +typedef struct +{ + uint8_t RTC_WeekDay; /*!< Specifies the RTC Date WeekDay. + This parameter can be a value of @ref RTC_WeekDay_Definitions */ + + uint8_t RTC_Month; /*!< Specifies the RTC Date Month (in BCD format). + This parameter can be a value of @ref RTC_Month_Date_Definitions */ + + uint8_t RTC_Date; /*!< Specifies the RTC Date. + This parameter must be set to a value in the 1-31 range. */ + + uint8_t RTC_Year; /*!< Specifies the RTC Date Year. + This parameter must be set to a value in the 0-99 range. */ +}RTC_DateTypeDef; + +/** + * @brief RTC Alarm structure definition + */ +typedef struct +{ + RTC_TimeTypeDef RTC_AlarmTime; /*!< Specifies the RTC Alarm Time members. */ + + uint32_t RTC_AlarmMask; /*!< Specifies the RTC Alarm Masks. + This parameter can be a value of @ref RTC_AlarmMask_Definitions */ + + uint32_t RTC_AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on Date or WeekDay. + This parameter can be a value of @ref RTC_AlarmDateWeekDay_Definitions */ + + uint8_t RTC_AlarmDateWeekDay; /*!< Specifies the RTC Alarm Date/WeekDay. + If the Alarm Date is selected, this parameter + must be set to a value in the 1-31 range. + If the Alarm WeekDay is selected, this + parameter can be a value of @ref RTC_WeekDay_Definitions */ +}RTC_AlarmTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RTC_Exported_Constants + * @{ + */ + + +/** @defgroup RTC_Hour_Formats + * @{ + */ +#define RTC_HourFormat_24 ((uint32_t)0x00000000) +#define RTC_HourFormat_12 ((uint32_t)0x00000040) +#define IS_RTC_HOUR_FORMAT(FORMAT) (((FORMAT) == RTC_HourFormat_12) || \ + ((FORMAT) == RTC_HourFormat_24)) +/** + * @} + */ + +/** @defgroup RTC_Asynchronous_Predivider + * @{ + */ +#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7F) + +/** + * @} + */ + + +/** @defgroup RTC_Synchronous_Predivider + * @{ + */ +#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7FFF) + +/** + * @} + */ + +/** @defgroup RTC_Time_Definitions + * @{ + */ +#define IS_RTC_HOUR12(HOUR) (((HOUR) > 0) && ((HOUR) <= 12)) +#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23) +#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59) +#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59) + +/** + * @} + */ + +/** @defgroup RTC_AM_PM_Definitions + * @{ + */ +#define RTC_H12_AM ((uint8_t)0x00) +#define RTC_H12_PM ((uint8_t)0x40) +#define IS_RTC_H12(PM) (((PM) == RTC_H12_AM) || ((PM) == RTC_H12_PM)) + +/** + * @} + */ + +/** @defgroup RTC_Year_Date_Definitions + * @{ + */ +#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99) + +/** + * @} + */ + +/** @defgroup RTC_Month_Date_Definitions + * @{ + */ + +/* Coded in BCD format */ +#define RTC_Month_January ((uint8_t)0x01) +#define RTC_Month_February ((uint8_t)0x02) +#define RTC_Month_March ((uint8_t)0x03) +#define RTC_Month_April ((uint8_t)0x04) +#define RTC_Month_May ((uint8_t)0x05) +#define RTC_Month_June ((uint8_t)0x06) +#define RTC_Month_July ((uint8_t)0x07) +#define RTC_Month_August ((uint8_t)0x08) +#define RTC_Month_September ((uint8_t)0x09) +#define RTC_Month_October ((uint8_t)0x10) +#define RTC_Month_November ((uint8_t)0x11) +#define RTC_Month_December ((uint8_t)0x12) +#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1) && ((MONTH) <= 12)) +#define IS_RTC_DATE(DATE) (((DATE) >= 1) && ((DATE) <= 31)) + +/** + * @} + */ + +/** @defgroup RTC_WeekDay_Definitions + * @{ + */ + +#define RTC_Weekday_Monday ((uint8_t)0x01) +#define RTC_Weekday_Tuesday ((uint8_t)0x02) +#define RTC_Weekday_Wednesday ((uint8_t)0x03) +#define RTC_Weekday_Thursday ((uint8_t)0x04) +#define RTC_Weekday_Friday ((uint8_t)0x05) +#define RTC_Weekday_Saturday ((uint8_t)0x06) +#define RTC_Weekday_Sunday ((uint8_t)0x07) +#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ + ((WEEKDAY) == RTC_Weekday_Tuesday) || \ + ((WEEKDAY) == RTC_Weekday_Wednesday) || \ + ((WEEKDAY) == RTC_Weekday_Thursday) || \ + ((WEEKDAY) == RTC_Weekday_Friday) || \ + ((WEEKDAY) == RTC_Weekday_Saturday) || \ + ((WEEKDAY) == RTC_Weekday_Sunday)) +/** + * @} + */ + + +/** @defgroup RTC_Alarm_Definitions + * @{ + */ +#define IS_RTC_ALARM_DATE_WEEKDAY_DATE(DATE) (((DATE) > 0) && ((DATE) <= 31)) +#define IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ + ((WEEKDAY) == RTC_Weekday_Tuesday) || \ + ((WEEKDAY) == RTC_Weekday_Wednesday) || \ + ((WEEKDAY) == RTC_Weekday_Thursday) || \ + ((WEEKDAY) == RTC_Weekday_Friday) || \ + ((WEEKDAY) == RTC_Weekday_Saturday) || \ + ((WEEKDAY) == RTC_Weekday_Sunday)) + +/** + * @} + */ + + +/** @defgroup RTC_AlarmDateWeekDay_Definitions + * @{ + */ +#define RTC_AlarmDateWeekDaySel_Date ((uint32_t)0x00000000) +#define RTC_AlarmDateWeekDaySel_WeekDay ((uint32_t)0x40000000) + +#define IS_RTC_ALARM_DATE_WEEKDAY_SEL(SEL) (((SEL) == RTC_AlarmDateWeekDaySel_Date) || \ + ((SEL) == RTC_AlarmDateWeekDaySel_WeekDay)) + +/** + * @} + */ + + +/** @defgroup RTC_AlarmMask_Definitions + * @{ + */ +#define RTC_AlarmMask_None ((uint32_t)0x00000000) +#define RTC_AlarmMask_DateWeekDay ((uint32_t)0x80000000) +#define RTC_AlarmMask_Hours ((uint32_t)0x00800000) +#define RTC_AlarmMask_Minutes ((uint32_t)0x00008000) +#define RTC_AlarmMask_Seconds ((uint32_t)0x00000080) +#define RTC_AlarmMask_All ((uint32_t)0x80808080) +#define IS_ALARM_MASK(MASK) (((MASK) & 0x7F7F7F7F) == (uint32_t)RESET) + +/** + * @} + */ + +/** @defgroup RTC_Alarms_Definitions + * @{ + */ +#define RTC_Alarm_A ((uint32_t)0x00000100) +#define RTC_Alarm_B ((uint32_t)0x00000200) +#define IS_RTC_ALARM(ALARM) (((ALARM) == RTC_Alarm_A) || ((ALARM) == RTC_Alarm_B)) +#define IS_RTC_CMD_ALARM(ALARM) (((ALARM) & (RTC_Alarm_A | RTC_Alarm_B)) != (uint32_t)RESET) + +/** + * @} + */ + +/** @defgroup RTC_Alarm_Sub_Seconds_Masks_Definitions + * @{ + */ +#define RTC_AlarmSubSecondMask_All ((uint32_t)0x00000000) /*!< All Alarm SS fields are masked. + There is no comparison on sub seconds + for Alarm */ +#define RTC_AlarmSubSecondMask_SS14_1 ((uint32_t)0x01000000) /*!< SS[14:1] are don't care in Alarm + comparison. Only SS[0] is compared. */ +#define RTC_AlarmSubSecondMask_SS14_2 ((uint32_t)0x02000000) /*!< SS[14:2] are don't care in Alarm + comparison. Only SS[1:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_3 ((uint32_t)0x03000000) /*!< SS[14:3] are don't care in Alarm + comparison. Only SS[2:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_4 ((uint32_t)0x04000000) /*!< SS[14:4] are don't care in Alarm + comparison. Only SS[3:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_5 ((uint32_t)0x05000000) /*!< SS[14:5] are don't care in Alarm + comparison. Only SS[4:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_6 ((uint32_t)0x06000000) /*!< SS[14:6] are don't care in Alarm + comparison. Only SS[5:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_7 ((uint32_t)0x07000000) /*!< SS[14:7] are don't care in Alarm + comparison. Only SS[6:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_8 ((uint32_t)0x08000000) /*!< SS[14:8] are don't care in Alarm + comparison. Only SS[7:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_9 ((uint32_t)0x09000000) /*!< SS[14:9] are don't care in Alarm + comparison. Only SS[8:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_10 ((uint32_t)0x0A000000) /*!< SS[14:10] are don't care in Alarm + comparison. Only SS[9:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_11 ((uint32_t)0x0B000000) /*!< SS[14:11] are don't care in Alarm + comparison. Only SS[10:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_12 ((uint32_t)0x0C000000) /*!< SS[14:12] are don't care in Alarm + comparison.Only SS[11:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14_13 ((uint32_t)0x0D000000) /*!< SS[14:13] are don't care in Alarm + comparison. Only SS[12:0] are compared */ +#define RTC_AlarmSubSecondMask_SS14 ((uint32_t)0x0E000000) /*!< SS[14] is don't care in Alarm + comparison.Only SS[13:0] are compared */ +#define RTC_AlarmSubSecondMask_None ((uint32_t)0x0F000000) /*!< SS[14:0] are compared and must match + to activate alarm. */ +#define IS_RTC_ALARM_SUB_SECOND_MASK(MASK) (((MASK) == RTC_AlarmSubSecondMask_All) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_1) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_2) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_3) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_4) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_5) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_6) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_7) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_8) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_9) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_10) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_11) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_12) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14_13) || \ + ((MASK) == RTC_AlarmSubSecondMask_SS14) || \ + ((MASK) == RTC_AlarmSubSecondMask_None)) +/** + * @} + */ + +/** @defgroup RTC_Alarm_Sub_Seconds_Value + * @{ + */ + +#define IS_RTC_ALARM_SUB_SECOND_VALUE(VALUE) ((VALUE) <= 0x00007FFF) + +/** + * @} + */ + +/** @defgroup RTC_Wakeup_Timer_Definitions + * @{ + */ +#define RTC_WakeUpClock_RTCCLK_Div16 ((uint32_t)0x00000000) +#define RTC_WakeUpClock_RTCCLK_Div8 ((uint32_t)0x00000001) +#define RTC_WakeUpClock_RTCCLK_Div4 ((uint32_t)0x00000002) +#define RTC_WakeUpClock_RTCCLK_Div2 ((uint32_t)0x00000003) +#define RTC_WakeUpClock_CK_SPRE_16bits ((uint32_t)0x00000004) +#define RTC_WakeUpClock_CK_SPRE_17bits ((uint32_t)0x00000006) +#define IS_RTC_WAKEUP_CLOCK(CLOCK) (((CLOCK) == RTC_WakeUpClock_RTCCLK_Div16) || \ + ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div8) || \ + ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div4) || \ + ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div2) || \ + ((CLOCK) == RTC_WakeUpClock_CK_SPRE_16bits) || \ + ((CLOCK) == RTC_WakeUpClock_CK_SPRE_17bits)) +#define IS_RTC_WAKEUP_COUNTER(COUNTER) ((COUNTER) <= 0xFFFF) +/** + * @} + */ + +/** @defgroup RTC_Time_Stamp_Edges_definitions + * @{ + */ +#define RTC_TimeStampEdge_Rising ((uint32_t)0x00000000) +#define RTC_TimeStampEdge_Falling ((uint32_t)0x00000008) +#define IS_RTC_TIMESTAMP_EDGE(EDGE) (((EDGE) == RTC_TimeStampEdge_Rising) || \ + ((EDGE) == RTC_TimeStampEdge_Falling)) +/** + * @} + */ + +/** @defgroup RTC_Output_selection_Definitions + * @{ + */ +#define RTC_Output_Disable ((uint32_t)0x00000000) +#define RTC_Output_AlarmA ((uint32_t)0x00200000) +#define RTC_Output_AlarmB ((uint32_t)0x00400000) +#define RTC_Output_WakeUp ((uint32_t)0x00600000) + +#define IS_RTC_OUTPUT(OUTPUT) (((OUTPUT) == RTC_Output_Disable) || \ + ((OUTPUT) == RTC_Output_AlarmA) || \ + ((OUTPUT) == RTC_Output_AlarmB) || \ + ((OUTPUT) == RTC_Output_WakeUp)) + +/** + * @} + */ + +/** @defgroup RTC_Output_Polarity_Definitions + * @{ + */ +#define RTC_OutputPolarity_High ((uint32_t)0x00000000) +#define RTC_OutputPolarity_Low ((uint32_t)0x00100000) +#define IS_RTC_OUTPUT_POL(POL) (((POL) == RTC_OutputPolarity_High) || \ + ((POL) == RTC_OutputPolarity_Low)) +/** + * @} + */ + +/** @defgroup RTC_Coarse_Calibration_Definitions + * @{ + */ +#define RTC_CalibSign_Positive ((uint32_t)0x00000000) +#define RTC_CalibSign_Negative ((uint32_t)0x00000080) +#define IS_RTC_CALIB_SIGN(SIGN) (((SIGN) == RTC_CalibSign_Positive) || \ + ((SIGN) == RTC_CalibSign_Negative)) +#define IS_RTC_CALIB_VALUE(VALUE) ((VALUE) < 0x20) + +/** + * @} + */ + + /** @defgroup RTC_Calib_Output_selection_Definitions + * @{ + */ +#define RTC_CalibOutput_512Hz ((uint32_t)0x00000000) +#define RTC_CalibOutput_1Hz ((uint32_t)0x00080000) +#define IS_RTC_CALIB_OUTPUT(OUTPUT) (((OUTPUT) == RTC_CalibOutput_512Hz) || \ + ((OUTPUT) == RTC_CalibOutput_1Hz)) +/** + * @} + */ + +/** @defgroup RTC_Smooth_calib_period_Definitions + * @{ + */ +#define RTC_SmoothCalibPeriod_32sec ((uint32_t)0x00000000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 32s, else 2exp20 RTCCLK seconds */ +#define RTC_SmoothCalibPeriod_16sec ((uint32_t)0x00002000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 16s, else 2exp19 RTCCLK seconds */ +#define RTC_SmoothCalibPeriod_8sec ((uint32_t)0x00004000) /*!< if RTCCLK = 32768 Hz, Smooth calibation + period is 8s, else 2exp18 RTCCLK seconds */ +#define IS_RTC_SMOOTH_CALIB_PERIOD(PERIOD) (((PERIOD) == RTC_SmoothCalibPeriod_32sec) || \ + ((PERIOD) == RTC_SmoothCalibPeriod_16sec) || \ + ((PERIOD) == RTC_SmoothCalibPeriod_8sec)) + +/** + * @} + */ + +/** @defgroup RTC_Smooth_calib_Plus_pulses_Definitions + * @{ + */ +#define RTC_SmoothCalibPlusPulses_Set ((uint32_t)0x00008000) /*!< The number of RTCCLK pulses added + during a X -second window = Y - CALM[8:0]. + with Y = 512, 256, 128 when X = 32, 16, 8 */ +#define RTC_SmoothCalibPlusPulses_Reset ((uint32_t)0x00000000) /*!< The number of RTCCLK pulses subbstited + during a 32-second window = CALM[8:0]. */ +#define IS_RTC_SMOOTH_CALIB_PLUS(PLUS) (((PLUS) == RTC_SmoothCalibPlusPulses_Set) || \ + ((PLUS) == RTC_SmoothCalibPlusPulses_Reset)) + +/** + * @} + */ + +/** @defgroup RTC_Smooth_calib_Minus_pulses_Definitions + * @{ + */ +#define IS_RTC_SMOOTH_CALIB_MINUS(VALUE) ((VALUE) <= 0x000001FF) + +/** + * @} + */ + +/** @defgroup RTC_DayLightSaving_Definitions + * @{ + */ +#define RTC_DayLightSaving_SUB1H ((uint32_t)0x00020000) +#define RTC_DayLightSaving_ADD1H ((uint32_t)0x00010000) +#define IS_RTC_DAYLIGHT_SAVING(SAVE) (((SAVE) == RTC_DayLightSaving_SUB1H) || \ + ((SAVE) == RTC_DayLightSaving_ADD1H)) + +#define RTC_StoreOperation_Reset ((uint32_t)0x00000000) +#define RTC_StoreOperation_Set ((uint32_t)0x00040000) +#define IS_RTC_STORE_OPERATION(OPERATION) (((OPERATION) == RTC_StoreOperation_Reset) || \ + ((OPERATION) == RTC_StoreOperation_Set)) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Trigger_Definitions + * @{ + */ +#define RTC_TamperTrigger_RisingEdge ((uint32_t)0x00000000) +#define RTC_TamperTrigger_FallingEdge ((uint32_t)0x00000001) +#define RTC_TamperTrigger_LowLevel ((uint32_t)0x00000000) +#define RTC_TamperTrigger_HighLevel ((uint32_t)0x00000001) +#define IS_RTC_TAMPER_TRIGGER(TRIGGER) (((TRIGGER) == RTC_TamperTrigger_RisingEdge) || \ + ((TRIGGER) == RTC_TamperTrigger_FallingEdge) || \ + ((TRIGGER) == RTC_TamperTrigger_LowLevel) || \ + ((TRIGGER) == RTC_TamperTrigger_HighLevel)) + +/** + * @} + */ + +/** @defgroup RTC_Tamper_Filter_Definitions + * @{ + */ +#define RTC_TamperFilter_Disable ((uint32_t)0x00000000) /*!< Tamper filter is disabled */ + +#define RTC_TamperFilter_2Sample ((uint32_t)0x00000800) /*!< Tamper is activated after 2 + consecutive samples at the active level */ +#define RTC_TamperFilter_4Sample ((uint32_t)0x00001000) /*!< Tamper is activated after 4 + consecutive samples at the active level */ +#define RTC_TamperFilter_8Sample ((uint32_t)0x00001800) /*!< Tamper is activated after 8 + consecutive samples at the active leve. */ +#define IS_RTC_TAMPER_FILTER(FILTER) (((FILTER) == RTC_TamperFilter_Disable) || \ + ((FILTER) == RTC_TamperFilter_2Sample) || \ + ((FILTER) == RTC_TamperFilter_4Sample) || \ + ((FILTER) == RTC_TamperFilter_8Sample)) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Sampling_Frequencies_Definitions + * @{ + */ +#define RTC_TamperSamplingFreq_RTCCLK_Div32768 ((uint32_t)0x00000000) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 32768 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div16384 ((uint32_t)0x000000100) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 16384 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div8192 ((uint32_t)0x00000200) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 8192 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div4096 ((uint32_t)0x00000300) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 4096 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div2048 ((uint32_t)0x00000400) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 2048 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div1024 ((uint32_t)0x00000500) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 1024 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div512 ((uint32_t)0x00000600) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 512 */ +#define RTC_TamperSamplingFreq_RTCCLK_Div256 ((uint32_t)0x00000700) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 256 */ +#define IS_RTC_TAMPER_SAMPLING_FREQ(FREQ) (((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div32768) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div16384) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div8192) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div4096) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div2048) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div1024) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div512) || \ + ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div256)) + +/** + * @} + */ + + /** @defgroup RTC_Tamper_Pin_Precharge_Duration_Definitions + * @{ + */ +#define RTC_TamperPrechargeDuration_1RTCCLK ((uint32_t)0x00000000) /*!< Tamper pins are pre-charged before + sampling during 1 RTCCLK cycle */ +#define RTC_TamperPrechargeDuration_2RTCCLK ((uint32_t)0x00002000) /*!< Tamper pins are pre-charged before + sampling during 2 RTCCLK cycles */ +#define RTC_TamperPrechargeDuration_4RTCCLK ((uint32_t)0x00004000) /*!< Tamper pins are pre-charged before + sampling during 4 RTCCLK cycles */ +#define RTC_TamperPrechargeDuration_8RTCCLK ((uint32_t)0x00006000) /*!< Tamper pins are pre-charged before + sampling during 8 RTCCLK cycles */ + +#define IS_RTC_TAMPER_PRECHARGE_DURATION(DURATION) (((DURATION) == RTC_TamperPrechargeDuration_1RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_2RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_4RTCCLK) || \ + ((DURATION) == RTC_TamperPrechargeDuration_8RTCCLK)) +/** + * @} + */ + +/** @defgroup RTC_Tamper_Pins_Definitions + * @{ + */ +#define RTC_Tamper_1 RTC_TAFCR_TAMP1E /*!< Tamper detection enable for + input tamper 1 */ +#define RTC_Tamper_2 RTC_TAFCR_TAMP2E /*!< Tamper detection enable for + input tamper 2 */ +#define RTC_Tamper_3 RTC_TAFCR_TAMP3E /*!< Tamper detection enable for + input tamper 3 */ + +#define IS_RTC_TAMPER(TAMPER) ((((TAMPER) & (uint32_t)0xFFFFFFD6) == 0x00) && ((TAMPER) != (uint32_t)RESET)) + + +/** + * @} + */ + +/** @defgroup RTC_Output_Type_ALARM_OUT + * @{ + */ +#define RTC_OutputType_OpenDrain ((uint32_t)0x00000000) +#define RTC_OutputType_PushPull ((uint32_t)0x00040000) +#define IS_RTC_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_OutputType_OpenDrain) || \ + ((TYPE) == RTC_OutputType_PushPull)) + +/** + * @} + */ + +/** @defgroup RTC_Add_1_Second_Parameter_Definitions + * @{ + */ +#define RTC_ShiftAdd1S_Reset ((uint32_t)0x00000000) +#define RTC_ShiftAdd1S_Set ((uint32_t)0x80000000) +#define IS_RTC_SHIFT_ADD1S(SEL) (((SEL) == RTC_ShiftAdd1S_Reset) || \ + ((SEL) == RTC_ShiftAdd1S_Set)) +/** + * @} + */ + +/** @defgroup RTC_Substract_Fraction_Of_Second_Value + * @{ + */ +#define IS_RTC_SHIFT_SUBFS(FS) ((FS) <= 0x00007FFF) + +/** + * @} + */ + +/** @defgroup RTC_Backup_Registers_Definitions + * @{ + */ + +#define RTC_BKP_DR0 ((uint32_t)0x00000000) +#define RTC_BKP_DR1 ((uint32_t)0x00000001) +#define RTC_BKP_DR2 ((uint32_t)0x00000002) +#define RTC_BKP_DR3 ((uint32_t)0x00000003) +#define RTC_BKP_DR4 ((uint32_t)0x00000004) +#define RTC_BKP_DR5 ((uint32_t)0x00000005) +#define RTC_BKP_DR6 ((uint32_t)0x00000006) +#define RTC_BKP_DR7 ((uint32_t)0x00000007) +#define RTC_BKP_DR8 ((uint32_t)0x00000008) +#define RTC_BKP_DR9 ((uint32_t)0x00000009) +#define RTC_BKP_DR10 ((uint32_t)0x0000000A) +#define RTC_BKP_DR11 ((uint32_t)0x0000000B) +#define RTC_BKP_DR12 ((uint32_t)0x0000000C) +#define RTC_BKP_DR13 ((uint32_t)0x0000000D) +#define RTC_BKP_DR14 ((uint32_t)0x0000000E) +#define RTC_BKP_DR15 ((uint32_t)0x0000000F) +#define RTC_BKP_DR16 ((uint32_t)0x00000010) +#define RTC_BKP_DR17 ((uint32_t)0x00000011) +#define RTC_BKP_DR18 ((uint32_t)0x00000012) +#define RTC_BKP_DR19 ((uint32_t)0x00000013) +#define RTC_BKP_DR20 ((uint32_t)0x00000014) +#define RTC_BKP_DR21 ((uint32_t)0x00000015) +#define RTC_BKP_DR22 ((uint32_t)0x00000016) +#define RTC_BKP_DR23 ((uint32_t)0x00000017) +#define RTC_BKP_DR24 ((uint32_t)0x00000018) +#define RTC_BKP_DR25 ((uint32_t)0x00000019) +#define RTC_BKP_DR26 ((uint32_t)0x0000001A) +#define RTC_BKP_DR27 ((uint32_t)0x0000001B) +#define RTC_BKP_DR28 ((uint32_t)0x0000001C) +#define RTC_BKP_DR29 ((uint32_t)0x0000001D) +#define RTC_BKP_DR30 ((uint32_t)0x0000001E) +#define RTC_BKP_DR31 ((uint32_t)0x0000001F) +#define IS_RTC_BKP(BKP) (((BKP) == RTC_BKP_DR0) || \ + ((BKP) == RTC_BKP_DR1) || \ + ((BKP) == RTC_BKP_DR2) || \ + ((BKP) == RTC_BKP_DR3) || \ + ((BKP) == RTC_BKP_DR4) || \ + ((BKP) == RTC_BKP_DR5) || \ + ((BKP) == RTC_BKP_DR6) || \ + ((BKP) == RTC_BKP_DR7) || \ + ((BKP) == RTC_BKP_DR8) || \ + ((BKP) == RTC_BKP_DR9) || \ + ((BKP) == RTC_BKP_DR10) || \ + ((BKP) == RTC_BKP_DR11) || \ + ((BKP) == RTC_BKP_DR12) || \ + ((BKP) == RTC_BKP_DR13) || \ + ((BKP) == RTC_BKP_DR14) || \ + ((BKP) == RTC_BKP_DR15) || \ + ((BKP) == RTC_BKP_DR16) || \ + ((BKP) == RTC_BKP_DR17) || \ + ((BKP) == RTC_BKP_DR18) || \ + ((BKP) == RTC_BKP_DR19) || \ + ((BKP) == RTC_BKP_DR20) || \ + ((BKP) == RTC_BKP_DR21) || \ + ((BKP) == RTC_BKP_DR22) || \ + ((BKP) == RTC_BKP_DR23) || \ + ((BKP) == RTC_BKP_DR24) || \ + ((BKP) == RTC_BKP_DR25) || \ + ((BKP) == RTC_BKP_DR26) || \ + ((BKP) == RTC_BKP_DR27) || \ + ((BKP) == RTC_BKP_DR28) || \ + ((BKP) == RTC_BKP_DR29) || \ + ((BKP) == RTC_BKP_DR30) || \ + ((BKP) == RTC_BKP_DR31)) +/** + * @} + */ + +/** @defgroup RTC_Input_parameter_format_definitions + * @{ + */ +#define RTC_Format_BIN ((uint32_t)0x000000000) +#define RTC_Format_BCD ((uint32_t)0x000000001) +#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_Format_BIN) || ((FORMAT) == RTC_Format_BCD)) + +/** + * @} + */ + +/** @defgroup RTC_Flags_Definitions + * @{ + */ +#define RTC_FLAG_RECALPF ((uint32_t)0x00010000) +#define RTC_FLAG_TAMP3F ((uint32_t)0x00008000) +#define RTC_FLAG_TAMP2F ((uint32_t)0x00004000) +#define RTC_FLAG_TAMP1F ((uint32_t)0x00002000) +#define RTC_FLAG_TSOVF ((uint32_t)0x00001000) +#define RTC_FLAG_TSF ((uint32_t)0x00000800) +#define RTC_FLAG_WUTF ((uint32_t)0x00000400) +#define RTC_FLAG_ALRBF ((uint32_t)0x00000200) +#define RTC_FLAG_ALRAF ((uint32_t)0x00000100) +#define RTC_FLAG_INITF ((uint32_t)0x00000040) +#define RTC_FLAG_RSF ((uint32_t)0x00000020) +#define RTC_FLAG_INITS ((uint32_t)0x00000010) +#define RTC_FLAG_SHPF ((uint32_t)0x00000008) +#define RTC_FLAG_WUTWF ((uint32_t)0x00000004) +#define RTC_FLAG_ALRBWF ((uint32_t)0x00000002) +#define RTC_FLAG_ALRAWF ((uint32_t)0x00000001) +#define IS_RTC_GET_FLAG(FLAG) (((FLAG) == RTC_FLAG_TSOVF) || ((FLAG) == RTC_FLAG_TSF) || \ + ((FLAG) == RTC_FLAG_WUTF) || ((FLAG) == RTC_FLAG_ALRBF) || \ + ((FLAG) == RTC_FLAG_ALRAF) || ((FLAG) == RTC_FLAG_INITF) || \ + ((FLAG) == RTC_FLAG_RSF) || ((FLAG) == RTC_FLAG_WUTWF) || \ + ((FLAG) == RTC_FLAG_ALRBWF) || ((FLAG) == RTC_FLAG_ALRAWF) || \ + ((FLAG) == RTC_FLAG_TAMP1F) || ((FLAG) == RTC_FLAG_TAMP2F) || \ + ((FLAG) == RTC_FLAG_TAMP3F) || ((FLAG) == RTC_FLAG_RECALPF) || \ + ((FLAG) == RTC_FLAG_SHPF)) +#define IS_RTC_CLEAR_FLAG(FLAG) (((FLAG) != (uint32_t)RESET) && (((FLAG) & 0xFFFF00DF) == (uint32_t)RESET)) + +/** + * @} + */ + +/** @defgroup RTC_Interrupts_Definitions + * @{ + */ +#define RTC_IT_TS ((uint32_t)0x00008000) +#define RTC_IT_WUT ((uint32_t)0x00004000) +#define RTC_IT_ALRB ((uint32_t)0x00002000) +#define RTC_IT_ALRA ((uint32_t)0x00001000) +#define RTC_IT_TAMP ((uint32_t)0x00000004) /* Used only to Enable the Tamper Interrupt */ +#define RTC_IT_TAMP1 ((uint32_t)0x00020000) +#define RTC_IT_TAMP2 ((uint32_t)0x00040000) +#define RTC_IT_TAMP3 ((uint32_t)0x00080000) + + +#define IS_RTC_CONFIG_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFF0FFB) == (uint32_t)RESET)) +#define IS_RTC_GET_IT(IT) (((IT) == RTC_IT_TS) || ((IT) == RTC_IT_WUT) || \ + ((IT) == RTC_IT_ALRB) || ((IT) == RTC_IT_ALRA) || \ + ((IT) == RTC_IT_TAMP1) || ((IT) == RTC_IT_TAMP2) || \ + ((IT) == RTC_IT_TAMP3)) +#define IS_RTC_CLEAR_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFF10FFF) == (uint32_t)RESET)) + +/** + * @} + */ + +/** @defgroup RTC_Legacy + * @{ + */ +#define RTC_DigitalCalibConfig RTC_CoarseCalibConfig +#define RTC_DigitalCalibCmd RTC_CoarseCalibCmd + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the RTC configuration to the default reset state *****/ +ErrorStatus RTC_DeInit(void); + + +/* Initialization and Configuration functions *********************************/ +ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct); +void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct); +void RTC_WriteProtectionCmd(FunctionalState NewState); +ErrorStatus RTC_EnterInitMode(void); +void RTC_ExitInitMode(void); +ErrorStatus RTC_WaitForSynchro(void); +ErrorStatus RTC_RefClockCmd(FunctionalState NewState); +void RTC_BypassShadowCmd(FunctionalState NewState); + +/* Time and Date configuration functions **************************************/ +ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); +void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct); +void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); +uint32_t RTC_GetSubSecond(void); +ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct); +void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct); +void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct); + +/* Alarms (Alarm A and Alarm B) configuration functions **********************/ +void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); +void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct); +void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); +ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState); +void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask); +uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm); + +/* WakeUp Timer configuration functions ***************************************/ +void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock); +void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter); +uint32_t RTC_GetWakeUpCounter(void); +ErrorStatus RTC_WakeUpCmd(FunctionalState NewState); + +/* Daylight Saving configuration functions ************************************/ +void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation); +uint32_t RTC_GetStoreOperation(void); + +/* Output pin Configuration function ******************************************/ +void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity); + +/* Coarse and Smooth Calibration configuration functions **********************/ +ErrorStatus RTC_CoarseCalibConfig(uint32_t RTC_CalibSign, uint32_t Value); +ErrorStatus RTC_CoarseCalibCmd(FunctionalState NewState); +void RTC_CalibOutputCmd(FunctionalState NewState); +void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput); +ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod, + uint32_t RTC_SmoothCalibPlusPulses, + uint32_t RTC_SmouthCalibMinusPulsesValue); + +/* TimeStamp configuration functions ******************************************/ +void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState); +void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, + RTC_DateTypeDef* RTC_StampDateStruct); +uint32_t RTC_GetTimeStampSubSecond(void); + +/* Tampers configuration functions ********************************************/ +void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger); +void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState); +void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter); +void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq); +void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration); +void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState); +void RTC_TamperPullUpCmd(FunctionalState NewState); + +/* Backup Data Registers configuration functions ******************************/ +void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data); +uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR); + +/* Output Type Config configuration functions *********************************/ +void RTC_OutputTypeConfig(uint32_t RTC_OutputType); + +/* RTC_Shift_control_synchonisation_functions *********************************/ +ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS); + +/* Interrupts and flags management functions **********************************/ +void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState); +FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG); +void RTC_ClearFlag(uint32_t RTC_FLAG); +ITStatus RTC_GetITStatus(uint32_t RTC_IT); +void RTC_ClearITPendingBit(uint32_t RTC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_RTC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_sdio.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_sdio.c new file mode 100644 index 0000000000..fcb11a075b --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_sdio.c @@ -0,0 +1,984 @@ +/** + ****************************************************************************** + * @file stm32l1xx_sdio.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the SDIO peripheral: + * + Initialization + * + Interrupts and flags management + * + * @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) The SDIO clock (SDIOCLK = 48 MHz) is coming from a specific output of PLL + (PLLVCO) througth a fixed divider by 2. + Before to start working with SDIO peripheral make sure that the PLLVCO is + well configured to 96MHz. + The SDIO peripheral uses two clock signals: + (++) SDIO adapter clock (SDIOCLK = 48 MHz). + (++) APB2 bus clock (PCLK2). + PCLK2 and SDIO_CK clock frequencies must respect the following + condition: Frequenc(PCLK2) >= (3 / 8 x Frequency(SDIO_CK)). + (#) Enable peripheral clock using + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE). + (#) According to the SDIO mode, enable the GPIO clocks using + RCC_AHBPeriphClockCmd() function. + The I/O can be one of the following configurations: + (++) 1-bit data length: SDIO_CMD, SDIO_CK and D0. + (++) 4-bit data length: SDIO_CMD, SDIO_CK and D[3:0]. + (++) 8-bit data length: SDIO_CMD, SDIO_CK and D[7:0]. + + (#) Peripheral's alternate function: + (++) Connect the pin to the desired peripherals' Alternate + Function (AF) using GPIO_PinAFConfig() function. + (++) Configure the desired pin in alternate function by: + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF. + (++) Select the type, pull-up/pull-down and output speed via + GPIO_PuPd, GPIO_OType and GPIO_Speed members. + (++) Call GPIO_Init() function. + + (#) Program the Clock Edge, Clock Bypass, Clock Power Save, Bus Wide, + hardware, flow control and the Clock Divider using the SDIO_Init() + function. + (#) Enable the Power ON State using the SDIO_SetPowerState(SDIO_PowerState_ON) + function. + (#) Enable the clock using the SDIO_ClockCmd() function. + (#) Enable the NVIC and the corresponding interrupt using the function + SDIO_ITConfig() if you need to use interrupt mode. + (#) When using the DMA mode + (++) Configure the DMA using DMA_Init() function. + (++) Active the needed channel Request using SDIO_DMACmd() function. + (#) Enable the DMA using the DMA_Cmd() function, when using DMA mode. + (#) To control the CPSM (Command Path State Machine) and send commands to the + card use the SDIO_SendCommand(), SDIO_GetCommandResponse() and + SDIO_GetResponse() functions. First, user has to fill the command + structure (pointer to SDIO_CmdInitTypeDef) according to the selected + command to be sent. The parameters that should be filled are: + (++) Command Argument. + (++) Command Index. + (++) Command Response type. + (++) Command Wait. + (++) CPSM Status (Enable or Disable). + To check if the command is well received, read the SDIO_CMDRESP register + using the SDIO_GetCommandResponse(). The SDIO responses registers + (SDIO_RESP1 to SDIO_RESP2), use the SDIO_GetResponse() function. + (#) To control the DPSM (Data Path State Machine) and send/receive + data to/from the card use the SDIO_DataConfig(), SDIO_GetDataCounter(), + SDIO_ReadData(), SDIO_WriteData() and SDIO_GetFIFOCount() functions. + + *** Read Operations *** + ----------------------- + [..] + (#) First, user has to fill the data structure (pointer to + SDIO_DataInitTypeDef) according to the selected data type to be received. + The parameters that should be filled are: + (++) Data TimeOut. + (++) Data Length. + (++) Data Block size. + (++) Data Transfer direction: should be from card (To SDIO). + (++) Data Transfer mode. + (++) DPSM Status (Enable or Disable). + (#) Configure the SDIO resources to receive the data from the card + according to selected transfer mode (Refer to Step 8, 9 and 10). + (#) Send the selected Read command (refer to step 11). + (#) Use the SDIO flags/interrupts to check the transfer status. + + *** Write Operations *** + ------------------------ + [..] + (#) First, user has to fill the data structure (pointer to + SDIO_DataInitTypeDef) according to the selected data type to be received. + The parameters that should be filled are: + (++) Data TimeOut. + (++) Data Length. + (++) Data Block size. + (++) Data Transfer direction: should be to card (To CARD). + (++) Data Transfer mode. + (++) DPSM Status (Enable or Disable). + (#) Configure the SDIO resources to send the data to the card + according to selected transfer mode (Refer to Step 8, 9 and 10). + (#) Send the selected Write command (refer to step 11). + (#) Use the SDIO flags/interrupts to check the transfer status. + + @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_sdio.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup SDIO + * @brief SDIO driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ------------ SDIO registers bit address in the alias region ----------- */ +#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE) + +/* --- CLKCR Register ---*/ + +/* Alias word address of CLKEN bit */ +#define CLKCR_OFFSET (SDIO_OFFSET + 0x04) +#define CLKEN_BitNumber 0x08 +#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32) + (CLKEN_BitNumber * 4)) + +/* --- CMD Register ---*/ + +/* Alias word address of SDIOSUSPEND bit */ +#define CMD_OFFSET (SDIO_OFFSET + 0x0C) +#define SDIOSUSPEND_BitNumber 0x0B +#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (SDIOSUSPEND_BitNumber * 4)) + +/* Alias word address of ENCMDCOMPL bit */ +#define ENCMDCOMPL_BitNumber 0x0C +#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ENCMDCOMPL_BitNumber * 4)) + +/* Alias word address of NIEN bit */ +#define NIEN_BitNumber 0x0D +#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (NIEN_BitNumber * 4)) + +/* Alias word address of ATACMD bit */ +#define ATACMD_BitNumber 0x0E +#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ATACMD_BitNumber * 4)) + +/* --- DCTRL Register ---*/ + +/* Alias word address of DMAEN bit */ +#define DCTRL_OFFSET (SDIO_OFFSET + 0x2C) +#define DMAEN_BitNumber 0x03 +#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (DMAEN_BitNumber * 4)) + +/* Alias word address of RWSTART bit */ +#define RWSTART_BitNumber 0x08 +#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTART_BitNumber * 4)) + +/* Alias word address of RWSTOP bit */ +#define RWSTOP_BitNumber 0x09 +#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTOP_BitNumber * 4)) + +/* Alias word address of RWMOD bit */ +#define RWMOD_BitNumber 0x0A +#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWMOD_BitNumber * 4)) + +/* Alias word address of SDIOEN bit */ +#define SDIOEN_BitNumber 0x0B +#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (SDIOEN_BitNumber * 4)) + +/* ---------------------- SDIO registers bit mask ------------------------ */ + +/* --- CLKCR Register ---*/ + +/* CLKCR register clear mask */ +#define CLKCR_CLEAR_MASK ((uint32_t)0xFFFF8100) + +/* --- PWRCTRL Register ---*/ + +/* SDIO PWRCTRL Mask */ +#define PWR_PWRCTRL_MASK ((uint32_t)0xFFFFFFFC) + +/* --- DCTRL Register ---*/ + +/* SDIO DCTRL Clear Mask */ +#define DCTRL_CLEAR_MASK ((uint32_t)0xFFFFFF08) + +/* --- CMD Register ---*/ + +/* CMD Register clear mask */ +#define CMD_CLEAR_MASK ((uint32_t)0xFFFFF800) + +/* SDIO RESP Registers Address */ +#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14)) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SDIO_Private_Functions + * @{ + */ + +/** @defgroup SDIO_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the SDIO peripheral registers to their default reset values. + * @param None + * @retval None + */ +void SDIO_DeInit(void) +{ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE); +} + +/** + * @brief Initializes the SDIO peripheral according to the specified + * parameters in the SDIO_InitStruct. + * @param SDIO_InitStruct : pointer to a SDIO_InitTypeDef structure + * that contains the configuration information for the SDIO peripheral. + * @retval None + */ +void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_CLOCK_EDGE(SDIO_InitStruct->SDIO_ClockEdge)); + assert_param(IS_SDIO_CLOCK_BYPASS(SDIO_InitStruct->SDIO_ClockBypass)); + assert_param(IS_SDIO_CLOCK_POWER_SAVE(SDIO_InitStruct->SDIO_ClockPowerSave)); + assert_param(IS_SDIO_BUS_WIDE(SDIO_InitStruct->SDIO_BusWide)); + assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(SDIO_InitStruct->SDIO_HardwareFlowControl)); + +/*---------------------------- SDIO CLKCR Configuration ------------------------*/ + /* Get the SDIO CLKCR value */ + tmpreg = SDIO->CLKCR; + + /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */ + tmpreg &= CLKCR_CLEAR_MASK; + + /* Set CLKDIV bits according to SDIO_ClockDiv value */ + /* Set PWRSAV bit according to SDIO_ClockPowerSave value */ + /* Set BYPASS bit according to SDIO_ClockBypass value */ + /* Set WIDBUS bits according to SDIO_BusWide value */ + /* Set NEGEDGE bits according to SDIO_ClockEdge value */ + /* Set HWFC_EN bits according to SDIO_HardwareFlowControl value */ + tmpreg |= (SDIO_InitStruct->SDIO_ClockDiv | SDIO_InitStruct->SDIO_ClockPowerSave | + SDIO_InitStruct->SDIO_ClockBypass | SDIO_InitStruct->SDIO_BusWide | + SDIO_InitStruct->SDIO_ClockEdge | SDIO_InitStruct->SDIO_HardwareFlowControl); + + /* Write to SDIO CLKCR */ + SDIO->CLKCR = tmpreg; +} + +/** + * @brief Fills each SDIO_InitStruct member with its default value. + * @param SDIO_InitStruct: pointer to an SDIO_InitTypeDef structure which + * will be initialized. + * @retval None + */ +void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct) +{ + /* SDIO_InitStruct members default value */ + SDIO_InitStruct->SDIO_ClockDiv = 0x00; + SDIO_InitStruct->SDIO_ClockEdge = SDIO_ClockEdge_Rising; + SDIO_InitStruct->SDIO_ClockBypass = SDIO_ClockBypass_Disable; + SDIO_InitStruct->SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; + SDIO_InitStruct->SDIO_BusWide = SDIO_BusWide_1b; + SDIO_InitStruct->SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; +} + +/** + * @brief Enables or disables the SDIO Clock. + * @param NewState: new state of the SDIO Clock. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_ClockCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CLKCR_CLKEN_BB = (uint32_t)NewState; +} + +/** + * @brief Sets the power status of the controller. + * @param SDIO_PowerState: new state of the Power state. + * This parameter can be one of the following values: + * @arg SDIO_PowerState_OFF: SDIO Power OFF. + * @arg SDIO_PowerState_ON: SDIO Power ON. + * @retval None + */ +void SDIO_SetPowerState(uint32_t SDIO_PowerState) +{ + /* Check the parameters */ + assert_param(IS_SDIO_POWER_STATE(SDIO_PowerState)); + + SDIO->POWER = SDIO_PowerState; +} + +/** + * @brief Gets the power status of the controller. + * @param None + * @retval Power status of the controller. The returned value can + * be one of the following: + * - 0x00: Power OFF + * - 0x02: Power UP + * - 0x03: Power ON + */ +uint32_t SDIO_GetPowerState(void) +{ + return (SDIO->POWER & (~PWR_PWRCTRL_MASK)); +} + +/** + * @} + */ + +/** @defgroup SDIO_Group2 DMA transfers management functions + * @brief DMA transfers management functions + * + @verbatim + ============================================================================== + ##### DMA transfers management functions ##### + ============================================================================== + [..] This section provide functions allowing to program SDIO DMA transfer. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the SDIO DMA request. + * @param NewState: new state of the selected SDIO DMA request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_DMACmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_DMAEN_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup SDIO_Group3 Command path state machine (CPSM) management functions + * @brief Command path state machine (CPSM) management functions + * + @verbatim + ============================================================================== + ##### Command path state machine (CPSM) management functions ##### + ============================================================================== + [..] This section provide functions allowing to program and read the Command + path state machine (CPSM). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SDIO Command according to the specified + * parameters in the SDIO_CmdInitStruct and send the command. + * @param SDIO_CmdInitStruct : pointer to a SDIO_CmdInitTypeDef + * structure that contains the configuration information for the SDIO command. + * @retval None + */ +void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_CMD_INDEX(SDIO_CmdInitStruct->SDIO_CmdIndex)); + assert_param(IS_SDIO_RESPONSE(SDIO_CmdInitStruct->SDIO_Response)); + assert_param(IS_SDIO_WAIT(SDIO_CmdInitStruct->SDIO_Wait)); + assert_param(IS_SDIO_CPSM(SDIO_CmdInitStruct->SDIO_CPSM)); + +/*---------------------------- SDIO ARG Configuration ------------------------*/ + /* Set the SDIO Argument value */ + SDIO->ARG = SDIO_CmdInitStruct->SDIO_Argument; + +/*---------------------------- SDIO CMD Configuration ------------------------*/ + /* Get the SDIO CMD value */ + tmpreg = SDIO->CMD; + /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, CPSMEN bits */ + tmpreg &= CMD_CLEAR_MASK; + /* Set CMDINDEX bits according to SDIO_CmdIndex value */ + /* Set WAITRESP bits according to SDIO_Response value */ + /* Set WAITINT and WAITPEND bits according to SDIO_Wait value */ + /* Set CPSMEN bits according to SDIO_CPSM value */ + tmpreg |= (uint32_t)SDIO_CmdInitStruct->SDIO_CmdIndex | SDIO_CmdInitStruct->SDIO_Response + | SDIO_CmdInitStruct->SDIO_Wait | SDIO_CmdInitStruct->SDIO_CPSM; + + /* Write to SDIO CMD */ + SDIO->CMD = tmpreg; +} + +/** + * @brief Fills each SDIO_CmdInitStruct member with its default value. + * @param SDIO_CmdInitStruct: pointer to an SDIO_CmdInitTypeDef + * structure which will be initialized. + * @retval None + */ +void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct) +{ + /* SDIO_CmdInitStruct members default value */ + SDIO_CmdInitStruct->SDIO_Argument = 0x00; + SDIO_CmdInitStruct->SDIO_CmdIndex = 0x00; + SDIO_CmdInitStruct->SDIO_Response = SDIO_Response_No; + SDIO_CmdInitStruct->SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStruct->SDIO_CPSM = SDIO_CPSM_Disable; +} + +/** + * @brief Returns command index of last command for which response received. + * @param None + * @retval Returns the command index of the last command response received. + */ +uint8_t SDIO_GetCommandResponse(void) +{ + return (uint8_t)(SDIO->RESPCMD); +} + +/** + * @brief Returns response received from the card for the last command. + * @param SDIO_RESP: Specifies the SDIO response register. + * This parameter can be one of the following values: + * @arg SDIO_RESP1: Response Register 1. + * @arg SDIO_RESP2: Response Register 2. + * @arg SDIO_RESP3: Response Register 3. + * @arg SDIO_RESP4: Response Register 4. + * @retval The Corresponding response register value. + */ +uint32_t SDIO_GetResponse(uint32_t SDIO_RESP) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_RESP(SDIO_RESP)); + + tmp = SDIO_RESP_ADDR + SDIO_RESP; + + return (*(__IO uint32_t *) tmp); +} + +/** + * @} + */ + +/** @defgroup SDIO_Group4 Data path state machine (DPSM) management functions + * @brief Data path state machine (DPSM) management functions + * + @verbatim + ============================================================================== + ##### Data path state machine (DPSM) management functions ##### + ============================================================================== + [..] This section provide functions allowing to program and read the Data path + state machine (DPSM). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SDIO data path according to the specified + * parameters in the SDIO_DataInitStruct. + * @param SDIO_DataInitStruct : pointer to a SDIO_DataInitTypeDef structure that + * contains the configuration information for the SDIO command. + * @retval None + */ +void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_DATA_LENGTH(SDIO_DataInitStruct->SDIO_DataLength)); + assert_param(IS_SDIO_BLOCK_SIZE(SDIO_DataInitStruct->SDIO_DataBlockSize)); + assert_param(IS_SDIO_TRANSFER_DIR(SDIO_DataInitStruct->SDIO_TransferDir)); + assert_param(IS_SDIO_TRANSFER_MODE(SDIO_DataInitStruct->SDIO_TransferMode)); + assert_param(IS_SDIO_DPSM(SDIO_DataInitStruct->SDIO_DPSM)); + +/*---------------------------- SDIO DTIMER Configuration ---------------------*/ + /* Set the SDIO Data TimeOut value */ + SDIO->DTIMER = SDIO_DataInitStruct->SDIO_DataTimeOut; + +/*---------------------------- SDIO DLEN Configuration -----------------------*/ + /* Set the SDIO DataLength value */ + SDIO->DLEN = SDIO_DataInitStruct->SDIO_DataLength; + +/*---------------------------- SDIO DCTRL Configuration ----------------------*/ + /* Get the SDIO DCTRL value */ + tmpreg = SDIO->DCTRL; + /* Clear DEN, DTMODE, DTDIR and DBCKSIZE bits */ + tmpreg &= DCTRL_CLEAR_MASK; + /* Set DEN bit according to SDIO_DPSM value */ + /* Set DTMODE bit according to SDIO_TransferMode value */ + /* Set DTDIR bit according to SDIO_TransferDir value */ + /* Set DBCKSIZE bits according to SDIO_DataBlockSize value */ + tmpreg |= (uint32_t)SDIO_DataInitStruct->SDIO_DataBlockSize | SDIO_DataInitStruct->SDIO_TransferDir + | SDIO_DataInitStruct->SDIO_TransferMode | SDIO_DataInitStruct->SDIO_DPSM; + + /* Write to SDIO DCTRL */ + SDIO->DCTRL = tmpreg; +} + +/** + * @brief Fills each SDIO_DataInitStruct member with its default value. + * @param SDIO_DataInitStruct: pointer to an SDIO_DataInitTypeDef structure which + * will be initialized. + * @retval None + */ +void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct) +{ + /* SDIO_DataInitStruct members default value */ + SDIO_DataInitStruct->SDIO_DataTimeOut = 0xFFFFFFFF; + SDIO_DataInitStruct->SDIO_DataLength = 0x00; + SDIO_DataInitStruct->SDIO_DataBlockSize = SDIO_DataBlockSize_1b; + SDIO_DataInitStruct->SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStruct->SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStruct->SDIO_DPSM = SDIO_DPSM_Disable; +} + +/** + * @brief Returns number of remaining data bytes to be transferred. + * @param None + * @retval Number of remaining data bytes to be transferred + */ +uint32_t SDIO_GetDataCounter(void) +{ + return SDIO->DCOUNT; +} + +/** + * @brief Read one data word from Rx FIFO. + * @param None + * @retval Data received + */ +uint32_t SDIO_ReadData(void) +{ + return SDIO->FIFO; +} + +/** + * @brief Write one data word to Tx FIFO. + * @param Data: 32-bit data word to write. + * @retval None + */ +void SDIO_WriteData(uint32_t Data) +{ + SDIO->FIFO = Data; +} + +/** + * @brief Returns the number of words left to be written to or read from FIFO. + * @param None + * @retval Remaining number of words. + */ +uint32_t SDIO_GetFIFOCount(void) +{ + return SDIO->FIFOCNT; +} + +/** + * @} + */ + +/** @defgroup SDIO_Group5 SDIO IO Cards mode management functions + * @brief SDIO IO Cards mode management functions + * + @verbatim + ============================================================================== + ##### SDIO IO Cards mode management functions ##### + ============================================================================== + [..] This section provide functions allowing to program and read the SDIO IO + Cards. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the SD I/O Read Wait operation. + * @param NewState: new state of the Start SDIO Read Wait operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_StartSDIOReadWait(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_RWSTART_BB = (uint32_t) NewState; +} + +/** + * @brief Stops the SD I/O Read Wait operation. + * @param NewState: new state of the Stop SDIO Read Wait operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_StopSDIOReadWait(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_RWSTOP_BB = (uint32_t) NewState; +} + +/** + * @brief Sets one of the two options of inserting read wait interval. + * @param SDIO_ReadWaitMode: SD I/O Read Wait operation mode. + * This parametre can be: + * @arg SDIO_ReadWaitMode_CLK: Read Wait control by stopping SDIOCLK. + * @arg SDIO_ReadWaitMode_DATA2: Read Wait control using SDIO_DATA2. + * @retval None + */ +void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode) +{ + /* Check the parameters */ + assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode)); + + *(__IO uint32_t *) DCTRL_RWMOD_BB = SDIO_ReadWaitMode; +} + +/** + * @brief Enables or disables the SD I/O Mode Operation. + * @param NewState: new state of SDIO specific operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SetSDIOOperation(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_SDIOEN_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the SD I/O Mode suspend command sending. + * @param NewState: new state of the SD I/O Mode suspend command. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SendSDIOSuspendCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_SDIOSUSPEND_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup SDIO_Group6 CE-ATA mode management functions + * @brief CE-ATA mode management functions + * + @verbatim + ============================================================================== + ##### CE-ATA mode management functions ##### + ============================================================================== + [..] This section provide functions allowing to program and read the CE-ATA + card. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the command completion signal. + * @param NewState: new state of command completion signal. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_CommandCompletionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_ENCMDCOMPL_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the CE-ATA interrupt. + * @param NewState: new state of CE-ATA interrupt. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_CEATAITCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)((~((uint32_t)NewState)) & ((uint32_t)0x1)); +} + +/** + * @brief Sends CE-ATA command (CMD61). + * @param NewState: new state of CE-ATA command. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SendCEATACmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_ATACMD_BB = (uint32_t)NewState; +} + +/** + * @} + */ + +/** @defgroup SDIO_Group7 Interrupts and flags management functions + * @brief Interrupts and flags management functions + + + @verbatim + ============================================================================== + ##### Interrupts and flags management functions ##### + ============================================================================== + + @endverbatim + * @{ + */ + +/** + * @brief Enables or disables the SDIO interrupts. + * @param SDIO_IT: specifies the SDIO interrupt sources to be enabled or disabled. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt. + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt. + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt. + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt. + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt. + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt. + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt. + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt. + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt. + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt. + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt. + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt. + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt. + * @arg SDIO_IT_RXACT: Data receive in progress interrupt. + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt. + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt. + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt. + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt. + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt. + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt. + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt. + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt. + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt. + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt. + * @param NewState: new state of the specified SDIO interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SDIO_IT(SDIO_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the SDIO interrupts */ + SDIO->MASK |= SDIO_IT; + } + else + { + /* Disable the SDIO interrupts */ + SDIO->MASK &= ~SDIO_IT; + } +} + +/** + * @brief Checks whether the specified SDIO flag is set or not. + * @param SDIO_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed). + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed). + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout. + * @arg SDIO_FLAG_DTIMEOUT: Data timeout. + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error. + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error. + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed). + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required). + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero). + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide + * bus mode. + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed). + * @arg SDIO_FLAG_CMDACT: Command transfer in progress. + * @arg SDIO_FLAG_TXACT: Data transmit in progress. + * @arg SDIO_FLAG_RXACT: Data receive in progress. + * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty. + * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full. + * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full. + * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full. + * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty. + * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty. + * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO. + * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO. + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received. + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61. + * @retval The new state of SDIO_FLAG (SET or RESET). + */ +FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_SDIO_FLAG(SDIO_FLAG)); + + if ((SDIO->STA & SDIO_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the SDIO's pending flags. + * @param SDIO_FLAG: specifies the flag to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed). + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed). + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout. + * @arg SDIO_FLAG_DTIMEOUT: Data timeout. + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error. + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error. + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed). + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required). + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero). + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide + * bus mode. + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed). + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received. + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61. + * @retval None + */ +void SDIO_ClearFlag(uint32_t SDIO_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SDIO_CLEAR_FLAG(SDIO_FLAG)); + + SDIO->ICR = SDIO_FLAG; +} + +/** + * @brief Checks whether the specified SDIO interrupt has occurred or not. + * @param SDIO_IT: specifies the SDIO interrupt source to check. + * This parameter can be one of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt. + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt. + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt. + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt. + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt. + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt. + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt. + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt. + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt. + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt. + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt. + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt. + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt. + * @arg SDIO_IT_RXACT: Data receive in progress interrupt. + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt. + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt. + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt. + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt. + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt. + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt. + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt. + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt. + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt. + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt. + * @retval The new state of SDIO_IT (SET or RESET). + */ +ITStatus SDIO_GetITStatus(uint32_t SDIO_IT) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_SDIO_GET_IT(SDIO_IT)); + if ((SDIO->STA & SDIO_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the SDIO's interrupt pending bits. + * @param SDIO_IT: specifies the interrupt pending bit to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt. + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt. + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt. + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt. + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt. + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt. + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt. + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt. + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt. + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt. + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt. + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61. + * @retval None + */ +void SDIO_ClearITPendingBit(uint32_t SDIO_IT) +{ + /* Check the parameters */ + assert_param(IS_SDIO_CLEAR_IT(SDIO_IT)); + + SDIO->ICR = SDIO_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_sdio.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_sdio.h new file mode 100644 index 0000000000..54599fa966 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_sdio.h @@ -0,0 +1,535 @@ +/** + ****************************************************************************** + * @file stm32l1xx_sdio.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the SDIO firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_SDIO_H +#define __STM32L1xx_SDIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup SDIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +typedef struct +{ + uint32_t SDIO_ClockEdge; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref SDIO_Clock_Edge */ + + uint32_t SDIO_ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is + enabled or disabled. + This parameter can be a value of @ref SDIO_Clock_Bypass */ + + uint32_t SDIO_ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or + disabled when the bus is idle. + This parameter can be a value of @ref SDIO_Clock_Power_Save */ + + uint32_t SDIO_BusWide; /*!< Specifies the SDIO bus width. + This parameter can be a value of @ref SDIO_Bus_Wide */ + + uint32_t SDIO_HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled. + This parameter can be a value of @ref SDIO_Hardware_Flow_Control */ + + uint8_t SDIO_ClockDiv; /*!< Specifies the clock frequency of the SDIO controller. + This parameter can be a value between 0x00 and 0xFF. */ + +} SDIO_InitTypeDef; + +typedef struct +{ + uint32_t SDIO_Argument; /*!< Specifies the SDIO command argument which is sent + to a card as part of a command message. If a command + contains an argument, it must be loaded into this register + before writing the command to the command register */ + + uint32_t SDIO_CmdIndex; /*!< Specifies the SDIO command index. It must be lower than 0x40. */ + + uint32_t SDIO_Response; /*!< Specifies the SDIO response type. + This parameter can be a value of @ref SDIO_Response_Type */ + + uint32_t SDIO_Wait; /*!< Specifies whether SDIO wait-for-interrupt request is enabled or disabled. + This parameter can be a value of @ref SDIO_Wait_Interrupt_State */ + + uint32_t SDIO_CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM) + is enabled or disabled. + This parameter can be a value of @ref SDIO_CPSM_State */ +} SDIO_CmdInitTypeDef; + +typedef struct +{ + uint32_t SDIO_DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */ + + uint32_t SDIO_DataLength; /*!< Specifies the number of data bytes to be transferred. */ + + uint32_t SDIO_DataBlockSize; /*!< Specifies the data block size for block transfer. + This parameter can be a value of @ref SDIO_Data_Block_Size */ + + uint32_t SDIO_TransferDir; /*!< Specifies the data transfer direction, whether the transfer + is a read or write. + This parameter can be a value of @ref SDIO_Transfer_Direction */ + + uint32_t SDIO_TransferMode; /*!< Specifies whether data transfer is in stream or block mode. + This parameter can be a value of @ref SDIO_Transfer_Type */ + + uint32_t SDIO_DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM) + is enabled or disabled. + This parameter can be a value of @ref SDIO_DPSM_State */ +} SDIO_DataInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SDIO_Exported_Constants + * @{ + */ + +/** @defgroup SDIO_Clock_Edge + * @{ + */ + +#define SDIO_ClockEdge_Rising ((uint32_t)0x00000000) +#define SDIO_ClockEdge_Falling ((uint32_t)0x00002000) +#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_ClockEdge_Rising) || \ + ((EDGE) == SDIO_ClockEdge_Falling)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Bypass + * @{ + */ + +#define SDIO_ClockBypass_Disable ((uint32_t)0x00000000) +#define SDIO_ClockBypass_Enable ((uint32_t)0x00000400) +#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_ClockBypass_Disable) || \ + ((BYPASS) == SDIO_ClockBypass_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Power_Save + * @{ + */ + +#define SDIO_ClockPowerSave_Disable ((uint32_t)0x00000000) +#define SDIO_ClockPowerSave_Enable ((uint32_t)0x00000200) +#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_ClockPowerSave_Disable) || \ + ((SAVE) == SDIO_ClockPowerSave_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Bus_Wide + * @{ + */ + +#define SDIO_BusWide_1b ((uint32_t)0x00000000) +#define SDIO_BusWide_4b ((uint32_t)0x00000800) +#define SDIO_BusWide_8b ((uint32_t)0x00001000) +#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BusWide_1b) || ((WIDE) == SDIO_BusWide_4b) || \ + ((WIDE) == SDIO_BusWide_8b)) + +/** + * @} + */ + +/** @defgroup SDIO_Hardware_Flow_Control + * @{ + */ + +#define SDIO_HardwareFlowControl_Disable ((uint32_t)0x00000000) +#define SDIO_HardwareFlowControl_Enable ((uint32_t)0x00004000) +#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HardwareFlowControl_Disable) || \ + ((CONTROL) == SDIO_HardwareFlowControl_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Power_State + * @{ + */ + +#define SDIO_PowerState_OFF ((uint32_t)0x00000000) +#define SDIO_PowerState_ON ((uint32_t)0x00000003) +#define IS_SDIO_POWER_STATE(STATE) (((STATE) == SDIO_PowerState_OFF) || ((STATE) == SDIO_PowerState_ON)) +/** + * @} + */ + + +/** @defgroup SDIO_Interrupt_soucres + * @{ + */ + +#define SDIO_IT_CCRCFAIL ((uint32_t)0x00000001) +#define SDIO_IT_DCRCFAIL ((uint32_t)0x00000002) +#define SDIO_IT_CTIMEOUT ((uint32_t)0x00000004) +#define SDIO_IT_DTIMEOUT ((uint32_t)0x00000008) +#define SDIO_IT_TXUNDERR ((uint32_t)0x00000010) +#define SDIO_IT_RXOVERR ((uint32_t)0x00000020) +#define SDIO_IT_CMDREND ((uint32_t)0x00000040) +#define SDIO_IT_CMDSENT ((uint32_t)0x00000080) +#define SDIO_IT_DATAEND ((uint32_t)0x00000100) +#define SDIO_IT_STBITERR ((uint32_t)0x00000200) +#define SDIO_IT_DBCKEND ((uint32_t)0x00000400) +#define SDIO_IT_CMDACT ((uint32_t)0x00000800) +#define SDIO_IT_TXACT ((uint32_t)0x00001000) +#define SDIO_IT_RXACT ((uint32_t)0x00002000) +#define SDIO_IT_TXFIFOHE ((uint32_t)0x00004000) +#define SDIO_IT_RXFIFOHF ((uint32_t)0x00008000) +#define SDIO_IT_TXFIFOF ((uint32_t)0x00010000) +#define SDIO_IT_RXFIFOF ((uint32_t)0x00020000) +#define SDIO_IT_TXFIFOE ((uint32_t)0x00040000) +#define SDIO_IT_RXFIFOE ((uint32_t)0x00080000) +#define SDIO_IT_TXDAVL ((uint32_t)0x00100000) +#define SDIO_IT_RXDAVL ((uint32_t)0x00200000) +#define SDIO_IT_SDIOIT ((uint32_t)0x00400000) +#define SDIO_IT_CEATAEND ((uint32_t)0x00800000) +#define IS_SDIO_IT(IT) ((((IT) & (uint32_t)0xFF000000) == 0x00) && ((IT) != (uint32_t)0x00)) +/** + * @} + */ + +/** @defgroup SDIO_Command_Index + * @{ + */ + +#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40) +/** + * @} + */ + +/** @defgroup SDIO_Response_Type + * @{ + */ + +#define SDIO_Response_No ((uint32_t)0x00000000) +#define SDIO_Response_Short ((uint32_t)0x00000040) +#define SDIO_Response_Long ((uint32_t)0x000000C0) +#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_Response_No) || \ + ((RESPONSE) == SDIO_Response_Short) || \ + ((RESPONSE) == SDIO_Response_Long)) +/** + * @} + */ + +/** @defgroup SDIO_Wait_Interrupt_State + * @{ + */ + +#define SDIO_Wait_No ((uint32_t)0x00000000) /*!< SDIO No Wait, TimeOut is enabled */ +#define SDIO_Wait_IT ((uint32_t)0x00000100) /*!< SDIO Wait Interrupt Request */ +#define SDIO_Wait_Pend ((uint32_t)0x00000200) /*!< SDIO Wait End of transfer */ +#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_Wait_No) || ((WAIT) == SDIO_Wait_IT) || \ + ((WAIT) == SDIO_Wait_Pend)) +/** + * @} + */ + +/** @defgroup SDIO_CPSM_State + * @{ + */ + +#define SDIO_CPSM_Disable ((uint32_t)0x00000000) +#define SDIO_CPSM_Enable ((uint32_t)0x00000400) +#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_Enable) || ((CPSM) == SDIO_CPSM_Disable)) +/** + * @} + */ + +/** @defgroup SDIO_Response_Registers + * @{ + */ + +#define SDIO_RESP1 ((uint32_t)0x00000000) +#define SDIO_RESP2 ((uint32_t)0x00000004) +#define SDIO_RESP3 ((uint32_t)0x00000008) +#define SDIO_RESP4 ((uint32_t)0x0000000C) +#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || ((RESP) == SDIO_RESP2) || \ + ((RESP) == SDIO_RESP3) || ((RESP) == SDIO_RESP4)) +/** + * @} + */ + +/** @defgroup SDIO_Data_Length + * @{ + */ + +#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF) +/** + * @} + */ + +/** @defgroup SDIO_Data_Block_Size + * @{ + */ + +#define SDIO_DataBlockSize_1b ((uint32_t)0x00000000) +#define SDIO_DataBlockSize_2b ((uint32_t)0x00000010) +#define SDIO_DataBlockSize_4b ((uint32_t)0x00000020) +#define SDIO_DataBlockSize_8b ((uint32_t)0x00000030) +#define SDIO_DataBlockSize_16b ((uint32_t)0x00000040) +#define SDIO_DataBlockSize_32b ((uint32_t)0x00000050) +#define SDIO_DataBlockSize_64b ((uint32_t)0x00000060) +#define SDIO_DataBlockSize_128b ((uint32_t)0x00000070) +#define SDIO_DataBlockSize_256b ((uint32_t)0x00000080) +#define SDIO_DataBlockSize_512b ((uint32_t)0x00000090) +#define SDIO_DataBlockSize_1024b ((uint32_t)0x000000A0) +#define SDIO_DataBlockSize_2048b ((uint32_t)0x000000B0) +#define SDIO_DataBlockSize_4096b ((uint32_t)0x000000C0) +#define SDIO_DataBlockSize_8192b ((uint32_t)0x000000D0) +#define SDIO_DataBlockSize_16384b ((uint32_t)0x000000E0) +#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DataBlockSize_1b) || \ + ((SIZE) == SDIO_DataBlockSize_2b) || \ + ((SIZE) == SDIO_DataBlockSize_4b) || \ + ((SIZE) == SDIO_DataBlockSize_8b) || \ + ((SIZE) == SDIO_DataBlockSize_16b) || \ + ((SIZE) == SDIO_DataBlockSize_32b) || \ + ((SIZE) == SDIO_DataBlockSize_64b) || \ + ((SIZE) == SDIO_DataBlockSize_128b) || \ + ((SIZE) == SDIO_DataBlockSize_256b) || \ + ((SIZE) == SDIO_DataBlockSize_512b) || \ + ((SIZE) == SDIO_DataBlockSize_1024b) || \ + ((SIZE) == SDIO_DataBlockSize_2048b) || \ + ((SIZE) == SDIO_DataBlockSize_4096b) || \ + ((SIZE) == SDIO_DataBlockSize_8192b) || \ + ((SIZE) == SDIO_DataBlockSize_16384b)) +/** + * @} + */ + +/** @defgroup SDIO_Transfer_Direction + * @{ + */ + +#define SDIO_TransferDir_ToCard ((uint32_t)0x00000000) +#define SDIO_TransferDir_ToSDIO ((uint32_t)0x00000002) +#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TransferDir_ToCard) || \ + ((DIR) == SDIO_TransferDir_ToSDIO)) +/** + * @} + */ + +/** @defgroup SDIO_Transfer_Type + * @{ + */ + +#define SDIO_TransferMode_Block ((uint32_t)0x00000000) +#define SDIO_TransferMode_Stream ((uint32_t)0x00000004) +#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TransferMode_Stream) || \ + ((MODE) == SDIO_TransferMode_Block)) +/** + * @} + */ + +/** @defgroup SDIO_DPSM_State + * @{ + */ + +#define SDIO_DPSM_Disable ((uint32_t)0x00000000) +#define SDIO_DPSM_Enable ((uint32_t)0x00000001) +#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_Enable) || ((DPSM) == SDIO_DPSM_Disable)) +/** + * @} + */ + +/** @defgroup SDIO_Flags + * @{ + */ + +#define SDIO_FLAG_CCRCFAIL ((uint32_t)0x00000001) +#define SDIO_FLAG_DCRCFAIL ((uint32_t)0x00000002) +#define SDIO_FLAG_CTIMEOUT ((uint32_t)0x00000004) +#define SDIO_FLAG_DTIMEOUT ((uint32_t)0x00000008) +#define SDIO_FLAG_TXUNDERR ((uint32_t)0x00000010) +#define SDIO_FLAG_RXOVERR ((uint32_t)0x00000020) +#define SDIO_FLAG_CMDREND ((uint32_t)0x00000040) +#define SDIO_FLAG_CMDSENT ((uint32_t)0x00000080) +#define SDIO_FLAG_DATAEND ((uint32_t)0x00000100) +#define SDIO_FLAG_STBITERR ((uint32_t)0x00000200) +#define SDIO_FLAG_DBCKEND ((uint32_t)0x00000400) +#define SDIO_FLAG_CMDACT ((uint32_t)0x00000800) +#define SDIO_FLAG_TXACT ((uint32_t)0x00001000) +#define SDIO_FLAG_RXACT ((uint32_t)0x00002000) +#define SDIO_FLAG_TXFIFOHE ((uint32_t)0x00004000) +#define SDIO_FLAG_RXFIFOHF ((uint32_t)0x00008000) +#define SDIO_FLAG_TXFIFOF ((uint32_t)0x00010000) +#define SDIO_FLAG_RXFIFOF ((uint32_t)0x00020000) +#define SDIO_FLAG_TXFIFOE ((uint32_t)0x00040000) +#define SDIO_FLAG_RXFIFOE ((uint32_t)0x00080000) +#define SDIO_FLAG_TXDAVL ((uint32_t)0x00100000) +#define SDIO_FLAG_RXDAVL ((uint32_t)0x00200000) +#define SDIO_FLAG_SDIOIT ((uint32_t)0x00400000) +#define SDIO_FLAG_CEATAEND ((uint32_t)0x00800000) +#define IS_SDIO_FLAG(FLAG) (((FLAG) == SDIO_FLAG_CCRCFAIL) || \ + ((FLAG) == SDIO_FLAG_DCRCFAIL) || \ + ((FLAG) == SDIO_FLAG_CTIMEOUT) || \ + ((FLAG) == SDIO_FLAG_DTIMEOUT) || \ + ((FLAG) == SDIO_FLAG_TXUNDERR) || \ + ((FLAG) == SDIO_FLAG_RXOVERR) || \ + ((FLAG) == SDIO_FLAG_CMDREND) || \ + ((FLAG) == SDIO_FLAG_CMDSENT) || \ + ((FLAG) == SDIO_FLAG_DATAEND) || \ + ((FLAG) == SDIO_FLAG_STBITERR) || \ + ((FLAG) == SDIO_FLAG_DBCKEND) || \ + ((FLAG) == SDIO_FLAG_CMDACT) || \ + ((FLAG) == SDIO_FLAG_TXACT) || \ + ((FLAG) == SDIO_FLAG_RXACT) || \ + ((FLAG) == SDIO_FLAG_TXFIFOHE) || \ + ((FLAG) == SDIO_FLAG_RXFIFOHF) || \ + ((FLAG) == SDIO_FLAG_TXFIFOF) || \ + ((FLAG) == SDIO_FLAG_RXFIFOF) || \ + ((FLAG) == SDIO_FLAG_TXFIFOE) || \ + ((FLAG) == SDIO_FLAG_RXFIFOE) || \ + ((FLAG) == SDIO_FLAG_TXDAVL) || \ + ((FLAG) == SDIO_FLAG_RXDAVL) || \ + ((FLAG) == SDIO_FLAG_SDIOIT) || \ + ((FLAG) == SDIO_FLAG_CEATAEND)) + +#define IS_SDIO_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFF3FF800) == 0x00) && ((FLAG) != (uint32_t)0x00)) + +#define IS_SDIO_GET_IT(IT) (((IT) == SDIO_IT_CCRCFAIL) || \ + ((IT) == SDIO_IT_DCRCFAIL) || \ + ((IT) == SDIO_IT_CTIMEOUT) || \ + ((IT) == SDIO_IT_DTIMEOUT) || \ + ((IT) == SDIO_IT_TXUNDERR) || \ + ((IT) == SDIO_IT_RXOVERR) || \ + ((IT) == SDIO_IT_CMDREND) || \ + ((IT) == SDIO_IT_CMDSENT) || \ + ((IT) == SDIO_IT_DATAEND) || \ + ((IT) == SDIO_IT_STBITERR) || \ + ((IT) == SDIO_IT_DBCKEND) || \ + ((IT) == SDIO_IT_CMDACT) || \ + ((IT) == SDIO_IT_TXACT) || \ + ((IT) == SDIO_IT_RXACT) || \ + ((IT) == SDIO_IT_TXFIFOHE) || \ + ((IT) == SDIO_IT_RXFIFOHF) || \ + ((IT) == SDIO_IT_TXFIFOF) || \ + ((IT) == SDIO_IT_RXFIFOF) || \ + ((IT) == SDIO_IT_TXFIFOE) || \ + ((IT) == SDIO_IT_RXFIFOE) || \ + ((IT) == SDIO_IT_TXDAVL) || \ + ((IT) == SDIO_IT_RXDAVL) || \ + ((IT) == SDIO_IT_SDIOIT) || \ + ((IT) == SDIO_IT_CEATAEND)) + +#define IS_SDIO_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFF3FF800) == 0x00) && ((IT) != (uint32_t)0x00)) + +/** + * @} + */ + +/** @defgroup SDIO_Read_Wait_Mode + * @{ + */ + +#define SDIO_ReadWaitMode_CLK ((uint32_t)0x00000001) +#define SDIO_ReadWaitMode_DATA2 ((uint32_t)0x00000000) +#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_ReadWaitMode_CLK) || \ + ((MODE) == SDIO_ReadWaitMode_DATA2)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Function used to set the SDIO configuration to the default reset state ****/ +void SDIO_DeInit(void); + +/* Initialization and Configuration functions *********************************/ +void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct); +void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct); +void SDIO_ClockCmd(FunctionalState NewState); +void SDIO_SetPowerState(uint32_t SDIO_PowerState); +uint32_t SDIO_GetPowerState(void); + +/* DMA transfers management functions *****************************************/ +void SDIO_DMACmd(FunctionalState NewState); + +/* Command path state machine (CPSM) management functions *********************/ +void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct); +void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct); +uint8_t SDIO_GetCommandResponse(void); +uint32_t SDIO_GetResponse(uint32_t SDIO_RESP); + +/* Data path state machine (DPSM) management functions ************************/ +void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct); +void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct); +uint32_t SDIO_GetDataCounter(void); +uint32_t SDIO_ReadData(void); +void SDIO_WriteData(uint32_t Data); +uint32_t SDIO_GetFIFOCount(void); + +/* SDIO IO Cards mode management functions ************************************/ +void SDIO_StartSDIOReadWait(FunctionalState NewState); +void SDIO_StopSDIOReadWait(FunctionalState NewState); +void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode); +void SDIO_SetSDIOOperation(FunctionalState NewState); +void SDIO_SendSDIOSuspendCmd(FunctionalState NewState); + +/* CE-ATA mode management functions *******************************************/ +void SDIO_CommandCompletionCmd(FunctionalState NewState); +void SDIO_CEATAITCmd(FunctionalState NewState); +void SDIO_SendCEATACmd(FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState); +FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG); +void SDIO_ClearFlag(uint32_t SDIO_FLAG); +ITStatus SDIO_GetITStatus(uint32_t SDIO_IT); +void SDIO_ClearITPendingBit(uint32_t SDIO_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_SDIO_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_spi.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_spi.c new file mode 100644 index 0000000000..19edb722e3 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_spi.c @@ -0,0 +1,1076 @@ +/** + ****************************************************************************** + * @file stm32l1xx_spi.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Serial peripheral interface (SPI): + * + Initialization and Configuration + * + Data transfers functions + * + Hardware CRC Calculation + * + DMA transfers management + * + Interrupts and flags management + * + * @verbatim + [..] The I2S feature is not implemented in STM32L1xx Ultra Low Power + Medium-density devices and it's supported only STM32L1xx Ultra Low Power + Medium-density Plus and High-density devices. + + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + (#) Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE) + function for SPI1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE) + function for SPI2 or using RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) + for SPI3. + + (#) Enable SCK, MOSI, MISO and NSS GPIO clocks using + RCC_AHBPeriphClockCmd() function. + + (#) Peripherals alternate function: + (++) Connect the pin to the desired peripherals' Alternate + Function (AF) using GPIO_PinAFConfig() function. + (++) Configure the desired pin in alternate function by: + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF. + (++) Select the type, pull-up/pull-down and output speed via + GPIO_PuPd, GPIO_OType and GPIO_Speed members. + (++) Call GPIO_Init() function. + + (#) Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave + Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() + function.In I2S mode, program the Mode, Standard, Data Format, MCLK + Output, Audio frequency and Polarity using I2S_Init() function. + + (#) Enable the NVIC and the corresponding interrupt using the function + SPI_ITConfig() if you need to use interrupt mode. + + (#) When using the DMA mode + (++) Configure the DMA using DMA_Init() function. + (++) Active the needed channel Request using SPI_I2S_DMACmd() function. + + (#) Enable the SPI using the SPI_Cmd() function or enable the I2S using + I2S_Cmd(). + + (#) Enable the DMA using the DMA_Cmd() function when using DMA mode. + + (#) Optionally, you can enable/configure the following parameters without + re-initialization (i.e there is no need to call again SPI_Init() function): + (++) When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx) + is programmed as Data direction parameter using the SPI_Init() + function it can be possible to switch between SPI_Direction_Tx + or SPI_Direction_Rx using the SPI_BiDirectionalLineConfig() function. + (++) When SPI_NSS_Soft is selected as Slave Select Management parameter + using the SPI_Init() function it can be possible to manage the + NSS internal signal using the SPI_NSSInternalSoftwareConfig() function. + (++) Reconfigure the data size using the SPI_DataSizeConfig() function. + (++) Enable or disable the SS output using the SPI_SSOutputCmd() function. + + (#) To use the CRC Hardware calculation feature refer to the Peripheral + CRC hardware Calculation subsection. + + @endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_spi.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup SPI + * @brief SPI driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* SPI registers Masks */ +#define CR1_CLEAR_MASK ((uint16_t)0x3040) +#define I2SCFGR_CLEAR_Mask ((uint16_t)0xF040) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SPI_Private_Functions + * @{ + */ + +/** @defgroup SPI_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides a set of functions allowing to initialize the SPI + Direction, SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS + Management, SPI Baud Rate Prescaler, SPI First Bit and SPI CRC Polynomial. + [..] The SPI_Init() function follows the SPI configuration procedures for + Master mode and Slave mode (details for these procedures are available + in reference manual (RM0038)). + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the SPIx peripheral registers to their default + * reset values. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + * @retval None + */ +void SPI_I2S_DeInit(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + if (SPIx == SPI1) + { + /* Enable SPI1 reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); + /* Release SPI1 from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); + } + else if (SPIx == SPI2) + { + /* Enable SPI2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); + /* Release SPI2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); + } + else + { + if (SPIx == SPI3) + { + /* Enable SPI3 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE); + /* Release SPI3 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE); + } + } +} + +/** + * @brief Initializes the SPIx peripheral according to the specified + * parameters in the SPI_InitStruct. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral. + * @retval None + */ +void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct) +{ + uint16_t tmpreg = 0; + + /* check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Check the SPI parameters */ + assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); + assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); + assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); + assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); + assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); + assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS)); + assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler)); + assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit)); + assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial)); + +/*---------------------------- SPIx CR1 Configuration ------------------------*/ + /* Get the SPIx CR1 value */ + tmpreg = SPIx->CR1; + /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */ + tmpreg &= CR1_CLEAR_MASK; + /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler + master/salve mode, CPOL and CPHA */ + /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */ + /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */ + /* Set LSBFirst bit according to SPI_FirstBit value */ + /* Set BR bits according to SPI_BaudRatePrescaler value */ + /* Set CPOL bit according to SPI_CPOL value */ + /* Set CPHA bit according to SPI_CPHA value */ + tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode | + SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL | + SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS | + SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit); + /* Write to SPIx CR1 */ + SPIx->CR1 = tmpreg; + + /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ + SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD); +/*---------------------------- SPIx CRCPOLY Configuration --------------------*/ + /* Write to SPIx CRCPOLY */ + SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial; +} + +/** + * @brief Initializes the SPIx peripheral according to the specified + * parameters in the I2S_InitStruct. + * @param SPIx: where x can be 2 or 3 to select the SPI peripheral + * (configured in I2S mode). + * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral + * configured in I2S mode. + * @note + * The function calculates the optimal prescaler needed to obtain the most + * accurate audio frequency (depending on the I2S clock source, the PLL values + * and the product configuration). But in case the prescaler value is greater + * than 511, the default value (0x02) will be configured instead. + * @retval None + */ +void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct) +{ + uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1; + uint32_t tmp = 0; + RCC_ClocksTypeDef RCC_Clocks; + uint32_t sourceclock = 0; + + /* Check the I2S parameters */ + assert_param(IS_SPI_23_PERIPH(SPIx)); + assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode)); + assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard)); + assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); + assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput)); + assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq)); + assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL)); + +/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/ + /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ + SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask; + SPIx->I2SPR = 0x0002; + + /* Get the I2SCFGR register value */ + tmpreg = SPIx->I2SCFGR; + + /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/ + if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default) + { + i2sodd = (uint16_t)0; + i2sdiv = (uint16_t)2; + } + /* If the requested audio frequency is not the default, compute the prescaler */ + else + { + /* Check the frame length (For the Prescaler computing) */ + if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b) + { + /* Packet length is 16 bits */ + packetlength = 1; + } + else + { + /* Packet length is 32 bits */ + packetlength = 2; + } + + /* I2S Clock source is System clock: Get System Clock frequency */ + RCC_GetClocksFreq(&RCC_Clocks); + + /* Get the source clock value: based on System Clock value */ + sourceclock = RCC_Clocks.SYSCLK_Frequency; + + /* Compute the Real divider depending on the MCLK output state with a flaoting point */ + if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable) + { + /* MCLK output is enabled */ + tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5); + } + else + { + /* MCLK output is disabled */ + tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5); + } + + /* Remove the flaoting point */ + tmp = tmp / 10; + + /* Check the parity of the divider */ + i2sodd = (uint16_t)(tmp & (uint16_t)0x0001); + + /* Compute the i2sdiv prescaler */ + i2sdiv = (uint16_t)((tmp - i2sodd) / 2); + + /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ + i2sodd = (uint16_t) (i2sodd << 8); + } + + /* Test if the divider is 1 or 0 or greater than 0xFF */ + if ((i2sdiv < 2) || (i2sdiv > 0xFF)) + { + /* Set the default values */ + i2sdiv = 2; + i2sodd = 0; + } + + /* Write to SPIx I2SPR register the computed value */ + SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput)); + + /* Configure the I2S with the SPI_InitStruct values */ + tmpreg |= (uint16_t)(SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \ + (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \ + (uint16_t)I2S_InitStruct->I2S_CPOL)))); + + /* Write to SPIx I2SCFGR */ + SPIx->I2SCFGR = tmpreg; +} + +/** + * @brief Fills each SPI_InitStruct member with its default value. + * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized. + * @retval None + */ +void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) +{ +/*--------------- Reset SPI init structure parameters values -----------------*/ + /* Initialize the SPI_Direction member */ + SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex; + /* initialize the SPI_Mode member */ + SPI_InitStruct->SPI_Mode = SPI_Mode_Slave; + /* initialize the SPI_DataSize member */ + SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; + /* Initialize the SPI_CPOL member */ + SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low; + /* Initialize the SPI_CPHA member */ + SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge; + /* Initialize the SPI_NSS member */ + SPI_InitStruct->SPI_NSS = SPI_NSS_Hard; + /* Initialize the SPI_BaudRatePrescaler member */ + SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; + /* Initialize the SPI_FirstBit member */ + SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB; + /* Initialize the SPI_CRCPolynomial member */ + SPI_InitStruct->SPI_CRCPolynomial = 7; +} + +/** + * @brief Fills each I2S_InitStruct member with its default value. + * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct) +{ +/*--------------- Reset I2S init structure parameters values -----------------*/ + /* Initialize the I2S_Mode member */ + I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx; + + /* Initialize the I2S_Standard member */ + I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips; + + /* Initialize the I2S_DataFormat member */ + I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b; + + /* Initialize the I2S_MCLKOutput member */ + I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable; + + /* Initialize the I2S_AudioFreq member */ + I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default; + + /* Initialize the I2S_CPOL member */ + I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low; +} + +/** + * @brief Enables or disables the specified SPI peripheral. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI peripheral */ + SPIx->CR1 |= SPI_CR1_SPE; + } + else + { + /* Disable the selected SPI peripheral */ + SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE); + } +} + +/** + * @brief Enables or disables the specified SPI peripheral (in I2S mode). + * @param SPIx: where x can be 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_23_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI peripheral (in I2S mode) */ + SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE; + } + else + { + /* Disable the selected SPI peripheral in I2S mode */ + SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE); + } +} + +/** + * @brief Configures the data size for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_DataSize: specifies the SPI data size. + * This parameter can be one of the following values: + * @arg SPI_DataSize_16b: Set data frame format to 16bit. + * @arg SPI_DataSize_8b: Set data frame format to 8bit. + * @retval None. + */ +void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DATASIZE(SPI_DataSize)); + /* Clear DFF bit */ + SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b; + /* Set new DFF bit value */ + SPIx->CR1 |= SPI_DataSize; +} + +/** + * @brief Selects the data transfer direction in bidirectional mode for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_Direction: specifies the data transfer direction in bidirectional mode. + * This parameter can be one of the following values: + * @arg SPI_Direction_Tx: Selects Tx transmission direction. + * @arg SPI_Direction_Rx: Selects Rx receive direction. + * @retval None + */ +void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DIRECTION(SPI_Direction)); + if (SPI_Direction == SPI_Direction_Tx) + { + /* Set the Tx only mode */ + SPIx->CR1 |= SPI_Direction_Tx; + } + else + { + /* Set the Rx only mode */ + SPIx->CR1 &= SPI_Direction_Rx; + } +} + +/** + * @brief Configures internally by software the NSS pin for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state. + * This parameter can be one of the following values: + * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally. + * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally. + * @retval None + */ +void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft)); + if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset) + { + /* Set NSS pin internally by software */ + SPIx->CR1 |= SPI_NSSInternalSoft_Set; + } + else + { + /* Reset NSS pin internally by software */ + SPIx->CR1 &= SPI_NSSInternalSoft_Reset; + } +} + +/** + * @brief Enables or disables the SS output for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx SS output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI SS output */ + SPIx->CR2 |= (uint16_t)SPI_CR2_SSOE; + } + else + { + /* Disable the selected SPI SS output */ + SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE); + } +} + +/** + * @} + */ + +/** @defgroup SPI_Group2 Data transfers functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### Data transfers functions ##### + =============================================================================== +....[..] This section provides a set of functions allowing to manage the SPI data + transfers. +....[..] In reception, data are received and then stored into an internal Rx buffer + while In transmission, data are first stored into an internal Tx buffer + before being transmitted. +....[..] The read access of the SPI_DR register can be done using the + SPI_I2S_ReceiveData() function and returns the Rx buffered value. + Whereas a write access to the SPI_DR can be done using SPI_I2S_SendData() + function and stores the written data into Tx buffer. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the most recent received data by the SPIx/I2Sx peripheral. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + * @retval The value of the received data. + */ +uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Return the data in the DR register */ + return SPIx->DR; +} + +/** + * @brief Transmits a Data through the SPIx/I2Sx peripheral. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + * @param Data: Data to be transmitted. + * @retval None + */ +void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Write in the DR register the data to be sent */ + SPIx->DR = Data; +} + +/** + * @} + */ + +/** @defgroup SPI_Group3 Hardware CRC Calculation functions + * @brief Hardware CRC Calculation functions + * +@verbatim + =============================================================================== + ##### Hardware CRC Calculation functions ##### + =============================================================================== + [..] This section provides a set of functions allowing to manage the SPI CRC + hardware calculation SPI communication using CRC is possible through + the following procedure: + (#) Program the Data direction, Polarity, Phase, First Data, Baud Rate + Prescaler, Slave Management, Peripheral Mode and CRC Polynomial + values using the SPI_Init() function. + (#) Enable the CRC calculation using the SPI_CalculateCRC() function. + (#) Enable the SPI using the SPI_Cmd() function. + (#) Before writing the last data to the TX buffer, set the CRCNext bit + using the SPI_TransmitCRC() function to indicate that after + transmission of the last data, the CRC should be transmitted. + (#) After transmitting the last data, the SPI transmits the CRC. + The SPI_CR1_CRCNEXT bit is reset. The CRC is also received and + compared against the SPI_RXCRCR value. + If the value does not match, the SPI_FLAG_CRCERR flag is set and an + interrupt can be generated when the SPI_I2S_IT_ERR interrupt is enabled. + -@- + (+@) It is advised to don't read the calculate CRC values during the communication. + (+@) When the SPI is in slave mode, be careful to enable CRC calculation only + when the clock is stable, that is, when the clock is in the steady state. + If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive + to the SCK slave input clock as soon as CRCEN is set, and this, whatever + the value of the SPE bit. + (+@) With high bitrate frequencies, be careful when transmitting the CRC. + As the number of used CPU cycles has to be as low as possible in the CRC + transfer phase, it is forbidden to call software functions in the CRC + transmission sequence to avoid errors in the last data and CRC reception. + In fact, CRCNEXT bit has to be written before the end of the transmission/ + reception of the last data. + (+@) For high bit rate frequencies, it is advised to use the DMA mode to avoid the + degradation of the SPI speed performance due to CPU accesses impacting the + SPI bandwidth. + (+@) When the STM32L15xxx are configured as slaves and the NSS hardware mode is + used, the NSS pin needs to be kept low between the data phase and the CRC + phase. + (+@) When the SPI is configured in slave mode with the CRC feature enabled, CRC + calculation takes place even if a high level is applied on the NSS pin. + This may happen for example in case of a multislave environment where the + communication master addresses slaves alternately. + (+@) Between a slave deselection (high level on NSS) and a new slave selection + (low level on NSS), the CRC value should be cleared on both master and slave + sides in order to resynchronize the master and slave for their respective + CRC calculation. + -@- To clear the CRC, follow the procedure below: + (#@) Disable SPI using the SPI_Cmd() function + (#@) Disable the CRC calculation using the SPI_CalculateCRC() function. + (#@) Enable the CRC calculation using the SPI_CalculateCRC() function. + (#@) Enable SPI using the SPI_Cmd() function. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the CRC value calculation of the transferred bytes. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx CRC value calculation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI CRC calculation */ + SPIx->CR1 |= SPI_CR1_CRCEN; + } + else + { + /* Disable the selected SPI CRC calculation */ + SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN); + } +} + +/** + * @brief Transmit the SPIx CRC value. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @retval None + */ +void SPI_TransmitCRC(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Enable the selected SPI CRC transmission */ + SPIx->CR1 |= SPI_CR1_CRCNEXT; +} + +/** + * @brief Returns the transmit or the receive CRC register value for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_CRC: specifies the CRC register to be read. + * This parameter can be one of the following values: + * @arg SPI_CRC_Tx: Selects Tx CRC register. + * @arg SPI_CRC_Rx: Selects Rx CRC register. + * @retval The selected CRC register value. + */ +uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC) +{ + uint16_t crcreg = 0; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_CRC(SPI_CRC)); + if (SPI_CRC != SPI_CRC_Rx) + { + /* Get the Tx CRC register */ + crcreg = SPIx->TXCRCR; + } + else + { + /* Get the Rx CRC register */ + crcreg = SPIx->RXCRCR; + } + /* Return the selected CRC register */ + return crcreg; +} + +/** + * @brief Returns the CRC Polynomial register value for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @retval The CRC Polynomial register value. + */ +uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Return the CRC polynomial register */ + return SPIx->CRCPR; +} + +/** + * @} + */ + +/** @defgroup SPI_Group4 DMA transfers management functions + * @brief DMA transfers management functions + * +@verbatim + =============================================================================== + ##### DMA transfers management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the SPIx/I2Sx DMA interface. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + * @param SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request. + * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request. + * @param NewState: new state of the selected SPI DMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI DMA requests */ + SPIx->CR2 |= SPI_I2S_DMAReq; + } + else + { + /* Disable the selected SPI DMA requests */ + SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq; + } +} + +/** + * @} + */ + +/** @defgroup SPI_Group5 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + [..] This section provides a set of functions allowing to configure the SPI + Interrupts sources and check or clear the flags or pending bits status. + The user should identify which mode will be used in his application to + manage the communication: Polling mode, Interrupt mode or DMA mode. + *** Polling Mode *** + ==================== + [..] In Polling Mode, the SPI/I2S communication can be managed by 9 flags: + (#) SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer + register. + (#) SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer + register. + (#) SPI_I2S_FLAG_BSY : to indicate the state of the communication layer + of the SPI. + (#) SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur. + (#) SPI_FLAG_MODF : to indicate if a Mode Fault error occur. + (#) SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur. + (#) SPI_I2S_FLAG_FRE: to indicate a Frame Format error occurs. + (#) I2S_FLAG_UDR: to indicate an Underrun error occurs. + (#) I2S_FLAG_CHSIDE: to indicate Channel Side. + -@- Do not use the BSY flag to handle each data transmission or reception. + It is better to use the TXE and RXNE flags instead. + [..] In this Mode it is advised to use the following functions: + (+) FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG). + (+) void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG). + + *** Interrupt Mode *** + ====================== + [..] In Interrupt Mode, the SPI communication can be managed by 3 interrupt + sources and 7 pending bits: + [..] Pending Bits: + (#) SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register. + (#) SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register. + (#) SPI_IT_CRCERR : to indicate if a CRC Calculation error occur. + (#) SPI_IT_MODF : to indicate if a Mode Fault error occur. + (#) SPI_I2S_IT_OVR : to indicate if an Overrun error occur. + (#) I2S_IT_UDR : to indicate an Underrun Error occurs. + (#) SPI_I2S_FLAG_FRE : to indicate a Frame Format error occurs. + [..] Interrupt Source: + (#) SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty + interrupt. + (#) SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not + empty interrupt. + (#) SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt. + [..] In this Mode it is advised to use the following functions: + (+) void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, + FunctionalState NewState). + (+) ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT). + (+) void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT). + + *** DMA Mode *** + ================ + [..] In DMA Mode, the SPI communication can be managed by 2 DMA Channel + requests: + (#) SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request. + (#) SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request. + + [..] In this Mode it is advised to use the following function: + (+) void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, + FunctionalState NewState). + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified SPI/I2S interrupts. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + + * @param SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask. + * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask. + * @arg SPI_I2S_IT_ERR: Error interrupt mask. + * @param NewState: new state of the specified SPI interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState) +{ + uint16_t itpos = 0, itmask = 0 ; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT)); + + /* Get the SPI IT index */ + itpos = SPI_I2S_IT >> 4; + + /* Set the IT mask */ + itmask = (uint16_t)1 << (uint16_t)itpos; + + if (NewState != DISABLE) + { + /* Enable the selected SPI interrupt */ + SPIx->CR2 |= itmask; + } + else + { + /* Disable the selected SPI interrupt */ + SPIx->CR2 &= (uint16_t)~itmask; + } +} + +/** + * @brief Checks whether the specified SPIx/I2Sx flag is set or not. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + + * @param SPI_I2S_FLAG: specifies the SPI flag to check. + * This parameter can be one of the following values: + * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag. + * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag. + * @arg SPI_I2S_FLAG_BSY: Busy flag. + * @arg SPI_I2S_FLAG_OVR: Overrun flag. + * @arg SPI_FLAG_MODF: Mode Fault flag. + * @arg SPI_FLAG_CRCERR: CRC Error flag. + * @arg SPI_I2S_FLAG_FRE: Format Error. + * @arg I2S_FLAG_UDR: Underrun Error flag. + * @arg I2S_FLAG_CHSIDE: Channel Side flag. + * @retval The new state of SPI_I2S_FLAG (SET or RESET). + */ +FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG)); + + /* Check the status of the specified SPI flag */ + if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET) + { + /* SPI_I2S_FLAG is set */ + bitstatus = SET; + } + else + { + /* SPI_I2S_FLAG is reset */ + bitstatus = RESET; + } + /* Return the SPI_I2S_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the SPIx CRC Error (CRCERR) flag. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + + * @param SPI_I2S_FLAG: specifies the SPI flag to clear. + * This function clears only CRCERR flag. + + * @note OVR (OverRun error) flag is cleared by software sequence: a read + * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read + * operation to SPI_SR register (SPI_I2S_GetFlagStatus()). + * @note UDR (UnderRun error) flag is cleared by a read operation to + * SPI_SR register (SPI_I2S_GetFlagStatus()). + * @note MODF (Mode Fault) flag is cleared by software sequence: a read/write + * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a + * write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). + * @retval None + */ +void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG)); + + /* Clear the selected SPI CRC Error (CRCERR) flag */ + SPIx->SR = (uint16_t)~SPI_I2S_FLAG; +} + +/** + * @brief Checks whether the specified SPIx/I2Sx interrupt has occurred or not. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + + * @param SPI_I2S_IT: specifies the SPI interrupt source to check. + * This parameter can be one of the following values: + * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt. + * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt. + * @arg SPI_I2S_IT_OVR: Overrun interrupt. + * @arg SPI_IT_MODF: Mode Fault interrupt. + * @arg SPI_IT_CRCERR: CRC Error interrupt. + * @arg I2S_IT_UDR: Underrun interrupt. + * @arg SPI_I2S_IT_FRE: Format Error interrupt. + * @retval The new state of SPI_I2S_IT (SET or RESET). + */ +ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) +{ + ITStatus bitstatus = RESET; + uint16_t itpos = 0, itmask = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT)); + + /* Get the SPI_I2S_IT index */ + itpos = 0x01 << (SPI_I2S_IT & 0x0F); + + /* Get the SPI_I2S_IT IT mask */ + itmask = SPI_I2S_IT >> 4; + + /* Set the IT mask */ + itmask = 0x01 << itmask; + + /* Get the SPI_I2S_IT enable bit status */ + enablestatus = (SPIx->CR2 & itmask) ; + + /* Check the status of the specified SPI interrupt */ + if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus) + { + /* SPI_I2S_IT is set */ + bitstatus = SET; + } + else + { + /* SPI_I2S_IT is reset */ + bitstatus = RESET; + } + /* Return the SPI_I2S_IT status */ + return bitstatus; +} + +/** + * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit. + * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 + * in SPI mode or 2 or 3 in I2S mode. + + * @param SPI_I2S_IT: specifies the SPI interrupt pending bit to clear. + * This function clears only CRCERR interrupt pending bit. + + * OVR (OverRun Error) interrupt pending bit is cleared by software + * sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData()) + * followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()). + * @note UDR (UnderRun Error) interrupt pending bit is cleared by a read + * operation to SPI_SR register (SPI_I2S_GetITStatus()). + * @note MODF (Mode Fault) interrupt pending bit is cleared by software sequence: + * a read/write operation to SPI_SR register (SPI_I2S_GetITStatus()) + * followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable + * the SPI). + * @retval None + */ +void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) +{ + uint16_t itpos = 0; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT)); + + /* Get the SPI_I2S IT index */ + itpos = 0x01 << (SPI_I2S_IT & 0x0F); + + /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */ + SPIx->SR = (uint16_t)~itpos; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_spi.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_spi.h new file mode 100644 index 0000000000..cd205eab61 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_spi.h @@ -0,0 +1,524 @@ +/** + ****************************************************************************** + * @file stm32l1xx_spi.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the SPI + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_SPI_H +#define __STM32L1xx_SPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup SPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief SPI Init structure definition + */ + +typedef struct +{ + uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. + This parameter can be a value of @ref SPI_data_direction */ + + uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. + This parameter can be a value of @ref SPI_mode */ + + uint16_t SPI_DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of @ref SPI_data_size */ + + uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by + hardware (NSS pin) or by software using the SSI bit. + This parameter can be a value of @ref SPI_Slave_Select_management */ + + uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be + used to configure the transmit and receive SCK clock. + This parameter can be a value of @ref SPI_BaudRate_Prescaler + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ + + uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SPI_MSB_LSB_transmission */ + + uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */ +}SPI_InitTypeDef; + +/** + * @brief I2S Init structure definition + */ + +typedef struct +{ + + uint16_t I2S_Mode; /*!< Specifies the I2S operating mode. + This parameter can be a value of @ref SPI_I2S_Mode */ + + uint16_t I2S_Standard; /*!< Specifies the standard used for the I2S communication. + This parameter can be a value of @ref SPI_I2S_Standard */ + + uint16_t I2S_DataFormat; /*!< Specifies the data format for the I2S communication. + This parameter can be a value of @ref SPI_I2S_Data_Format */ + + uint16_t I2S_MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. + This parameter can be a value of @ref SPI_I2S_MCLK_Output */ + + uint32_t I2S_AudioFreq; /*!< Specifies the frequency selected for the I2S communication. + This parameter can be a value of @ref SPI_I2S_Audio_Frequency */ + + uint16_t I2S_CPOL; /*!< Specifies the idle state of the I2S clock. + This parameter can be a value of @ref SPI_I2S_Clock_Polarity */ +}I2S_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SPI_Exported_Constants + * @{ + */ + +#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \ + ((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3)) +#define IS_SPI_23_PERIPH(PERIPH) (((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3)) + +/** @defgroup SPI_data_direction + * @{ + */ + +#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000) +#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400) +#define SPI_Direction_1Line_Rx ((uint16_t)0x8000) +#define SPI_Direction_1Line_Tx ((uint16_t)0xC000) +#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \ + ((MODE) == SPI_Direction_2Lines_RxOnly) || \ + ((MODE) == SPI_Direction_1Line_Rx) || \ + ((MODE) == SPI_Direction_1Line_Tx)) +/** + * @} + */ + +/** @defgroup SPI_mode + * @{ + */ + +#define SPI_Mode_Master ((uint16_t)0x0104) +#define SPI_Mode_Slave ((uint16_t)0x0000) +#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ + ((MODE) == SPI_Mode_Slave)) +/** + * @} + */ + +/** @defgroup SPI_data_size + * @{ + */ + +#define SPI_DataSize_16b ((uint16_t)0x0800) +#define SPI_DataSize_8b ((uint16_t)0x0000) +#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_16b) || \ + ((DATASIZE) == SPI_DataSize_8b)) +/** + * @} + */ + +/** @defgroup SPI_Clock_Polarity + * @{ + */ + +#define SPI_CPOL_Low ((uint16_t)0x0000) +#define SPI_CPOL_High ((uint16_t)0x0002) +#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ + ((CPOL) == SPI_CPOL_High)) +/** + * @} + */ + +/** @defgroup SPI_Clock_Phase + * @{ + */ + +#define SPI_CPHA_1Edge ((uint16_t)0x0000) +#define SPI_CPHA_2Edge ((uint16_t)0x0001) +#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ + ((CPHA) == SPI_CPHA_2Edge)) +/** + * @} + */ + +/** @defgroup SPI_Slave_Select_management + * @{ + */ + +#define SPI_NSS_Soft ((uint16_t)0x0200) +#define SPI_NSS_Hard ((uint16_t)0x0000) +#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \ + ((NSS) == SPI_NSS_Hard)) +/** + * @} + */ + +/** @defgroup SPI_BaudRate_Prescaler + * @{ + */ + +#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) +#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) +#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) +#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) +#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) +#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) +#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) +#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) +#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_256)) +/** + * @} + */ + +/** @defgroup SPI_MSB_LSB_transmission + * @{ + */ + +#define SPI_FirstBit_MSB ((uint16_t)0x0000) +#define SPI_FirstBit_LSB ((uint16_t)0x0080) +#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \ + ((BIT) == SPI_FirstBit_LSB)) +/** + * @} + */ + +/** @defgroup SPI_I2S_Mode + * @{ + */ + +#define I2S_Mode_SlaveTx ((uint16_t)0x0000) +#define I2S_Mode_SlaveRx ((uint16_t)0x0100) +#define I2S_Mode_MasterTx ((uint16_t)0x0200) +#define I2S_Mode_MasterRx ((uint16_t)0x0300) +#define IS_I2S_MODE(MODE) (((MODE) == I2S_Mode_SlaveTx) || \ + ((MODE) == I2S_Mode_SlaveRx) || \ + ((MODE) == I2S_Mode_MasterTx)|| \ + ((MODE) == I2S_Mode_MasterRx)) +/** + * @} + */ + + +/** @defgroup SPI_I2S_Standard + * @{ + */ + +#define I2S_Standard_Phillips ((uint16_t)0x0000) +#define I2S_Standard_MSB ((uint16_t)0x0010) +#define I2S_Standard_LSB ((uint16_t)0x0020) +#define I2S_Standard_PCMShort ((uint16_t)0x0030) +#define I2S_Standard_PCMLong ((uint16_t)0x00B0) +#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Standard_Phillips) || \ + ((STANDARD) == I2S_Standard_MSB) || \ + ((STANDARD) == I2S_Standard_LSB) || \ + ((STANDARD) == I2S_Standard_PCMShort) || \ + ((STANDARD) == I2S_Standard_PCMLong)) +/** + * @} + */ + +/** @defgroup SPI_I2S_Data_Format + * @{ + */ + +#define I2S_DataFormat_16b ((uint16_t)0x0000) +#define I2S_DataFormat_16bextended ((uint16_t)0x0001) +#define I2S_DataFormat_24b ((uint16_t)0x0003) +#define I2S_DataFormat_32b ((uint16_t)0x0005) +#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DataFormat_16b) || \ + ((FORMAT) == I2S_DataFormat_16bextended) || \ + ((FORMAT) == I2S_DataFormat_24b) || \ + ((FORMAT) == I2S_DataFormat_32b)) +/** + * @} + */ + +/** @defgroup SPI_I2S_MCLK_Output + * @{ + */ + +#define I2S_MCLKOutput_Enable ((uint16_t)0x0200) +#define I2S_MCLKOutput_Disable ((uint16_t)0x0000) +#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOutput_Enable) || \ + ((OUTPUT) == I2S_MCLKOutput_Disable)) +/** + * @} + */ + +/** @defgroup SPI_I2S_Audio_Frequency + * @{ + */ + +#define I2S_AudioFreq_192k ((uint32_t)192000) +#define I2S_AudioFreq_96k ((uint32_t)96000) +#define I2S_AudioFreq_48k ((uint32_t)48000) +#define I2S_AudioFreq_44k ((uint32_t)44100) +#define I2S_AudioFreq_32k ((uint32_t)32000) +#define I2S_AudioFreq_22k ((uint32_t)22050) +#define I2S_AudioFreq_16k ((uint32_t)16000) +#define I2S_AudioFreq_11k ((uint32_t)11025) +#define I2S_AudioFreq_8k ((uint32_t)8000) +#define I2S_AudioFreq_Default ((uint32_t)2) + +#define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AudioFreq_8k) && \ + ((FREQ) <= I2S_AudioFreq_192k)) || \ + ((FREQ) == I2S_AudioFreq_Default)) +/** + * @} + */ + +/** @defgroup SPI_I2S_Clock_Polarity + * @{ + */ + +#define I2S_CPOL_Low ((uint16_t)0x0000) +#define I2S_CPOL_High ((uint16_t)0x0008) +#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_Low) || \ + ((CPOL) == I2S_CPOL_High)) +/** + * @} + */ + +/** @defgroup SPI_I2S_DMA_transfer_requests + * @{ + */ + +#define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002) +#define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001) +#define IS_SPI_I2S_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((DMAREQ) != 0x00)) +/** + * @} + */ + +/** @defgroup SPI_NSS_internal_software_management + * @{ + */ + +#define SPI_NSSInternalSoft_Set ((uint16_t)0x0100) +#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF) +#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \ + ((INTERNAL) == SPI_NSSInternalSoft_Reset)) +/** + * @} + */ + +/** @defgroup SPI_CRC_Transmit_Receive + * @{ + */ + +#define SPI_CRC_Tx ((uint8_t)0x00) +#define SPI_CRC_Rx ((uint8_t)0x01) +#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx)) +/** + * @} + */ + +/** @defgroup SPI_direction_transmit_receive + * @{ + */ + +#define SPI_Direction_Rx ((uint16_t)0xBFFF) +#define SPI_Direction_Tx ((uint16_t)0x4000) +#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \ + ((DIRECTION) == SPI_Direction_Tx)) +/** + * @} + */ + +/** @defgroup SPI_I2S_interrupts_definition + * @{ + */ + +#define SPI_I2S_IT_TXE ((uint8_t)0x71) +#define SPI_I2S_IT_RXNE ((uint8_t)0x60) +#define SPI_I2S_IT_ERR ((uint8_t)0x50) +#define I2S_IT_UDR ((uint8_t)0x53) +#define SPI_I2S_IT_FRE ((uint8_t)0x58) + +#define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \ + ((IT) == SPI_I2S_IT_RXNE) || \ + ((IT) == SPI_I2S_IT_ERR)) + +#define SPI_I2S_IT_OVR ((uint8_t)0x56) +#define SPI_IT_MODF ((uint8_t)0x55) +#define SPI_IT_CRCERR ((uint8_t)0x54) + +#define IS_SPI_I2S_CLEAR_IT(IT) (((IT) == SPI_IT_CRCERR)) + +#define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE) || ((IT) == SPI_I2S_IT_TXE) || \ + ((IT) == SPI_IT_CRCERR) || ((IT) == SPI_IT_MODF) || \ + ((IT) == SPI_I2S_IT_OVR) || ((IT) == I2S_IT_UDR) ||\ + ((IT) == SPI_I2S_IT_FRE)) +/** + * @} + */ + +/** @defgroup SPI_I2S_flags_definition + * @{ + */ + +#define SPI_I2S_FLAG_RXNE ((uint16_t)0x0001) +#define SPI_I2S_FLAG_TXE ((uint16_t)0x0002) +#define I2S_FLAG_CHSIDE ((uint16_t)0x0004) +#define I2S_FLAG_UDR ((uint16_t)0x0008) +#define SPI_FLAG_CRCERR ((uint16_t)0x0010) +#define SPI_FLAG_MODF ((uint16_t)0x0020) +#define SPI_I2S_FLAG_OVR ((uint16_t)0x0040) +#define SPI_I2S_FLAG_BSY ((uint16_t)0x0080) +#define SPI_I2S_FLAG_FRE ((uint16_t)0x0100) + +#define IS_SPI_I2S_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR)) +#define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \ + ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \ + ((FLAG) == I2S_FLAG_UDR) || ((FLAG) == I2S_FLAG_CHSIDE) || \ + ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)|| \ + ((FLAG) == SPI_I2S_FLAG_FRE)) +/** + * @} + */ + +/** @defgroup SPI_CRC_polynomial + * @{ + */ + +#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1) +/** + * @} + */ + +/** @defgroup SPI_I2S_Legacy + * @{ + */ + +#define SPI_DMAReq_Tx SPI_I2S_DMAReq_Tx +#define SPI_DMAReq_Rx SPI_I2S_DMAReq_Rx +#define SPI_IT_TXE SPI_I2S_IT_TXE +#define SPI_IT_RXNE SPI_I2S_IT_RXNE +#define SPI_IT_ERR SPI_I2S_IT_ERR +#define SPI_IT_OVR SPI_I2S_IT_OVR +#define SPI_FLAG_RXNE SPI_I2S_FLAG_RXNE +#define SPI_FLAG_TXE SPI_I2S_FLAG_TXE +#define SPI_FLAG_OVR SPI_I2S_FLAG_OVR +#define SPI_FLAG_BSY SPI_I2S_FLAG_BSY +#define SPI_DeInit SPI_I2S_DeInit +#define SPI_ITConfig SPI_I2S_ITConfig +#define SPI_DMACmd SPI_I2S_DMACmd +#define SPI_SendData SPI_I2S_SendData +#define SPI_ReceiveData SPI_I2S_ReceiveData +#define SPI_GetFlagStatus SPI_I2S_GetFlagStatus +#define SPI_ClearFlag SPI_I2S_ClearFlag +#define SPI_GetITStatus SPI_I2S_GetITStatus +#define SPI_ClearITPendingBit SPI_I2S_ClearITPendingBit +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the SPI configuration to the default reset state *****/ +void SPI_I2S_DeInit(SPI_TypeDef* SPIx); + +/* Initialization and Configuration functions *********************************/ +void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); +void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct); +void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct); +void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct); +void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize); +void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction); +void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft); +void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState); + +/* Data transfers functions ***************************************************/ +void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); +uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); + +/* Hardware CRC Calculation functions *****************************************/ +void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_TransmitCRC(SPI_TypeDef* SPIx); +uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC); +uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx); + +/* DMA transfers management functions *****************************************/ +void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); +FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); +void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); +ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); +void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_SPI_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_syscfg.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_syscfg.c new file mode 100644 index 0000000000..792bf4e199 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_syscfg.c @@ -0,0 +1,652 @@ +/** + ****************************************************************************** + * @file stm32l1xx_syscfg.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the SYSCFG and RI peripherals: + * + SYSCFG Initialization and Configuration + * + RI Initialization and Configuration + * +@verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] This driver provides functions for: + (#) Remapping the memory accessible in the code area using + SYSCFG_MemoryRemapConfig(). + (#) Manage the EXTI lines connection to the GPIOs using + SYSCFG_EXTILineConfig(). + (#) Routing of I/Os toward the input captures of timers (TIM2, TIM3 and TIM4). + (#) Input routing of COMP1 and COMP2. + (#) Routing of internal reference voltage VREFINT to PB0 and PB1. + (#) The RI registers can be accessed only when the comparator + APB interface clock is enabled. + To enable comparator clock use: + RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE). + Following functions uses RI registers: + (++) SYSCFG_RIDeInit() + (++) SYSCFG_RITIMSelect() + (++) SYSCFG_RITIMInputCaptureConfig() + (++) SYSCFG_RIResistorConfig() + (++) SYSCFG_RIChannelSpeedConfig() + (++) SYSCFG_RIIOSwitchConfig() + (++) SYSCFG_RISwitchControlModeCmd() + (++) SYSCFG_RIHysteresisConfig() + (#) The SYSCFG registers can be accessed only when the SYSCFG + interface APB clock is enabled. + To enable SYSCFG APB clock use: + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); + Following functions uses SYSCFG registers: + (++) SYSCFG_DeInit() + (++) SYSCFG_MemoryRemapConfig() + (++) SYSCFG_GetBootMode() + (++) SYSCFG_USBPuCmd() + (++) SYSCFG_EXTILineConfig() +@endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_syscfg.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup SYSCFG + * @brief SYSCFG driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define TIM_SELECT_MASK ((uint32_t)0xFFFCFFFF) /*!< TIM select mask */ +#define IC_ROUTING_MASK ((uint32_t)0x0000000F) /*!< Input Capture routing mask */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SYSCFG_Private_Functions + * @{ + */ + +/** @defgroup SYSCFG_Group1 SYSCFG Initialization and Configuration functions + * @brief SYSCFG Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### SYSCFG Initialization and Configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the SYSCFG registers to their default reset values. + * @param None. + * @retval None. + * @Note: MEMRMP bits are not reset by APB2 reset. + */ +void SYSCFG_DeInit(void) +{ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, DISABLE); +} + +/** + * @brief Deinitializes the RI registers to their default reset values. + * @param None. + * @retval None. + */ +void SYSCFG_RIDeInit(void) +{ + RI->ICR = ((uint32_t)0x00000000); /*!< Set RI->ICR to reset value */ + RI->ASCR1 = ((uint32_t)0x00000000); /*!< Set RI->ASCR1 to reset value */ + RI->ASCR2 = ((uint32_t)0x00000000); /*!< Set RI->ASCR2 to reset value */ + RI->HYSCR1 = ((uint32_t)0x00000000); /*!< Set RI->HYSCR1 to reset value */ + RI->HYSCR2 = ((uint32_t)0x00000000); /*!< Set RI->HYSCR2 to reset value */ + RI->HYSCR3 = ((uint32_t)0x00000000); /*!< Set RI->HYSCR3 to reset value */ + RI->HYSCR4 = ((uint32_t)0x00000000); /*!< Set RI->HYSCR4 to reset value */ +} + +/** + * @brief Changes the mapping of the specified memory. + * @param SYSCFG_Memory: selects the memory remapping. + * This parameter can be one of the following values: + * @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_SystemFlash: System Flash memory mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_FSMC: FSMC memory mapped at 0x00000000 + * @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM mapped at 0x00000000 + * @retval None + */ +void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap) +{ + /* Check the parameters */ + assert_param(IS_SYSCFG_MEMORY_REMAP_CONFING(SYSCFG_MemoryRemap)); + SYSCFG->MEMRMP = SYSCFG_MemoryRemap; +} + +/** + * @brief Returns the boot mode as configured by user. + * @param None. + * @retval The boot mode as configured by user. The returned value can be one + * of the following values: + * - 0x00000000: Boot is configured in Main Flash memory + * - 0x00000100: Boot is configured in System Flash memory + * - 0x00000200: Boot is configured in FSMC memory + * - 0x00000300: Boot is configured in Embedded SRAM memory + */ +uint32_t SYSCFG_GetBootMode(void) +{ + return (SYSCFG->MEMRMP & SYSCFG_MEMRMP_BOOT_MODE); +} + +/** + * @brief Control the internal pull-up on USB DP line. + * @param NewState: New state of the internal pull-up on USB DP line. + * This parameter can be ENABLE: Connect internal pull-up on USB DP line. + * or DISABLE: Disconnect internal pull-up on USB DP line. + * @retval None + */ +void SYSCFG_USBPuCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Connect internal pull-up on USB DP line */ + SYSCFG->PMC |= (uint32_t) SYSCFG_PMC_USB_PU; + } + else + { + /* Disconnect internal pull-up on USB DP line */ + SYSCFG->PMC &= (uint32_t)(~SYSCFG_PMC_USB_PU); + } +} + +/** + * @brief Selects the GPIO pin used as EXTI Line. + * @param EXTI_PortSourceGPIOx : selects the GPIO port to be used as source + * for EXTI lines where x can be (A, B, C, D, E, F, G or H). + * @param EXTI_PinSourcex: specifies the EXTI line to be configured. + * This parameter can be EXTI_PinSourcex where x can be (0..15). + * @retval None + */ +void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex) +{ + uint32_t tmp = 0x00; + + /* Check the parameters */ + assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx)); + assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex)); + + tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)); + SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp; + SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03))); +} + +/** + * @} + */ + +/** @defgroup SYSCFG_Group2 RI Initialization and Configuration functions + * @brief RI Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### RI Initialization and Configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the routing interface to select which Timer to be routed. + * @note Routing capability can be applied only on one of the three timers + * (TIM2, TIM3 or TIM4) at a time. + * @param TIM_Select: Timer select. + * This parameter can be one of the following values: + * @arg TIM_Select_None: No timer selected and default Timer mapping is enabled. + * @arg TIM_Select_TIM2: Timer 2 Input Captures to be routed. + * @arg TIM_Select_TIM3: Timer 3 Input Captures to be routed. + * @arg TIM_Select_TIM4: Timer 4 Input Captures to be routed. + * @retval None. + */ +void SYSCFG_RITIMSelect(uint32_t TIM_Select) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RI_TIM(TIM_Select)); + + /* Get the old register value */ + tmpreg = RI->ICR; + + /* Clear the TIMx select bits */ + tmpreg &= TIM_SELECT_MASK; + + /* Select the Timer */ + tmpreg |= (TIM_Select); + + /* Write to RI->ICR register */ + RI->ICR = tmpreg; +} + +/** + * @brief Configures the routing interface to map Input Capture 1, 2, 3 or 4 + * to a selected I/O pin. + * @param RI_InputCapture selects which input capture to be routed. + * This parameter can be one (or combination) of the following parameters: + * @arg RI_InputCapture_IC1: Input capture 1 is selected. + * @arg RI_InputCapture_IC2: Input capture 2 is selected. + * @arg RI_InputCapture_IC3: Input capture 3 is selected. + * @arg RI_InputCapture_IC4: Input capture 4 is selected. + * @param RI_InputCaptureRouting: selects which pin to be routed to Input Capture. + * This parameter can be one of the following values: + * @param RI_InputCaptureRouting_0 to RI_InputCaptureRouting_15 + * e.g. + * SYSCFG_RITIMSelect(TIM_Select_TIM2) + * SYSCFG_RITIMInputCaptureConfig(RI_InputCapture_IC1, RI_InputCaptureRouting_1) + * allows routing of Input capture IC1 of TIM2 to PA4. + * For details about correspondence between RI_InputCaptureRouting_x + * and I/O pins refer to the parameters' description in the header file + * or refer to the product reference manual. + * @note Input capture selection bits are not reset by this function. + * To reset input capture selection bits, use SYSCFG_RIDeInit() function. + * @note The I/O should be configured in alternate function mode (AF14) using + * GPIO_PinAFConfig() function. + * @retval None. + */ +void SYSCFG_RITIMInputCaptureConfig(uint32_t RI_InputCapture, uint32_t RI_InputCaptureRouting) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RI_INPUTCAPTURE(RI_InputCapture)); + assert_param(IS_RI_INPUTCAPTURE_ROUTING(RI_InputCaptureRouting)); + + /* Get the old register value */ + tmpreg = RI->ICR; + + /* Select input captures to be routed */ + tmpreg |= (RI_InputCapture); + + if((RI_InputCapture & RI_InputCapture_IC1) == RI_InputCapture_IC1) + { + /* Clear the input capture select bits */ + tmpreg &= (uint32_t)(~IC_ROUTING_MASK); + + /* Set RI_InputCaptureRouting bits */ + tmpreg |= (uint32_t)( RI_InputCaptureRouting); + } + + if((RI_InputCapture & RI_InputCapture_IC2) == RI_InputCapture_IC2) + { + /* Clear the input capture select bits */ + tmpreg &= (uint32_t)(~(IC_ROUTING_MASK << 4)); + + /* Set RI_InputCaptureRouting bits */ + tmpreg |= (uint32_t)( (RI_InputCaptureRouting << 4)); + } + + if((RI_InputCapture & RI_InputCapture_IC3) == RI_InputCapture_IC3) + { + /* Clear the input capture select bits */ + tmpreg &= (uint32_t)(~(IC_ROUTING_MASK << 8)); + + /* Set RI_InputCaptureRouting bits */ + tmpreg |= (uint32_t)( (RI_InputCaptureRouting << 8)); + } + + if((RI_InputCapture & RI_InputCapture_IC4) == RI_InputCapture_IC4) + { + /* Clear the input capture select bits */ + tmpreg &= (uint32_t)(~(IC_ROUTING_MASK << 12)); + + /* Set RI_InputCaptureRouting bits */ + tmpreg |= (uint32_t)( (RI_InputCaptureRouting << 12)); + } + + /* Write to RI->ICR register */ + RI->ICR = tmpreg; +} + +/** + * @brief Configures the Pull-up and Pull-down Resistors + * @param RI_Resistor selects the resistor to connect. + * This parameter can be one of the following values: + * @arg RI_Resistor_10KPU: 10K pull-up resistor. + * @arg RI_Resistor_400KPU: 400K pull-up resistor. + * @arg RI_Resistor_10KPD: 10K pull-down resistor. + * @arg RI_Resistor_400KPD: 400K pull-down resistor. + * @param NewState: New state of the analog switch associated to the selected + * resistor. + * This parameter can be: + * ENABLE so the selected resistor is connected + * or DISABLE so the selected resistor is disconnected. + * @note To avoid extra power consumption, only one resistor should be enabled + * at a time. + * @retval None + */ +void SYSCFG_RIResistorConfig(uint32_t RI_Resistor, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RI_RESISTOR(RI_Resistor)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the resistor */ + COMP->CSR |= (uint32_t) RI_Resistor; + } + else + { + /* Disable the Resistor */ + COMP->CSR &= (uint32_t) (~RI_Resistor); + } +} + +/** + * @brief Configures the ADC channels speed. + * @param RI_Channel selects the channel. + * This parameter can be one of the following values: + * @arg RI_Channel_3: Channel 3 is selected. + * @arg RI_Channel_8: Channel 8 is selected. + * @arg RI_Channel_13: Channel 13 is selected. + * @param RI_ChannelSpeed: The speed of the selected ADC channel + * This parameter can be: + * RI_ChannelSpeed_Fast: The selected channel is a fast ADC channel + * or RI_ChannelSpeed_Slow: The selected channel is a slow ADC channel. + * @retval None + */ +void SYSCFG_RIChannelSpeedConfig(uint32_t RI_Channel, uint32_t RI_ChannelSpeed) +{ + /* Check the parameters */ + assert_param(IS_RI_CHANNEL(RI_Channel)); + assert_param(IS_RI_CHANNELSPEED(RI_ChannelSpeed)); + + if(RI_ChannelSpeed != RI_ChannelSpeed_Fast) + { + /* Set the selected channel as a slow ADC channel */ + COMP->CSR &= (uint32_t) (~RI_Channel); + } + else + { + /* Set the selected channel as a fast ADC channel */ + COMP->CSR |= (uint32_t) (RI_Channel); + } +} + +/** + * @brief Close or Open the routing interface Input Output switches. + * @param RI_IOSwitch: selects the I/O analog switch number. + * This parameter can be one of the following values: + * @param RI_IOSwitch_CH0 --> RI_IOSwitch_CH15. + * @param RI_IOSwitch_CH18 --> RI_IOSwitch_CH25. + * @param RI_IOSwitch_GR10_1 --> RI_IOSwitch_GR10_4. + * @param RI_IOSwitch_GR6_1 --> RI_IOSwitch_GR6_2. + * @param RI_IOSwitch_GR5_1 --> RI_IOSwitch_GR5_3. + * @param RI_IOSwitch_GR4_1 --> RI_IOSwitch_GR4_3. + * @param RI_IOSwitch_VCOMP + * RI_IOSwitch_CH27 + * @param RI_IOSwitch_CH28 --> RI_IOSwitch_CH30 + * @param RI_IOSwitch_GR10_1 --> RI_IOSwitch_GR10_4 + * @param RI_IOSwitch_GR6_1 + * @param RI_IOSwitch_GR6_2 + * @param RI_IOSwitch_GR5_1 --> RI_IOSwitch_GR5_3 + * @param RI_IOSwitch_GR4_1 --> RI_IOSwitch_GR4_4 + * @param RI_IOSwitch_CH0b --> RI_IOSwitch_CH3b + * @param RI_IOSwitch_CH6b --> RI_IOSwitch_CH12b + * @param RI_IOSwitch_GR6_3 + * @param RI_IOSwitch_GR6_4 + * @param RI_IOSwitch_GR5_4 + + * @param NewState: New state of the analog switch. + * This parameter can be + * ENABLE so the Input Output switch is closed + * or DISABLE so the Input Output switch is open. + * @retval None + */ +void SYSCFG_RIIOSwitchConfig(uint32_t RI_IOSwitch, FunctionalState NewState) +{ + uint32_t ioswitchmask = 0; + + /* Check the parameters */ + assert_param(IS_RI_IOSWITCH(RI_IOSwitch)); + + /* Read Analog switch register index */ + ioswitchmask = RI_IOSwitch >> 31; + + /* Get Bits[30:0] of the IO switch */ + RI_IOSwitch &= 0x7FFFFFFF; + + + if (NewState != DISABLE) + { + if (ioswitchmask != 0) + { + /* Close the analog switches */ + RI->ASCR1 |= RI_IOSwitch; + } + else + { + /* Open the analog switches */ + RI->ASCR2 |= RI_IOSwitch; + } + } + else + { + if (ioswitchmask != 0) + { + /* Close the analog switches */ + RI->ASCR1 &= (~ (uint32_t)RI_IOSwitch); + } + else + { + /* Open the analog switches */ + RI->ASCR2 &= (~ (uint32_t)RI_IOSwitch); + } + } +} + +/** + * @brief Enable or disable the switch control mode. + * @param NewState: New state of the switch control mode. This parameter can + * be ENABLE: ADC analog switches closed if the corresponding + * I/O switch is also closed. + * When using COMP1, switch control mode must be enabled. + * or DISABLE: ADC analog switches open or controlled by the ADC interface. + * When using the ADC for acquisition, switch control mode + * must be disabled. + * @note COMP1 comparator and ADC cannot be used at the same time since + * they share the ADC switch matrix. + * @retval None + */ +void SYSCFG_RISwitchControlModeCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Switch control mode */ + RI->ASCR1 |= (uint32_t) RI_ASCR1_SCM; + } + else + { + /* Disable the Switch control mode */ + RI->ASCR1 &= (uint32_t)(~RI_ASCR1_SCM); + } +} + +/** + * @brief Enable or disable Hysteresis of the input schmitt triger of Ports A..E + * When the I/Os are programmed in input mode by standard I/O port + * registers, the Schmitt trigger and the hysteresis are enabled by default. + * When hysteresis is disabled, it is possible to read the + * corresponding port with a trigger level of VDDIO/2. + * @param RI_Port: selects the GPIO Port. + * This parameter can be one of the following values: + * @arg RI_PortA: Port A is selected + * @arg RI_PortB: Port B is selected + * @arg RI_PortC: Port C is selected + * @arg RI_PortD: Port D is selected + * @arg RI_PortE: Port E is selected + * @arg RI_PortF: Port F is selected + * @arg RI_PortG: Port G is selected + * @param RI_Pin : Selects the pin(s) on which to enable or disable hysteresis. + * This parameter can any value from RI_Pin_x where x can be (0..15) or RI_Pin_All. + * @param NewState new state of the Hysteresis. + * This parameter can be: + * ENABLE so the Hysteresis is on + * or DISABLE so the Hysteresis is off + * @retval None + */ +void SYSCFG_RIHysteresisConfig(uint8_t RI_Port, uint16_t RI_Pin, + FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RI_PORT(RI_Port)); + assert_param(IS_RI_PIN(RI_Pin)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(RI_Port == RI_PortA) + { + if (NewState != DISABLE) + { + /* Hysteresis on */ + RI->HYSCR1 &= (uint32_t)~((uint32_t)RI_Pin); + } + else + { + /* Hysteresis off */ + RI->HYSCR1 |= (uint32_t) RI_Pin; + } + } + + else if(RI_Port == RI_PortB) + { + + if (NewState != DISABLE) + { + /* Hysteresis on */ + RI->HYSCR1 &= (uint32_t) (~((uint32_t)RI_Pin) << 16); + } + else + { + /* Hysteresis off */ + RI->HYSCR1 |= (uint32_t) ((uint32_t)(RI_Pin) << 16); + } + } + + else if(RI_Port == RI_PortC) + { + + if (NewState != DISABLE) + { + /* Hysteresis on */ + RI->HYSCR2 &= (uint32_t) (~((uint32_t)RI_Pin)); + } + else + { + /* Hysteresis off */ + RI->HYSCR2 |= (uint32_t) (RI_Pin ); + } + } + else if(RI_Port == RI_PortD) + { + if (NewState != DISABLE) + { + /* Hysteresis on */ + RI->HYSCR2 &= (uint32_t) (~((uint32_t)RI_Pin) << 16); + } + else + { + /* Hysteresis off */ + RI->HYSCR2 |= (uint32_t) ((uint32_t)(RI_Pin) << 16); + + } + } + else if(RI_Port == RI_PortE) + { + if (NewState != DISABLE) + { + /* Hysteresis on */ + RI->HYSCR3 &= (uint32_t) (~((uint32_t)RI_Pin)); + } + else + { + /* Hysteresis off */ + RI->HYSCR3 |= (uint32_t) (RI_Pin ); + } + } + else if(RI_Port == RI_PortF) + { + if (NewState != DISABLE) + { + /* Hysteresis on */ + RI->HYSCR3 &= (uint32_t) (~((uint32_t)RI_Pin) << 16); + } + else + { + /* Hysteresis off */ + RI->HYSCR3 |= (uint32_t) ((uint32_t)(RI_Pin) << 16); + } + } + else /* RI_Port == RI_PortG */ + { + if (NewState != DISABLE) + { + /* Hysteresis on */ + RI->HYSCR4 &= (uint32_t) (~((uint32_t)RI_Pin)); + } + else + { + /* Hysteresis off */ + RI->HYSCR4 |= (uint32_t) (RI_Pin); + } + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_syscfg.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_syscfg.h new file mode 100644 index 0000000000..b8d529662d --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_syscfg.h @@ -0,0 +1,476 @@ +/** + ****************************************************************************** + * @file stm32l1xx_syscfg.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the SYSCFG + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/*!< Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_SYSCFG_H +#define __STM32L1xx_SYSCFG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*!< Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup SYSCFG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SYSCFG_Exported_Constants + * @{ + */ + +/** @defgroup EXTI_Port_Sources + * @{ + */ +#define EXTI_PortSourceGPIOA ((uint8_t)0x00) +#define EXTI_PortSourceGPIOB ((uint8_t)0x01) +#define EXTI_PortSourceGPIOC ((uint8_t)0x02) +#define EXTI_PortSourceGPIOD ((uint8_t)0x03) +#define EXTI_PortSourceGPIOE ((uint8_t)0x04) +#define EXTI_PortSourceGPIOH ((uint8_t)0x05) +#define EXTI_PortSourceGPIOF ((uint8_t)0x06) +#define EXTI_PortSourceGPIOG ((uint8_t)0x07) + +#define IS_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == EXTI_PortSourceGPIOA) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOB) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOC) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOD) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOE) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOF) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOG) || \ + ((PORTSOURCE) == EXTI_PortSourceGPIOH)) +/** + * @} + */ + +/** @defgroup EXTI_Pin_sources + * @{ + */ +#define EXTI_PinSource0 ((uint8_t)0x00) +#define EXTI_PinSource1 ((uint8_t)0x01) +#define EXTI_PinSource2 ((uint8_t)0x02) +#define EXTI_PinSource3 ((uint8_t)0x03) +#define EXTI_PinSource4 ((uint8_t)0x04) +#define EXTI_PinSource5 ((uint8_t)0x05) +#define EXTI_PinSource6 ((uint8_t)0x06) +#define EXTI_PinSource7 ((uint8_t)0x07) +#define EXTI_PinSource8 ((uint8_t)0x08) +#define EXTI_PinSource9 ((uint8_t)0x09) +#define EXTI_PinSource10 ((uint8_t)0x0A) +#define EXTI_PinSource11 ((uint8_t)0x0B) +#define EXTI_PinSource12 ((uint8_t)0x0C) +#define EXTI_PinSource13 ((uint8_t)0x0D) +#define EXTI_PinSource14 ((uint8_t)0x0E) +#define EXTI_PinSource15 ((uint8_t)0x0F) +#define IS_EXTI_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == EXTI_PinSource0) || \ + ((PINSOURCE) == EXTI_PinSource1) || \ + ((PINSOURCE) == EXTI_PinSource2) || \ + ((PINSOURCE) == EXTI_PinSource3) || \ + ((PINSOURCE) == EXTI_PinSource4) || \ + ((PINSOURCE) == EXTI_PinSource5) || \ + ((PINSOURCE) == EXTI_PinSource6) || \ + ((PINSOURCE) == EXTI_PinSource7) || \ + ((PINSOURCE) == EXTI_PinSource8) || \ + ((PINSOURCE) == EXTI_PinSource9) || \ + ((PINSOURCE) == EXTI_PinSource10) || \ + ((PINSOURCE) == EXTI_PinSource11) || \ + ((PINSOURCE) == EXTI_PinSource12) || \ + ((PINSOURCE) == EXTI_PinSource13) || \ + ((PINSOURCE) == EXTI_PinSource14) || \ + ((PINSOURCE) == EXTI_PinSource15)) +/** + * @} + */ + +/** @defgroup SYSCFG_Memory_Remap_Config + * @{ + */ +#define SYSCFG_MemoryRemap_Flash ((uint8_t)0x00) +#define SYSCFG_MemoryRemap_SystemFlash ((uint8_t)0x01) +#define SYSCFG_MemoryRemap_FSMC ((uint8_t)0x02) +#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03) + +#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \ + ((REMAP) == SYSCFG_MemoryRemap_SystemFlash) || \ + ((REMAP) == SYSCFG_MemoryRemap_FSMC) || \ + ((REMAP) == SYSCFG_MemoryRemap_SRAM)) + +/** + * @} + */ + +/** @defgroup RI_Resistor + * @{ + */ + +#define RI_Resistor_10KPU COMP_CSR_10KPU +#define RI_Resistor_400KPU COMP_CSR_400KPU +#define RI_Resistor_10KPD COMP_CSR_10KPD +#define RI_Resistor_400KPD COMP_CSR_400KPD + +#define IS_RI_RESISTOR(RESISTOR) (((RESISTOR) == COMP_CSR_10KPU) || \ + ((RESISTOR) == COMP_CSR_400KPU) || \ + ((RESISTOR) == COMP_CSR_10KPD) || \ + ((RESISTOR) == COMP_CSR_400KPD)) + +/** + * @} + */ + +/** @defgroup RI_Channel + * @{ + */ + +#define RI_Channel_3 ((uint32_t)0x04000000) +#define RI_Channel_8 ((uint32_t)0x08000000) +#define RI_Channel_13 ((uint32_t)0x10000000) + +#define IS_RI_CHANNEL(CHANNEL) (((CHANNEL) == RI_Channel_3) || \ + ((CHANNEL) == RI_Channel_8) || \ + ((CHANNEL) == RI_Channel_13)) + +/** + * @} + */ + +/** @defgroup RI_ChannelSpeed + * @{ + */ + +#define RI_ChannelSpeed_Fast ((uint32_t)0x00000000) +#define RI_ChannelSpeed_Slow ((uint32_t)0x00000001) + +#define IS_RI_CHANNELSPEED(SPEED) (((SPEED) == RI_ChannelSpeed_Fast) || \ + ((SPEED) == RI_ChannelSpeed_Slow)) + +/** + * @} + */ + +/** @defgroup RI_InputCapture + * @{ + */ + +#define RI_InputCapture_IC1 RI_ICR_IC1 /*!< Input Capture 1 */ +#define RI_InputCapture_IC2 RI_ICR_IC2 /*!< Input Capture 2 */ +#define RI_InputCapture_IC3 RI_ICR_IC3 /*!< Input Capture 3 */ +#define RI_InputCapture_IC4 RI_ICR_IC4 /*!< Input Capture 4 */ + +#define IS_RI_INPUTCAPTURE(INPUTCAPTURE) ((((INPUTCAPTURE) & (uint32_t)0xFFC2FFFF) == 0x00) && ((INPUTCAPTURE) != (uint32_t)0x00)) +/** + * @} + */ + +/** @defgroup TIM_Select + * @{ + */ + +#define TIM_Select_None ((uint32_t)0x00000000) /*!< None selected */ +#define TIM_Select_TIM2 ((uint32_t)0x00010000) /*!< Timer 2 selected */ +#define TIM_Select_TIM3 ((uint32_t)0x00020000) /*!< Timer 3 selected */ +#define TIM_Select_TIM4 ((uint32_t)0x00030000) /*!< Timer 4 selected */ + +#define IS_RI_TIM(TIM) (((TIM) == TIM_Select_None) || \ + ((TIM) == TIM_Select_TIM2) || \ + ((TIM) == TIM_Select_TIM3) || \ + ((TIM) == TIM_Select_TIM4)) + +/** + * @} + */ + +/** @defgroup RI_InputCaptureRouting + * @{ + */ + /* TIMx_IC1 TIMx_IC2 TIMx_IC3 TIMx_IC4 */ +#define RI_InputCaptureRouting_0 ((uint32_t)0x00000000) /* PA0 PA1 PA2 PA3 */ +#define RI_InputCaptureRouting_1 ((uint32_t)0x00000001) /* PA4 PA5 PA6 PA7 */ +#define RI_InputCaptureRouting_2 ((uint32_t)0x00000002) /* PA8 PA9 PA10 PA11 */ +#define RI_InputCaptureRouting_3 ((uint32_t)0x00000003) /* PA12 PA13 PA14 PA15 */ +#define RI_InputCaptureRouting_4 ((uint32_t)0x00000004) /* PC0 PC1 PC2 PC3 */ +#define RI_InputCaptureRouting_5 ((uint32_t)0x00000005) /* PC4 PC5 PC6 PC7 */ +#define RI_InputCaptureRouting_6 ((uint32_t)0x00000006) /* PC8 PC9 PC10 PC11 */ +#define RI_InputCaptureRouting_7 ((uint32_t)0x00000007) /* PC12 PC13 PC14 PC15 */ +#define RI_InputCaptureRouting_8 ((uint32_t)0x00000008) /* PD0 PD1 PD2 PD3 */ +#define RI_InputCaptureRouting_9 ((uint32_t)0x00000009) /* PD4 PD5 PD6 PD7 */ +#define RI_InputCaptureRouting_10 ((uint32_t)0x0000000A) /* PD8 PD9 PD10 PD11 */ +#define RI_InputCaptureRouting_11 ((uint32_t)0x0000000B) /* PD12 PD13 PD14 PD15 */ +#define RI_InputCaptureRouting_12 ((uint32_t)0x0000000C) /* PE0 PE1 PE2 PE3 */ +#define RI_InputCaptureRouting_13 ((uint32_t)0x0000000D) /* PE4 PE5 PE6 PE7 */ +#define RI_InputCaptureRouting_14 ((uint32_t)0x0000000E) /* PE8 PE9 PE10 PE11 */ +#define RI_InputCaptureRouting_15 ((uint32_t)0x0000000F) /* PE12 PE13 PE14 PE15 */ + +#define IS_RI_INPUTCAPTURE_ROUTING(ROUTING) (((ROUTING) == RI_InputCaptureRouting_0) || \ + ((ROUTING) == RI_InputCaptureRouting_1) || \ + ((ROUTING) == RI_InputCaptureRouting_2) || \ + ((ROUTING) == RI_InputCaptureRouting_3) || \ + ((ROUTING) == RI_InputCaptureRouting_4) || \ + ((ROUTING) == RI_InputCaptureRouting_5) || \ + ((ROUTING) == RI_InputCaptureRouting_6) || \ + ((ROUTING) == RI_InputCaptureRouting_7) || \ + ((ROUTING) == RI_InputCaptureRouting_8) || \ + ((ROUTING) == RI_InputCaptureRouting_9) || \ + ((ROUTING) == RI_InputCaptureRouting_10) || \ + ((ROUTING) == RI_InputCaptureRouting_11) || \ + ((ROUTING) == RI_InputCaptureRouting_12) || \ + ((ROUTING) == RI_InputCaptureRouting_13) || \ + ((ROUTING) == RI_InputCaptureRouting_14) || \ + ((ROUTING) == RI_InputCaptureRouting_15)) + +/** + * @} + */ + +/** @defgroup RI_IOSwitch + * @{ + */ + +/* ASCR1 I/O switch: bit 31 is set to '1' to indicate that the mask is in ASCR1 register */ +#define RI_IOSwitch_CH0 ((uint32_t)0x80000001) +#define RI_IOSwitch_CH1 ((uint32_t)0x80000002) +#define RI_IOSwitch_CH2 ((uint32_t)0x80000004) +#define RI_IOSwitch_CH3 ((uint32_t)0x80000008) +#define RI_IOSwitch_CH4 ((uint32_t)0x80000010) +#define RI_IOSwitch_CH5 ((uint32_t)0x80000020) +#define RI_IOSwitch_CH6 ((uint32_t)0x80000040) +#define RI_IOSwitch_CH7 ((uint32_t)0x80000080) +#define RI_IOSwitch_CH8 ((uint32_t)0x80000100) +#define RI_IOSwitch_CH9 ((uint32_t)0x80000200) +#define RI_IOSwitch_CH10 ((uint32_t)0x80000400) +#define RI_IOSwitch_CH11 ((uint32_t)0x80000800) +#define RI_IOSwitch_CH12 ((uint32_t)0x80001000) +#define RI_IOSwitch_CH13 ((uint32_t)0x80002000) +#define RI_IOSwitch_CH14 ((uint32_t)0x80004000) +#define RI_IOSwitch_CH15 ((uint32_t)0x80008000) +#define RI_IOSwitch_CH31 ((uint32_t)0x80010000) +#define RI_IOSwitch_CH18 ((uint32_t)0x80040000) +#define RI_IOSwitch_CH19 ((uint32_t)0x80080000) +#define RI_IOSwitch_CH20 ((uint32_t)0x80100000) +#define RI_IOSwitch_CH21 ((uint32_t)0x80200000) +#define RI_IOSwitch_CH22 ((uint32_t)0x80400000) +#define RI_IOSwitch_CH23 ((uint32_t)0x80800000) +#define RI_IOSwitch_CH24 ((uint32_t)0x81000000) +#define RI_IOSwitch_CH25 ((uint32_t)0x82000000) +#define RI_IOSwitch_VCOMP ((uint32_t)0x84000000) /* VCOMP is an internal switch used to connect + selected channel to COMP1 non inverting input */ +#define RI_IOSwitch_CH27 ((uint32_t)0x88000000) +#define RI_IOSwitch_CH28 ((uint32_t)0x90000000) +#define RI_IOSwitch_CH29 ((uint32_t)0xA0000000) +#define RI_IOSwitch_CH30 ((uint32_t)0xC0000000) + +/* ASCR2 IO switch: bit 31 is set to '0' to indicate that the mask is in ASCR2 register */ +#define RI_IOSwitch_GR10_1 ((uint32_t)0x00000001) +#define RI_IOSwitch_GR10_2 ((uint32_t)0x00000002) +#define RI_IOSwitch_GR10_3 ((uint32_t)0x00000004) +#define RI_IOSwitch_GR10_4 ((uint32_t)0x00000008) +#define RI_IOSwitch_GR6_1 ((uint32_t)0x00000010) +#define RI_IOSwitch_GR6_2 ((uint32_t)0x00000020) +#define RI_IOSwitch_GR5_1 ((uint32_t)0x00000040) +#define RI_IOSwitch_GR5_2 ((uint32_t)0x00000080) +#define RI_IOSwitch_GR5_3 ((uint32_t)0x00000100) +#define RI_IOSwitch_GR4_1 ((uint32_t)0x00000200) +#define RI_IOSwitch_GR4_2 ((uint32_t)0x00000400) +#define RI_IOSwitch_GR4_3 ((uint32_t)0x00000800) +#define RI_IOSwitch_GR4_4 ((uint32_t)0x00008000) +#define RI_IOSwitch_CH0b ((uint32_t)0x00010000) +#define RI_IOSwitch_CH1b ((uint32_t)0x00020000) +#define RI_IOSwitch_CH2b ((uint32_t)0x00040000) +#define RI_IOSwitch_CH3b ((uint32_t)0x00080000) +#define RI_IOSwitch_CH6b ((uint32_t)0x00100000) +#define RI_IOSwitch_CH7b ((uint32_t)0x00200000) +#define RI_IOSwitch_CH8b ((uint32_t)0x00400000) +#define RI_IOSwitch_CH9b ((uint32_t)0x00800000) +#define RI_IOSwitch_CH10b ((uint32_t)0x01000000) +#define RI_IOSwitch_CH11b ((uint32_t)0x02000000) +#define RI_IOSwitch_CH12b ((uint32_t)0x04000000) +#define RI_IOSwitch_GR6_3 ((uint32_t)0x08000000) +#define RI_IOSwitch_GR6_4 ((uint32_t)0x10000000) +#define RI_IOSwitch_GR5_4 ((uint32_t)0x20000000) + + +#define IS_RI_IOSWITCH(IOSWITCH) (((IOSWITCH) == RI_IOSwitch_CH0) || \ + ((IOSWITCH) == RI_IOSwitch_CH1) || \ + ((IOSWITCH) == RI_IOSwitch_CH2) || \ + ((IOSWITCH) == RI_IOSwitch_CH3) || \ + ((IOSWITCH) == RI_IOSwitch_CH4) || \ + ((IOSWITCH) == RI_IOSwitch_CH5) || \ + ((IOSWITCH) == RI_IOSwitch_CH6) || \ + ((IOSWITCH) == RI_IOSwitch_CH7) || \ + ((IOSWITCH) == RI_IOSwitch_CH8) || \ + ((IOSWITCH) == RI_IOSwitch_CH9) || \ + ((IOSWITCH) == RI_IOSwitch_CH10) || \ + ((IOSWITCH) == RI_IOSwitch_CH11) || \ + ((IOSWITCH) == RI_IOSwitch_CH12) || \ + ((IOSWITCH) == RI_IOSwitch_CH13) || \ + ((IOSWITCH) == RI_IOSwitch_CH14) || \ + ((IOSWITCH) == RI_IOSwitch_CH15) || \ + ((IOSWITCH) == RI_IOSwitch_CH18) || \ + ((IOSWITCH) == RI_IOSwitch_CH19) || \ + ((IOSWITCH) == RI_IOSwitch_CH20) || \ + ((IOSWITCH) == RI_IOSwitch_CH21) || \ + ((IOSWITCH) == RI_IOSwitch_CH22) || \ + ((IOSWITCH) == RI_IOSwitch_CH23) || \ + ((IOSWITCH) == RI_IOSwitch_CH24) || \ + ((IOSWITCH) == RI_IOSwitch_CH25) || \ + ((IOSWITCH) == RI_IOSwitch_VCOMP) || \ + ((IOSWITCH) == RI_IOSwitch_CH27) || \ + ((IOSWITCH) == RI_IOSwitch_CH28) || \ + ((IOSWITCH) == RI_IOSwitch_CH29) || \ + ((IOSWITCH) == RI_IOSwitch_CH30) || \ + ((IOSWITCH) == RI_IOSwitch_CH31) || \ + ((IOSWITCH) == RI_IOSwitch_GR10_1) || \ + ((IOSWITCH) == RI_IOSwitch_GR10_2) || \ + ((IOSWITCH) == RI_IOSwitch_GR10_3) || \ + ((IOSWITCH) == RI_IOSwitch_GR10_4) || \ + ((IOSWITCH) == RI_IOSwitch_GR6_1) || \ + ((IOSWITCH) == RI_IOSwitch_GR6_2) || \ + ((IOSWITCH) == RI_IOSwitch_GR6_3) || \ + ((IOSWITCH) == RI_IOSwitch_GR6_4) || \ + ((IOSWITCH) == RI_IOSwitch_GR5_1) || \ + ((IOSWITCH) == RI_IOSwitch_GR5_2) || \ + ((IOSWITCH) == RI_IOSwitch_GR5_3) || \ + ((IOSWITCH) == RI_IOSwitch_GR5_4) || \ + ((IOSWITCH) == RI_IOSwitch_GR4_1) || \ + ((IOSWITCH) == RI_IOSwitch_GR4_2) || \ + ((IOSWITCH) == RI_IOSwitch_GR4_3) || \ + ((IOSWITCH) == RI_IOSwitch_GR4_4) || \ + ((IOSWITCH) == RI_IOSwitch_CH0b) || \ + ((IOSWITCH) == RI_IOSwitch_CH1b) || \ + ((IOSWITCH) == RI_IOSwitch_CH2b) || \ + ((IOSWITCH) == RI_IOSwitch_CH3b) || \ + ((IOSWITCH) == RI_IOSwitch_CH6b) || \ + ((IOSWITCH) == RI_IOSwitch_CH7b) || \ + ((IOSWITCH) == RI_IOSwitch_CH8b) || \ + ((IOSWITCH) == RI_IOSwitch_CH9b) || \ + ((IOSWITCH) == RI_IOSwitch_CH10b) || \ + ((IOSWITCH) == RI_IOSwitch_CH11b) || \ + ((IOSWITCH) == RI_IOSwitch_CH12b)) + +/** + * @} + */ + +/** @defgroup RI_Port + * @{ + */ + +#define RI_PortA ((uint8_t)0x01) /*!< GPIOA selected */ +#define RI_PortB ((uint8_t)0x02) /*!< GPIOB selected */ +#define RI_PortC ((uint8_t)0x03) /*!< GPIOC selected */ +#define RI_PortD ((uint8_t)0x04) /*!< GPIOD selected */ +#define RI_PortE ((uint8_t)0x05) /*!< GPIOE selected */ +#define RI_PortF ((uint8_t)0x06) /*!< GPIOF selected */ +#define RI_PortG ((uint8_t)0x07) /*!< GPIOG selected */ + +#define IS_RI_PORT(PORT) (((PORT) == RI_PortA) || \ + ((PORT) == RI_PortB) || \ + ((PORT) == RI_PortC) || \ + ((PORT) == RI_PortD) || \ + ((PORT) == RI_PortE) || \ + ((PORT) == RI_PortF) || \ + ((PORT) == RI_PortG)) +/** + * @} + */ + +/** @defgroup RI_Pin define + * @{ + */ +#define RI_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ +#define RI_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ +#define RI_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ +#define RI_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ +#define RI_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ +#define RI_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ +#define RI_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ +#define RI_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ +#define RI_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ +#define RI_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ +#define RI_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ +#define RI_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ +#define RI_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ +#define RI_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ +#define RI_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ +#define RI_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */ +#define RI_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */ + +#define IS_RI_PIN(PIN) ((PIN) != (uint16_t)0x00) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the SYSCFG and RI configuration to the default reset state **/ +void SYSCFG_DeInit(void); +void SYSCFG_RIDeInit(void); + +/* SYSCFG Initialization and Configuration functions **************************/ +void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap); +uint32_t SYSCFG_GetBootMode(void); +void SYSCFG_USBPuCmd(FunctionalState NewState); +void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex); + +/* RI Initialization and Configuration functions ******************************/ +void SYSCFG_RITIMSelect(uint32_t TIM_Select); +void SYSCFG_RITIMInputCaptureConfig(uint32_t RI_InputCapture, uint32_t RI_InputCaptureRouting); +void SYSCFG_RIResistorConfig(uint32_t RI_Resistor, FunctionalState NewState); +void SYSCFG_RIChannelSpeedConfig(uint32_t RI_Channel, uint32_t RI_ChannelSpeed); +void SYSCFG_RISwitchControlModeCmd(FunctionalState NewState); +void SYSCFG_RIIOSwitchConfig(uint32_t RI_IOSwitch, FunctionalState NewState); +void SYSCFG_RIHysteresisConfig(uint8_t RI_Port, uint16_t RI_Pin, FunctionalState NewState); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_SYSCFG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_tim.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_tim.c new file mode 100644 index 0000000000..3ff431947b --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_tim.c @@ -0,0 +1,2843 @@ +/** + ****************************************************************************** + * @file stm32l1xx_tim.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the TIM peripheral: + * + TimeBase management + * + Output Compare management + * + Input Capture management + * + Interrupts, DMA and flags management + * + Clocks management + * + Synchronization management + * + Specific interface management + * + Specific remapping management + * +* @verbatim + + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] This driver provides functions to configure and program the TIM + of all STM32L1xx devices These functions are split in 8 groups: + (#) TIM TimeBase management: this group includes all needed functions + to configure the TM Timebase unit: + (++) Set/Get Prescaler. + (++) Set/Get Autoreload. + (++) Counter modes configuration. + (++) Set Clock division. + (++) Select the One Pulse mode. + (++) Update Request Configuration. + (++) Update Disable Configuration. + (++) Auto-Preload Configuration. + (++) Enable/Disable the counter. + + (#) TIM Output Compare management: this group includes all needed + functions to configure the Capture/Compare unit used in Output + compare mode: + (++) Configure each channel, independently, in Output Compare mode. + (++) Select the output compare modes. + (++) Select the Polarities of each channel. + (++) Set/Get the Capture/Compare register values. + (++) Select the Output Compare Fast mode. + (++) Select the Output Compare Forced mode. + (++) Output Compare-Preload Configuration. + (++) Clear Output Compare Reference. + (++) Select the OCREF Clear signal. + (++) Enable/Disable the Capture/Compare Channels. + + (#) TIM Input Capture management: this group includes all needed + functions to configure the Capture/Compare unit used in + Input Capture mode: + (++) Configure each channel in input capture mode. + (++) Configure Channel1/2 in PWM Input mode. + (++) Set the Input Capture Prescaler. + (++) Get the Capture/Compare values. + + (#) TIM interrupts, DMA and flags management. + (++) Enable/Disable interrupt sources. + (++) Get flags status. + (++) Clear flags/ Pending bits. + (++) Enable/Disable DMA requests. + (++) Configure DMA burst mode. + (++) Select CaptureCompare DMA request. + + (#) TIM clocks management: this group includes all needed functions + to configure the clock controller unit: + (++) Select internal/External clock. + (++) Select the external clock mode: ETR(Mode1/Mode2), TIx or ITRx. + + (#) TIM synchronization management: this group includes all needed. + functions to configure the Synchronization unit: + (++) Select Input Trigger. + (++) Select Output Trigger. + (++) Select Master Slave Mode. + (++) ETR Configuration when used as external trigger. + + (#) TIM specific interface management, this group includes all + needed functions to use the specific TIM interface: + (++) Encoder Interface Configuration. + (++) Select Hall Sensor. + + (#) TIM specific remapping management includes the Remapping + configuration of specific timers + +@endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_tim.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup TIM + * @brief TIM driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ---------------------- TIM registers bit mask ------------------------ */ +#define SMCR_ETR_MASK ((uint16_t)0x00FF) +#define CCMR_OFFSET ((uint16_t)0x0018) +#define CCER_CCE_SET ((uint16_t)0x0001) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup TIM_Private_Functions + * @{ + */ + +/** @defgroup TIM_Group1 TimeBase management functions + * @brief TimeBase management functions + * +@verbatim + =============================================================================== + ##### TimeBase management functions ##### + =============================================================================== + + *** TIM Driver: how to use it in Timing(Time base) Mode *** + =============================================================================== + [..] To use the Timer in Timing(Time base) mode, the following steps are + mandatory: + (#) Enable TIM clock using + RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function. + (#) Fill the TIM_TimeBaseInitStruct with the desired parameters. + (#) Call TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct) to configure + the Time Base unit with the corresponding configuration. + (#) Enable the NVIC if you need to generate the update interrupt. + (#) Enable the corresponding interrupt using the function + TIM_ITConfig(TIMx, TIM_IT_Update). + (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + [..] + (@) All other functions can be used seperatly to modify, if needed, + a specific feature of the Timer. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the TIMx peripheral registers to their default reset values. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @retval None + * + */ +void TIM_DeInit(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + if (TIMx == TIM2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); + } + else if (TIMx == TIM3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); + } + else if (TIMx == TIM4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE); + } + else if (TIMx == TIM5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE); + } + else if (TIMx == TIM6) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE); + } + else if (TIMx == TIM7) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE); + } + + else if (TIMx == TIM9) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE); + } + else if (TIMx == TIM10) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE); + } + else + { + if (TIMx == TIM11) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE); + } + } + +} + +/** + * @brief Initializes the TIMx Time Base Unit peripheral according to + * the specified parameters in the TIM_TimeBaseInitStruct. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef + * structure that contains the configuration information for + * the specified TIM peripheral. + * @retval None + */ +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + uint16_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); + assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); + + tmpcr1 = TIMx->CR1; + + if(((TIMx) == TIM2) || ((TIMx) == TIM3) || ((TIMx) == TIM4) || ((TIMx) == TIM5)) + { + /* Select the Counter Mode */ + tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; + } + + if(((TIMx) != TIM6) && ((TIMx) != TIM7)) + { + /* Set the clock division */ + tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD)); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; + } + + TIMx->CR1 = tmpcr1; + + /* Set the Autoreload value */ + TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; + + /* Set the Prescaler value */ + TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; + + /* Generate an update event to reload the Prescaler value immediatly */ + TIMx->EGR = TIM_PSCReloadMode_Immediate; +} + +/** + * @brief Fills each TIM_TimeBaseInitStruct member with its default value. + * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef + * structure which will be initialized. + * @retval None + */ +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + /* Set the default configuration */ + TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF; + TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000; + TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up; +} + +/** + * @brief Configures the TIMx Prescaler. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param Prescaler: specifies the Prescaler Register value. + * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode + * This parameter can be one of the following values: + * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event. + * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediatly. + * @retval None + */ +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode)); + + /* Set the Prescaler value */ + TIMx->PSC = Prescaler; + /* Set or reset the UG Bit */ + TIMx->EGR = TIM_PSCReloadMode; +} + +/** + * @brief Specifies the TIMx Counter Mode to be used. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_CounterMode: specifies the Counter Mode to be used + * This parameter can be one of the following values: + * @arg TIM_CounterMode_Up: TIM Up Counting Mode. + * @arg TIM_CounterMode_Down: TIM Down Counting Mode. + * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1. + * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2. + * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3. + * @retval None + */ +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode) +{ + uint16_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode)); + + tmpcr1 = TIMx->CR1; + /* Reset the CMS and DIR Bits */ + tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); + /* Set the Counter Mode */ + tmpcr1 |= TIM_CounterMode; + /* Write to TIMx CR1 register */ + TIMx->CR1 = tmpcr1; +} + +/** + * @brief Sets the TIMx Counter Register value + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param Counter: specifies the Counter register new value. + * @retval None + */ +void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Set the Counter Register value */ + TIMx->CNT = Counter; +} + +/** + * @brief Sets the TIMx Autoreload Register value + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param Autoreload: specifies the Autoreload register new value. + * @retval None + */ +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Set the Autoreload Register value */ + TIMx->ARR = Autoreload; +} + +/** + * @brief Gets the TIMx Counter value. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @retval Counter Register value. + */ +uint32_t TIM_GetCounter(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Get the Counter Register value */ + return TIMx->CNT; +} + +/** + * @brief Gets the TIMx Prescaler value. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @retval Prescaler Register value. + */ +uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Get the Prescaler Register value */ + return TIMx->PSC; +} + +/** + * @brief Enables or Disables the TIMx Update event. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param NewState: new state of the TIMx UDIS bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the Update Disable Bit */ + TIMx->CR1 |= TIM_CR1_UDIS; + } + else + { + /* Reset the Update Disable Bit */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_UDIS); + } +} + +/** + * @brief Configures the TIMx Update Request Interrupt source. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param TIM_UpdateSource: specifies the Update source. + * This parameter can be one of the following values: + * @arg TIM_UpdateSource_Global: Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. + * @arg TIM_UpdateSource_Regular: Source of update is counter overflow/underflow. + * @retval None + */ +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource)); + + if (TIM_UpdateSource != TIM_UpdateSource_Global) + { + /* Set the URS Bit */ + TIMx->CR1 |= TIM_CR1_URS; + } + else + { + /* Reset the URS Bit */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_URS); + } +} + +/** + * @brief Enables or disables TIMx peripheral Preload register on ARR. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param NewState: new state of the TIMx peripheral Preload register + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the ARR Preload Bit */ + TIMx->CR1 |= TIM_CR1_ARPE; + } + else + { + /* Reset the ARR Preload Bit */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_ARPE); + } +} + +/** + * @brief Selects the TIMx's One Pulse Mode. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param TIM_OPMode: specifies the OPM Mode to be used. + * This parameter can be one of the following values: + * @arg TIM_OPMode_Single:: TIM One Pulse Single Mode (Counter stops counting + * at the next update event (clearing the bit CEN)). + * @arg TIM_OPMode_Repetitive: TIM One Pulse Repetitive Mode + * (Counter is not stopped at update event). + * @retval None + */ +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_OPM_MODE(TIM_OPMode)); + + /* Reset the OPM Bit */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_OPM); + /* Configure the OPM Mode */ + TIMx->CR1 |= TIM_OPMode; +} + +/** + * @brief Sets the TIMx Clock Division value. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_CKD: specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CKD_DIV1: TDTS = Tck_tim. + * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim. + * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim. + * @retval None + */ +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_CKD_DIV(TIM_CKD)); + + /* Reset the CKD Bits */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_CKD); + /* Set the CKD value */ + TIMx->CR1 |= TIM_CKD; +} + +/** + * @brief Enables or disables the specified TIM peripheral. + * @param TIMx: where x can be 2 to 11 to select the TIMx peripheral. + * @param NewState: new state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Counter */ + TIMx->CR1 |= TIM_CR1_CEN; + } + else + { + /* Disable the TIM Counter */ + TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); + } +} + +/** + * @} + */ + +/** @defgroup TIM_Group2 Output Compare management functions + * @brief Output Compare management functions + * +@verbatim + =============================================================================== + ##### Output Compare management functions ##### + =============================================================================== + *** TIM Driver: how to use it in Output Compare Mode *** + =============================================================================== + [..] To use the Timer in Output Compare mode, the following steps are mandatory: + (#) Enable TIM clock using + RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function. + (#) Configure the TIM pins by configuring the corresponding GPIO pins + (#) Configure the Time base unit as described in the first part of this + driver, if needed, else the Timer will run with the default + configuration: + (++) Autoreload value = 0xFFFF. + (++) Prescaler value = 0x0000. + (++) Counter mode = Up counting. + (++) Clock Division = TIM_CKD_DIV1. + (#) Fill the TIM_OCInitStruct with the desired parameters including: + (++) The TIM Output Compare mode: TIM_OCMode. + (++) TIM Output State: TIM_OutputState. + (++) TIM Pulse value: TIM_Pulse. + (++) TIM Output Compare Polarity : TIM_OCPolarity. + (#) Call TIM_OCxInit(TIMx, &TIM_OCInitStruct) to configure the desired + channel with the corresponding configuration. + (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + [..] + (@) All other functions can be used separately to modify, if needed, + a specific feature of the Timer. + (@) In case of PWM mode, this function is mandatory: + TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_ENABLE). + (@) If the corresponding interrupt or DMA request are needed, the user should: + (#@) Enable the NVIC (or the DMA) to use the TIM interrupts (or DMA requests). + (#@) Enable the corresponding interrupt (or DMA request) using the function + TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIMx Channel1 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC1M)); + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC1S)); + + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1P)); + /* Set the Output Compare Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; + + /* Set the Output State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputState; + + /* Set the Capture Compare Register value */ + TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel2 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC2E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC2M)); + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4); + + /* Set the Capture Compare Register value */ + TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel3 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC3E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC3M)); + + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8); + + /* Set the Capture Compare Register value */ + TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel4 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 2: Reset the CC4E Bit */ + TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC4E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC4M)); + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC4P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12); + + /* Set the Capture Compare Register value */ + TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Fills each TIM_OCInitStruct member with its default value. + * @param TIM_OCInitStruct : pointer to a TIM_OCInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + /* Set the default configuration */ + TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing; + TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct->TIM_Pulse = 0x0000; + TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High; +} + +/** + * @brief Selects the TIM Output Compare Mode. + * @note This function disables the selected channel before changing the Output + * Compare Mode. + * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel. + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1. + * @arg TIM_Channel_2: TIM Channel 2. + * @arg TIM_Channel_3: TIM Channel 3. + * @arg TIM_Channel_4: TIM Channel 4. + * @param TIM_OCMode: specifies the TIM Output Compare Mode. + * This parameter can be one of the following values: + * @arg TIM_OCMode_Timing: TIM Output Compare Timing mode. + * @arg TIM_OCMode_Active: TIM Output Compare Active mode. + * @arg TIM_OCMode_Inactive: TIM Output Compare Inactive mode. + * @arg TIM_OCMode_Toggle: TIM Output Compare Toggle mode. + * @arg TIM_OCMode_PWM1: TIM Output Compare PWM1 mode. + * @arg TIM_OCMode_PWM2: TIM Output Compare PWM2 mode. + * @arg TIM_ForcedAction_Active: TIM Forced Action Active mode. + * @arg TIM_ForcedAction_InActive: TIM Forced Action Inactive mode. + * @retval None + */ +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode) +{ + uint32_t tmp = 0; + uint16_t tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCM(TIM_OCMode)); + + tmp = (uint32_t) TIMx; + tmp += CCMR_OFFSET; + + tmp1 = CCER_CCE_SET << (uint16_t)TIM_Channel; + + /* Disable the Channel: Reset the CCxE Bit */ + TIMx->CCER &= (uint16_t) ~tmp1; + + if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) + { + tmp += (TIM_Channel>>1); + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M); + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= TIM_OCMode; + } + else + { + tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1; + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M); + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8); + } +} + +/** + * @brief Sets the TIMx Capture Compare1 Register value + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param Compare1: specifies the Capture Compare1 register new value. + * @retval None + */ +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + + /* Set the Capture Compare1 Register value */ + TIMx->CCR1 = Compare1; +} + +/** + * @brief Sets the TIMx Capture Compare2 Register value. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param Compare2: specifies the Capture Compare2 register new value. + * @retval None + */ +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Set the Capture Compare2 Register value */ + TIMx->CCR2 = Compare2; +} + +/** + * @brief Sets the TIMx Capture Compare3 Register value. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param Compare3: specifies the Capture Compare3 register new value. + * @retval None + */ +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Set the Capture Compare3 Register value */ + TIMx->CCR3 = Compare3; +} + +/** + * @brief Sets the TIMx Capture Compare4 Register value. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param Compare4: specifies the Capture Compare4 register new value. + * @retval None + */ +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Set the Capture Compare4 Register value */ + TIMx->CCR4 = Compare4; +} + +/** + * @brief Forces the TIMx output 1 waveform to active or inactive level. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC1REF. + * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF. + * @retval None + */ +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC1M Bits */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1M); + /* Configure The Forced output Mode */ + tmpccmr1 |= TIM_ForcedAction; + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 2 waveform to active or inactive level. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM + * peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC2REF. + * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF. + * @retval None + */ +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC2M Bits */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2M); + /* Configure The Forced output Mode */ + tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8); + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 3 waveform to active or inactive level. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC3REF. + * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF. + * @retval None + */ +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC1M Bits */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3M); + /* Configure The Forced output Mode */ + tmpccmr2 |= TIM_ForcedAction; + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Forces the TIMx output 4 waveform to active or inactive level. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC4REF. + * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF. + * @retval None + */ +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC2M Bits */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4M); + /* Configure The Forced output Mode */ + tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8); + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR1. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register. + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable: Enable TIM output compare Preload + * @arg TIM_OCPreload_Disable: Disable TIM output compare Preload + * @retval None + */ +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC1PE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1PE); + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= TIM_OCPreload; + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR2. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register. + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable: Enable TIM output compare Preload + * @arg TIM_OCPreload_Disable: Disable TIM output compare Preload + * @retval None + */ +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC2PE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2PE); + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8); + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR3. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register. + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable: Enable TIM output compare Preload + * @arg TIM_OCPreload_Disable: Disable TIM output compare Preload + * @retval None + */ +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC3PE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3PE); + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= TIM_OCPreload; + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR4. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register. + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable: Enable TIM output compare Preload + * @arg TIM_OCPreload_Disable: Disable TIM output compare Preload + * @retval None + */ +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC4PE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4PE); + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8); + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 1 Fast feature. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable. + * @arg TIM_OCFast_Disable: TIM output compare fast disable. + * @retval None + */ +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC1FE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1FE); + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= TIM_OCFast; + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 2 Fast feature. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable. + * @arg TIM_OCFast_Disable: TIM output compare fast disable. + * @retval None + */ +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC2FE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2FE); + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= (uint16_t)(TIM_OCFast << 8); + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 3 Fast feature. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable. + * @arg TIM_OCFast_Disable: TIM output compare fast disable. + * @retval None + */ +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC3FE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3FE); + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= TIM_OCFast; + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 4 Fast feature. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable. + * @arg TIM_OCFast_Disable: TIM output compare fast disable. + * @retval None + */ +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC4FE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4FE); + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= (uint16_t)(TIM_OCFast << 8); + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF1 signal on an external event + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable. + * @arg TIM_OCClear_Disable: TIM Output clear disable. + * @retval None + */ +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC1CE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1CE); + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= TIM_OCClear; + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF2 signal on an external event + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable. + * @arg TIM_OCClear_Disable: TIM Output clear disable . + * @retval None + */ +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC2CE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2CE); + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= (uint16_t)(TIM_OCClear << 8); + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF3 signal on an external event + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable. + * @arg TIM_OCClear_Disable: TIM Output clear disable. + * @retval None + */ +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC3CE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3CE); + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= TIM_OCClear; + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF4 signal on an external event + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable. + * @arg TIM_OCClear_Disable: TIM Output clear disable. + * @retval None + */ +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC4CE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4CE); + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= (uint16_t)(TIM_OCClear << 8); + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx channel 1 polarity. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC1 Polarity. + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high. + * @arg TIM_OCPolarity_Low: Output Compare active low. + * @retval None + */ +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + /* Set or Reset the CC1P Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1P); + tmpccer |= TIM_OCPolarity; + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 2 polarity. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC2 Polarity. + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high. + * @arg TIM_OCPolarity_Low: Output Compare active low. + * @retval None + */ +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + /* Set or Reset the CC2P Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2P); + tmpccer |= (uint16_t)(TIM_OCPolarity << 4); + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 3 polarity. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC3 Polarity. + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high. + * @arg TIM_OCPolarity_Low: Output Compare active low. + * @retval None + */ +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + /* Set or Reset the CC3P Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3P); + tmpccer |= (uint16_t)(TIM_OCPolarity << 8); + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 4 polarity. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC4 Polarity. + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high. + * @arg TIM_OCPolarity_Low: Output Compare active low. + * @retval None + */ +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + /* Set or Reset the CC4P Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC4P); + tmpccer |= (uint16_t)(TIM_OCPolarity << 12); + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Selects the OCReference Clear source. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_OCReferenceClear: specifies the OCReference Clear source. + * This parameter can be one of the following values: + * @arg TIM_OCReferenceClear_ETRF: The internal OCreference clear input is connected to ETRF. + * @arg TIM_OCReferenceClear_OCREFCLR: The internal OCreference clear input is connected to OCREF_CLR input. + * @retval None + */ +void TIM_SelectOCREFClear(TIM_TypeDef* TIMx, uint16_t TIM_OCReferenceClear) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(TIM_OCREFERENCECECLEAR_SOURCE(TIM_OCReferenceClear)); + + /* Set the TIM_OCReferenceClear source */ + TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_OCCS); + TIMx->SMCR |= TIM_OCReferenceClear; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel. + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1. + * @arg TIM_Channel_2: TIM Channel 2. + * @arg TIM_Channel_3: TIM Channel 3. + * @arg TIM_Channel_4: TIM Channel 4. + * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. + * @retval None + */ +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx) +{ + uint16_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_CCX(TIM_CCx)); + + tmp = CCER_CCE_SET << TIM_Channel; + + /* Reset the CCxE Bit */ + TIMx->CCER &= (uint16_t)~ tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel); +} + +/** + * @} + */ + +/** @defgroup TIM_Group3 Input Capture management functions + * @brief Input Capture management functions + * +@verbatim + =============================================================================== + ##### Input Capture management functions ##### + =============================================================================== + + *** TIM Driver: how to use it in Input Capture Mode *** + =============================================================================== + [..] To use the Timer in Input Capture mode, the following steps are mandatory: + (#) Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) + function. + (#) Configure the TIM pins by configuring the corresponding GPIO pins. + (#) Configure the Time base unit as described in the first part of this + driver, if needed, else the Timer will run with the default configuration: + (++) Autoreload value = 0xFFFF. + (++) Prescaler value = 0x0000. + (++) Counter mode = Up counting. + (++) Clock Division = TIM_CKD_DIV1. + (#) Fill the TIM_ICInitStruct with the desired parameters including: + (++) TIM Channel: TIM_Channel. + (++) TIM Input Capture polarity: TIM_ICPolarity. + (++) TIM Input Capture selection: TIM_ICSelection. + (++) TIM Input Capture Prescaler: TIM_ICPrescaler. + (++) TIM Input CApture filter value: TIM_ICFilter. + (#) Call TIM_ICInit(TIMx, &TIM_ICInitStruct) to configure the desired + channel with the corresponding configuration and to measure only + frequency or duty cycle of the input signal,or, Call + TIM_PWMIConfig(TIMx, &TIM_ICInitStruct) to configure the desired + channels with the corresponding configuration and to measure the + frequency and the duty cycle of the input signal. + (#) Enable the NVIC or the DMA to read the measured frequency. + (#) Enable the corresponding interrupt (or DMA request) to read + the Captured value, using the function TIM_ITConfig(TIMx, TIM_IT_CCx) + (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)). + (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + (#) Use TIM_GetCapturex(TIMx); to read the captured value. + [..] + (@) All other functions can be used separately to modify, if needed, + a specific feature of the Timer. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIM peripheral according to the specified + * parameters in the TIM_ICInitStruct. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity)); + assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter)); + + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2) + { + /* TI2 Configuration */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3) + { + /* TI3 Configuration */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + /* TI4 Configuration */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Fills each TIM_ICInitStruct member with its default value. + * @param TIM_ICInitStruct : pointer to a TIM_ICInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Set the default configuration */ + TIM_ICInitStruct->TIM_Channel = TIM_Channel_1; + TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1; + TIM_ICInitStruct->TIM_ICFilter = 0x00; +} + +/** + * @brief Configures the TIM peripheral according to the specified + * parameters in the TIM_ICInitStruct to measure an external PWM signal. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure + * that contains the configuration information for the specified TIM + * peripheral. + * @retval None + */ +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + uint16_t icoppositepolarity = TIM_ICPolarity_Rising; + uint16_t icoppositeselection = TIM_ICSelection_DirectTI; + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + /* Select the Opposite Input Polarity */ + if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising) + { + icoppositepolarity = TIM_ICPolarity_Falling; + } + else + { + icoppositepolarity = TIM_ICPolarity_Rising; + } + /* Select the Opposite Input */ + if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI) + { + icoppositeselection = TIM_ICSelection_IndirectTI; + } + else + { + icoppositeselection = TIM_ICSelection_DirectTI; + } + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI2 Configuration */ + TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + /* TI2 Configuration */ + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI1 Configuration */ + TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Gets the TIMx Input Capture 1 value. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @retval Capture Compare 1 Register value. + */ +uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + + /* Get the Capture 1 Register value */ + return TIMx->CCR1; +} + +/** + * @brief Gets the TIMx Input Capture 2 value. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @retval Capture Compare 2 Register value. + */ +uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Get the Capture 2 Register value */ + return TIMx->CCR2; +} + +/** + * @brief Gets the TIMx Input Capture 3 value. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @retval Capture Compare 3 Register value. + */ +uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Get the Capture 3 Register value */ + return TIMx->CCR3; +} + +/** + * @brief Gets the TIMx Input Capture 4 value. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @retval Capture Compare 4 Register value. + */ +uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Get the Capture 4 Register value */ + return TIMx->CCR4; +} + +/** + * @brief Sets the TIMx Input Capture 1 prescaler. + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler. + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events. + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events. + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events. + * @retval None + */ +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC1PSC Bits */ + TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC1PSC); + /* Set the IC1PSC value */ + TIMx->CCMR1 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 2 prescaler. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler. + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events. + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events. + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events. + * @retval None + */ +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC2PSC Bits */ + TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC2PSC); + /* Set the IC2PSC value */ + TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8); +} + +/** + * @brief Sets the TIMx Input Capture 3 prescaler. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler. + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events. + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events. + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events. + * @retval None + */ +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC3PSC Bits */ + TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC3PSC); + /* Set the IC3PSC value */ + TIMx->CCMR2 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 4 prescaler. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler. + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events. + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events. + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events. + * @retval None + */ +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC4PSC Bits */ + TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC4PSC); + /* Set the IC4PSC value */ + TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8); +} + +/** + * @} + */ + +/** @defgroup TIM_Group4 Interrupts DMA and flags management functions + * @brief Interrupts, DMA and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts, DMA and flags management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified TIM interrupts. + * @param TIMx: where x can be 2 to 11 to select the TIMx peripheral. + * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source. + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source. + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source. + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source. + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source. + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source. + * @note TIM6 and TIM7 can only generate an update interrupt. + * @note TIM_IT_CC2, TIM_IT_CC3, TIM_IT_CC4 and TIM_IT_Trigger can not be used with TIM10 and TIM11. + * @note TIM_IT_CC3, TIM_IT_CC4 can not be used with TIM9. + * @param NewState: new state of the TIM interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_IT(TIM_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Interrupt sources */ + TIMx->DIER |= TIM_IT; + } + else + { + /* Disable the Interrupt sources */ + TIMx->DIER &= (uint16_t)~TIM_IT; + } +} + +/** + * @brief Configures the TIMx event to be generate by software. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param TIM_EventSource: specifies the event source. + * This parameter can be one or more of the following values: + * @arg TIM_EventSource_Update: Timer update Event source. + * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source. + * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source. + * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source. + * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source. + * @arg TIM_EventSource_Trigger: Timer Trigger Event source. + * @note TIM6 and TIM7 can only generate an update event. + * @note TIM9 can only generate an update event, Capture Compare 1 event, + * Capture Compare 2 event and TIM_EventSource_Trigger. + * @note TIM10 and TIM11 can only generate an update event and Capture Compare 1 event. + * @retval None + */ +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource)); + /* Set the event sources */ + TIMx->EGR = TIM_EventSource; +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param TIM_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_Update: TIM update Flag. + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag. + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag. + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag. + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag. + * @arg TIM_FLAG_Trigger: TIM Trigger Flag. + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag. + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag. + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag. + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag. + * + * @note TIM6 and TIM7 can have only one update flag. + * @note TIM9 can have only update flag, TIM_FLAG_CC1, TIM_FLAG_CC2 and TIM_FLAG_Trigger, + * TIM_FLAG_CC1OF or TIM_FLAG_CC2OF flags. + * @note TIM10 and TIM11 can have only update flag, TIM_FLAG_CC1 or TIM_FLAG_CC1OF flags + * @retval The new state of TIM_FLAG (SET or RESET). + */ +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_FLAG(TIM_FLAG)); + + if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's pending flags. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param TIM_FLAG: specifies the flag bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_FLAG_Update: TIM update Flag. + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag. + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag. + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag. + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag. + * @arg TIM_FLAG_Trigger: TIM Trigger Flag. + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag. + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag. + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag. + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag. + * @note TIM6 and TIM7 can have only one update flag. + * @note TIM9 can have only update flag, TIM_FLAG_CC1, TIM_FLAG_CC2 and TIM_FLAG_Trigger flags + * TIM_FLAG_CC1OF or TIM_FLAG_CC2OF flags. + * @note TIM10 and TIM11 can have only update flag, TIM_FLAG_CC1 + * or TIM_FLAG_CC1OF flags + * @retval None + */ +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_CLEAR_FLAG(TIM_FLAG)); + + /* Clear the flags */ + TIMx->SR = (uint16_t)~TIM_FLAG; +} + +/** + * @brief Checks whether the TIM interrupt has occurred or not. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param TIM_IT: specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source. + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source. + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source. + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source. + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source. + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source. + * + * @note TIM6 and TIM7 can generate only an update interrupt. + * @note TIM9 can have only update interrupt, TIM_FLAG_CC1 or TIM_FLAG_CC2, + * interrupt and TIM_IT_Trigger interrupt. + * @note TIM10 and TIM11 can have only update interrupt or TIM_FLAG_CC1 + * interrupt + * @retval The new state of the TIM_IT(SET or RESET). + */ +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) +{ + ITStatus bitstatus = RESET; + uint16_t itstatus = 0x0, itenable = 0x0; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_IT(TIM_IT)); + + itstatus = TIMx->SR & TIM_IT; + + itenable = TIMx->DIER & TIM_IT; + if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's interrupt pending bits. + * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. + * @param TIM_IT: specifies the pending bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source. + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source. + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source. + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source. + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source. + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source. + * @note + * @note TIM6 and TIM7 can generate only an update interrupt. + * @note TIM9 can have only update interrupt, TIM_IT_CC1 or TIM_IT_CC2, + * and TIM_IT_Trigger interrupt. + * @note TIM10 and TIM11 can have only update interrupt or TIM_IT_CC1 + * interrupt + * @retval None + */ +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_IT(TIM_IT)); + + /* Clear the IT pending Bit */ + TIMx->SR = (uint16_t)~TIM_IT; +} + +/** + * @brief Configures the TIMx's DMA interface. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_DMABase: DMA Base address. + * This parameter can be one of the following values: + * @arg TIM_DMABase_CR1: TIM CR1 register as TIM DMA Base. + * @arg TIM_DMABase_CR2: TIM CR2 register as TIM DMA Base. + * @arg TIM_DMABase_SMCR: TIM SMCR register as TIM DMA Base. + * @arg TIM_DMABase_DIER: TIM DIER register as TIM DMA Base. + * @arg TIM_DMABase_SR: TIM SR register as TIM DMA Base. + * @arg TIM_DMABase_EGR: TIM EGR register as TIM DMA Base. + * @arg TIM_DMABase_CCMR1: TIM CCMR1 register as TIM DMA Base. + * @arg TIM_DMABase_CCMR2: TIM CCMR2 register as TIM DMA Base. + * @arg TIM_DMABase_CCER: TIM CCER register as TIM DMA Base. + * @arg TIM_DMABase_CNT: TIM CNT register as TIM DMA Base. + * @arg TIM_DMABase_PSC: TIM PSC register as TIM DMA Base. + * @arg TIM_DMABase_ARR: TIM ARR register as TIM DMA Base. + * @arg TIM_DMABase_CCR1: TIM CCR1 register as TIM DMA Base. + * @arg TIM_DMABase_CCR2: TIM CCR2 register as TIM DMA Base. + * @arg TIM_DMABase_CCR3: TIM CCR3 register as TIM DMA Base. + * @arg TIM_DMABase_CCR4: TIM CCR4 register as TIM DMA Base. + * @arg TIM_DMABase_DCR: TIM DCR register as TIM DMA Base. + * @arg TIM_DMABase_OR: TIM OR register as TIM DMA Base. + * @param TIM_DMABurstLength: DMA Burst length. + * This parameter can be one value between: + * TIM_DMABurstLength_1Transfer and TIM_DMABurstLength_18Transfers. + * @retval None + */ +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_BASE(TIM_DMABase)); + assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength)); + /* Set the DMA Base and the DMA Burst Length */ + TIMx->DCR = TIM_DMABase | TIM_DMABurstLength; +} + +/** + * @brief Enables or disables the TIMx's DMA Requests. + * @param TIMx: where x can be 2, 3, 4, 5, 6 or 7 to select the TIM peripheral. + * @param TIM_DMASource: specifies the DMA Request sources. + * This parameter can be any combination of the following values: + * @arg TIM_DMA_Update: TIM update Interrupt source. + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source. + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source. + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source. + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source. + * @arg TIM_DMA_Trigger: TIM Trigger DMA source. + * @param NewState: new state of the DMA Request sources. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA sources */ + TIMx->DIER |= TIM_DMASource; + } + else + { + /* Disable the DMA sources */ + TIMx->DIER &= (uint16_t)~TIM_DMASource; + } +} + +/** + * @brief Selects the TIMx peripheral Capture Compare DMA source. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param NewState: new state of the Capture Compare DMA source + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the CCDS Bit */ + TIMx->CR2 |= TIM_CR2_CCDS; + } + else + { + /* Reset the CCDS Bit */ + TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCDS); + } +} + +/** + * @} + */ + +/** @defgroup TIM_Group5 Clocks management functions + * @brief Clocks management functions + * +@verbatim + =============================================================================== + ##### Clocks management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIMx internal Clock + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @retval None + */ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + /* Disable slave mode to clock the prescaler directly with the internal clock */ + TIMx->SMCR &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); +} + +/** + * @brief Configures the TIMx Internal Trigger as External Clock + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_ITRSource: Trigger source. + * This parameter can be one of the following values: + * @param TIM_TS_ITR0: Internal Trigger 0. + * @param TIM_TS_ITR1: Internal Trigger 1. + * @param TIM_TS_ITR2: Internal Trigger 2. + * @param TIM_TS_ITR3: Internal Trigger 3. + * @retval None + */ +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource)); + /* Select the Internal Trigger */ + TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource); + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the TIMx Trigger as External Clock + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_TIxExternalCLKSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector. + * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1. + * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2. + * @param TIM_ICPolarity: specifies the TIx Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising: + * @arg TIM_ICPolarity_Falling: + * @param ICFilter : specifies the filter value. + * This parameter must be a value between 0x0 and 0xF. + * @retval None + */ +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, + uint16_t TIM_ICPolarity, uint16_t ICFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity)); + assert_param(IS_TIM_IC_FILTER(ICFilter)); + + /* Configure the Timer Input Clock Source */ + if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2) + { + TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + else + { + TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + /* Select the Trigger source */ + TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the External clock Mode1 + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the SMS Bits */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); + /* Select the External clock mode1 */ + tmpsmcr |= TIM_SlaveMode_External1; + /* Select the Trigger selection : ETRF */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS)); + tmpsmcr |= TIM_TS_ETRF; + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the External clock Mode2 + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + /* Enable the External clock mode2 */ + TIMx->SMCR |= TIM_SMCR_ECE; +} + +/** + * @} + */ + +/** @defgroup TIM_Group6 Synchronization management functions + * @brief Synchronization management functions + * +@verbatim + =============================================================================== + ##### Synchronization management functions ##### + =============================================================================== + *** TIM Driver: how to use it in synchronization Mode *** + =============================================================================== + [..] Case of two/several Timers + (#) Configure the Master Timers using the following functions: + (++) void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, + uint16_t TIM_TRGOSource). + (++) void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, + uint16_t TIM_MasterSlaveMode); + (#) Configure the Slave Timers using the following functions: + (++) void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, + uint16_t TIM_InputTriggerSource); + (++) void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); + [..] Case of Timers and external trigger(ETR pin) + (#) Configure the Etrenal trigger using this function: + (++) void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); + (#) Configure the Slave Timers using the following functions: + (++) void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, + uint16_t TIM_InputTriggerSource); + (++) void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); + +@endverbatim + * @{ + */ + +/** + * @brief Selects the Input Trigger source + * @param TIMx: where x can be 2, 3, 4, 5, or 9 to select the TIM peripheral. + * @param TIM_InputTriggerSource: The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0. + * @arg TIM_TS_ITR1: Internal Trigger 1. + * @arg TIM_TS_ITR2: Internal Trigger 2. + * @arg TIM_TS_ITR3: Internal Trigger 3. + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector. + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1. + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2. + * @arg TIM_TS_ETRF: External Trigger input. + * @retval None + */ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the TS Bits */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS)); + /* Set the Input Trigger source */ + tmpsmcr |= TIM_InputTriggerSource; + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Selects the TIMx Trigger Output Mode. + * @param TIMx: where x can be 2, 3, 4, 5, 6, 7 or 9 to select the TIM peripheral. + * @param TIM_TRGOSource: specifies the Trigger Output source. + * This paramter can be one of the following values: + * + * @param For all TIMx + * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output (TRGO). + * + * @param For all TIMx except TIM6 and TIM7 + * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag + * is to be set, as soon as a capture or compare match occurs (TRGO). + * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output (TRGO). + + * @param For all TIMx except TIM6, TIM7, TIM10 and TIM11 + * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output (TRGO). + + * @param For TIM2, TIM3 and TIM4 + * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output (TRGO). + * + * @retval None + */ +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource)); + + /* Reset the MMS Bits */ + TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_MMS); + /* Select the TRGO source */ + TIMx->CR2 |= TIM_TRGOSource; +} + +/** + * @brief Selects the TIMx Slave Mode. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_SlaveMode: specifies the Timer Slave Mode. + * This paramter can be one of the following values: + * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal (TRGI) re-initializes + * the counter and triggers an update of the registers. + * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high. + * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI. + * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter. + * @retval None + */ +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode)); + + /* Reset the SMS Bits */ + TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_SMS); + /* Select the Slave Mode */ + TIMx->SMCR |= TIM_SlaveMode; +} + +/** + * @brief Sets or Resets the TIMx Master/Slave Mode. + * @param TIMx: where x can be 2, 3, 4, 5 or 9 to select the TIM peripheral. + * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode. + * This paramter can be one of the following values: + * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer + * and its slaves (through TRGO). + * @arg TIM_MasterSlaveMode_Disable: No action + * @retval None + */ +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); + + /* Reset the MSM Bit */ + TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_MSM); + + /* Set or Reset the MSM Bit */ + TIMx->SMCR |= TIM_MasterSlaveMode; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx: where x can be 2, 3, 4, 5, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + tmpsmcr = TIMx->SMCR; + /* Reset the ETR Bits */ + tmpsmcr &= SMCR_ETR_MASK; + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8))); + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @} + */ + +/** @defgroup TIM_Group7 Specific interface management functions + * @brief Specific interface management functions + * +@verbatim + =============================================================================== + ##### Specific interface management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIMx Encoder Interface. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param TIM_EncoderMode: specifies the TIMx Encoder Mode. + * This parameter can be one of the following values: + * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. + * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. + * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending + * on the level of the other input. + * @param TIM_IC1Polarity: specifies the IC1 Polarity. + * This parmeter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @param TIM_IC2Polarity: specifies the IC2 Polarity + * This parmeter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @retval None + */ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, + uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity) +{ + uint16_t tmpsmcr = 0; + uint16_t tmpccmr1 = 0; + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Set the encoder Mode */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); + tmpsmcr |= TIM_EncoderMode; + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S))); + tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P))); + tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4)); + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Enables or disables the TIMx's Hall sensor interface. + * @param TIMx: where x can be 2, 3, 4 or 5 to select the TIM peripheral. + * @param NewState: new state of the TIMx Hall sensor interface. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the TI1S Bit */ + TIMx->CR2 |= TIM_CR2_TI1S; + } + else + { + /* Reset the TI1S Bit */ + TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_TI1S); + } +} + +/** + * @} + */ + +/** @defgroup TIM_Group8 Specific remapping management function + * @brief Specific remapping management function + * +@verbatim + =============================================================================== + ##### Specific remapping management function ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIM2, TIM3, TIM9, TIM10 and TIM11 Remapping input + * Capabilities. + * @param TIMx: where x can be 2, 3, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_Remap: specifies the TIM input remapping source. + * This parameter can be one of the following values: + * @arg TIM2_TIM10_OC: TIM2 ITR1 is connected to TIM10 output compare(default). + * @arg TIM2_TIM5_TRGO: TIM2 ITR1 is connected to TIM5 Trigger output. + * @arg TIM3_TIM11_OC: TIM3 ITR2 is connected to TIM11 output compare(default). + * @arg TIM3_TIM5_TRGO: TIM3 ITR2 is connected to TIM5 Trigger output. + * @arg TIM9_GPIO: TIM9 Channel 1 is connected to dedicated Timer pin(default). + * @arg TIM9_LSE: TIM9 Channel 1 is connected to LSE clock. + * @arg TIM9_TIM3_TRGO: TIM9 ITR1 is connected to TIM3 TRGO. + * @arg TIM9_TS_IO: TIM9 ITR1 is connected to Touch Sense IO. + * @arg TIM10_GPIO: TIM10 Channel 1 is connected to dedicated Timer pin(default). + * @arg TIM10_LSI: TIM10 Channel 1 is connected to LSI clock. + * @arg TIM10_LSE: TIM10 Channel 1 is connected to LSE clock. + * @arg TIM10_RTC: TIM10 Channel 1 is connected to RTC Output event. + * @arg TIM10_RI: TIM10 Channel 1 is connected to Routing Interface (RI). + * @arg TIM10_ETR_LSE: TIM10 ETR input is connected to LSE Clock. + * @arg TIM10_ETR_TIM9_TRGO: TIM10 ETR input is connected to TIM9 Trigger Output. + * @arg TIM11_GPIO: TIM11 Channel 1 is connected to dedicated Timer pin(default). + * @arg TIM11_MSI: TIM11 Channel 1 is connected to MSI clock. + * @arg TIM11_HSE_RTC: TIM11 Channel 1 is connected to HSE_RTC clock. + * @arg TIM11_RI: TIM11 Channel 1 is connected to Routing Interface (RI). + * @arg TIM11_ETR_LSE: TIM11 ETR input is connected to LSE Clock. + * @arg TIM11_ETR_TIM9_TRGO: TIM11 ETR input is connected to TIM9 Trigger Output. + * @retval None + */ +void TIM_RemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_Remap) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_REMAP(TIM_Remap)); + + /* Set the Timer remapping configuration */ + TIMx->OR &= (uint16_t)(TIM_Remap >> 16); + TIMx->OR |= (uint16_t)TIM_Remap; +} + +/** + * @} + */ + +/** + * @brief Configure the TI1 as Input. + * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr1 = 0, tmpccer = 0; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC1E); + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + /* Select the Input and set the filter */ + tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC1F))); + tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P | TIM_CCER_CC1NP)); + tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E); + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC2E); + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 4); + /* Select the Input and set the filter */ + tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC2S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC2F))); + tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12); + tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8); + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P | TIM_CCER_CC2NP)); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E); + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC3E); + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 8); + /* Select the Input and set the filter */ + tmpccmr2 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR2_CC3S)) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC3F))); + tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P | TIM_CCER_CC3NP)); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E); + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI4 as Input. + * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC4E); + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 12); + /* Select the Input and set the filter */ + tmpccmr2 &= (uint16_t)((uint16_t)(~(uint16_t)TIM_CCMR2_CC4S) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC4F))); + tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8); + tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC4P | TIM_CCER_CC4NP)); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E); + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer ; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_tim.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_tim.h new file mode 100644 index 0000000000..d644009428 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_tim.h @@ -0,0 +1,977 @@ +/** + ****************************************************************************** + * @file stm32l1xx_tim.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the TIM firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_TIM_H +#define __STM32L1xx_TIM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup TIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief TIM Time Base Init structure definition + * @note This structure is used with all TIMx except for TIM6 and TIM7. + */ + +typedef struct +{ + uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint16_t TIM_CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between 0x0000 and 0xFFFF. */ + + uint16_t TIM_ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_Clock_Division_CKD */ + +} TIM_TimeBaseInitTypeDef; + +/** + * @brief TIM Output Compare Init structure definition + */ + +typedef struct +{ + uint16_t TIM_OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_state */ + + uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint16_t TIM_OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + +} TIM_OCInitTypeDef; + +/** + * @brief TIM Input Capture Init structure definition + */ + +typedef struct +{ + + uint16_t TIM_Channel; /*!< Specifies the TIM channel. + This parameter can be a value of @ref TIM_Channel */ + + uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint16_t TIM_ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between 0x0 and 0xF */ +} TIM_ICInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + + +/** @defgroup TIM_Exported_constants + * @{ + */ + +#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11)) + +/* LIST1: TIM2, TIM3, TIM4, TIM5, TIM9, TIM10 and TIM11 */ +#define IS_TIM_LIST1_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11)) + +/* LIST3: TIM2, TIM3, TIM4 and TIM5 */ +#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5)) + +/* LIST2: TIM2, TIM3, TIM4, TIM5 and TIM9 */ +#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM9)) + +/* LIST5: TIM2, TIM3, TIM4, TIM5, TIM6, TIM7 and TIM9 */ +#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) ||\ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) ||\ + ((PERIPH) == TIM9)) + +/* LIST4: TIM2, TIM3, TIM4, TIM5, TIM6 and TIM7 */ +#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) ||\ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7)) + +/* LIST6: TIM2, TIM3, TIM9, TIM10 and TIM11 */ +#define IS_TIM_LIST6_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11)) + + + +/** @defgroup TIM_Output_Compare_and_PWM_modes + * @{ + */ + +#define TIM_OCMode_Timing ((uint16_t)0x0000) +#define TIM_OCMode_Active ((uint16_t)0x0010) +#define TIM_OCMode_Inactive ((uint16_t)0x0020) +#define TIM_OCMode_Toggle ((uint16_t)0x0030) +#define TIM_OCMode_PWM1 ((uint16_t)0x0060) +#define TIM_OCMode_PWM2 ((uint16_t)0x0070) +#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \ + ((MODE) == TIM_OCMode_Active) || \ + ((MODE) == TIM_OCMode_Inactive) || \ + ((MODE) == TIM_OCMode_Toggle)|| \ + ((MODE) == TIM_OCMode_PWM1) || \ + ((MODE) == TIM_OCMode_PWM2)) +#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \ + ((MODE) == TIM_OCMode_Active) || \ + ((MODE) == TIM_OCMode_Inactive) || \ + ((MODE) == TIM_OCMode_Toggle)|| \ + ((MODE) == TIM_OCMode_PWM1) || \ + ((MODE) == TIM_OCMode_PWM2) || \ + ((MODE) == TIM_ForcedAction_Active) || \ + ((MODE) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode + * @{ + */ + +#define TIM_OPMode_Single ((uint16_t)0x0008) +#define TIM_OPMode_Repetitive ((uint16_t)0x0000) +#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \ + ((MODE) == TIM_OPMode_Repetitive)) +/** + * @} + */ + +/** @defgroup TIM_Channel + * @{ + */ + +#define TIM_Channel_1 ((uint16_t)0x0000) +#define TIM_Channel_2 ((uint16_t)0x0004) +#define TIM_Channel_3 ((uint16_t)0x0008) +#define TIM_Channel_4 ((uint16_t)0x000C) + +#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3) || \ + ((CHANNEL) == TIM_Channel_4)) + +#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2)) + +/** + * @} + */ + +/** @defgroup TIM_Clock_Division_CKD + * @{ + */ + +#define TIM_CKD_DIV1 ((uint16_t)0x0000) +#define TIM_CKD_DIV2 ((uint16_t)0x0100) +#define TIM_CKD_DIV4 ((uint16_t)0x0200) +#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \ + ((DIV) == TIM_CKD_DIV2) || \ + ((DIV) == TIM_CKD_DIV4)) +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode + * @{ + */ + +#define TIM_CounterMode_Up ((uint16_t)0x0000) +#define TIM_CounterMode_Down ((uint16_t)0x0010) +#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) +#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) +#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) +#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \ + ((MODE) == TIM_CounterMode_Down) || \ + ((MODE) == TIM_CounterMode_CenterAligned1) || \ + ((MODE) == TIM_CounterMode_CenterAligned2) || \ + ((MODE) == TIM_CounterMode_CenterAligned3)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity + * @{ + */ + +#define TIM_OCPolarity_High ((uint16_t)0x0000) +#define TIM_OCPolarity_Low ((uint16_t)0x0002) +#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ + ((POLARITY) == TIM_OCPolarity_Low)) +/** + * @} + */ + + +/** @defgroup TIM_Output_Compare_state + * @{ + */ + +#define TIM_OutputState_Disable ((uint16_t)0x0000) +#define TIM_OutputState_Enable ((uint16_t)0x0001) +#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \ + ((STATE) == TIM_OutputState_Enable)) +/** + * @} + */ + + +/** @defgroup TIM_Capture_Compare_state + * @{ + */ + +#define TIM_CCx_Enable ((uint16_t)0x0001) +#define TIM_CCx_Disable ((uint16_t)0x0000) +#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \ + ((CCX) == TIM_CCx_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity + * @{ + */ + +#define TIM_ICPolarity_Rising ((uint16_t)0x0000) +#define TIM_ICPolarity_Falling ((uint16_t)0x0002) +#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A) +#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ + ((POLARITY) == TIM_ICPolarity_Falling)|| \ + ((POLARITY) == TIM_ICPolarity_BothEdge)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection + * @{ + */ + +#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC1, IC2, IC3 or IC4, respectively */ +#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC2, IC1, IC4 or IC3, respectively. */ +#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */ +#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \ + ((SELECTION) == TIM_ICSelection_IndirectTI) || \ + ((SELECTION) == TIM_ICSelection_TRC)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler + * @{ + */ + +#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */ +#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */ +#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */ +#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */ +#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ + ((PRESCALER) == TIM_ICPSC_DIV2) || \ + ((PRESCALER) == TIM_ICPSC_DIV4) || \ + ((PRESCALER) == TIM_ICPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_interrupt_sources + * @{ + */ + +#define TIM_IT_Update ((uint16_t)0x0001) +#define TIM_IT_CC1 ((uint16_t)0x0002) +#define TIM_IT_CC2 ((uint16_t)0x0004) +#define TIM_IT_CC3 ((uint16_t)0x0008) +#define TIM_IT_CC4 ((uint16_t)0x0010) +#define TIM_IT_Trigger ((uint16_t)0x0040) +#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFFA0) == 0x0000) && ((IT) != 0x0000)) + +#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \ + ((IT) == TIM_IT_CC1) || \ + ((IT) == TIM_IT_CC2) || \ + ((IT) == TIM_IT_CC3) || \ + ((IT) == TIM_IT_CC4) || \ + ((IT) == TIM_IT_Trigger)) +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address + * @{ + */ + +#define TIM_DMABase_CR1 ((uint16_t)0x0000) +#define TIM_DMABase_CR2 ((uint16_t)0x0001) +#define TIM_DMABase_SMCR ((uint16_t)0x0002) +#define TIM_DMABase_DIER ((uint16_t)0x0003) +#define TIM_DMABase_SR ((uint16_t)0x0004) +#define TIM_DMABase_EGR ((uint16_t)0x0005) +#define TIM_DMABase_CCMR1 ((uint16_t)0x0006) +#define TIM_DMABase_CCMR2 ((uint16_t)0x0007) +#define TIM_DMABase_CCER ((uint16_t)0x0008) +#define TIM_DMABase_CNT ((uint16_t)0x0009) +#define TIM_DMABase_PSC ((uint16_t)0x000A) +#define TIM_DMABase_ARR ((uint16_t)0x000B) +#define TIM_DMABase_CCR1 ((uint16_t)0x000D) +#define TIM_DMABase_CCR2 ((uint16_t)0x000E) +#define TIM_DMABase_CCR3 ((uint16_t)0x000F) +#define TIM_DMABase_CCR4 ((uint16_t)0x0010) +#define TIM_DMABase_DCR ((uint16_t)0x0012) +#define TIM_DMABase_OR ((uint16_t)0x0013) +#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \ + ((BASE) == TIM_DMABase_CR2) || \ + ((BASE) == TIM_DMABase_SMCR) || \ + ((BASE) == TIM_DMABase_DIER) || \ + ((BASE) == TIM_DMABase_SR) || \ + ((BASE) == TIM_DMABase_EGR) || \ + ((BASE) == TIM_DMABase_CCMR1) || \ + ((BASE) == TIM_DMABase_CCMR2) || \ + ((BASE) == TIM_DMABase_CCER) || \ + ((BASE) == TIM_DMABase_CNT) || \ + ((BASE) == TIM_DMABase_PSC) || \ + ((BASE) == TIM_DMABase_ARR) || \ + ((BASE) == TIM_DMABase_CCR1) || \ + ((BASE) == TIM_DMABase_CCR2) || \ + ((BASE) == TIM_DMABase_CCR3) || \ + ((BASE) == TIM_DMABase_CCR4) || \ + ((BASE) == TIM_DMABase_DCR) || \ + ((BASE) == TIM_DMABase_OR)) +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length + * @{ + */ + +#define TIM_DMABurstLength_1Transfer ((uint16_t)0x0000) +#define TIM_DMABurstLength_2Transfers ((uint16_t)0x0100) +#define TIM_DMABurstLength_3Transfers ((uint16_t)0x0200) +#define TIM_DMABurstLength_4Transfers ((uint16_t)0x0300) +#define TIM_DMABurstLength_5Transfers ((uint16_t)0x0400) +#define TIM_DMABurstLength_6Transfers ((uint16_t)0x0500) +#define TIM_DMABurstLength_7Transfers ((uint16_t)0x0600) +#define TIM_DMABurstLength_8Transfers ((uint16_t)0x0700) +#define TIM_DMABurstLength_9Transfers ((uint16_t)0x0800) +#define TIM_DMABurstLength_10Transfers ((uint16_t)0x0900) +#define TIM_DMABurstLength_11Transfers ((uint16_t)0x0A00) +#define TIM_DMABurstLength_12Transfers ((uint16_t)0x0B00) +#define TIM_DMABurstLength_13Transfers ((uint16_t)0x0C00) +#define TIM_DMABurstLength_14Transfers ((uint16_t)0x0D00) +#define TIM_DMABurstLength_15Transfers ((uint16_t)0x0E00) +#define TIM_DMABurstLength_16Transfers ((uint16_t)0x0F00) +#define TIM_DMABurstLength_17Transfers ((uint16_t)0x1000) +#define TIM_DMABurstLength_18Transfers ((uint16_t)0x1100) +#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Transfer) || \ + ((LENGTH) == TIM_DMABurstLength_2Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_3Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_4Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_5Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_6Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_7Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_8Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_9Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_10Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_11Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_12Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_13Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_14Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_15Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_16Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_17Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_18Transfers)) +/** + * @} + */ + +/** @defgroup TIM_DMA_sources + * @{ + */ + +#define TIM_DMA_Update ((uint16_t)0x0100) +#define TIM_DMA_CC1 ((uint16_t)0x0200) +#define TIM_DMA_CC2 ((uint16_t)0x0400) +#define TIM_DMA_CC3 ((uint16_t)0x0800) +#define TIM_DMA_CC4 ((uint16_t)0x1000) +#define TIM_DMA_Trigger ((uint16_t)0x4000) +#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xA0FF) == 0x0000) && ((SOURCE) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Prescaler + * @{ + */ + +#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000) +#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000) +#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000) +#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000) +#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_Internal_Trigger_Selection + * @{ + */ + +#define TIM_TS_ITR0 ((uint16_t)0x0000) +#define TIM_TS_ITR1 ((uint16_t)0x0010) +#define TIM_TS_ITR2 ((uint16_t)0x0020) +#define TIM_TS_ITR3 ((uint16_t)0x0030) +#define TIM_TS_TI1F_ED ((uint16_t)0x0040) +#define TIM_TS_TI1FP1 ((uint16_t)0x0050) +#define TIM_TS_TI2FP2 ((uint16_t)0x0060) +#define TIM_TS_ETRF ((uint16_t)0x0070) +#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3) || \ + ((SELECTION) == TIM_TS_TI1F_ED) || \ + ((SELECTION) == TIM_TS_TI1FP1) || \ + ((SELECTION) == TIM_TS_TI2FP2) || \ + ((SELECTION) == TIM_TS_ETRF)) +#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3)) +/** + * @} + */ + +/** @defgroup TIM_TIx_External_Clock_Source + * @{ + */ + +#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) +#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) +#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Polarity + * @{ + */ +#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000) +#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000) +#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \ + ((POLARITY) == TIM_ExtTRGPolarity_NonInverted)) +/** + * @} + */ + +/** @defgroup TIM_Prescaler_Reload_Mode + * @{ + */ + +#define TIM_PSCReloadMode_Update ((uint16_t)0x0000) +#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001) +#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \ + ((RELOAD) == TIM_PSCReloadMode_Immediate)) +/** + * @} + */ + +/** @defgroup TIM_Forced_Action + * @{ + */ + +#define TIM_ForcedAction_Active ((uint16_t)0x0050) +#define TIM_ForcedAction_InActive ((uint16_t)0x0040) +#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \ + ((ACTION) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode + * @{ + */ + +#define TIM_EncoderMode_TI1 ((uint16_t)0x0001) +#define TIM_EncoderMode_TI2 ((uint16_t)0x0002) +#define TIM_EncoderMode_TI12 ((uint16_t)0x0003) +#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \ + ((MODE) == TIM_EncoderMode_TI2) || \ + ((MODE) == TIM_EncoderMode_TI12)) +/** + * @} + */ + + +/** @defgroup TIM_Event_Source + * @{ + */ + +#define TIM_EventSource_Update ((uint16_t)0x0001) +#define TIM_EventSource_CC1 ((uint16_t)0x0002) +#define TIM_EventSource_CC2 ((uint16_t)0x0004) +#define TIM_EventSource_CC3 ((uint16_t)0x0008) +#define TIM_EventSource_CC4 ((uint16_t)0x0010) +#define TIM_EventSource_Trigger ((uint16_t)0x0040) +#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFFA0) == 0x0000) && ((SOURCE) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_Update_Source + * @{ + */ + +#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. */ +#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */ +#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \ + ((SOURCE) == TIM_UpdateSource_Regular)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Preload_State + * @{ + */ + +#define TIM_OCPreload_Enable ((uint16_t)0x0008) +#define TIM_OCPreload_Disable ((uint16_t)0x0000) +#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \ + ((STATE) == TIM_OCPreload_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Fast_State + * @{ + */ + +#define TIM_OCFast_Enable ((uint16_t)0x0004) +#define TIM_OCFast_Disable ((uint16_t)0x0000) +#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \ + ((STATE) == TIM_OCFast_Disable)) + +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Clear_State + * @{ + */ + +#define TIM_OCClear_Enable ((uint16_t)0x0080) +#define TIM_OCClear_Disable ((uint16_t)0x0000) +#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \ + ((STATE) == TIM_OCClear_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Trigger_Output_Source + * @{ + */ + +#define TIM_TRGOSource_Reset ((uint16_t)0x0000) +#define TIM_TRGOSource_Enable ((uint16_t)0x0010) +#define TIM_TRGOSource_Update ((uint16_t)0x0020) +#define TIM_TRGOSource_OC1 ((uint16_t)0x0030) +#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040) +#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050) +#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060) +#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070) +#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \ + ((SOURCE) == TIM_TRGOSource_Enable) || \ + ((SOURCE) == TIM_TRGOSource_Update) || \ + ((SOURCE) == TIM_TRGOSource_OC1) || \ + ((SOURCE) == TIM_TRGOSource_OC1Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC2Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC3Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC4Ref)) +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode + * @{ + */ + +#define TIM_SlaveMode_Reset ((uint16_t)0x0004) +#define TIM_SlaveMode_Gated ((uint16_t)0x0005) +#define TIM_SlaveMode_Trigger ((uint16_t)0x0006) +#define TIM_SlaveMode_External1 ((uint16_t)0x0007) +#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \ + ((MODE) == TIM_SlaveMode_Gated) || \ + ((MODE) == TIM_SlaveMode_Trigger) || \ + ((MODE) == TIM_SlaveMode_External1)) +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode + * @{ + */ + +#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080) +#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000) +#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \ + ((STATE) == TIM_MasterSlaveMode_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Flags + * @{ + */ + +#define TIM_FLAG_Update ((uint16_t)0x0001) +#define TIM_FLAG_CC1 ((uint16_t)0x0002) +#define TIM_FLAG_CC2 ((uint16_t)0x0004) +#define TIM_FLAG_CC3 ((uint16_t)0x0008) +#define TIM_FLAG_CC4 ((uint16_t)0x0010) +#define TIM_FLAG_Trigger ((uint16_t)0x0040) +#define TIM_FLAG_CC1OF ((uint16_t)0x0200) +#define TIM_FLAG_CC2OF ((uint16_t)0x0400) +#define TIM_FLAG_CC3OF ((uint16_t)0x0800) +#define TIM_FLAG_CC4OF ((uint16_t)0x1000) +#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \ + ((FLAG) == TIM_FLAG_CC1) || \ + ((FLAG) == TIM_FLAG_CC2) || \ + ((FLAG) == TIM_FLAG_CC3) || \ + ((FLAG) == TIM_FLAG_CC4) || \ + ((FLAG) == TIM_FLAG_Trigger) || \ + ((FLAG) == TIM_FLAG_CC1OF) || \ + ((FLAG) == TIM_FLAG_CC2OF) || \ + ((FLAG) == TIM_FLAG_CC3OF) || \ + ((FLAG) == TIM_FLAG_CC4OF)) +#define IS_TIM_CLEAR_FLAG(TIM_FLAG) ((((TIM_FLAG) & (uint16_t)0xE1A0) == 0x0000) && ((TIM_FLAG) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Filer_Value + * @{ + */ + +#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Filter + * @{ + */ + +#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_OCReferenceClear + * @{ + */ +#define TIM_OCReferenceClear_ETRF ((uint16_t)0x0008) +#define TIM_OCReferenceClear_OCREFCLR ((uint16_t)0x0000) +#define TIM_OCREFERENCECECLEAR_SOURCE(SOURCE) (((SOURCE) == TIM_OCReferenceClear_ETRF) || \ + ((SOURCE) == TIM_OCReferenceClear_OCREFCLR)) + +/** + * @} + */ + +/** @defgroup TIM_Remap + * @{ + */ + +#define TIM2_TIM10_OC ((uint32_t)0xFFFE0000) +#define TIM2_TIM5_TRGO ((uint32_t)0xFFFE0001) + +#define TIM3_TIM11_OC ((uint32_t)0xFFFE0000) +#define TIM3_TIM5_TRGO ((uint32_t)0xFFFE0001) + +#define TIM9_GPIO ((uint32_t)0xFFFC0000) +#define TIM9_LSE ((uint32_t)0xFFFC0001) + +#define TIM9_TIM3_TRGO ((uint32_t)0xFFFB0000) +#define TIM9_TS_IO ((uint32_t)0xFFFB0004) + +#define TIM10_GPIO ((uint32_t)0xFFF40000) +#define TIM10_LSI ((uint32_t)0xFFF40001) +#define TIM10_LSE ((uint32_t)0xFFF40002) +#define TIM10_RTC ((uint32_t)0xFFF40003) +#define TIM10_RI ((uint32_t)0xFFF40008) + +#define TIM10_ETR_LSE ((uint32_t)0xFFFB0000) +#define TIM10_ETR_TIM9_TRGO ((uint32_t)0xFFFB0004) + +#define TIM11_GPIO ((uint32_t)0xFFF40000) +#define TIM11_MSI ((uint32_t)0xFFF40001) +#define TIM11_HSE_RTC ((uint32_t)0xFFF40002) +#define TIM11_RI ((uint32_t)0xFFF40008) + +#define TIM11_ETR_LSE ((uint32_t)0xFFFB0000) +#define TIM11_ETR_TIM9_TRGO ((uint32_t)0xFFFB0004) + +#define IS_TIM_REMAP(TIM_REMAP) (((TIM_REMAP) == TIM2_TIM10_OC)|| \ + ((TIM_REMAP) == TIM2_TIM5_TRGO)|| \ + ((TIM_REMAP) == TIM3_TIM11_OC)|| \ + ((TIM_REMAP) == TIM3_TIM5_TRGO)|| \ + ((TIM_REMAP) == TIM9_GPIO)|| \ + ((TIM_REMAP) == TIM9_LSE)|| \ + ((TIM_REMAP) == TIM9_TIM3_TRGO)|| \ + ((TIM_REMAP) == TIM9_TS_IO)|| \ + ((TIM_REMAP) == TIM10_GPIO)|| \ + ((TIM_REMAP) == TIM10_LSI)|| \ + ((TIM_REMAP) == TIM10_LSE)|| \ + ((TIM_REMAP) == TIM10_RTC)|| \ + ((TIM_REMAP) == TIM10_RI)|| \ + ((TIM_REMAP) == TIM10_ETR_LSE)|| \ + ((TIM_REMAP) == TIM10_ETR_TIM9_TRGO)|| \ + ((TIM_REMAP) == TIM11_GPIO)|| \ + ((TIM_REMAP) == TIM11_MSI)|| \ + ((TIM_REMAP) == TIM11_HSE_RTC)|| \ + ((TIM_REMAP) == TIM11_RI)|| \ + ((TIM_REMAP) == TIM11_ETR_LSE)|| \ + ((TIM_REMAP) == TIM11_ETR_TIM9_TRGO)) + +/** + * @} + */ + +/** @defgroup TIM_Legacy + * @{ + */ + +#define TIM_DMABurstLength_1Byte TIM_DMABurstLength_1Transfer +#define TIM_DMABurstLength_2Bytes TIM_DMABurstLength_2Transfers +#define TIM_DMABurstLength_3Bytes TIM_DMABurstLength_3Transfers +#define TIM_DMABurstLength_4Bytes TIM_DMABurstLength_4Transfers +#define TIM_DMABurstLength_5Bytes TIM_DMABurstLength_5Transfers +#define TIM_DMABurstLength_6Bytes TIM_DMABurstLength_6Transfers +#define TIM_DMABurstLength_7Bytes TIM_DMABurstLength_7Transfers +#define TIM_DMABurstLength_8Bytes TIM_DMABurstLength_8Transfers +#define TIM_DMABurstLength_9Bytes TIM_DMABurstLength_9Transfers +#define TIM_DMABurstLength_10Bytes TIM_DMABurstLength_10Transfers +#define TIM_DMABurstLength_11Bytes TIM_DMABurstLength_11Transfers +#define TIM_DMABurstLength_12Bytes TIM_DMABurstLength_12Transfers +#define TIM_DMABurstLength_13Bytes TIM_DMABurstLength_13Transfers +#define TIM_DMABurstLength_14Bytes TIM_DMABurstLength_14Transfers +#define TIM_DMABurstLength_15Bytes TIM_DMABurstLength_15Transfers +#define TIM_DMABurstLength_16Bytes TIM_DMABurstLength_16Transfers +#define TIM_DMABurstLength_17Bytes TIM_DMABurstLength_17Transfers +#define TIM_DMABurstLength_18Bytes TIM_DMABurstLength_18Transfers +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* TimeBase management ********************************************************/ +void TIM_DeInit(TIM_TypeDef* TIMx); +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); +void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter); +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload); +uint32_t TIM_GetCounter(TIM_TypeDef* TIMx); +uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource); +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode); +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD); +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Output Compare management **************************************************/ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1); +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2); +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3); +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4); +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_SelectOCREFClear(TIM_TypeDef* TIMx, uint16_t TIM_OCReferenceClear); +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx); + +/* Input Capture management ***************************************************/ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx); +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); + +/* Interrupts, DMA and flags management ***************************************/ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource); +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength); +void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState); +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Clocks management **********************************************************/ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx); +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, + uint16_t TIM_ICPolarity, uint16_t ICFilter); +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); + + +/* Synchronization management *************************************************/ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); + +/* Specific interface management **********************************************/ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, + uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity); +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Specific remapping management **********************************************/ +void TIM_RemapConfig(TIM_TypeDef* TIMx, uint32_t TIM_Remap); + + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32L1xx_TIM_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_usart.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_usart.c new file mode 100644 index 0000000000..f31a6592c9 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_usart.c @@ -0,0 +1,1459 @@ +/** + ****************************************************************************** + * @file stm32l1xx_usart.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Universal synchronous asynchronous receiver + * transmitter (USART): + * + Initialization and Configuration + * + Data transfers + * + Multi-Processor Communication + * + LIN mode + * + Half-duplex mode + * + Smartcard mode + * + IrDA mode + * + DMA transfers management + * + Interrupts and flags management + * + * @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + (#) Enable peripheral clock using + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE) function for + USART1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) + function for USART2 and USART3. + (#) According to the USART mode, enable the GPIO clocks using + RCC_AHBPeriphClockCmd() function. (The I/O can be TX, RX, CTS, + or and SCLK). + (#) Peripheral's alternate function: + (++) Connect the pin to the desired peripherals' Alternate + Function (AF) using GPIO_PinAFConfig() function. + (++) Configure the desired pin in alternate function by: + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF. + (++) Select the type, pull-up/pull-down and output speed via + GPIO_PuPd, GPIO_OType and GPIO_Speed members. + (++) Call GPIO_Init() function. + (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware + flow control and Mode(Receiver/Transmitter) using the SPI_Init() + function. + (#) For synchronous mode, enable the clock and program the polarity, + phase and last bit using the USART_ClockInit() function. + (#) Enable the NVIC and the corresponding interrupt using the function + USART_ITConfig() if you need to use interrupt mode. + (#) When using the DMA mode. + (++) Configure the DMA using DMA_Init() function. + (++) Active the needed channel Request using USART_DMACmd() function. + (#) Enable the USART using the USART_Cmd() function. + (#) Enable the DMA using the DMA_Cmd() function, when using DMA mode. + [..] + Refer to Multi-Processor, LIN, half-duplex, Smartcard, IrDA sub-sections + for more details. + +@endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_usart.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup USART + * @brief USART driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/*!< USART CR1 register clear Mask ((~(uint16_t)0xE9F3)) */ +#define CR1_CLEAR_MASK ((uint16_t)(USART_CR1_M | USART_CR1_PCE | \ + USART_CR1_PS | USART_CR1_TE | \ + USART_CR1_RE)) + +/*!< USART CR2 register clock bits clear Mask ((~(uint16_t)0xF0FF)) */ +#define CR2_CLOCK_CLEAR_MASK ((uint16_t)(USART_CR2_CLKEN | USART_CR2_CPOL | \ + USART_CR2_CPHA | USART_CR2_LBCL)) + +/*!< USART CR3 register clear Mask ((~(uint16_t)0xFCFF)) */ +#define CR3_CLEAR_MASK ((uint16_t)(USART_CR3_RTSE | USART_CR3_CTSE)) + +/*!< USART Interrupts mask */ +#define IT_MASK ((uint16_t)0x001F) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup USART_Private_Functions + * @{ + */ + +/** @defgroup USART_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USART + in asynchronous and in synchronous modes. + (+) For the asynchronous mode only these parameters can be configured: + (+) Baud Rate. + (+) Word Length. + (+) Stop Bit. + (+) Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + Depending on the frame length defined by the M bit (8-bits or 9-bits), + the possible USART frame formats are as listed in the following table: + [..] + +-------------------------------------------------------------+ + | M bit | PCE bit | USART frame | + |---------------------|---------------------------------------| + | 0 | 0 | | SB | 8 bit data | STB | | + |---------|-----------|---------------------------------------| + | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|-----------|---------------------------------------| + | 1 | 0 | | SB | 9 bit data | STB | | + |---------|-----------|---------------------------------------| + | 1 | 1 | | SB | 8 bit data | PB | STB | | + +-------------------------------------------------------------+ + [..] + (+) Hardware flow control. + (+) Receiver/transmitter modes. + [..] The USART_Init() function follows the USART asynchronous configuration + procedure(details for the procedure are available in reference manual + (RM0038)). + (+) For the synchronous mode in addition to the asynchronous mode parameters + these parameters should be also configured: + (++) USART Clock Enabled. + (++) USART polarity. + (++) USART phase. + (++) USART LastBit. + [..] These parameters can be configured using the USART_ClockInit() function. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the USARTx peripheral registers to their default reset values. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: USART1, USART2, USART3, + * UART4 or UART5. + * @retval None. + */ +void USART_DeInit(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + if (USARTx == USART1) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); + } + else if (USARTx == USART2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); + } + else if (USARTx == USART3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); + } + else if (USARTx == UART4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE); + } + else + { + if (USARTx == UART5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE); + } + } +} + +/** + * @brief Initializes the USARTx peripheral according to the specified + * parameters in the USART_InitStruct. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: USART1, USART2, USART3, + * UART4 or UART5. + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure that + * contains the configuration information for the specified USART peripheral. + * @retval None. + */ +void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) +{ + uint32_t tmpreg = 0x00, apbclock = 0x00; + uint32_t integerdivider = 0x00; + uint32_t fractionaldivider = 0x00; + RCC_ClocksTypeDef RCC_ClocksStatus; + + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate)); + assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength)); + assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits)); + assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity)); + assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode)); + assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl)); + + /* The hardware flow control is available only for USART1, USART2 and USART3 */ + if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + +/*---------------------------- USART CR2 Configuration -----------------------*/ + tmpreg = USARTx->CR2; + /* Clear STOP[13:12] bits */ + tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP); + + /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/ + /* Set STOP[13:12] bits according to USART_StopBits value */ + tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits; + + /* Write to USART CR2 */ + USARTx->CR2 = (uint16_t)tmpreg; + +/*---------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = USARTx->CR1; + /* Clear M, PCE, PS, TE and RE bits */ + tmpreg &= (uint32_t)~((uint32_t)CR1_CLEAR_MASK); + + /* Configure the USART Word Length, Parity and mode ----------------------- */ + /* Set the M bits according to USART_WordLength value */ + /* Set PCE and PS bits according to USART_Parity value */ + /* Set TE and RE bits according to USART_Mode value */ + tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity | + USART_InitStruct->USART_Mode; + + /* Write to USART CR1 */ + USARTx->CR1 = (uint16_t)tmpreg; + +/*---------------------------- USART CR3 Configuration -----------------------*/ + tmpreg = USARTx->CR3; + /* Clear CTSE and RTSE bits */ + tmpreg &= (uint32_t)~((uint32_t)CR3_CLEAR_MASK); + + /* Configure the USART HFC -------------------------------------------------*/ + /* Set CTSE and RTSE bits according to USART_HardwareFlowControl value */ + tmpreg |= USART_InitStruct->USART_HardwareFlowControl; + + /* Write to USART CR3 */ + USARTx->CR3 = (uint16_t)tmpreg; + +/*---------------------------- USART BRR Configuration -----------------------*/ + /* Configure the USART Baud Rate -------------------------------------------*/ + RCC_GetClocksFreq(&RCC_ClocksStatus); + if (USARTx == USART1) + { + apbclock = RCC_ClocksStatus.PCLK2_Frequency; + } + else + { + apbclock = RCC_ClocksStatus.PCLK1_Frequency; + } + + /* Determine the integer part */ + if ((USARTx->CR1 & USART_CR1_OVER8) != 0) + { + /* Integer part computing in case Oversampling mode is 8 Samples */ + integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate))); + } + else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */ + { + /* Integer part computing in case Oversampling mode is 16 Samples */ + integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate))); + } + tmpreg = (integerdivider / 100) << 4; + + /* Determine the fractional part */ + fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); + + /* Implement the fractional part in the register */ + if ((USARTx->CR1 & USART_CR1_OVER8) != 0) + { + tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); + } + else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */ + { + tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); + } + + /* Write to USART BRR */ + USARTx->BRR = (uint16_t)tmpreg; +} + +/** + * @brief Fills each USART_InitStruct member with its default value. + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure + * which will be initialized. + * @retval None + */ +void USART_StructInit(USART_InitTypeDef* USART_InitStruct) +{ + /* USART_InitStruct members default value */ + USART_InitStruct->USART_BaudRate = 9600; + USART_InitStruct->USART_WordLength = USART_WordLength_8b; + USART_InitStruct->USART_StopBits = USART_StopBits_1; + USART_InitStruct->USART_Parity = USART_Parity_No ; + USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None; +} + +/** + * @brief Initializes the USARTx peripheral Clock according to the + * specified parameters in the USART_ClockInitStruct. + * @param USARTx: where x can be 1, 2, 3 to select the USART peripheral. + * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef + * structure that contains the configuration information for the specified + * USART peripheral. + * @note The Smart Card and Synchronous modes are not available for UART4 and UART5. + * @retval None. + */ +void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct) +{ + uint32_t tmpreg = 0x00; + /* Check the parameters */ + assert_param(IS_USART_123_PERIPH(USARTx)); + assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock)); + assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL)); + assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA)); + assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit)); + +/*---------------------------- USART CR2 Configuration -----------------------*/ + tmpreg = USARTx->CR2; + /* Clear CLKEN, CPOL, CPHA and LBCL bits */ + tmpreg &= (uint32_t)~((uint32_t)CR2_CLOCK_CLEAR_MASK); + /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/ + /* Set CLKEN bit according to USART_Clock value */ + /* Set CPOL bit according to USART_CPOL value */ + /* Set CPHA bit according to USART_CPHA value */ + /* Set LBCL bit according to USART_LastBit value */ + tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL | + USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit; + /* Write to USART CR2 */ + USARTx->CR2 = (uint16_t)tmpreg; +} + +/** + * @brief Fills each USART_ClockInitStruct member with its default value. + * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef + * structure which will be initialized. + * @retval None + */ +void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct) +{ + /* USART_ClockInitStruct members default value */ + USART_ClockInitStruct->USART_Clock = USART_Clock_Disable; + USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low; + USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge; + USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable; +} + +/** + * @brief Enables or disables the specified USART peripheral. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USARTx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected USART by setting the UE bit in the CR1 register */ + USARTx->CR1 |= USART_CR1_UE; + } + else + { + /* Disable the selected USART by clearing the UE bit in the CR1 register */ + USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_UE); + } +} + +/** + * @brief Sets the system clock prescaler. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_Prescaler: specifies the prescaler clock. + * @note The function is used for IrDA mode with UART4 and UART5. + * @retval None. + */ +void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Clear the USART prescaler */ + USARTx->GTPR &= USART_GTPR_GT; + /* Set the USART prescaler */ + USARTx->GTPR |= USART_Prescaler; +} + +/** + * @brief Enables or disables the USART's 8x oversampling mode. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART 8x oversampling mode. + * This parameter can be: ENABLE or DISABLE. + * + * @note + * This function has to be called before calling USART_Init() + * function in order to have correct baudrate Divider value. + * @retval None + */ +void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */ + USARTx->CR1 |= USART_CR1_OVER8; + } + else + { + /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */ + USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_OVER8); + } +} + +/** + * @brief Enables or disables the USART's one bit sampling method. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART one bit sampling method. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_ONEBIT; + } + else + { + /* Disable the one bit method by clearing the ONEBITE bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT); + } +} + +/** + * @} + */ + +/** @defgroup USART_Group2 Data transfers functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### Data transfers functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage + the USART data transfers. + [..] During an USART reception, data shifts in least significant bit first + through the RX pin. In this mode, the USART_DR register consists of + a buffer (RDR) between the internal bus and the received shift register. + When a transmission is taking place, a write instruction to + the USART_DR register stores the data in the TDR register and which is + copied in the shift register at the end of the current transmission. + [..] The read access of the USART_DR register can be done using + the USART_ReceiveData() function and returns the RDR buffered value. + Whereas a write access to the USART_DR can be done using USART_SendData() + function and stores the written data into TDR buffer. + +@endverbatim + * @{ + */ + +/** + * @brief Transmits single data through the USARTx peripheral. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param Data: the data to transmit. + * @retval None. + */ +void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_DATA(Data)); + + /* Transmit Data */ + USARTx->DR = (Data & (uint16_t)0x01FF); +} + +/** + * @brief Returns the most recent received data by the USARTx peripheral. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @retval The received data. + */ +uint16_t USART_ReceiveData(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Receive Data */ + return (uint16_t)(USARTx->DR & (uint16_t)0x01FF); +} + +/** + * @} + */ + +/** @defgroup USART_Group3 MultiProcessor Communication functions + * @brief Multi-Processor Communication functions + * +@verbatim + =============================================================================== + ##### Multi-Processor Communication functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USART + multiprocessor communication. + [..] For instance one of the USARTs can be the master, its TX output is + connected to the RX input of the other USART. The others are slaves, + their respective TX outputs are logically ANDed together and connected + to the RX input of the master. USART multiprocessor communication is + possible through the following procedure: + (#) Program the Baud rate, Word length = 9 bits, Stop bits, Parity, + Mode transmitter or Mode receiver and hardware flow control values + using the USART_Init() function. + (#) Configures the USART address using the USART_SetAddress() function. + (#) Configures the wake up methode (USART_WakeUp_IdleLine or + USART_WakeUp_AddressMark) using USART_WakeUpConfig() function only + for the slaves. + (#) Enable the USART using the USART_Cmd() function. + (#) Enter the USART slaves in mute mode using USART_ReceiverWakeUpCmd() + function. + + [..] The USART Slave exit from mute mode when receive the wake up condition. + +@endverbatim + * @{ + */ + +/** + * @brief Sets the address of the USART node. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_Address: Indicates the address of the USART node. + * @retval None + */ +void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_ADDRESS(USART_Address)); + + /* Clear the USART address */ + USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_ADD); + /* Set the USART address node */ + USARTx->CR2 |= USART_Address; +} + +/** + * @brief Determines if the USART is in mute mode or not. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART mute mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ + USARTx->CR1 |= USART_CR1_RWU; + } + else + { + /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ + USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_RWU); + } +} +/** + * @brief Selects the USART WakeUp method. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_WakeUp: specifies the USART wakeup method. + * This parameter can be one of the following values: + * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection. + * @arg USART_WakeUp_AddressMark: WakeUp by an address mark. + * @retval None. + */ +void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_WAKEUP(USART_WakeUp)); + + USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_WAKE); + USARTx->CR1 |= USART_WakeUp; +} + +/** + * @} + */ + +/** @defgroup USART_Group4 LIN mode functions + * @brief LIN mode functions + * +@verbatim + =============================================================================== + ##### LIN mode functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USART + LIN Mode communication. + [..] In LIN mode, 8-bit data format with 1 stop bit is required in accordance + with the LIN standard. + [..] Only this LIN Feature is supported by the USART IP: + (+) LIN Master Synchronous Break send capability and LIN slave break + detection capability : 13-bit break generation and 10/11 bit break + detection. + [..] USART LIN Master transmitter communication is possible through the + following procedure: + (#) Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity, + Mode transmitter or Mode receiver and hardware flow control values + using the USART_Init() function. + (#) Enable the USART using the USART_Cmd() function. + (#) Enable the LIN mode using the USART_LINCmd() function. + (#) Send the break character using USART_SendBreak() function. + [..] USART LIN Master receiver communication is possible through the + following procedure: + (#) Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity, + Mode transmitter or Mode receiver and hardware flow control values + using the USART_Init() function. + (#) Enable the USART using the USART_Cmd() function. + (#) Configures the break detection length + using the USART_LINBreakDetectLengthConfig() function. + (#) Enable the LIN mode using the USART_LINCmd() function. + -@- In LIN mode, the following bits must be kept cleared: + (+@) CLKEN in the USART_CR2 register. + (+@) STOP[1:0], SCEN, HDSEL and IREN in the USART_CR3 register. + +@endverbatim + * @{ + */ + +/** + * @brief Sets the USART LIN Break detection length. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_LINBreakDetectLength: specifies the LIN break detection length. + * This parameter can be one of the following values: + * @arg USART_LINBreakDetectLength_10b: 10-bit break detection. + * @arg USART_LINBreakDetectLength_11b: 11-bit break detection. + * @retval None. + */ +void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength)); + + USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LBDL); + USARTx->CR2 |= USART_LINBreakDetectLength; +} + +/** + * @brief Enables or disables the USART's LIN mode. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART LIN mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ + USARTx->CR2 |= USART_CR2_LINEN; + } + else + { + /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */ + USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LINEN); + } +} + +/** + * @brief Transmits break characters. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @retval None. + */ +void USART_SendBreak(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Send break characters */ + USARTx->CR1 |= USART_CR1_SBK; +} + +/** + * @} + */ + +/** @defgroup USART_Group5 Halfduplex mode function + * @brief Half-duplex mode function + * +@verbatim + =============================================================================== + ##### Half-duplex mode function ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USART + Half-duplex communication. + [..] The USART can be configured to follow a single-wire half-duplex protocol + where the TX and RX lines are internally connected. + [..] USART Half duplex communication is possible through the following procedure: + (#) Program the Baud rate, Word length, Stop bits, Parity, Mode transmitter + or Mode receiver and hardware flow control values using the USART_Init() + function. + (#) Configures the USART address using the USART_SetAddress() function. + (#) Enable the USART using the USART_Cmd() function. + (#) Enable the half duplex mode using USART_HalfDuplexCmd() function. + -@- The RX pin is no longer used. + -@- In Half-duplex mode the following bits must be kept cleared: + (+@) LINEN and CLKEN bits in the USART_CR2 register. + (+@) SCEN and IREN bits in the USART_CR3 register. + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the USART's Half Duplex communication. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART Communication. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_HDSEL; + } + else + { + /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_HDSEL); + } +} + +/** + * @} + */ + + +/** @defgroup USART_Group6 Smartcard mode functions + * @brief Smartcard mode functions + * +@verbatim + =============================================================================== + ##### Smartcard mode functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USART + Smartcard communication. + [..] The Smartcard interface is designed to support asynchronous protocol + Smartcards as defined in the ISO 7816-3 standard. The USART can provide + a clock to the smartcard through the SCLK output. In smartcard mode, + SCLK is not associated to the communication but is simply derived from + the internal peripheral input clock through a 5-bit prescaler. + [..] Smartcard communication is possible through the following procedure: + (#) Configures the Smartcard Prsecaler using the USART_SetPrescaler() + function. + (#) Configures the Smartcard Guard Time using the USART_SetGuardTime() + function. + (#) Program the USART clock using the USART_ClockInit() function as following: + (++) USART Clock enabled. + (++) USART CPOL Low. + (++) USART CPHA on first edge. + (++) USART Last Bit Clock Enabled. + (#) Program the Smartcard interface using the USART_Init() function as + following: + (++) Word Length = 9 Bits. + (++) 1.5 Stop Bit. + (++) Even parity. + (++) BaudRate = 12096 baud. + (++) Hardware flow control disabled (RTS and CTS signals). + (++) Tx and Rx enabled + (#) Optionally you can enable the parity error interrupt using + the USART_ITConfig() function. + (#) Enable the USART using the USART_Cmd() function. + (#) Enable the Smartcard NACK using the USART_SmartCardNACKCmd() function. + (#) Enable the Smartcard interface using the USART_SmartCardCmd() function. + [..] + Please refer to the ISO 7816-3 specification for more details. + [..] + (@) It is also possible to choose 0.5 stop bit for receiving but it is + recommended to use 1.5 stop bits for both transmitting and receiving + to avoid switching between the two configurations. + (@) In smartcard mode, the following bits must be kept cleared: + (+@) LINEN bit in the USART_CR2 register. + (+@) HDSEL and IREN bits in the USART_CR3 register. + +@endverbatim + * @{ + */ + +/** + * @brief Sets the specified USART guard time. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2 or USART3. + * @param USART_GuardTime: specifies the guard time. + * @retval None. + */ +void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime) +{ + /* Check the parameters */ + assert_param(IS_USART_123_PERIPH(USARTx)); + + /* Clear the USART Guard time */ + USARTx->GTPR &= USART_GTPR_PSC; + /* Set the USART guard time */ + USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08); +} + +/** + * @brief Enables or disables the USART's Smart Card mode. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2 or USART3. + * @param NewState: new state of the Smart Card mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_123_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the SC mode by setting the SCEN bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_SCEN; + } + else + { + /* Disable the SC mode by clearing the SCEN bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_SCEN); + } +} + +/** + * @brief Enables or disables NACK transmission. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2 or USART3. + * @param NewState: new state of the NACK transmission. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_123_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the NACK transmission by setting the NACK bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_NACK; + } + else + { + /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_NACK); + } +} + +/** + * @} + */ + +/** @defgroup USART_Group7 IrDA mode functions + * @brief IrDA mode functions + * +@verbatim + =============================================================================== + ##### IrDA mode functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USART + IrDA communication. + [..] IrDA is a half duplex communication protocol. If the Transmitter is busy, + any data on the IrDA receive line will be ignored by the IrDA decoder + and if the Receiver is busy, data on the TX from the USART to IrDA will + not be encoded by IrDA. While receiving data, transmission should be + avoided as the data to be transmitted could be corrupted. + + [..] IrDA communication is possible through the following procedure: + (#) Program the Baud rate, Word length = 8 bits, Stop bits, Parity, + Transmitter/Receiver modes and hardware flow control values using + the USART_Init() function. + (#) Enable the USART using the USART_Cmd() function. + (#) Configures the IrDA pulse width by configuring the prescaler using + the USART_SetPrescaler() function. + (#) Configures the IrDA USART_IrDAMode_LowPower or USART_IrDAMode_Normal + mode using the USART_IrDAConfig() function. + (#) Enable the IrDA using the USART_IrDACmd() function. + + [..] + (@) A pulse of width less than two and greater than one PSC period(s) may or + may not be rejected. + (@) The receiver set up time should be managed by software. The IrDA physical + layer specification specifies a minimum of 10 ms delay between + transmission and reception (IrDA is a half duplex protocol). + (@) In IrDA mode, the following bits must be kept cleared: + (+@) LINEN, STOP and CLKEN bits in the USART_CR2 register. + (+@) SCEN and HDSEL bits in the USART_CR3 register. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the USART's IrDA interface. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_IrDAMode: specifies the IrDA mode. + * This parameter can be one of the following values: + * @arg USART_IrDAMode_LowPower: USART IrDA Low Power mode selected. + * @arg USART_IrDAMode_Normal: USART IrDA Normal mode selected. + * @retval None + */ +void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_IRDA_MODE(USART_IrDAMode)); + + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IRLP); + USARTx->CR3 |= USART_IrDAMode; +} + +/** + * @brief Enables or disables the USART's IrDA interface. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the IrDA mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the IrDA mode by setting the IREN bit in the CR3 register */ + USARTx->CR3 |= USART_CR3_IREN; + } + else + { + /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */ + USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IREN); + } +} + +/** + * @} + */ + +/** @defgroup USART_Group8 DMA transfers management functions + * @brief DMA transfers management functions + * +@verbatim + =============================================================================== + ##### DMA transfers management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the USART's DMA interface. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_DMAReq: specifies the DMA request. + * This parameter can be any combination of the following values: + * @arg USART_DMAReq_Tx: USART DMA transmit request. + * @arg USART_DMAReq_Rx: USART DMA receive request. + * @param NewState: new state of the DMA Request sources. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_DMAREQ(USART_DMAReq)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA transfer for selected requests by setting the DMAT and/or + DMAR bits in the USART CR3 register */ + USARTx->CR3 |= USART_DMAReq; + } + else + { + /* Disable the DMA transfer for selected requests by clearing the DMAT and/or + DMAR bits in the USART CR3 register */ + USARTx->CR3 &= (uint16_t)~USART_DMAReq; + } +} + +/** + * @} + */ + +/** @defgroup USART_Group9 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to configure the + USART Interrupts sources, DMA channels requests and check or clear the + flags or pending bits status. The user should identify which mode will + be used in his application to manage the communication: Polling mode, + Interrupt mode or DMA mode. + *** Polling Mode *** + ==================== + [..] In Polling Mode, the SPI communication can be managed by 10 flags: + (#) USART_FLAG_TXE: to indicate the status of the transmit buffer register. + (#) USART_FLAG_RXNE: to indicate the status of the receive buffer register. + (#) USART_FLAG_TC: to indicate the status of the transmit operation. + (#) USART_FLAG_IDLE: to indicate the status of the Idle Line. + (#) USART_FLAG_CTS: to indicate the status of the nCTS input. + (#) USART_FLAG_LBD: to indicate the status of the LIN break detection. + (#) USART_FLAG_NE: to indicate if a noise error occur. + (#) USART_FLAG_FE: to indicate if a frame error occur. + (#) USART_FLAG_PE: to indicate if a parity error occur. + (#) USART_FLAG_ORE: to indicate if an Overrun error occur. + [..] In this Mode it is advised to use the following functions: + (+) FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG). + (+) void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG). + + *** Interrupt Mode *** + ====================== + [..] In Interrupt Mode, the USART communication can be managed by 8 interrupt + sources and 10 pending bits: + (+) Pending Bits: + (##) USART_IT_TXE: to indicate the status of the transmit buffer + register. + (##) USART_IT_RXNE: to indicate the status of the receive buffer + register. + (##) USART_IT_TC: to indicate the status of the transmit operation. + (##) USART_IT_IDLE: to indicate the status of the Idle Line. + (##) USART_IT_CTS: to indicate the status of the nCTS input. + (##) USART_IT_LBD: to indicate the status of the LIN break detection. + (##) USART_IT_NE: to indicate if a noise error occur. + (##) USART_IT_FE: to indicate if a frame error occur. + (##) USART_IT_PE: to indicate if a parity error occur. + (##) USART_IT_ORE: to indicate if an Overrun error occur + (if the RXNEIE or EIE bits are set). + + (+) Interrupt Source: + (##) USART_IT_TXE: specifies the interrupt source for the Tx buffer + empty interrupt. + (##) USART_IT_RXNE: specifies the interrupt source for the Rx buffer + not empty interrupt. + (##) USART_IT_TC: specifies the interrupt source for the Transmit + complete interrupt. + (##) USART_IT_IDLE: specifies the interrupt source for the Idle Line + interrupt. + (##) USART_IT_CTS: specifies the interrupt source for the CTS interrupt. + (##) USART_IT_LBD: specifies the interrupt source for the LIN break + detection interrupt. + (##) USART_IT_PE: specifies the interrupt source for theparity error + interrupt. + (##) USART_IT_ERR: specifies the interrupt source for the errors + interrupt. + -@@- Some parameters are coded in order to use them as interrupt + source or as pending bits. + [..] In this Mode it is advised to use the following functions: + (+) void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, + FunctionalState NewState). + (+) ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT). + (+) void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT). + + *** DMA Mode *** + ================ + [..] In DMA Mode, the USART communication can be managed by 2 DMA Channel + requests: + (#) USART_DMAReq_Tx: specifies the Tx buffer DMA transfer request. + (#) USART_DMAReq_Rx: specifies the Rx buffer DMA transfer request. + [..] In this Mode it is advised to use the following function: + (+) void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, + FunctionalState NewState). +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified USART interrupts. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt. + * @arg USART_IT_LBD: LIN Break detection interrupt. + * @arg USART_IT_TXE: Tansmit Data Register empty interrupt. + * @arg USART_IT_TC: Transmission complete interrupt. + * @arg USART_IT_RXNE: Receive Data register not empty interrupt. + * @arg USART_IT_IDLE: Idle line detection interrupt. + * @arg USART_IT_PE: Parity Error interrupt. + * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error). + * @param NewState: new state of the specified USARTx interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) +{ + uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00; + uint32_t usartxbase = 0x00; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CONFIG_IT(USART_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + usartxbase = (uint32_t)USARTx; + + /* Get the USART register index */ + usartreg = (((uint8_t)USART_IT) >> 0x05); + + /* Get the interrupt position */ + itpos = USART_IT & IT_MASK; + itmask = (((uint32_t)0x01) << itpos); + + if (usartreg == 0x01) /* The IT is in CR1 register */ + { + usartxbase += 0x0C; + } + else if (usartreg == 0x02) /* The IT is in CR2 register */ + { + usartxbase += 0x10; + } + else /* The IT is in CR3 register */ + { + usartxbase += 0x14; + } + if (NewState != DISABLE) + { + *(__IO uint32_t*)usartxbase |= itmask; + } + else + { + *(__IO uint32_t*)usartxbase &= ~itmask; + } +} + +/** + * @brief Checks whether the specified USART flag is set or not. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5). + * @arg USART_FLAG_LBD: LIN Break detection flag. + * @arg USART_FLAG_TXE: Transmit data register empty flag. + * @arg USART_FLAG_TC: Transmission Complete flag. + * @arg USART_FLAG_RXNE: Receive data register not empty flag. + * @arg USART_FLAG_IDLE: Idle Line detection flag. + * @arg USART_FLAG_ORE: OverRun Error flag. + * @arg USART_FLAG_NE: Noise Error flag. + * @arg USART_FLAG_FE: Framing Error flag. + * @arg USART_FLAG_PE: Parity Error flag. + * @retval The new state of USART_FLAG (SET or RESET). + */ +FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_FLAG(USART_FLAG)); + + /* The CTS flag is not available for UART4 and UART5 */ + if (USART_FLAG == USART_FLAG_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the USARTx's pending flags. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5). + * @arg USART_FLAG_LBD: LIN Break detection flag. + * @arg USART_FLAG_TC: Transmission Complete flag. + * @arg USART_FLAG_RXNE: Receive data register not empty flag. + * + * + * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun + * error) and IDLE (Idle line detected) flags are cleared by software + * sequence: a read operation to USART_SR register (USART_GetFlagStatus()) + * followed by a read operation to USART_DR register (USART_ReceiveData()). + * @note RXNE flag can be also cleared by a read to the USART_DR register + * (USART_ReceiveData()). + * @note TC flag can be also cleared by software sequence: a read operation to + * USART_SR register (USART_GetFlagStatus()) followed by a write operation + * to USART_DR register (USART_SendData()). + * @note TXE flag is cleared only by a write to the USART_DR register + * (USART_SendData()). + * @retval None + */ +void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLEAR_FLAG(USART_FLAG)); + + /* The CTS flag is not available for UART4 and UART5 */ + if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + USARTx->SR = (uint16_t)~USART_FLAG; +} + +/** + * @brief Checks whether the specified USART interrupt has occurred or not. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_IT: specifies the USART interrupt source to check. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TXE: Tansmit Data Register empty interrupt + * @arg USART_IT_TC: Transmission complete interrupt + * @arg USART_IT_RXNE: Receive Data register not empty interrupt + * @arg USART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_ORE_RX: OverRun Error interrupt if the RXNEIE bit is set. + * @arg USART_IT_ORE_ER: OverRun Error interrupt if the EIE bit is set. + * @arg USART_IT_NE: Noise Error interrupt + * @arg USART_IT_FE: Framing Error interrupt + * @arg USART_IT_PE: Parity Error interrupt + * @retval The new state of USART_IT (SET or RESET). + */ +ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) +{ + uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00; + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_GET_IT(USART_IT)); + + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + /* Get the USART register index */ + usartreg = (((uint8_t)USART_IT) >> 0x05); + /* Get the interrupt position */ + itmask = USART_IT & IT_MASK; + itmask = (uint32_t)0x01 << itmask; + + if (usartreg == 0x01) /* The IT is in CR1 register */ + { + itmask &= USARTx->CR1; + } + else if (usartreg == 0x02) /* The IT is in CR2 register */ + { + itmask &= USARTx->CR2; + } + else /* The IT is in CR3 register */ + { + itmask &= USARTx->CR3; + } + + bitpos = USART_IT >> 0x08; + bitpos = (uint32_t)0x01 << bitpos; + bitpos &= USARTx->SR; + if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + return bitstatus; +} + +/** + * @brief Clears the USARTx's interrupt pending bits. + * @param USARTx: Select the USART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_IT: specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TC: Transmission complete interrupt. + * @arg USART_IT_RXNE: Receive Data register not empty interrupt. + * + + * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun + * error) and IDLE (Idle line detected) pending bits are cleared by + * software sequence: a read operation to USART_SR register + * (USART_GetITStatus()) followed by a read operation to USART_DR register + * (USART_ReceiveData()). + * @note RXNE pending bit can be also cleared by a read to the USART_DR register + * (USART_ReceiveData()). + * @note TC pending bit can be also cleared by software sequence: a read + * operation to USART_SR register (USART_GetITStatus()) followed by a write + * operation to USART_DR register (USART_SendData()). + * @note TXE pending bit is cleared only by a write to the USART_DR register + * (USART_SendData()). + * @retval None + */ +void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT) +{ + uint16_t bitpos = 0x00, itmask = 0x00; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLEAR_IT(USART_IT)); + + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + bitpos = USART_IT >> 0x08; + itmask = ((uint16_t)0x01 << (uint16_t)bitpos); + USARTx->SR = (uint16_t)~itmask; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_usart.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_usart.h new file mode 100644 index 0000000000..590c1ed15f --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_usart.h @@ -0,0 +1,427 @@ +/** + ****************************************************************************** + * @file stm32l1xx_usart.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the USART + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_USART_H +#define __STM32L1xx_USART_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup USART + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief USART Init Structure definition + */ + +typedef struct +{ + uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. + The baud rate is computed using the following formula: + - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (USART_InitStruct->USART_BaudRate))) + - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 8 * (OVR8+1)) + 0.5 + Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */ + + uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref USART_Word_Length */ + + uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref USART_Stop_Bits */ + + uint16_t USART_Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref USART_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref USART_Mode */ + + uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled + or disabled. + This parameter can be a value of @ref USART_Hardware_Flow_Control */ +} USART_InitTypeDef; + +/** + * @brief USART Clock Init Structure definition + */ + +typedef struct +{ + + uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled. + This parameter can be a value of @ref USART_Clock */ + + uint16_t USART_CPOL; /*!< Specifies the steady state of the serial clock. + This parameter can be a value of @ref USART_Clock_Polarity */ + + uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref USART_Clock_Phase */ + + uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. + This parameter can be a value of @ref USART_Last_Bit */ +} USART_ClockInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup USART_Exported_Constants + * @{ + */ + +#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \ + ((PERIPH) == USART2) || \ + ((PERIPH) == USART3) || \ + ((PERIPH) == UART4) || \ + ((PERIPH) == UART5)) + +#define IS_USART_123_PERIPH(PERIPH) (((PERIPH) == USART1) || \ + ((PERIPH) == USART2) || \ + ((PERIPH) == USART3)) + +/** @defgroup USART_Word_Length + * @{ + */ + +#define USART_WordLength_8b ((uint16_t)0x0000) +#define USART_WordLength_9b ((uint16_t)0x1000) + +#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ + ((LENGTH) == USART_WordLength_9b)) +/** + * @} + */ + +/** @defgroup USART_Stop_Bits + * @{ + */ + +#define USART_StopBits_1 ((uint16_t)0x0000) +#define USART_StopBits_0_5 ((uint16_t)0x1000) +#define USART_StopBits_2 ((uint16_t)0x2000) +#define USART_StopBits_1_5 ((uint16_t)0x3000) +#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \ + ((STOPBITS) == USART_StopBits_0_5) || \ + ((STOPBITS) == USART_StopBits_2) || \ + ((STOPBITS) == USART_StopBits_1_5)) +/** + * @} + */ + +/** @defgroup USART_Parity + * @{ + */ + +#define USART_Parity_No ((uint16_t)0x0000) +#define USART_Parity_Even ((uint16_t)0x0400) +#define USART_Parity_Odd ((uint16_t)0x0600) +#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ + ((PARITY) == USART_Parity_Even) || \ + ((PARITY) == USART_Parity_Odd)) +/** + * @} + */ + +/** @defgroup USART_Mode + * @{ + */ + +#define USART_Mode_Rx ((uint16_t)0x0004) +#define USART_Mode_Tx ((uint16_t)0x0008) +#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00)) +/** + * @} + */ + +/** @defgroup USART_Hardware_Flow_Control + * @{ + */ +#define USART_HardwareFlowControl_None ((uint16_t)0x0000) +#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100) +#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200) +#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300) +#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\ + (((CONTROL) == USART_HardwareFlowControl_None) || \ + ((CONTROL) == USART_HardwareFlowControl_RTS) || \ + ((CONTROL) == USART_HardwareFlowControl_CTS) || \ + ((CONTROL) == USART_HardwareFlowControl_RTS_CTS)) +/** + * @} + */ + +/** @defgroup USART_Clock + * @{ + */ +#define USART_Clock_Disable ((uint16_t)0x0000) +#define USART_Clock_Enable ((uint16_t)0x0800) +#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \ + ((CLOCK) == USART_Clock_Enable)) +/** + * @} + */ + +/** @defgroup USART_Clock_Polarity + * @{ + */ + +#define USART_CPOL_Low ((uint16_t)0x0000) +#define USART_CPOL_High ((uint16_t)0x0400) +#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High)) + +/** + * @} + */ + +/** @defgroup USART_Clock_Phase + * @{ + */ + +#define USART_CPHA_1Edge ((uint16_t)0x0000) +#define USART_CPHA_2Edge ((uint16_t)0x0200) +#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge)) + +/** + * @} + */ + +/** @defgroup USART_Last_Bit + * @{ + */ + +#define USART_LastBit_Disable ((uint16_t)0x0000) +#define USART_LastBit_Enable ((uint16_t)0x0100) +#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \ + ((LASTBIT) == USART_LastBit_Enable)) +/** + * @} + */ + +/** @defgroup USART_Interrupt_definition + * @{ + */ + +#define USART_IT_PE ((uint16_t)0x0028) +#define USART_IT_TXE ((uint16_t)0x0727) +#define USART_IT_TC ((uint16_t)0x0626) +#define USART_IT_RXNE ((uint16_t)0x0525) +#define USART_IT_IDLE ((uint16_t)0x0424) +#define USART_IT_LBD ((uint16_t)0x0846) +#define USART_IT_ORE_RX ((uint16_t)0x0325) /* In case interrupt is generated if the RXNEIE bit is set */ +#define USART_IT_CTS ((uint16_t)0x096A) +#define USART_IT_ERR ((uint16_t)0x0060) +#define USART_IT_ORE_ER ((uint16_t)0x0360) /* In case interrupt is generated if the EIE bit is set */ +#define USART_IT_NE ((uint16_t)0x0260) +#define USART_IT_FE ((uint16_t)0x0160) + +/** @defgroup USART_Legacy + * @{ + */ +#define USART_IT_ORE USART_IT_ORE_ER +/** + * @} + */ + +#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ + ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ + ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR)) +#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ + ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ + ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE_RX) || \ + ((IT) == USART_IT_ORE_ER) || ((IT) == USART_IT_NE) || \ + ((IT) == USART_IT_FE)) +#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS)) +/** + * @} + */ + +/** @defgroup USART_DMA_Requests + * @{ + */ + +#define USART_DMAReq_Tx ((uint16_t)0x0080) +#define USART_DMAReq_Rx ((uint16_t)0x0040) +#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00)) + +/** + * @} + */ + +/** @defgroup USART_WakeUp_methods + * @{ + */ + +#define USART_WakeUp_IdleLine ((uint16_t)0x0000) +#define USART_WakeUp_AddressMark ((uint16_t)0x0800) +#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \ + ((WAKEUP) == USART_WakeUp_AddressMark)) +/** + * @} + */ + +/** @defgroup USART_LIN_Break_Detection_Length + * @{ + */ + +#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000) +#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020) +#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \ + (((LENGTH) == USART_LINBreakDetectLength_10b) || \ + ((LENGTH) == USART_LINBreakDetectLength_11b)) +/** + * @} + */ + +/** @defgroup USART_IrDA_Low_Power + * @{ + */ + +#define USART_IrDAMode_LowPower ((uint16_t)0x0004) +#define USART_IrDAMode_Normal ((uint16_t)0x0000) +#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \ + ((MODE) == USART_IrDAMode_Normal)) +/** + * @} + */ + +/** @defgroup USART_Flags + * @{ + */ + +#define USART_FLAG_CTS ((uint16_t)0x0200) +#define USART_FLAG_LBD ((uint16_t)0x0100) +#define USART_FLAG_TXE ((uint16_t)0x0080) +#define USART_FLAG_TC ((uint16_t)0x0040) +#define USART_FLAG_RXNE ((uint16_t)0x0020) +#define USART_FLAG_IDLE ((uint16_t)0x0010) +#define USART_FLAG_ORE ((uint16_t)0x0008) +#define USART_FLAG_NE ((uint16_t)0x0004) +#define USART_FLAG_FE ((uint16_t)0x0002) +#define USART_FLAG_PE ((uint16_t)0x0001) +#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \ + ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \ + ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \ + ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \ + ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE)) + +#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00)) + +#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 0x003D0901)) +#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) +#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* Function used to set the USART configuration to the default reset state ***/ +void USART_DeInit(USART_TypeDef* USARTx); + +/* Initialization and Configuration functions *********************************/ +void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); +void USART_StructInit(USART_InitTypeDef* USART_InitStruct); +void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct); +void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct); +void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler); +void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* Data transfers functions ***************************************************/ +void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); +uint16_t USART_ReceiveData(USART_TypeDef* USARTx); + +/* Multi-Processor Communication functions ************************************/ +void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address); +void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp); +void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* LIN mode functions *********************************************************/ +void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength); +void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SendBreak(USART_TypeDef* USARTx); + +/* Half-duplex mode function **************************************************/ +void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* Smartcard mode functions ***************************************************/ +void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime); + +/* IrDA mode functions ********************************************************/ +void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode); +void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState); + +/* DMA transfers management functions *****************************************/ +void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); + +/* Interrupts and flags management functions **********************************/ +void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); +FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); +void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); +ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); +void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_USART_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_wwdg.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_wwdg.c new file mode 100644 index 0000000000..03029e4184 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_wwdg.c @@ -0,0 +1,313 @@ +/** + ****************************************************************************** + * @file stm32l1xx_wwdg.c + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file provides firmware functions to manage the following + * functionalities of the Window watchdog (WWDG) peripheral: + * + Prescaler, Refresh window and Counter configuration + * + WWDG activation + * + Interrupts and flags management + * + * @verbatim + * + ============================================================================== + ##### WWDG features ##### + ============================================================================== + [..] Once enabled the WWDG generates a system reset on expiry of a programmed + time period, unless the program refreshes the counter (downcounter) + before to reach 0x3F value (i.e. a reset is generated when the counter + value rolls over from 0x40 to 0x3F). + [..] An MCU reset is also generated if the counter value is refreshed + before the counter has reached the refresh window value. This + implies that the counter must be refreshed in a limited window. + + [..] Once enabled the WWDG cannot be disabled except by a system reset. + + [..] WWDGRST flag in RCC_CSR register can be used to inform when a WWDG + reset occurs. + + [..] The WWDG counter input clock is derived from the APB clock divided + by a programmable prescaler. + + [..] WWDG counter clock = PCLK1 / Prescaler. + [..] WWDG timeout = (WWDG counter clock) * (counter value). + + [..] Min-max timeout value @32MHz (PCLK1): ~128us / ~65.6ms. + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable WWDG clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE) + function. + + (#) Configure the WWDG prescaler using WWDG_SetPrescaler() function. + + (#) Configure the WWDG refresh window using WWDG_SetWindowValue() function. + + (#) Set the WWDG counter value and start it using WWDG_Enable() function. + When the WWDG is enabled the counter value should be configured to + a value greater than 0x40 to prevent generating an immediate reset. + + (#) Optionally you can enable the Early wakeup interrupt which is + generated when the counter reach 0x40. + Once enabled this interrupt cannot be disabled except by a system reset. + + (#) Then the application program must refresh the WWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + WWDG_SetCounter() function. This operation must occur only when + the counter value is lower than the refresh window value, + programmed using WWDG_SetWindowValue(). + + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx_wwdg.h" +#include "stm32l1xx_rcc.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup WWDG + * @brief WWDG driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ----------- WWDG registers bit address in the alias region ----------- */ +#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE) + +/* Alias word address of EWI bit */ +#define CFR_OFFSET (WWDG_OFFSET + 0x04) +#define EWI_BitNumber 0x09 +#define CFR_EWI_BB (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4)) + +/* --------------------- WWDG registers bit mask ------------------------ */ + +/* CFR register bit mask */ +#define CFR_WDGTB_MASK ((uint32_t)0xFFFFFE7F) +#define CFR_W_MASK ((uint32_t)0xFFFFFF80) +#define BIT_MASK ((uint8_t)0x7F) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup WWDG_Private_Functions + * @{ + */ + +/** @defgroup WWDG_Group1 Prescaler, Refresh window and Counter configuration functions + * @brief Prescaler, Refresh window and Counter configuration functions + * +@verbatim + ============================================================================== + ##### Prescaler, Refresh window and Counter configuration functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the WWDG peripheral registers to their default reset values. + * @param None + * @retval None + */ +void WWDG_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE); +} + +/** + * @brief Sets the WWDG Prescaler. + * @param WWDG_Prescaler: specifies the WWDG Prescaler. + * This parameter can be one of the following values: + * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1 + * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2 + * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4 + * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8 + * @retval None + */ +void WWDG_SetPrescaler(uint32_t WWDG_Prescaler) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler)); + /* Clear WDGTB[1:0] bits */ + tmpreg = WWDG->CFR & CFR_WDGTB_MASK; + /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */ + tmpreg |= WWDG_Prescaler; + /* Store the new value */ + WWDG->CFR = tmpreg; +} + +/** + * @brief Sets the WWDG window value. + * @param WindowValue: specifies the window value to be compared to the downcounter. + * This parameter value must be lower than 0x80. + * @retval None + */ +void WWDG_SetWindowValue(uint8_t WindowValue) +{ + __IO uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_WWDG_WINDOW_VALUE(WindowValue)); + /* Clear W[6:0] bits */ + + tmpreg = WWDG->CFR & CFR_W_MASK; + + /* Set W[6:0] bits according to WindowValue value */ + tmpreg |= WindowValue & (uint32_t) BIT_MASK; + + /* Store the new value */ + WWDG->CFR = tmpreg; +} + +/** + * @brief Enables the WWDG Early Wakeup interrupt(EWI). + * @note Once enabled this interrupt cannot be disabled except by a system reset. + * @param None + * @retval None + */ +void WWDG_EnableIT(void) +{ + *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE; +} + +/** + * @brief Sets the WWDG counter value. + * @param Counter: specifies the watchdog counter value. + * This parameter must be a number between 0x40 and 0x7F (to prevent generating + * an immediate reset). + * @retval None + */ +void WWDG_SetCounter(uint8_t Counter) +{ + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + /* Write to T[6:0] bits to configure the counter value, no need to do + a read-modify-write; writing a 0 to WDGA bit does nothing */ + WWDG->CR = Counter & BIT_MASK; +} + +/** + * @} + */ + +/** @defgroup WWDG_Group2 WWDG activation functions + * @brief WWDG activation functions + * +@verbatim + ============================================================================== + ##### WWDG activation function ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables WWDG and load the counter value. + * @param Counter: specifies the watchdog counter value. + * This parameter must be a number between 0x40 and 0x7F (to prevent generating + * an immediate reset). + * @retval None + */ +void WWDG_Enable(uint8_t Counter) +{ + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + WWDG->CR = WWDG_CR_WDGA | Counter; +} + +/** + * @} + */ + +/** @defgroup WWDG_Group3 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + ============================================================================== + ##### Interrupts and flags management functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Checks whether the Early Wakeup interrupt flag is set or not. + * @param None + * @retval The new state of the Early Wakeup interrupt flag (SET or RESET). + */ +FlagStatus WWDG_GetFlagStatus(void) +{ + FlagStatus bitstatus = RESET; + + if ((WWDG->SR) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears Early Wakeup interrupt flag. + * @param None + * @retval None + */ +void WWDG_ClearFlag(void) +{ + WWDG->SR = (uint32_t)RESET; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_wwdg.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_wwdg.h new file mode 100644 index 0000000000..a17c6e1070 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_wwdg.h @@ -0,0 +1,110 @@ +/** + ****************************************************************************** + * @file stm32l1xx_wwdg.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief This file contains all the functions prototypes for the WWDG + * firmware library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L1xx_WWDG_H +#define __STM32L1xx_WWDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l1xx.h" + +/** @addtogroup STM32L1xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup WWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup WWDG_Exported_Constants + * @{ + */ + +/** @defgroup WWDG_Prescaler + * @{ + */ + +#define WWDG_Prescaler_1 ((uint32_t)0x00000000) +#define WWDG_Prescaler_2 ((uint32_t)0x00000080) +#define WWDG_Prescaler_4 ((uint32_t)0x00000100) +#define WWDG_Prescaler_8 ((uint32_t)0x00000180) +#define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ + ((PRESCALER) == WWDG_Prescaler_2) || \ + ((PRESCALER) == WWDG_Prescaler_4) || \ + ((PRESCALER) == WWDG_Prescaler_8)) +#define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) +#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +/* Function used to set the WWDG configuration to the default reset state ****/ +void WWDG_DeInit(void); + +/* Prescaler, Refresh window and Counter configuration functions **************/ +void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); +void WWDG_SetWindowValue(uint8_t WindowValue); +void WWDG_EnableIT(void); +void WWDG_SetCounter(uint8_t Counter); + +/* WWDG activation functions **************************************************/ +void WWDG_Enable(uint8_t Counter); + +/* Interrupts and flags management functions **********************************/ +FlagStatus WWDG_GetFlagStatus(void); +void WWDG_ClearFlag(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L1xx_WWDG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.c new file mode 100644 index 0000000000..3e110b88f9 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.c @@ -0,0 +1,519 @@ +/** + ****************************************************************************** + * @file system_stm32l1xx.c + * @author MCD Application Team + * @version V1.2.0 + * @date 8-January-2014 + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. + * This file contains the system clock configuration for STM32L1xx Ultra + * Low power devices, and is generated by the clock configuration + * tool STM32L1xx_Clock_Configuration_V1.2.0.xls + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier + * and Divider factors, AHB/APBx prescalers and Flash settings), + * depending on the configuration made in the clock xls tool. + * This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32l1xx_xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * 2. After each device reset the MSI (2.1 MHz Range) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32l1xx_xx.s" file, to + * configure the system clock before to branch to main program. + * + * 3. If the system clock source selected by user fails to startup, the SystemInit() + * function will do nothing and MSI still used as system clock source. User can + * add some code to deal with this issue inside the SetSysClock() function. + * + * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define + * in "stm32l1xx.h" file. When HSE is used as system clock source, directly or + * through PLL, and you are using different crystal you have to adapt the HSE + * value to your own configuration. + * + * 5. This file configures the system clock as follows: + *============================================================================= + * System Clock Configuration + *============================================================================= + * System clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK | 16000000 Hz + *----------------------------------------------------------------------------- + * HCLK | 8000000 Hz + *----------------------------------------------------------------------------- + * AHB Prescaler | 2 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * HSE Frequency | 8000000 Hz + *----------------------------------------------------------------------------- + * PLL DIV | Not Used + *----------------------------------------------------------------------------- + * PLL MUL | Not Used + *----------------------------------------------------------------------------- + * VDD | 3.3 V + *----------------------------------------------------------------------------- + * Vcore | 1.5 V (Range 2) + *----------------------------------------------------------------------------- + * Flash Latency | 0 WS + *----------------------------------------------------------------------------- + * SDIO clock (SDIOCLK) | NA + *----------------------------------------------------------------------------- + * Require 48MHz for USB clock | Disabled + *----------------------------------------------------------------------------- + *============================================================================= + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32l1xx_system + * @{ + */ + +/** @addtogroup STM32L1xx_System_Private_Includes + * @{ + */ + +#include "stm32l1xx.h" + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_Defines + * @{ + */ + +/*!< Uncomment the following line if you need to use external SRAM mounted + on STM32L152D_EVAL board as data memory */ +/* #define DATA_IN_ExtSRAM */ + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_Variables + * @{ + */ +uint32_t SystemCoreClock = 16000000; +__I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_FunctionPrototypes + * @{ + */ + +static void SetSysClock(void); +#ifdef DATA_IN_ExtSRAM +static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM */ + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemCoreClock variable. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /*!< Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100; + + /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t)0x88FFC00C; + + /*!< Reset HSION, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xEEFEFFFE; + + /*!< Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFF; + + /*!< Disable all interrupts */ + RCC->CIR = 0x00000000; + +#ifdef DATA_IN_ExtSRAM +SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM */ + + /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ + SetSysClock(); + +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ +#endif +} + +/** + * @brief Update SystemCoreClock according to Clock Register Values + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI + * value as defined by the MSI range. + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32l1xx.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * @param None + * @retval None + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, msirange = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* MSI used as system clock */ + msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13; + SystemCoreClock = (32768 * (1 << (msirange + 1))); + break; + case 0x04: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + case 0x08: /* HSE used as system clock */ + SystemCoreClock = HSE_VALUE; + break; + case 0x0C: /* PLL used as system clock */ + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; + plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; + pllmul = PLLMulTable[(pllmul >> 18)]; + plldiv = (plldiv >> 22) + 1; + + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + + if (pllsource == 0x00) + { + /* HSI oscillator clock selected as PLL clock entry */ + SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); + } + else + { + /* HSE selected as PLL clock entry */ + SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); + } + break; + default: /* MSI used as system clock */ + msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13; + SystemCoreClock = (32768 * (1 << (msirange + 1))); + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash + * settings. + * @note This function should be called only once the RCC clock configuration + * is reset to the default reset state (done in SystemInit() function). + * @param None + * @retval None + */ +static void SetSysClock(void) +{ + __IO uint32_t StartUpCounter = 0, HSIStatus = 0; + + /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ + /* Enable HSI */ + RCC->CR |= ((uint32_t)RCC_CR_HSION); + + /* Wait till HSI is ready and if Time out is reached exit */ + do + { + HSIStatus = RCC->CR & RCC_CR_HSIRDY; + } while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSIRDY) != RESET) + { + HSIStatus = (uint32_t)0x01; + } + else + { + HSIStatus = (uint32_t)0x00; + } + + if (HSIStatus == (uint32_t)0x01) + { + /* Flash 0 wait state */ + FLASH->ACR &= ~FLASH_ACR_LATENCY; + + /* Disable Prefetch Buffer */ + FLASH->ACR &= ~FLASH_ACR_PRFTEN; + + /* Disable 64-bit access */ + FLASH->ACR &= ~FLASH_ACR_ACC64; + + + /* Power enable */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + + /* Select the Voltage Range 2 (1.5 V) */ + PWR->CR = PWR_CR_VOS_1; + + + /* Wait Until the Voltage Regulator is ready */ + while((PWR->CSR & PWR_CSR_VOSF) != RESET) + { + } + + /* HCLK = SYSCLK /2*/ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV2; + /* PCLK2 = HCLK /1*/ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK /1*/ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; + + /* Select HSI as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI; + + /* Wait till HSI is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_HSI) + { + } + } + else + { + /* If HSI fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} + +#ifdef DATA_IN_ExtSRAM +/** + * @brief Setup the external memory controller. + * Called in SystemInit() function before jump to main. + * This function configures the external SRAM mounted on STM32L152D_EVAL board + * This SRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ +/*-- GPIOs Configuration -----------------------------------------------------*/ +/* + +-------------------+--------------------+------------------+------------------+ + + SRAM pins assignment + + +-------------------+--------------------+------------------+------------------+ + | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | + | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | + | PD4 <-> FSMC_NOE | PE7 <-> FSMC_D4 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | + | PD5 <-> FSMC_NWE | PE8 <-> FSMC_D5 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | + | PD8 <-> FSMC_D13 | PE9 <-> FSMC_D6 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | + | PD9 <-> FSMC_D14 | PE10 <-> FSMC_D7 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | + | PD10 <-> FSMC_D15 | PE11 <-> FSMC_D8 | PF12 <-> FSMC_A6 | PG10<-> FSMC_NE2 | + | PD11 <-> FSMC_A16 | PE12 <-> FSMC_D9 | PF13 <-> FSMC_A7 |------------------+ + | PD12 <-> FSMC_A17 | PE13 <-> FSMC_D10 | PF14 <-> FSMC_A8 | + | PD13 <-> FSMC_A18 | PE14 <-> FSMC_D11 | PF15 <-> FSMC_A9 | + | PD14 <-> FSMC_D0 | PE15 <-> FSMC_D12 |------------------+ + | PD15 <-> FSMC_D1 |--------------------+ + +-------------------+ +*/ + + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHBENR = 0x000080D8; + + /* Connect PDx pins to FSMC Alternate function */ + GPIOD->AFR[0] = 0x00CC00CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A0A; + /* Configure PDx pins speed to 40 MHz */ + GPIOD->OSPEEDR = 0xFFFF0F0F; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FSMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 40 MHz */ + GPIOE->OSPEEDR = 0xFFFFC00F; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FSMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCC0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA000AAA; + /* Configure PFx pins speed to 40 MHz */ + GPIOF->OSPEEDR = 0xFF000FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FSMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0x00000C00; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00200AAA; + /* Configure PGx pins speed to 40 MHz */ + GPIOG->OSPEEDR = 0x00300FFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FSMC Configuration ------------------------------------------------------*/ + /* Enable the FSMC interface clock */ + RCC->AHBENR = 0x400080D8; + + /* Configure and enable Bank1_SRAM3 */ + FSMC_Bank1->BTCR[4] = 0x00001011; + FSMC_Bank1->BTCR[5] = 0x00000300; + FSMC_Bank1E->BWTR[4] = 0x0FFFFFFF; +/* + Bank1_SRAM3 is configured as follow: + + p.FSMC_AddressSetupTime = 0; + p.FSMC_AddressHoldTime = 0; + p.FSMC_DataSetupTime = 3; + p.FSMC_BusTurnAroundDuration = 0; + p.FSMC_CLKDivision = 0; + p.FSMC_DataLatency = 0; + p.FSMC_AccessMode = FSMC_AccessMode_A; + + FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; + FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; + FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; + FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; + FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; + FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; + + FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); + + FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); +*/ + +} +#endif /* DATA_IN_ExtSRAM */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.h new file mode 100644 index 0000000000..25ad240969 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.h @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file system_stm32l1xx.h + * @author MCD Application Team + * @version V1.2.0 + * @date 22-February-2013 + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2013 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32l1xx_system + * @{ + */ + +/** + * @brief Define to prevent recursive inclusion + */ +#ifndef __SYSTEM_STM32L1XX_H +#define __SYSTEM_STM32L1XX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup STM32L1xx_System_Includes + * @{ + */ + +/** + * @} + */ + + +/** @addtogroup STM32L1xx_System_Exported_types + * @{ + */ + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L1xx_System_Exported_Functions + * @{ + */ + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__SYSTEM_STM32L1XX_H */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PeripheralNames.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PeripheralNames.h new file mode 100644 index 0000000000..b392c7a4a2 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PeripheralNames.h @@ -0,0 +1,72 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ADC_1 = (int)ADC1_BASE, + ADC_2 = (int)ADC_BASE +} ADCName; + +typedef enum { + UART_1 = (int)USART1_BASE, + UART_2 = (int)USART2_BASE +} UARTName; + +#define STDIO_UART_TX PA_2 +#define STDIO_UART_RX PA_3 +#define STDIO_UART UART_2 + +typedef enum { + SPI_1 = (int)SPI1_BASE, + SPI_2 = (int)SPI2_BASE +} SPIName; + +typedef enum { + I2C_1 = (int)I2C1_BASE, + I2C_2 = (int)I2C2_BASE +} I2CName; + +typedef enum { + PWM_2 = (int)TIM2_BASE, + PWM_3 = (int)TIM3_BASE +} PWMName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PinNames.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PinNames.h new file mode 100644 index 0000000000..b41df132e7 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PinNames.h @@ -0,0 +1,236 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// MODE (see GPIOMode_TypeDef structure) +// OTYPE (see GPIOOType_TypeDef structure) +// PUPD (see GPIOPuPd_TypeDef structure) +// AFNUM (see AF_mapping constant table) +#define STM_PIN_DATA(MODE, OTYPE, PUPD, AFNUM) (((AFNUM)<<8)|((PUPD)<<4)|((OTYPE)<<2)|((MODE)<<0)) +#define STM_PIN_MODE(X) (((X)>>0) & 0x3) +#define STM_PIN_OTYPE(X) (((X)>>2) & 0x1) +#define STM_PIN_PUPD(X) (((X)>>4) & 0x3) +#define STM_PIN_AFNUM(X) (((X)>>8) & 0xF) + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +typedef enum { + + // high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H) + // low nibble = pin number + PA_0 = 0x00, + PA_1 = 0x01, + PA_2 = 0x02, + PA_3 = 0x03, + PA_4 = 0x04, + PA_5 = 0x05, + PA_6 = 0x06, + PA_7 = 0x07, + PA_8 = 0x08, + PA_9 = 0x09, + PA_10 = 0x0A, + PA_11 = 0x0B, + PA_12 = 0x0C, + PA_13 = 0x0D, + PA_14 = 0x0E, + PA_15 = 0x0F, + + PB_0 = 0x10, + PB_1 = 0x11, + PB_2 = 0x12, + PB_3 = 0x13, + PB_4 = 0x14, + PB_5 = 0x15, + PB_6 = 0x16, + PB_7 = 0x17, + PB_8 = 0x18, + PB_9 = 0x19, + PB_10 = 0x1A, + PB_11 = 0x1B, + PB_12 = 0x1C, + PB_13 = 0x1D, + PB_14 = 0x1E, + PB_15 = 0x1F, + + PC_0 = 0x20, + PC_1 = 0x21, + PC_2 = 0x22, + PC_3 = 0x23, + PC_4 = 0x24, + PC_5 = 0x25, + PC_6 = 0x26, + PC_7 = 0x27, + PC_8 = 0x28, + PC_9 = 0x29, + PC_10 = 0x2A, + PC_11 = 0x2B, + PC_12 = 0x2C, + PC_13 = 0x2D, + PC_14 = 0x2E, + PC_15 = 0x2F, + + PD_0 = 0x30, + PD_1 = 0x31, + PD_2 = 0x32, + PD_3 = 0x33, + PD_4 = 0x34, + PD_5 = 0x35, + PD_6 = 0x36, + PD_7 = 0x37, + PD_8 = 0x38, + PD_9 = 0x39, + PD_10 = 0x3A, + PD_11 = 0x3B, + PD_12 = 0x3C, + PD_13 = 0x3D, + PD_14 = 0x3E, + PD_15 = 0x3F, + + PE_0 = 0x40, + PE_1 = 0x41, + PE_2 = 0x42, + PE_3 = 0x43, + PE_4 = 0x44, + PE_5 = 0x45, + PE_6 = 0x46, + PE_7 = 0x47, + PE_8 = 0x48, + PE_9 = 0x49, + PE_10 = 0x4A, + PE_11 = 0x4B, + PE_12 = 0x4C, + PE_13 = 0x4D, + PE_14 = 0x4E, + PE_15 = 0x4F, + + PF_0 = 0x50, + PF_1 = 0x51, + PF_2 = 0x52, + PF_3 = 0x53, + PF_4 = 0x54, + PF_5 = 0x55, + PF_6 = 0x56, + PF_7 = 0x57, + PF_8 = 0x58, + PF_9 = 0x59, + PF_10 = 0x5A, + PF_11 = 0x5B, + PF_12 = 0x5C, + PF_13 = 0x5D, + PF_14 = 0x5E, + PF_15 = 0x5F, + + PG_0 = 0x60, + PG_1 = 0x61, + PG_2 = 0x62, + PG_3 = 0x63, + PG_4 = 0x64, + PG_5 = 0x65, + PG_6 = 0x66, + PG_7 = 0x67, + PG_8 = 0x68, + PG_9 = 0x69, + PG_10 = 0x6A, + PG_11 = 0x6B, + PG_12 = 0x6C, + PG_13 = 0x6D, + PG_14 = 0x6E, + PG_15 = 0x6F, + + PH_0 = 0x70, + PH_1 = 0x71, + PH_2 = 0x72, + + // Arduino connector namings + A0 = PA_0, + A1 = PA_1, + A2 = PA_4, + A3 = PB_0, + A4 = PC_1, + A5 = PC_0, + D0 = PA_3, + D1 = PA_2, + D2 = PA_10, + D3 = PB_3, + D4 = PB_5, + D5 = PB_4, + D6 = PB_10, + D7 = PA_8, + D8 = PA_9, + D9 = PC_7, + D10 = PB_6, + D11 = PA_7, + D12 = PA_6, + D13 = PA_5, + D14 = PB_9, + D15 = PB_8, + + // Generic signals namings + LED1 = PA_5, + LED2 = PA_5, + LED3 = PA_5, + LED4 = PA_5, + USER_BUTTON = PC_13, + SERIAL_TX = PA_2, + SERIAL_RX = PA_3, + I2C_SCL = PB_8, + I2C_SDA = PB_9, + SPI_MOSI = PA_7, + SPI_MISO = PA_6, + SPI_SCK = PA_5, + SPI_CS = PB_6, + PWM_OUT = PB_3, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullNone = 0, + PullUp = 1, + PullDown = 2, + OpenDrain = 3 +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PortNames.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PortNames.h new file mode 100644 index 0000000000..4f9af48f2c --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/PortNames.h @@ -0,0 +1,51 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PortA = 0, + PortB = 1, + PortC = 2, + PortD = 3, + PortE = 4, + PortF = 5, + PortG = 6, + PortH = 7 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/analogin_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/analogin_api.c new file mode 100644 index 0000000000..538a89fd24 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/analogin_api.c @@ -0,0 +1,142 @@ +/* mbed Microcontroller Library + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "analogin_api.h" +#include "wait_api.h" + +#if DEVICE_ANALOGIN + +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +static const PinMap PinMap_ADC[] = { + {PA_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AIN, 0)}, + {PA_1, ADC_1, STM_PIN_DATA(GPIO_Mode_AIN, 0)}, + {PA_4, ADC_1, STM_PIN_DATA(GPIO_Mode_AIN, 0)}, + {PB_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AIN, 0)}, + {PC_1, ADC_1, STM_PIN_DATA(GPIO_Mode_AIN, 0)}, + {PC_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AIN, 0)}, + {NC, NC, 0} +}; + +int adc_inited = 0; + +void analogin_init(analogin_t *obj, PinName pin) { + + ADC_TypeDef *adc; + ADC_InitTypeDef ADC_InitStructure; + + // Get the peripheral name (ADC_1, ADC_2...) from the pin and assign it to the object + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + + if (obj->adc == (ADCName)NC) { + error("ADC pin mapping failed"); + } + + // Configure GPIO + pinmap_pinout(pin, PinMap_ADC); + + // Save pin number for the read function + obj->pin = pin; + + // The ADC initialization is done once + if (adc_inited == 0) { + adc_inited = 1; + + // Get ADC registers structure address + adc = (ADC_TypeDef *)(obj->adc); + + // Enable ADC clock + RCC_ADCCLKConfig(RCC_PCLK2_Div4); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); + + // Configure ADC + ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; + ADC_InitStructure.ADC_ScanConvMode = DISABLE; + ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; + ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; + ADC_InitStructure.ADC_NbrOfChannel = 1; + ADC_Init(adc, &ADC_InitStructure); + + // Enable ADC + ADC_Cmd(adc, ENABLE); + + // Calibrate ADC + ADC_ResetCalibration(adc); + while(ADC_GetResetCalibrationStatus(adc)); + ADC_StartCalibration(adc); + while(ADC_GetCalibrationStatus(adc)); + } +} + +static inline uint16_t adc_read(analogin_t *obj) { + // Get ADC registers structure address + ADC_TypeDef *adc = (ADC_TypeDef *)(obj->adc); + + // Configure ADC channel + switch (obj->pin) { + case PA_0: + ADC_RegularChannelConfig(adc, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5); + break; + case PA_1: + ADC_RegularChannelConfig(adc, ADC_Channel_1, 1, ADC_SampleTime_7Cycles5); + break; + case PA_4: + ADC_RegularChannelConfig(adc, ADC_Channel_4, 1, ADC_SampleTime_7Cycles5); + break; + case PB_0: + ADC_RegularChannelConfig(adc, ADC_Channel_8, 1, ADC_SampleTime_7Cycles5); + break; + case PC_1: + ADC_RegularChannelConfig(adc, ADC_Channel_11, 1, ADC_SampleTime_7Cycles5); + break; + case PC_0: + ADC_RegularChannelConfig(adc, ADC_Channel_10, 1, ADC_SampleTime_7Cycles5); + break; + default: + return 0; + } + + ADC_SoftwareStartConvCmd(adc, ENABLE); // Start conversion + + while(ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion + + return(ADC_GetConversionValue(adc)); // Get conversion value +} + +uint16_t analogin_read_u16(analogin_t *obj) { + return(adc_read(obj)); +} + +float analogin_read(analogin_t *obj) { + uint16_t value = adc_read(obj); + return (float)value * (1.0f / (float)0xFFF); // 12 bits range +} + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/device.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/device.h new file mode 100644 index 0000000000..7bc2ff249c --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/device.h @@ -0,0 +1,70 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 0 + +#define DEVICE_ANALOGIN 0 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 0 + +#define DEVICE_I2C 0 +#define DEVICE_I2CSLAVE 0 + +#define DEVICE_SPI 0 +#define DEVICE_SPISLAVE 0 + +#define DEVICE_RTC 0 + +#define DEVICE_PWMOUT 0 + +#define DEVICE_SLEEP 0 + +//======================================= + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 24 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +//#define DEVICE_ERROR_RED 0 + +#include "objects.h" + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_api.c new file mode 100644 index 0000000000..85b83b720c --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_api.c @@ -0,0 +1,108 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "gpio_api.h" +#include "pinmap.h" +#include "error.h" + +uint32_t gpio_set(PinName pin) { + if (pin == NC) return 0; + + pin_function(pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0)); + + return (uint32_t)(1 << ((uint32_t)pin & 0xF)); // Return the pin mask +} + +void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) { + GPIO_TypeDef *gpio; + + if (pin == NC) return; + + // Get GPIO structure base address + uint32_t pin_number = (uint32_t)pin; + uint32_t port_index = (pin_number >> 4); + + switch (port_index) { + case 0: + gpio = (GPIO_TypeDef *)GPIOA_BASE; + break; + case 1: + gpio = (GPIO_TypeDef *)GPIOB_BASE; + break; + case 2: + gpio = (GPIO_TypeDef *)GPIOC_BASE; + break; + case 3: + gpio = (GPIO_TypeDef *)GPIOD_BASE; + break; + case 4: + gpio = (GPIO_TypeDef *)GPIOE_BASE; + break; + case 5: + gpio = (GPIO_TypeDef *)GPIOF_BASE; + break; + case 6: + gpio = (GPIO_TypeDef *)GPIOG_BASE; + break; + case 7: + gpio = (GPIO_TypeDef *)GPIOH_BASE; + break; + default: + error("GPIO port number is not correct."); + break; + } + + // Fill GPIO object structure for future use + obj->pin = pin; + obj->mask = gpio_set(pin); + obj->reg_in = &gpio->IDR; + obj->reg_set = &gpio->BSRRL; + obj->reg_clr = &gpio->BSRRH; + + // Configure GPIO + if (direction == PIN_OUTPUT) { + pin_function(pin, STM_PIN_DATA(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0)); + } + else { // PIN_INPUT + pin_function(pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0)); + } +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + if (direction == PIN_OUTPUT) { + pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0)); + } + else { // PIN_INPUT + pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0)); + } +} diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_irq_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_irq_api.c new file mode 100644 index 0000000000..5a53f2f624 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_irq_api.c @@ -0,0 +1,256 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include +#include "cmsis.h" + +#include "gpio_irq_api.h" +#include "error.h" + +#define EDGE_NONE (0) +#define EDGE_RISE (1) +#define EDGE_FALL (2) +#define EDGE_BOTH (3) + +#define CHANNEL_NUM (16) + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; + +static gpio_irq_handler irq_handler; + +static void handle_interrupt_in(uint32_t channel) { + if (channel_ids[channel] == 0) return; + + uint32_t exti_line = (uint32_t)(1 << channel); + if (EXTI_GetITStatus(exti_line) != RESET) + { + EXTI_ClearITPendingBit(exti_line); + } + + // Warning: + // On this device we don't know if a rising or falling event occured. + // In case both rise and fall events are set, only the FALL event will be reported. + if (EXTI->FTSR & (uint32_t)(1 << channel)) { + irq_handler(channel_ids[channel], IRQ_FALL); + } + else { + irq_handler(channel_ids[channel], IRQ_RISE); + } +} + +static void gpio_irq0(void) {handle_interrupt_in(0);} +static void gpio_irq1(void) {handle_interrupt_in(1);} +static void gpio_irq2(void) {handle_interrupt_in(2);} +static void gpio_irq3(void) {handle_interrupt_in(3);} +static void gpio_irq4(void) {handle_interrupt_in(4);} +static void gpio_irq5(void) {handle_interrupt_in(5);} +static void gpio_irq6(void) {handle_interrupt_in(6);} +static void gpio_irq7(void) {handle_interrupt_in(7);} +static void gpio_irq8(void) {handle_interrupt_in(8);} +static void gpio_irq9(void) {handle_interrupt_in(9);} +static void gpio_irq10(void) {handle_interrupt_in(10);} +static void gpio_irq11(void) {handle_interrupt_in(11);} +static void gpio_irq12(void) {handle_interrupt_in(12);} +static void gpio_irq13(void) {handle_interrupt_in(13);} +static void gpio_irq14(void) {handle_interrupt_in(14);} +static void gpio_irq15(void) {handle_interrupt_in(15);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + + if (pin == NC) return -1; + + uint32_t pin_number = (uint32_t)pin; + uint32_t pin_index = (pin_number & 0xF); + uint32_t port_index = (pin_number >> 4); + + // Select irq number and vector + switch (pin_index) { + case 0: + irq_n = EXTI0_IRQn; + vector = (uint32_t)&gpio_irq0; + break; + case 1: + irq_n = EXTI1_IRQn; + vector = (uint32_t)&gpio_irq1; + break; + case 2: + irq_n = EXTI2_IRQn; + vector = (uint32_t)&gpio_irq2; + break; + case 3: + irq_n = EXTI3_IRQn; + vector = (uint32_t)&gpio_irq3; + break; + case 4: + irq_n = EXTI4_IRQn; + vector = (uint32_t)&gpio_irq4; + break; + case 5: + irq_n = EXTI9_5_IRQn; + vector = (uint32_t)&gpio_irq5; + break; + case 6: + irq_n = EXTI9_5_IRQn; + vector = (uint32_t)&gpio_irq6; + break; + case 7: + irq_n = EXTI9_5_IRQn; + vector = (uint32_t)&gpio_irq7; + break; + case 8: + irq_n = EXTI9_5_IRQn; + vector = (uint32_t)&gpio_irq8; + break; + case 9: + irq_n = EXTI9_5_IRQn; + vector = (uint32_t)&gpio_irq9; + break; + case 10: + irq_n = EXTI15_10_IRQn; + vector = (uint32_t)&gpio_irq10; + break; + case 11: + irq_n = EXTI15_10_IRQn; + vector = (uint32_t)&gpio_irq11; + break; + case 12: + irq_n = EXTI15_10_IRQn; + vector = (uint32_t)&gpio_irq12; + break; + case 13: + irq_n = EXTI15_10_IRQn; + vector = (uint32_t)&gpio_irq13; + break; + case 14: + irq_n = EXTI15_10_IRQn; + vector = (uint32_t)&gpio_irq14; + break; + case 15: + irq_n = EXTI15_10_IRQn; + vector = (uint32_t)&gpio_irq15; + break; + default: + return -1; + } + + // Enable GPIO and AFIO clocks + RCC_APB2PeriphClockCmd((uint32_t)(RCC_APB2Periph_GPIOA << port_index), ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); + + // Connect EXTI line to pin + GPIO_EXTILineConfig(port_index, pin_index); + + // Configure EXTI line + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + // Enable and set EXTI interrupt to the lowest priority + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = irq_n; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + + // Save for future use + obj->ch = pin_index; + obj->irq_n = irq_n; + obj->event = EDGE_NONE; + + channel_ids[obj->ch] = id; + + irq_handler = handler; + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; + // Disable EXTI line + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_StructInit(&EXTI_InitStructure); + EXTI_Init(&EXTI_InitStructure); + obj->event = EDGE_NONE; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + EXTI_InitTypeDef EXTI_InitStructure; + + EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << obj->ch); + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + + if (event == IRQ_RISE) { + if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; + obj->event = EDGE_BOTH; + } + else { // NONE or RISE + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; + obj->event = EDGE_RISE; + } + } + + if (event == IRQ_FALL) { + if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; + obj->event = EDGE_BOTH; + } + else { // NONE or FALL + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; + obj->event = EDGE_FALL; + } + } + + if (enable) { + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + } + else { + EXTI_InitStructure.EXTI_LineCmd = DISABLE; + } + + EXTI_Init(&EXTI_InitStructure); +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ(obj->irq_n); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ(obj->irq_n); + obj->event = EDGE_NONE; +} diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_object.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_object.h new file mode 100644 index 0000000000..c8c380f492 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/gpio_object.h @@ -0,0 +1,67 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + __IO uint16_t *reg_in; + __IO uint16_t *reg_set; + __IO uint16_t *reg_clr; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + if (value) { + *obj->reg_set = obj->mask; + } + else { + *obj->reg_clr = obj->mask; + } +} + +static inline int gpio_read(gpio_t *obj) { + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/i2c_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/i2c_api.c new file mode 100644 index 0000000000..9fa5603a4a --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/i2c_api.c @@ -0,0 +1,337 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "i2c_api.h" + +#if DEVICE_I2C + +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +/* Timeout values for flags and events waiting loops. These timeouts are + not based on accurate values, they just guarantee that the application will + not remain stuck if the I2C communication is corrupted. */ +#define FLAG_TIMEOUT ((int)0x1000) +#define LONG_TIMEOUT ((int)0x8000) + +static const PinMap PinMap_I2C_SDA[] = { + {PB_9, I2C_1, STM_PIN_DATA(GPIO_Mode_AF_OD, 8)}, // GPIO_Remap_I2C1 + {NC, NC, 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {PB_8, I2C_1, STM_PIN_DATA(GPIO_Mode_AF_OD, 8)}, // GPIO_Remap_I2C1 + {NC, NC, 0} +}; + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // Determine the I2C to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + + obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl); + + if (obj->i2c == (I2CName)NC) { + error("I2C pin mapping failed"); + } + + // Enable I2C clock + if (obj->i2c == I2C_1) { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); + } + if (obj->i2c == I2C_2) { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); + } + + // Configure I2C pins + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); + pin_mode(sda, OpenDrain); + pin_mode(scl, OpenDrain); + + // Reset to clear pending flags if any + i2c_reset(obj); + + // I2C configuration + i2c_frequency(obj, 100000); // 100 kHz per default +} + +void i2c_frequency(i2c_t *obj, int hz) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + I2C_InitTypeDef I2C_InitStructure; + + if ((hz != 0) && (hz <= 400000)) { + // I2C configuration + I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; + I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; + I2C_InitStructure.I2C_OwnAddress1 = 0; + I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; + I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_InitStructure.I2C_ClockSpeed = hz; + I2C_Cmd(i2c, ENABLE); + I2C_Init(i2c, &I2C_InitStructure); + } +} + +inline int i2c_start(i2c_t *obj) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + int timeout; + + I2C_ClearFlag(i2c, I2C_FLAG_AF); // Clear Acknowledge failure flag + + // Generate the START condition + I2C_GenerateSTART(i2c, ENABLE); + + // Wait the START condition has been correctly sent + timeout = FLAG_TIMEOUT; + //while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_MODE_SELECT) == ERROR) { + while (I2C_GetFlagStatus(i2c, I2C_FLAG_SB) == RESET) { + if ((timeout--) == 0) { + return 1; + } + } + + return 0; +} + +inline int i2c_stop(i2c_t *obj) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + + I2C_GenerateSTOP(i2c, ENABLE); + + return 0; +} + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + int timeout; + int count; + int value; + + if (length == 0) return 0; + +/* + // Wait until the bus is not busy anymore + timeout = LONG_TIMEOUT; + while (I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY) == SET) { + if ((timeout--) == 0) { + return 0; + } + } +*/ + + i2c_start(obj); + + // Send slave address for read + I2C_Send7bitAddress(i2c, address, I2C_Direction_Receiver); + + // Wait address is acknowledged + timeout = FLAG_TIMEOUT; + while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == ERROR) { + if ((timeout--) == 0) { + return 0; + } + } + + // Read all bytes except last one + for (count = 0; count < (length - 1); count++) { + value = i2c_byte_read(obj, 0); + data[count] = (char)value; + } + + // If not repeated start, send stop. + // Warning: must be done BEFORE the data is read. + if (stop) { + i2c_stop(obj); + } + + // Read the last byte + value = i2c_byte_read(obj, 1); + data[count] = (char)value; + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + int timeout; + int count; + +/* + // Wait until the bus is not busy anymore + timeout = LONG_TIMEOUT; + while (I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY) == SET) { + if ((timeout--) == 0) { + return 0; + } + } +*/ + + i2c_start(obj); + + // Send slave address for write + I2C_Send7bitAddress(i2c, address, I2C_Direction_Transmitter); + + // Wait address is acknowledged + timeout = FLAG_TIMEOUT; + while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR) { + if ((timeout--) == 0) { + return 0; + } + } + + for (count = 0; count < length; count++) { + if (i2c_byte_write(obj, data[count]) != 1) { + i2c_stop(obj); + return 0; + } + } + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return count; +} + +int i2c_byte_read(i2c_t *obj, int last) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + uint8_t data; + int timeout; + + if (last) { + // Don't acknowledge the last byte + I2C_AcknowledgeConfig(i2c, DISABLE); + } else { + // Acknowledge the byte + I2C_AcknowledgeConfig(i2c, ENABLE); + } + + // Wait until the byte is received + timeout = FLAG_TIMEOUT; + while (I2C_GetFlagStatus(i2c, I2C_FLAG_RXNE) == RESET) { + if ((timeout--) == 0) { + return 0; + } + } + + data = I2C_ReceiveData(i2c); + + return (int)data; +} + +int i2c_byte_write(i2c_t *obj, int data) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + int timeout; + + I2C_SendData(i2c, (uint8_t)data); + + // Wait until the byte is transmitted + timeout = FLAG_TIMEOUT; + //while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR) { + while ((I2C_GetFlagStatus(i2c, I2C_FLAG_TXE) == RESET) && + (I2C_GetFlagStatus(i2c, I2C_FLAG_BTF) == RESET)) { + if ((timeout--) == 0) { + return 0; + } + } + + return 1; +} + +void i2c_reset(i2c_t *obj) { + if (obj->i2c == I2C_1) { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); + } + if (obj->i2c == I2C_2) { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); + } +} + +#if DEVICE_I2CSLAVE + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + uint16_t tmpreg; + + // Get the old register value + tmpreg = i2c->OAR1; + // Reset address bits + tmpreg &= 0xFC00; + // Set new address + tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits + // Store the new register value + i2c->OAR1 = tmpreg; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + // Nothing to do +} + +// See I2CSlave.h +#define NoData 0 // the slave has not been addressed +#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter) +#define WriteGeneral 2 // the master is writing to all slave +#define WriteAddressed 3 // the master is writing to this slave (slave = receiver) + +int i2c_slave_receive(i2c_t *obj) { + // TO BE DONE + return(0); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + + // Read all bytes + for (count = 0; count < length; count++) { + data[count] = i2c_byte_read(obj, 0); + } + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + + // Write all bytes + for (count = 0; count < length; count++) { + i2c_byte_write(obj, data[count]); + } + + return count; +} + + +#endif // DEVICE_I2CSLAVE + +#endif // DEVICE_I2C diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/objects.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/objects.h new file mode 100644 index 0000000000..d546e5137c --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/objects.h @@ -0,0 +1,97 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; + IRQn_Type irq_n; + uint32_t event; // 0=none, 1=rise, 2=fall, 3=rise+fall +}; + +struct port_s { + PortName port; + uint32_t mask; + PinDirection direction; + __IO uint16_t *reg_in; + __IO uint16_t *reg_out; +}; + +struct analogin_s { + ADCName adc; + PinName pin; +}; + +struct serial_s { + UARTName uart; + int index; // Used by irq + uint32_t baudrate; + uint32_t databits; + uint32_t stopbits; + uint32_t parity; +}; + +struct spi_s { + SPIName spi; + uint32_t bits; + uint32_t cpol; + uint32_t cpha; + uint32_t mode; + uint32_t nss; + uint32_t br_presc; +}; + +struct i2c_s { + I2CName i2c; +}; + +struct pwmout_s { + PWMName pwm; + PinName pin; + uint32_t period; + uint32_t pulse; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/pinmap.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/pinmap.c new file mode 100644 index 0000000000..e6b5ff591a --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/pinmap.c @@ -0,0 +1,171 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "pinmap.h" +#include "error.h" + +/** + * Configure pin (mode, speed, output type and pull-up/pull-down) + */ +void pin_function(PinName pin, int data) { + GPIO_TypeDef *gpio; + GPIO_InitTypeDef GPIO_InitStructure; + + if (pin == NC) return; + + // Get the pin informations + uint32_t mode = STM_PIN_MODE(data); + uint32_t otype = STM_PIN_OTYPE(data); + uint32_t pupd = STM_PIN_PUPD(data); + uint32_t afnum = STM_PIN_AFNUM(data); + + // Get GPIO structure base address and enable clock + uint32_t pin_number = (uint32_t)pin; + uint32_t pin_index = (pin_number & 0xF); + uint32_t port_index = (pin_number >> 4); + + switch (port_index) { + case 0: + gpio = (GPIO_TypeDef *)GPIOA_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); + break; + case 1: + gpio = (GPIO_TypeDef *)GPIOB_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); + break; + case 2: + gpio = (GPIO_TypeDef *)GPIOC_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); + break; + case 3: + gpio = (GPIO_TypeDef *)GPIOD_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); + break; + case 4: + gpio = (GPIO_TypeDef *)GPIOE_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE); + break; + case 5: + gpio = (GPIO_TypeDef *)GPIOF_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); + break; + case 6: + gpio = (GPIO_TypeDef *)GPIOG_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOG, ENABLE); + break; + case 7: + gpio = (GPIO_TypeDef *)GPIOH_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOH, ENABLE); + break; + default: + error("GPIO port number is not correct."); + break; + } + + // Configure GPIO + GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index); + GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)mode; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; + GPIO_InitStructure.GPIO_OType = (GPIOOType_TypeDef)otype; + GPIO_InitStructure.GPIO_PuPd = (GPIOPuPd_TypeDef)pupd; + GPIO_Init(gpio, &GPIO_InitStructure); + + // Configure Alternate Function + if (afnum > 0) { + GPIO_PinAFConfig(gpio, (uint16_t)(1 << pin_index), afnum); + } + + // *** TODO *** + // Disconnect JTAG-DP + SW-DP signals. + // Warning: Need to reconnect under reset + //if ((pin == PA_13) || (pin == PA_14)) { + // + //} + //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { + // + //} +} + +/** + * Configure pin pull-up/pull-down + */ +void pin_mode(PinName pin, PinMode mode) { + GPIO_TypeDef *gpio; + + if (pin == NC) return; + + // Get GPIO structure base address and enable clock + uint32_t pin_number = (uint32_t)pin; + uint32_t port_index = (pin_number >> 4); + + switch (port_index) { + case 0: + gpio = (GPIO_TypeDef *)GPIOA_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); + break; + case 1: + gpio = (GPIO_TypeDef *)GPIOB_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); + break; + case 2: + gpio = (GPIO_TypeDef *)GPIOC_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); + break; + case 3: + gpio = (GPIO_TypeDef *)GPIOD_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); + break; + case 4: + gpio = (GPIO_TypeDef *)GPIOE_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE); + break; + case 5: + gpio = (GPIO_TypeDef *)GPIOF_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); + break; + case 6: + gpio = (GPIO_TypeDef *)GPIOG_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOG, ENABLE); + break; + case 7: + gpio = (GPIO_TypeDef *)GPIOH_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOH, ENABLE); + break; + default: + error("GPIO port number is not correct."); + break; + } + + // Configure pull-up/pull-down resistors + uint32_t pupd = (uint32_t)mode; + if (pupd > 2) pupd = 0; // Open-drain = No pull-up/No pull-down + gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_number * 2))); + gpio->PUPDR |= (uint32_t)(pupd << (pin_number * 2)); + +} diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/port_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/port_api.c new file mode 100644 index 0000000000..ca90d93b9b --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/port_api.c @@ -0,0 +1,134 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" +#include "error.h" + +#if DEVICE_PORTIN || DEVICE_PORTOUT + +// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) +// low nibble = pin number +PinName port_pin(PortName port, int pin_n) { + return (PinName)(pin_n + (port << 4)); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + GPIO_TypeDef *gpio; + + uint32_t port_index = (uint32_t)port; + + // Get GPIO structure base address and enable clock + switch (port_index) { + case 0: + gpio = (GPIO_TypeDef *)GPIOA_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); + break; + case 1: + gpio = (GPIO_TypeDef *)GPIOB_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); + break; + case 2: + gpio = (GPIO_TypeDef *)GPIOC_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); + break; + case 3: + gpio = (GPIO_TypeDef *)GPIOD_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); + break; + case 4: + gpio = (GPIO_TypeDef *)GPIOE_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE); + break; + case 5: + gpio = (GPIO_TypeDef *)GPIOF_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); + break; + case 6: + gpio = (GPIO_TypeDef *)GPIOG_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOG, ENABLE); + break; + case 7: + gpio = (GPIO_TypeDef *)GPIOH_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOH, ENABLE); + break; + default: + error("GPIO port number is not correct."); + break; + } + + // Fill PORT object structure for future use + obj->port = port; + obj->mask = mask; + obj->direction = dir; + obj->reg_in = &gpio->IDR; + obj->reg_out = &gpio->ODR; + + port_dir(obj, dir); +} + +void port_dir(port_t *obj, PinDirection dir) { + uint32_t i; + obj->direction = dir; + for (i = 0; i < 16; i++) { // Process all pins + if (obj->mask & (1 << i)) { // If the pin is used + if (dir == PIN_OUTPUT) { + pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0)); + } + else { // PIN_INPUT + pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0)); + } + } + } +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + for (i = 0; i < 16; i++) { // Process all pins + if (obj->mask & (1 << i)) { // If the pin is used + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); +} + +int port_read(port_t *obj) { + if (obj->direction == PIN_OUTPUT) { + return (*obj->reg_out & obj->mask); + } + else { // PIN_INPUT + return (*obj->reg_in & obj->mask); + } +} + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/pwmout_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/pwmout_api.c new file mode 100644 index 0000000000..995cf58c5e --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/pwmout_api.c @@ -0,0 +1,175 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "pwmout_api.h" + +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +// Only TIM2 and TIM3 can be used (TIM1 and TIM4 are used by the us_ticker) +static const PinMap PinMap_PWM[] = { + // TIM2 default + //{PA_2, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM2_CH3 - ARDUINO D1 + //{PA_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM2_CH4 - ARDUINO D0 + // TIM2 full remap + {PB_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 5)}, // TIM2fr_CH2 - ARDUINO D3 + //{PB_10, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 5)}, // TIM2fr_CH3 - ARDUINO D6 + // TIM3 default + //{PA_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH1 - ARDUINO D12 + //{PA_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH2 - ARDUINO D11 + // TIM3 full remap + //{PC_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 6)}, // TIM3fr_CH2 - ARDUINO D9 + // TIM3 partial remap + {PB_4, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 7)}, // TIM3pr_CH1 - ARDUINO D5 + {NC, NC, 0} +}; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // Get the peripheral name from the pin and assign it to the object + obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + + if (obj->pwm == (PWMName)NC) { + error("PWM pinout mapping failed"); + } + + // Enable TIM clock + if (obj->pwm == PWM_2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); + if (obj->pwm == PWM_3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); + + // Configure GPIO + pinmap_pinout(pin, PinMap_PWM); + + obj->pin = pin; + obj->period = 0; + obj->pulse = 0; + + pwmout_period_us(obj, 20000); // 20 ms per default +} + +void pwmout_free(pwmout_t* obj) { + TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm); + TIM_DeInit(tim); +} + +void pwmout_write(pwmout_t* obj, float value) { + TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm); + TIM_OCInitTypeDef TIM_OCInitStructure; + + if (value < 0.0) { + value = 0.0; + } else if (value > 1.0) { + value = 1.0; + } + + //while(TIM_GetFlagStatus(tim, TIM_FLAG_Update) == RESET); + //TIM_ClearFlag(tim, TIM_FLAG_Update); + + obj->pulse = (uint32_t)((float)obj->period * value); + + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = obj->pulse; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + + // Configure channel 1 + if (obj->pin == PB_4) { + TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable); + TIM_OC1Init(tim, &TIM_OCInitStructure); + } + + // Configure channel 2 + if (obj->pin == PB_3) { + TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable); + TIM_OC2Init(tim, &TIM_OCInitStructure); + } + + // Configure channel 3 + //if (obj->pin == PB_10) { + // TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable); + // TIM_OC3Init(tim, &TIM_OCInitStructure); + //} + + // Configure channel 4 + //if (obj->pin == PA_3) { + // TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable); + // TIM_OC4Init(tim, &TIM_OCInitStructure); + //} +} + +float pwmout_read(pwmout_t* obj) { + float value = 0; + if (obj->period > 0) { + value = (float)(obj->pulse) / (float)(obj->period); + } + return ((value > 1.0) ? (1.0) : (value)); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +void pwmout_period_us(pwmout_t* obj, int us) { + TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm); + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + float dc = pwmout_read(obj); + + TIM_Cmd(tim, DISABLE); + + obj->period = us; + + TIM_TimeBaseStructure.TIM_Period = obj->period - 1; + TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure); + + // Set duty cycle again + pwmout_write(obj, dc); + + TIM_ARRPreloadConfig(tim, ENABLE); + TIM_Cmd(tim, ENABLE); +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + float value = (float)us / (float)obj->period; + pwmout_write(obj, value); +} diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/rtc_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/rtc_api.c new file mode 100644 index 0000000000..b3a88b10fa --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/rtc_api.c @@ -0,0 +1,86 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "rtc_api.h" + +static int rtc_inited = 0; + +void rtc_init(void) { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // Enable PWR and Backup clock + + PWR_BackupAccessCmd(ENABLE); // Allow access to Backup Domain + + BKP_DeInit(); // Reset Backup Domain + + // Uncomment these lines if you use the LSE + // Enable LSE and wait till it's ready + //RCC_LSEConfig(RCC_LSE_ON); + //while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {} + //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select LSE as RTC Clock Source + + // Uncomment these lines if you use the LSI + // Enable LSI and wait till it's ready + RCC_LSICmd(ENABLE); + while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} + RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select LSI as RTC Clock Source + + RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock + + RTC_WaitForSynchro(); // Wait for RTC registers synchronization + + RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished + + // Set RTC period to 1 sec + // For LSE: prescaler = RTCCLK/RTC period = 32768Hz/1Hz = 32768 + // For LSI: prescaler = RTCCLK/RTC period = 40000Hz/1Hz = 40000 + RTC_SetPrescaler(39999); + + RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished + + rtc_inited = 1; +} + +void rtc_free(void) { + RCC_DeInit(); // Resets the RCC clock configuration to the default reset state + rtc_inited = 0; +} + +int rtc_isenabled(void) { + return rtc_inited; +} + +time_t rtc_read(void) { + return (time_t)RTC_GetCounter(); +} + +void rtc_write(time_t t) { + RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished + RTC_SetCounter(t); // Change the current time + RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished +} diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/serial_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/serial_api.c new file mode 100644 index 0000000000..6d5eb9fbed --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/serial_api.c @@ -0,0 +1,280 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" +#include + +static const PinMap PinMap_UART_TX[] = { + {PA_9, UART_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, + {PA_2, UART_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {PA_10, UART_1, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)}, + {PA_3, UART_2, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)}, + {NC, NC, 0} +}; + +#define UART_NUM (2) + +static uint32_t serial_irq_ids[UART_NUM] = {0}; + +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +static void init_usart(serial_t *obj) { + USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); + USART_InitTypeDef USART_InitStructure; + + USART_Cmd(usart, DISABLE); + + USART_InitStructure.USART_BaudRate = obj->baudrate; + USART_InitStructure.USART_WordLength = obj->databits; + USART_InitStructure.USART_StopBits = obj->stopbits; + USART_InitStructure.USART_Parity = obj->parity; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_Init(usart, &USART_InitStructure); + + USART_Cmd(usart, ENABLE); +} + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + // Determine the UART to use (UART_1, UART_2, ...) + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + + // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object + obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + + if (obj->uart == (UARTName)NC) { + error("Serial pinout mapping failed"); + } + + // Enable USART clock + if (obj->uart == UART_1) { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + } + if (obj->uart == UART_2) { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); + } + + // Configure the UART pins + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // Configure UART + obj->baudrate = 9600; + obj->databits = USART_WordLength_8b; + obj->stopbits = USART_StopBits_1; + obj->parity = USART_Parity_No; + + init_usart(obj); + + // The index is used by irq + if (obj->uart == UART_1) obj->index = 0; + if (obj->uart == UART_2) obj->index = 1; + + // For stdio management + if (obj->uart == STDIO_UART) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } + +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +void serial_baud(serial_t *obj, int baudrate) { + obj->baudrate = baudrate; + init_usart(obj); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + if (data_bits == 8) { + obj->databits = USART_WordLength_8b; + } + else { + obj->databits = USART_WordLength_9b; + } + + switch (parity) { + case ParityOdd: + case ParityForced0: + obj->parity = USART_Parity_Odd; + break; + case ParityEven: + case ParityForced1: + obj->parity = USART_Parity_Even; + break; + default: // ParityNone + obj->parity = USART_Parity_No; + break; + } + + if (stop_bits == 2) { + obj->stopbits = USART_StopBits_2; + } + else { + obj->stopbits = USART_StopBits_1; + } + + init_usart(obj); +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ + +// not api +static void uart_irq(USART_TypeDef* usart, int id) { + if (serial_irq_ids[id] != 0) { + if (USART_GetITStatus(usart, USART_IT_TC) != RESET) { + irq_handler(serial_irq_ids[id], TxIrq); + USART_ClearITPendingBit(usart, USART_IT_TC); + } + if (USART_GetITStatus(usart, USART_IT_RXNE) != RESET) { + irq_handler(serial_irq_ids[id], RxIrq); + USART_ClearITPendingBit(usart, USART_IT_RXNE); + } + } +} + +static void uart1_irq(void) {uart_irq((USART_TypeDef*)UART_1, 0);} +static void uart2_irq(void) {uart_irq((USART_TypeDef*)UART_2, 1);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); + + if (obj->uart == UART_1) { + irq_n = USART1_IRQn; + vector = (uint32_t)&uart1_irq; + } + + if (obj->uart == UART_2) { + irq_n = USART2_IRQn; + vector = (uint32_t)&uart2_irq; + } + + if (enable) { + + if (irq == RxIrq) { + USART_ITConfig(usart, USART_IT_RXNE, ENABLE); + } + else { // TxIrq + USART_ITConfig(usart, USART_IT_TC, ENABLE); + } + + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + + } else { // disable + + int all_disabled = 0; + + if (irq == RxIrq) { + USART_ITConfig(usart, USART_IT_RXNE, DISABLE); + // Check if TxIrq is disabled too + if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1; + } + else { // TxIrq + USART_ITConfig(usart, USART_IT_TXE, DISABLE); + // Check if RxIrq is disabled too + if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; + } + + if (all_disabled) NVIC_DisableIRQ(irq_n); + + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ + +int serial_getc(serial_t *obj) { + USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); + while (!serial_readable(obj)); + return (int)(USART_ReceiveData(usart)); +} + +void serial_putc(serial_t *obj, int c) { + USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); + while (!serial_writable(obj)); + USART_SendData(usart, (uint16_t)c); +} + +int serial_readable(serial_t *obj) { + int status; + USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); + // Check if data is received + status = ((USART_GetFlagStatus(usart, USART_FLAG_RXNE) != RESET) ? 1 : 0); + return status; +} + +int serial_writable(serial_t *obj) { + int status; + USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); + // Check if data is transmitted + status = ((USART_GetFlagStatus(usart, USART_FLAG_TXE) != RESET) ? 1 : 0); + return status; +} + +void serial_clear(serial_t *obj) { + USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); + USART_ClearFlag(usart, USART_FLAG_TXE); + USART_ClearFlag(usart, USART_FLAG_RXNE); +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); + USART_SendBreak(usart); +} + +void serial_break_clear(serial_t *obj) { +} diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/sleep.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/sleep.c new file mode 100644 index 0000000000..bea4eb96c0 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/sleep.c @@ -0,0 +1,70 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "sleep_api.h" +#include "cmsis.h" + +// This function is only necessary if the HSE is used. +/* +static void SYSCLKConfig_STOP(void) +{ + ErrorStatus HSEStartUpStatus; + + RCC_HSEConfig(RCC_HSE_ON); // Enable HSE + + HSEStartUpStatus = RCC_WaitForHSEStartUp(); // Wait till HSE is ready + + if (HSEStartUpStatus == SUCCESS) { + RCC_PLLCmd(ENABLE); // Enable PLL + while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {} // Wait till PLL is ready + RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source + while(RCC_GetSYSCLKSource() != 0x08) {} // Wait till PLL is used as system clock source + } +} +*/ + +void sleep(void) +{ + SCB->SCR = 0; // Normal sleep mode for ARM core + __WFI(); +} + +void deepsleep(void) +{ + // Enable PWR clock + RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); + + // Request to enter STOP mode with regulator in low power mode + PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); + + // At this stage the system has resumed from STOP mode. + // Re-configure the system clock: enable HSE, PLL and select + // PLL as system clock source (because HSE and PLL are disabled in STOP mode). + //SYSCLKConfig_STOP(); +} diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/spi_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/spi_api.c new file mode 100644 index 0000000000..ad671e4c52 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/spi_api.c @@ -0,0 +1,261 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "spi_api.h" + +#if DEVICE_SPI + +#include +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +static const PinMap PinMap_SPI_MOSI[] = { + {PA_7, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, + {PB_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 1)}, // Remap + {NC, NC, 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {PA_6, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, + {PB_4, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 1)}, // Remap + {NC, NC, 0} +}; + +static const PinMap PinMap_SPI_SCLK[] = { + {PA_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, + {PB_3, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 1)}, // Remap + {NC, NC, 0} +}; + +// Only used in Slave mode +static const PinMap PinMap_SPI_SSEL[] = { + {PB_6, SPI_1, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)}, // Generic IO, not real H/W NSS pin + //{PA_4, SPI_1, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)}, + //{PA_15, SPI_1, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 1)}, // Remap + {NC, NC, 0} +}; + +static void init_spi(spi_t *obj) { + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + SPI_InitTypeDef SPI_InitStructure; + + SPI_Cmd(spi, DISABLE); + + SPI_InitStructure.SPI_Mode = obj->mode; + SPI_InitStructure.SPI_NSS = obj->nss; + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_DataSize = obj->bits; + SPI_InitStructure.SPI_CPOL = obj->cpol; + SPI_InitStructure.SPI_CPHA = obj->cpha; + SPI_InitStructure.SPI_BaudRatePrescaler = obj->br_presc; + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + SPI_Init(spi, &SPI_InitStructure); + + SPI_Cmd(spi, ENABLE); +} + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // Determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + + obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); + + if (obj->spi == (SPIName)NC) { + error("SPI pinout mapping failed"); + } + + // Enable SPI clock + if (obj->spi == SPI_1) { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); + } + if (obj->spi == SPI_2) { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); + } + + // Configure the SPI pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + + // Save new values + obj->bits = SPI_DataSize_8b; + obj->cpol = SPI_CPOL_Low; + obj->cpha = SPI_CPHA_1Edge; + obj->br_presc = SPI_BaudRatePrescaler_64; // Closest to 1MHz (72MHz/64 = 1.125MHz) + + if (ssel == NC) { // Master + obj->mode = SPI_Mode_Master; + obj->nss = SPI_NSS_Soft; + } + else { // Slave + pinmap_pinout(ssel, PinMap_SPI_SSEL); + obj->mode = SPI_Mode_Slave; + obj->nss = SPI_NSS_Soft; + } + + init_spi(obj); +} + +void spi_free(spi_t *obj) { + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + SPI_I2S_DeInit(spi); +} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + // Save new values + if (bits == 8) { + obj->bits = SPI_DataSize_8b; + } + else { + obj->bits = SPI_DataSize_16b; + } + + switch (mode) { + case 0: + obj->cpol = SPI_CPOL_Low; + obj->cpha = SPI_CPHA_1Edge; + break; + case 1: + obj->cpol = SPI_CPOL_Low; + obj->cpha = SPI_CPHA_2Edge; + break; + case 2: + obj->cpol = SPI_CPOL_High; + obj->cpha = SPI_CPHA_1Edge; + break; + default: + obj->cpol = SPI_CPOL_High; + obj->cpha = SPI_CPHA_2Edge; + break; + } + + if (slave == 0) { + obj->mode = SPI_Mode_Master; + obj->nss = SPI_NSS_Soft; + } + else { + obj->mode = SPI_Mode_Slave; + obj->nss = SPI_NSS_Hard; + } + + init_spi(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + // Get SPI clock frequency + uint32_t PCLK = SystemCoreClock >> 1; + + // Choose the baud rate divisor (between 2 and 256) + uint32_t divisor = PCLK / hz; + + // Find the nearest power-of-2 + divisor = (divisor > 0 ? divisor-1 : 0); + divisor |= divisor >> 1; + divisor |= divisor >> 2; + divisor |= divisor >> 4; + divisor |= divisor >> 8; + divisor |= divisor >> 16; + divisor++; + + uint32_t baud_rate = __builtin_ffs(divisor) - 2; + + // Save new value + obj->br_presc = ((baud_rate > 7) ? (7 << 3) : (baud_rate << 3)); + + init_spi(obj); +} + +static inline int ssp_readable(spi_t *obj) { + int status; + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + // Check if data is received + status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_RXNE) != RESET) ? 1 : 0); + return status; +} + +static inline int ssp_writeable(spi_t *obj) { + int status; + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + // Check if data is transmitted + status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_TXE) != RESET) ? 1 : 0); + return status; +} + +static inline void ssp_write(spi_t *obj, int value) { + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + while (!ssp_writeable(obj)); + SPI_I2S_SendData(spi, (uint16_t)value); +} + +static inline int ssp_read(spi_t *obj) { + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + while (!ssp_readable(obj)); + return (int)SPI_I2S_ReceiveData(spi); +} + +static inline int ssp_busy(spi_t *obj) { + int status; + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_BSY) != RESET) ? 1 : 0); + return status; +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +}; + +int spi_slave_read(spi_t *obj) { + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + return (int)SPI_I2S_ReceiveData(spi); +} + +void spi_slave_write(spi_t *obj, int value) { + SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); + while (!ssp_writeable(obj)); + SPI_I2S_SendData(spi, (uint16_t)value); +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/us_ticker.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/us_ticker.c new file mode 100644 index 0000000000..6a1f20ae70 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/us_ticker.c @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; + + if (us_ticker_inited) return; + us_ticker_inited = 1; + + // Enable Timers clock + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); + + // Time base configuration + // TIM3 is used as "master", "TIM4" as "slave". TIM4 is clocked by TIM3. + TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); + TIM_TimeBaseStructure.TIM_Period = 0xFFFF; + TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); + TIM_TimeBaseStructure.TIM_Prescaler = 0; + TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); + + // Master timer configuration + TIM_OCStructInit(&TIM_OCInitStructure); + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OC1Init(TIM3, &TIM_OCInitStructure); + TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); + TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); + + // Slave timer configuration + TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1); + TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2); // Warning: connection between TIM3 and TIM4 + + // Enable timers + TIM_Cmd(TIM4, ENABLE); + TIM_Cmd(TIM3, ENABLE); +} + +uint32_t us_ticker_read() { + uint32_t counter, counter2; + if (!us_ticker_inited) us_ticker_init(); + // A situation might appear when Master overflows right after Slave is read and before the + // new (overflowed) value of Master is read. Which would make the code below consider the + // previous (incorrect) value of Slave and the new value of Master, which would return a + // value in the past. Avoid this by computing consecutive values of the timer until they + // are properly ordered. + counter = counter2 = (uint32_t)((uint32_t)TIM_GetCounter(TIM4) << 16) + (uint32_t)TIM_GetCounter(TIM3); + while (1) { + counter2 = (uint32_t)((uint32_t)TIM_GetCounter(TIM4) << 16) + (uint32_t)TIM_GetCounter(TIM3); + if (counter2 > counter) { + break; + } + counter = counter2; + } + return counter2; +} + +void us_ticker_set_interrupt(unsigned int timestamp) { + if (timestamp > 0xFFFF) { + TIM_SetCompare1(TIM4, (uint16_t)((timestamp >> 16) & 0xFFFF)); + TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE); + NVIC_SetVector(TIM4_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(TIM4_IRQn); + } + else { + TIM_SetCompare1(TIM3, (uint16_t)timestamp); + TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); + NVIC_SetVector(TIM3_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(TIM3_IRQn); + } +} + +void us_ticker_disable_interrupt(void) { + TIM_ITConfig(TIM3, TIM_IT_CC1, DISABLE); + TIM_ITConfig(TIM4, TIM_IT_CC1, DISABLE); +} + +void us_ticker_clear_interrupt(void) { + TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); + TIM_ClearITPendingBit(TIM4, TIM_IT_CC1); +} diff --git a/workspace_tools/build_release.py b/workspace_tools/build_release.py index 3092f5d5a4..d3093e5b5c 100644 --- a/workspace_tools/build_release.py +++ b/workspace_tools/build_release.py @@ -35,8 +35,11 @@ OFFICIAL_MBED_LIBRARY_BUILD = ( ('LPC4088', ('ARM', 'GCC_ARM', 'GCC_CR')), ('LPC1114', ('uARM',)), ('KL46Z', ('ARM', 'GCC_ARM')), - ('NUCLEO_F103RB', ('ARM',)), ('LPC11U35_401', ('ARM', 'uARM')), + ('NUCLEO_F103RB', ('ARM',)), + ('NUCLEO_L152RE', ('ARM',)), + ('NUCLEO_F401RE', ('ARM',)), + ('NUCLEO_F030R8', ('ARM',)), ) diff --git a/workspace_tools/export/iar.py b/workspace_tools/export/iar.py index 8803f1d883..1fd7db8dd2 100644 --- a/workspace_tools/export/iar.py +++ b/workspace_tools/export/iar.py @@ -19,7 +19,7 @@ from exporters import Exporter class IAREmbeddedWorkbench(Exporter): NAME = 'IAR' - TARGETS = ['LPC1768'] + TARGETS = ['LPC1768', 'NUCLEO_F401RE'] TOOLCHAIN = 'IAR' def generate(self): diff --git a/workspace_tools/export/uvision4.py b/workspace_tools/export/uvision4.py index 7954489603..88a403c2b4 100644 --- a/workspace_tools/export/uvision4.py +++ b/workspace_tools/export/uvision4.py @@ -21,9 +21,9 @@ from os.path import basename class Uvision4(Exporter): NAME = 'uVision4' - TARGETS = ['LPC1768', 'LPC11U24', 'KL05Z', 'KL25Z', 'KL46Z', 'K20D5M', 'LPC1347', 'LPC1114', 'LPC11C24', 'LPC4088', 'LPC812', 'NUCLEO_F103RB'] + TARGETS = ['LPC1768', 'LPC11U24', 'KL05Z', 'KL25Z', 'KL46Z', 'K20D5M', 'LPC1347', 'LPC1114', 'LPC11C24', 'LPC4088', 'LPC812', 'NUCLEO_F103RB', 'NUCLEO_L152RE', 'NUCLEO_F030R8'] - USING_MICROLIB = ['LPC11U24', 'LPC1114', 'LPC11C24', 'LPC812', 'NUCLEO_F103RB'] + USING_MICROLIB = ['LPC11U24', 'LPC1114', 'LPC11C24', 'LPC812', 'NUCLEO_F103RB', 'NUCLEO_L152RE', 'NUCLEO_F030R8'] FILE_TYPES = { 'c_sources':'1', diff --git a/workspace_tools/export/uvision4_nucleo_l152re.uvopt.tmpl b/workspace_tools/export/uvision4_nucleo_l152re.uvopt.tmpl new file mode 100644 index 0000000000..5fba3232fd --- /dev/null +++ b/workspace_tools/export/uvision4_nucleo_l152re.uvopt.tmpl @@ -0,0 +1,235 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + + + + 0 + 0 + + + + mbed NUCLEO_L152RE + 0x4 + ARM-ADS + + 8000000 + + 1 + 1 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + + 0 + Datasheet + DATASHTS\ST\STM32L151_152xE_DS.PDF + + + 1 + Technical Reference Manual + datashts\arm\cortex_m3\r1p1\DDI0337E_CORTEX_M3_R1P1_TRM.PDF + + + 2 + Generic User Guide + datashts\arm\cortex_m3\r2p1\DUI0552A_CORTEX_M3_DGUG.PDF + + + + SARMCM3.DLL + + DARMSTM.DLL + -pSTM32L152RE + SARMCM3.DLL + + TARMSTM.DLL + -pSTM32L152RE + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 13 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(111=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(180=-1,-1,-1,-1,0)(120=-1,-1,-1,-1,0)(121=-1,-1,-1,-1,0)(122=-1,-1,-1,-1,0)(123=-1,-1,-1,-1,0)(140=-1,-1,-1,-1,0)(240=-1,-1,-1,-1,0)(190=-1,-1,-1,-1,0)(200=-1,-1,-1,-1,0)(170=-1,-1,-1,-1,0)(130=-1,-1,-1,-1,0)(131=-1,-1,-1,-1,0)(132=-1,-1,-1,-1,0)(133=-1,-1,-1,-1,0)(160=-1,-1,-1,-1,0)(161=-1,-1,-1,-1,0)(162=-1,-1,-1,-1,0)(210=-1,-1,-1,-1,0)(211=-1,-1,-1,-1,0)(220=-1,-1,-1,-1,0)(221=-1,-1,-1,-1,0)(230=-1,-1,-1,-1,0)(231=-1,-1,-1,-1,0)(232=-1,-1,-1,-1,0)(233=-1,-1,-1,-1,0)(150=-1,-1,-1,-1,0)(151=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -S3 -C0 -N00("ARM CoreSight SW-DP") -D00(1BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32F10x_128 -FS08000000 -FL020000 + + + 0 + UL2CM3 + UL2CM3(-O14 -S0 -C0 -N00("ARM Cortex-M3") -D00(1BA00477) -L00(4) -FO7 -FN1 -FC800 -FD20000000 -FF0STM32F10x_128 -FL020000 -FS08000000 + + + 0 + ULP2CM3 + -O2510 -S0 -C0 -FO15 -FN1 -FC800 -FD20000000 -FF0MK_P128_48MHZ -FL020000 -FS00 + + + 0 + CMSIS_AGDI + -X"MBED CMSIS-DAP" -UA000000001 -O462 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -FO15 -FD20000000 -FC800 -FN1 -FF0MK_P128_48MHZ -FS00 -FL020000 + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + src + 1 + 0 + 0 + 0 + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + main.cpp + main.cpp + 0 + 0 + + + +
diff --git a/workspace_tools/export/uvision4_nucleo_l152re.uvproj.tmpl b/workspace_tools/export/uvision4_nucleo_l152re.uvproj.tmpl new file mode 100644 index 0000000000..3c157f2112 --- /dev/null +++ b/workspace_tools/export/uvision4_nucleo_l152re.uvproj.tmpl @@ -0,0 +1,432 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + mbed NUCLEO_L152RE + 0x4 + ARM-ADS + + + STM32L152RE + STMicroelectronics + IRAM(0x20000000-0x20003FFF) IROM(0x8000000-0x801FFFF) CLOCK(8000000) CPUTYPE("Cortex-M3") + + "STARTUP\ST\STM32L1xx\startup_stm32l1xx_hd.s" ("STM32L15xx High density Startup Code") + UL2CM3(-O14 -S0 -C0 -N00("ARM Cortex-M3") -D00(1BA00477) -L00(4) -FO7 -FD20000000 -FC800 -FN1 -FF0STM32L15x_128 -FS08000000 -FL020000) + 5249 + stm32l1xx.h + + + + + + + + + + SFD\ST\STM32L15x\STM32L15x.sfr + 0 + + + + ST\STM32L1xx\ + ST\STM32L1xx\ + + 0 + 0 + 0 + 0 + 1 + + .\build\ + {{name}} + 1 + 0 + 0 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 1 + 0 + fromelf --bin -o build\{{name}}_NUCLEO_L152RE.bin build\{{name}}.axf + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + + + SARMCM3.DLL + + DARMSTM.DLL + -pSTM32L152RE + SARMCM3.DLL + + TARMSTM.DLL + -pSTM32L152RE + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + + 0 + 13 + + + + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4104 + + 1 + BIN\CMSIS_AGDI.dll + "" () + + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M3" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x4000 + + + 1 + 0x8000000 + 0x20000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x20000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x4000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + --gnu + {% for s in symbols %} {{s}}, {% endfor %} + + {% for path in include_paths %} {{path}}; {% endfor %} + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x10000000 + {{scatter_file}} + + + + {% for file in object_files %} + {{file}} + {% endfor %} + + + + + + + + {% for group,files in source_files %} + + {{group}} + + {% for file in files %} + + {{file.name}} + {{file.type}} + {{file.path}} + + + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + + + + + {% endfor %} + + + {% endfor %} + + + + +
diff --git a/workspace_tools/export_test.py b/workspace_tools/export_test.py index ff414afc13..caafaffddd 100644 --- a/workspace_tools/export_test.py +++ b/workspace_tools/export_test.py @@ -77,7 +77,7 @@ if __name__ == '__main__': for toolchain, target in [ ('uvision', 'LPC1768'), ('uvision', 'LPC11U24'), ('uvision', 'KL25Z'), ('uvision', 'LPC1347'), ('uvision', 'LPC1114'), ('uvision', 'LPC4088'), - ('uvision', 'NUCLEO_F103RB'), + ('uvision', 'NUCLEO_F103RB'), ('uvision', 'NUCLEO_L152RE'), ('uvision', 'NUCLEO_F401RE'), ('uvision', 'NUCLEO_F030R8'), ('codered', 'LPC1768'), ('codered', 'LPC4088'), diff --git a/workspace_tools/targets.py b/workspace_tools/targets.py index cdae34a3c6..c3bf5d20e8 100644 --- a/workspace_tools/targets.py +++ b/workspace_tools/targets.py @@ -267,11 +267,44 @@ class NUCLEO_F103RB(Target): self.core = "Cortex-M3" - self.extra_labels = ['STM', 'STM32F10X', 'STM32F103RB'] + self.extra_labels = ['STM', 'STM32F1', 'STM32F103RB'] self.supported_toolchains = ["ARM", "uARM", "GCC_ARM"] +class NUCLEO_L152RE(Target): + def __init__(self): + Target.__init__(self) + + self.core = "Cortex-M3" + + self.extra_labels = ['STM', 'STM32L1', 'STM32L152RE'] + + self.supported_toolchains = ["ARM", "uARM", "GCC_ARM"] + + +class NUCLEO_F401RE(Target): + def __init__(self): + Target.__init__(self) + + self.core = "Cortex-M4" + + self.extra_labels = ['STM', 'STM32F4', 'STM32F401RE'] + + self.supported_toolchains = ["ARM", "uARM", "GCC_ARM"] + + +class NUCLEO_F030R8(Target): + def __init__(self): + Target.__init__(self) + + self.core = "Cortex-M0" + + self.extra_labels = ['STM', 'STM32F0', 'STM32F030R8'] + + self.supported_toolchains = ["ARM", "uARM", "GCC_ARM"] + + class MBED_MCU(Target): def __init__(self): Target.__init__(self) @@ -354,6 +387,9 @@ TARGETS = [ LPC4330_M4(), STM32F407(), NUCLEO_F103RB(), + NUCLEO_L152RE(), + NUCLEO_F401RE(), + NUCLEO_F030R8(), MBED_MCU(), LPC1347(), LPC1114(),