From 2707dfb87d5fcc7373d149409fb211456b7e7b0d Mon Sep 17 00:00:00 2001 From: Edmund Hsu Date: Fri, 20 Apr 2018 15:45:26 +1000 Subject: [PATCH 01/46] EV_COG_AD4050LZ: Rework linker scripts to support bootloader - fix compiler warning message of flash_api.c - fix compiler warning message of startup_ADuCM4050.c - eliminate absolute address of ROM tables - add MBED_APP_START and MBED_APP_SIZE to linker scripts --- .../device/startup_ADuCM4050.c | 19 ++++----- .../device/startup_ADuCM4050.h | 40 ++++++++++++------- .../TOOLCHAIN_ARM_STD/ADuCM4050.sct | 27 ++++++++++--- .../TOOLCHAIN_GCC_ARM/ADuCM4050.ld | 25 +++++++----- .../TOOLCHAIN_IAR/ADuCM4050.icf | 21 ++++++++-- .../TARGET_ADUCM4050/api/cmsis_nvic.h | 3 +- .../TARGET_ADUCM4050/api/flash_api.c | 4 +- 7 files changed, 88 insertions(+), 51 deletions(-) diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TARGET_EV_COG_AD4050LZ/device/startup_ADuCM4050.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TARGET_EV_COG_AD4050LZ/device/startup_ADuCM4050.c index 3c06ae2b24..c9ff9816e0 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TARGET_EV_COG_AD4050LZ/device/startup_ADuCM4050.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TARGET_EV_COG_AD4050LZ/device/startup_ADuCM4050.c @@ -6,7 +6,7 @@ * @date: $Date: $ *----------------------------------------------------------------------------- * -Copyright (c) 2010-2017 Analog Devices, Inc. +Copyright (c) 2010-2018 Analog Devices, Inc. All rights reserved. @@ -45,19 +45,22 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ #ifdef __ARMCC_VERSION -#include #include #endif #include #include #include +/*---------------------------------------------------------------------------- + External function Declaration + *----------------------------------------------------------------------------*/ +extern void SramInit(void); + /*---------------------------------------------------------------------------- Checksum options *----------------------------------------------------------------------------*/ -#if defined (__ARMCC_VERSION) -__attribute__((section(".ARM.__at_0x000001A0"))) -#elif defined(__ICCARM__) + +#if defined(__ICCARM__) __root #endif const uint32_t SECTION_PLACE(blank_checksum[],".checksum") = @@ -65,12 +68,6 @@ const uint32_t SECTION_PLACE(blank_checksum[],".checksum") = BLANKX60,BLANKX600 }; - -/*---------------------------------------------------------------------------- - External function Declaration - *----------------------------------------------------------------------------*/ -extern void SramInit(void); - /*---------------------------------------------------------------------------- Exception / Interrupt Handler *----------------------------------------------------------------------------*/ diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TARGET_EV_COG_AD4050LZ/device/startup_ADuCM4050.h b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TARGET_EV_COG_AD4050LZ/device/startup_ADuCM4050.h index d148540763..77a728fd42 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TARGET_EV_COG_AD4050LZ/device/startup_ADuCM4050.h +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TARGET_EV_COG_AD4050LZ/device/startup_ADuCM4050.h @@ -7,7 +7,7 @@ * @date: $Date: $ *----------------------------------------------------------------------------- * -Copyright (c) 2010-2017 Analog Devices, Inc. +Copyright (c) 2010-2018 Analog Devices, Inc. All rights reserved. @@ -63,6 +63,9 @@ RESET_EXCPT_HNDLR #include #define VECTOR_SECTION ".vectors" +/* IVT typedefs. */ +typedef void( *pFunc )( void ); + #ifdef __ARMCC_VERSION void Default_Handler(void); #define SECTION_NAME(sectionname) __attribute__((section(sectionname))) @@ -71,6 +74,9 @@ void Default_Handler(void); #define RESET_EXCPT_HNDLR __main #define COMPILER_NAME "ARMCC" #define WEAK_FUNCTION(x) void x (void) __attribute__((weak, alias("Default_Handler"))); +extern uint32_t Load$$LR$$LR_IROM1$$Base[]; +#define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)Load$$LR$$LR_IROM1$$Base) + #elif defined(__ICCARM__) /* * IAR MISRA C 2004 error suppressions: @@ -89,17 +95,20 @@ void Default_Handler(void); #define RESET_EXCPT_HNDLR __iar_program_start #define COMPILER_NAME "ICCARM" #define WEAK_FUNCTION(x) WEAK_FUNC ( void x (void)) { while(1){} } +#pragma section=VECTOR_SECTION +#define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)__section_begin(VECTOR_SECTION)) + #elif defined(__GNUC__) -extern unsigned __etext; -extern unsigned __data_start__; -extern unsigned __data_end__; -extern unsigned __copy_table_start__; -extern unsigned __copy_table_end__; -extern unsigned __zero_table_start__; -extern unsigned __zero_table_end__; -extern unsigned __bss_start__; -extern unsigned __bss_end__; -extern unsigned __StackTop; +extern uint32_t __etext; +extern uint32_t __data_start__; +extern uint32_t __data_end__; +extern uint32_t __copy_table_start__; +extern uint32_t __copy_table_end__; +extern uint32_t __zero_table_start__; +extern uint32_t __zero_table_end__; +extern uint32_t __bss_start__; +extern uint32_t __bss_end__; +extern uint32_t __StackTop; void Default_Handler(void); /*---------------------------------------------------------------------------- External References @@ -112,18 +121,21 @@ extern int __START(void) __attribute__((noreturn)); /* main entry point */ #define RESET_EXCPT_HNDLR __START #endif #ifndef __STACK_SIZE -#define __STACK_SIZE 0x00000400 +#define __STACK_SIZE 0x00000400 #endif #if !defined(__HEAP_SIZE) || (__HEAP_SIZE <= 0) -#define __HEAP_SIZE 0x00000C00 +#define __HEAP_SIZE 0x00000C00 #endif #define SECTION_NAME(sectionname) __attribute__ ((section(sectionname))) #define SECTION_PLACE(def,sectionname) def __attribute__ ((section(sectionname))) #define IVT_NAME __Vectors #define COMPILER_NAME "GNUC" #define WEAK_FUNCTION(x) void x (void) __attribute__ ((weak, alias("Default_Handler"))); +extern const pFunc IVT_NAME[]; +#define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)IVT_NAME) #define __STARTUP_CLEAR_BSS_MULTIPLE #endif // __GNUC__ + #define LASTCRCPAGE 0 #define BLANKX4 0xFFFFFFFF #define BLANKX20 BLANKX4,BLANKX4,BLANKX4,BLANKX4,BLANKX4,BLANKX4,BLANKX4,BLANKX4 @@ -132,8 +144,6 @@ extern int __START(void) __attribute__((noreturn)); /* main entry point */ #define BLANKX60 BLANKX20,BLANKX20,BLANKX20 void RESET_EXCPT_HNDLR(void); void Reset_Handler(void); -/* IVT typedefs. */ -typedef void( *pFunc )( void ); #define ADUCM4050_VECTORS \ /* Configure Initial Stack Pointer, using linker-generated symbols */\ diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_ARM_STD/ADuCM4050.sct b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_ARM_STD/ADuCM4050.sct index 0f7791ae5e..0cc6ed3835 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_ARM_STD/ADuCM4050.sct +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_ARM_STD/ADuCM4050.sct @@ -1,9 +1,10 @@ +#! armcc -E ;****************************************************************************** ; File: ADuCM4050.sct ; Scatter loading file for Analog Devices ADuCM4050 processor ; ; Copyright (c) 2011 - 2014 ARM LIMITED -; Copyright (c) 2016 - 2017 Analog Devices, Inc. +; Copyright (c) 2016 - 2018 Analog Devices, Inc. ; ; All rights reserved. ; Redistribution and use in source and binary forms, with or without @@ -29,14 +30,28 @@ ; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ; POSSIBILITY OF SUCH DAMAGE. ;****************************************************************************** -LR_IROM1 0x00000000 0x0007F000 { - FLASH0 0x00000000 0x00000800 { +#if !defined(MBED_APP_START) + #define MBED_APP_START 0 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x7F000 +#endif + +#define ADUCM_SECTOR_SIZE 0x800 + +#define ADUCM_VECTOR_SIZE 0x1A0 + +LR_IROM1 MBED_APP_START MBED_APP_SIZE { + FLASH0 MBED_APP_START ADUCM_VECTOR_SIZE { *(.vectors, +First) - *(.checksum) } - ER_IROM1 AlignExpr(ImageLimit(FLASH0), 16) 0x0007E800 { - ; load address = execution address + FLASH1 (MBED_APP_START + ADUCM_VECTOR_SIZE) (ADUCM_SECTOR_SIZE - ADUCM_VECTOR_SIZE) { + *(.checksum, +Last) + } + + ER_IROM1 (MBED_APP_START + ADUCM_SECTOR_SIZE) (MBED_APP_SIZE - ADUCM_SECTOR_SIZE) { *(InRoot$$Sections) *(+RO) } diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_GCC_ARM/ADuCM4050.ld b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_GCC_ARM/ADuCM4050.ld index 2ead54a157..4da717f2c6 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_GCC_ARM/ADuCM4050.ld +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_GCC_ARM/ADuCM4050.ld @@ -1,17 +1,27 @@ /* - * Portions Copyright (c) 2016 Analog Devices, Inc. + * Portions Copyright (c) 2016 - 2018 Analog Devices, Inc. * * Based on Device/ARM/ARMCM4/Source/GCC/gcc_arm.ld file in * ARM.CMSIS.4.5.0.pack. */ +#if !defined(MBED_APP_START) + #define MBED_APP_START 0 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x7F000 +#endif + +#define ADUCM_SECTOR_SIZE 0x800 + /* Linker script to configure memory regions. */ MEMORY { /* The first 0x800 bytes of flash */ - FLASH0 (rx) : ORIGIN = 0x00000000, LENGTH = 0x800 - /* The remaining bytes of flash minus 4KB Protected Key Storage */ - FLASH (rx) : ORIGIN = 0x00000800, LENGTH = 512k - 4k - 0x800 + FLASH0 (rx) : ORIGIN = MBED_APP_START, LENGTH = ADUCM_SECTOR_SIZE + /* The rest of the flash */ + FLASH (rx) : ORIGIN = MBED_APP_START + ADUCM_SECTOR_SIZE, LENGTH = MBED_APP_SIZE - ADUCM_SECTOR_SIZE /* SRAM bank 0 */ DSRAM_A (rwx) : ORIGIN = 0x20000200, LENGTH = 32k - 0x200 /* SRAM bank 3+4+5+6+7 */ @@ -76,13 +86,6 @@ SECTIONS KEEP(*(.checksum)) } > FLASH0 - .security_options : - { - . = ALIGN(4); - KEEP(*(.security_options)) - . = ALIGN(4); - } > FLASH0 - .text : { *(.text*) diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_IAR/ADuCM4050.icf b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_IAR/ADuCM4050.icf index 318ad52023..1956e65b47 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_IAR/ADuCM4050.icf +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/TOOLCHAIN_IAR/ADuCM4050.icf @@ -3,7 +3,7 @@ * ILINK Configuration File for Analog Devices ADuCM4050 processor * * Copyright (c) 2011 - 2014 ARM LIMITED -* Copyright (c) 2016 - 2017 Analog Devices, Inc. +* Copyright (c) 2016 - 2018 Analog Devices, Inc. * * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -29,10 +29,23 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ + +if (!isdefinedsymbol(MBED_APP_START)) { + define symbol MBED_APP_START = 0; +} + +if (!isdefinedsymbol(MBED_APP_SIZE)) { + define symbol MBED_APP_SIZE = 0x7F000; +} + +define symbol ADUCM_SECTOR_SIZE = 0x800; + +define symbol ADUCM_VECTOR_SIZE = 0x1A0; + define memory mem with size = 4G; -define region ROM_PAGE0_INTVEC = mem:[from 0x00000000 size 0x000001A0]; -define region ROM_PAGE0_CHECKSUM = mem:[from 0x000001A0 size 0x00000660]; -define region ROM_REGION = mem:[from 0x00000800 size 506K]; +define region ROM_PAGE0_INTVEC = mem:[from MBED_APP_START size ADUCM_VECTOR_SIZE]; +define region ROM_PAGE0_CHECKSUM = mem:[from MBED_APP_START+ADUCM_VECTOR_SIZE size ADUCM_SECTOR_SIZE-ADUCM_VECTOR_SIZE]; +define region ROM_REGION = mem:[from MBED_APP_START+ADUCM_SECTOR_SIZE size MBED_APP_SIZE-ADUCM_SECTOR_SIZE]; define region RAM_bank1_region = mem:[from 0x20040000 size 0x00008000]; define region RAM_bank2_region = mem:[from 0x20000200 size 0x00007E00] | mem:[from 0x20048000 size 0x00010000]; diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/cmsis_nvic.h b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/cmsis_nvic.h index 3a866a5d72..6c242dfa07 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/cmsis_nvic.h +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/cmsis_nvic.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010-2017 Analog Devices, Inc. + * Copyright (c) 2010-2018 Analog Devices, Inc. * * All rights reserved. * @@ -48,7 +48,6 @@ #define NVIC_NUM_VECTORS (NVIC_USER_IRQ_OFFSET + NVIC_USER_IRQ_NUMBER) #define NVIC_RAM_VECTOR_ADDRESS 0x20000000 -#define NVIC_FLASH_VECTOR_ADDRESS 0x0 #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/flash_api.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/flash_api.c index 2779c4cb5a..c29cdb8255 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/flash_api.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/flash_api.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010-2017 Analog Devices, Inc. + * Copyright (c) 2010-2018 Analog Devices, Inc. * * All rights reserved. * @@ -66,7 +66,7 @@ static const flash_algo_t flash_algo_config = { .erase_sector = 0x00000057, .program_page = 0x0000007F, .static_base = 0x0000013C, - .algo_blob = FLASH_ALGO + .algo_blob = (uint32_t *)FLASH_ALGO }; static const sector_info_t sectors_info[] = { From 91a3a02d5fad1fca1522ebf6586c6be103a46cde Mon Sep 17 00:00:00 2001 From: Edmund Hsu Date: Fri, 20 Apr 2018 15:57:05 +1000 Subject: [PATCH 02/46] EV_COG_AD3029LZ: Rework linker scripts to support bootloader - fix compiler warning message of flash_api.c - eliminate absolute address of ROM tables - add MBED_APP_START and MBED_APP_SIZE to linker scripts --- .../device/startup_ADuCM3029.c | 7 ++--- .../device/startup_ADuCM3029.h | 13 +++++++-- .../TOOLCHAIN_ARM_STD/ADuCM3029.sct | 28 +++++++++++++++---- .../TOOLCHAIN_GCC_ARM/ADuCM3029.ld | 20 +++++++++---- .../TOOLCHAIN_IAR/ADuCM3029.icf | 21 +++++++++++--- .../TARGET_ADUCM3029/api/cmsis_nvic.h | 3 +- .../TARGET_ADUCM3029/api/flash_api.c | 4 +-- 7 files changed, 70 insertions(+), 26 deletions(-) diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c index 7593a5ae04..133fcc13c1 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c @@ -44,7 +44,6 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ -#include #ifdef __ARMCC_VERSION #include #endif @@ -52,7 +51,6 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include - /*---------------------------------------------------------------------------- External function Declaration *----------------------------------------------------------------------------*/ @@ -61,9 +59,8 @@ extern void SramInit(void); /*---------------------------------------------------------------------------- Checksum options *----------------------------------------------------------------------------*/ -#if defined (__ARMCC_VERSION) -__attribute__((section(".ARM.__at_0x000001A0"))) -#elif defined( __ICCARM__) + +#if defined( __ICCARM__) __root #endif /* __ICCARM__ */ const uint32_t SECTION_PLACE(blank_checksum[],".checksum") = diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.h b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.h index 768bae88f9..af684f4d15 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.h +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.h @@ -7,7 +7,7 @@ * @date: $Date: $ *----------------------------------------------------------------------------- * -Copyright (c) 2010-2017 Analog Devices, Inc. +Copyright (c) 2010-2018 Analog Devices, Inc. All rights reserved. @@ -62,6 +62,8 @@ RESET_EXCPT_HNDLR #define __STARTUP_H__ #define VECTOR_SECTION ".vectors" +/* IVT typedefs. */ +typedef void( *pFunc )( void ); #ifdef __ARMCC_VERSION void Default_Handler(void); @@ -71,6 +73,8 @@ void Default_Handler(void); #define RESET_EXCPT_HNDLR __main #define COMPILER_NAME "ARMCC" #define WEAK_FUNCTION(x) void x (void) __attribute__((weak, alias("Default_Handler"))); +extern uint32_t Load$$LR$$LR_IROM1$$Base[]; +#define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)Load$$LR$$LR_IROM1$$Base) #elif defined(__ICCARM__) #pragma diag_suppress=Pm093,Pm140 @@ -80,6 +84,8 @@ void Default_Handler(void); #define RESET_EXCPT_HNDLR __iar_program_start #define COMPILER_NAME "ICCARM" #define WEAK_FUNCTION(x) WEAK_FUNC ( void x (void)) { while(1){} } +#pragma section=VECTOR_SECTION +#define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)__section_begin(VECTOR_SECTION)) #elif defined(__GNUC__) extern unsigned __etext; @@ -105,8 +111,11 @@ extern int __START(void) __attribute__((noreturn)); /* main entry point */ #define IVT_NAME __Vectors #define COMPILER_NAME "GNUC" #define WEAK_FUNCTION(x) void x (void) __attribute__ ((weak, alias("Default_Handler"))); +extern const pFunc IVT_NAME[]; +#define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)IVT_NAME) #define __STARTUP_CLEAR_BSS_MULTIPLE #endif // __GNUC__ + #define LASTCRCPAGE 0 #define BLANKX4 0xFFFFFFFF #define BLANKX20 BLANKX4,BLANKX4,BLANKX4,BLANKX4,BLANKX4,BLANKX4,BLANKX4,BLANKX4 @@ -115,8 +124,6 @@ extern int __START(void) __attribute__((noreturn)); /* main entry point */ #define BLANKX60 BLANKX20,BLANKX20,BLANKX20 void RESET_EXCPT_HNDLR(void); void Reset_Handler(void); -/* IVT typedefs. */ -typedef void( *pFunc )( void ); #define ADUCM3029_VECTORS /* Cortex-M3 Exceptions Handler */ \ Reset_Handler, /* -15 */ \ diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_ARM_STD/ADuCM3029.sct b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_ARM_STD/ADuCM3029.sct index f7087cac09..f075281ccc 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_ARM_STD/ADuCM3029.sct +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_ARM_STD/ADuCM3029.sct @@ -1,9 +1,10 @@ +#! armcc -E ;****************************************************************************** ; File: ADuCM3029.sct ; Scatter loading file for Analog Devices ADuCM3029 processor ; ; Copyright (c) 2011 - 2014 ARM LIMITED -; Copyright (c) 2016 - 2017 Analog Devices, Inc. +; Copyright (c) 2016 - 2018 Analog Devices, Inc. ; ; All rights reserved. ; Redistribution and use in source and binary forms, with or without @@ -32,13 +33,30 @@ ; Portions Copyright (c) 2017 Analog Devices, Inc. ; ;****************************************************************************** +#if !defined(MBED_APP_START) + #define MBED_APP_START 0 +#endif -LR_IROM1 0x00000000 0x00040000 { - ADUCM_IROM1 0x00000000 0x00040000 { ; romflash start address +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x40000 +#endif + +#define ADUCM_SECTOR_SIZE 0x800 + +#define ADUCM_VECTOR_SIZE 0x1A0 + +LR_IROM1 MBED_APP_START MBED_APP_SIZE { + FLASH0 MBED_APP_START ADUCM_VECTOR_SIZE { *(.vectors, +First) - *(.checksum) + } + + FLASH1 (MBED_APP_START + ADUCM_VECTOR_SIZE) (ADUCM_SECTOR_SIZE - ADUCM_VECTOR_SIZE) { + *(.checksum, +Last) + } + + ER_IROM1 (MBED_APP_START + ADUCM_SECTOR_SIZE) (MBED_APP_SIZE - ADUCM_SECTOR_SIZE) { *(InRoot$$Sections) - .ANY (+RO) + *(+RO) } RW_IRAM1 0x20000200 { ; data section diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_GCC_ARM/ADuCM3029.ld b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_GCC_ARM/ADuCM3029.ld index 23208ce7cd..690d65d966 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_GCC_ARM/ADuCM3029.ld +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_GCC_ARM/ADuCM3029.ld @@ -1,17 +1,27 @@ /* - * Portions Copyright (c) 2016 - 2017 Analog Devices, Inc. + * Portions Copyright (c) 2016 - 2018 Analog Devices, Inc. * * Based on Device/ARM/ARMCM3/Source/GCC/gcc_arm.ld file in * ARM.CMSIS.4.5.0.pack. */ +#if !defined(MBED_APP_START) + #define MBED_APP_START 0 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x40000 +#endif + +#define ADUCM_SECTOR_SIZE 0x800 + /* Linker script to configure memory regions. */ MEMORY { - /* Flash bank0 */ - FLASH0 (rx) : ORIGIN = 0x00000000, LENGTH = 0x800 - /* Flash bank0 - bank127*/ - FLASH (rx) : ORIGIN = 0x00000800, LENGTH = 256k - 0x800 + /* The first 0x800 bytes of flash */ + FLASH0 (rx) : ORIGIN = MBED_APP_START, LENGTH = ADUCM_SECTOR_SIZE + /* The rest of the flash */ + FLASH (rx) : ORIGIN = MBED_APP_START + ADUCM_SECTOR_SIZE, LENGTH = MBED_APP_SIZE - ADUCM_SECTOR_SIZE /* SRAM bank 0+1 */ DSRAM_V (rwx) : ORIGIN = 0x20000000, LENGTH = 0x200 DSRAM_A (rwx) : ORIGIN = 0x20000200, LENGTH = 16k - 0x200 diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_IAR/ADuCM3029.icf b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_IAR/ADuCM3029.icf index 8c15cd0b5c..57dfd53d0b 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_IAR/ADuCM3029.icf +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TOOLCHAIN_IAR/ADuCM3029.icf @@ -3,7 +3,7 @@ * ILINK Configuration File for Analog Devices ADuCM3029 processor * * Copyright (c) 2011 - 2014 ARM LIMITED -* Copyright (c) 2016 - 2017 Analog Devices, Inc. +* Copyright (c) 2016 - 2018 Analog Devices, Inc. * * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -29,10 +29,23 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ + +if (!isdefinedsymbol(MBED_APP_START)) { + define symbol MBED_APP_START = 0; +} + +if (!isdefinedsymbol(MBED_APP_SIZE)) { + define symbol MBED_APP_SIZE = 0x40000; +} + +define symbol ADUCM_SECTOR_SIZE = 0x800; + +define symbol ADUCM_VECTOR_SIZE = 0x1A0; + define memory mem with size = 4G; -define region ROM_PAGE0_INTVEC = mem:[from 0x00000000 size 0x000001A0]; -define region ROM_PAGE0_CHECKSUM = mem:[from 0x000001A0 size 0x00000660]; -define region ROM_REGION = mem:[from 0x00000800 size 254K]; +define region ROM_PAGE0_INTVEC = mem:[from MBED_APP_START size ADUCM_VECTOR_SIZE]; +define region ROM_PAGE0_CHECKSUM = mem:[from MBED_APP_START+ADUCM_VECTOR_SIZE size ADUCM_SECTOR_SIZE-ADUCM_VECTOR_SIZE]; +define region ROM_REGION = mem:[from MBED_APP_START+ADUCM_SECTOR_SIZE size MBED_APP_SIZE-ADUCM_SECTOR_SIZE]; define region RAM_bank1_region = mem:[from 0x20000200 size 0x00003E00]; define region RAM_bank2_region = mem:[from 0x20004000 size 0x00004000] | mem:[from 0x20040000 size 0x00008000]; diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/cmsis_nvic.h b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/cmsis_nvic.h index 8310b5fbbe..b1ce91cab7 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/cmsis_nvic.h +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/cmsis_nvic.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010-2017 Analog Devices, Inc. + * Copyright (c) 2010-2018 Analog Devices, Inc. * * All rights reserved. * @@ -48,7 +48,6 @@ #define NVIC_NUM_VECTORS (NVIC_USER_IRQ_OFFSET + NVIC_USER_IRQ_NUMBER) #define NVIC_RAM_VECTOR_ADDRESS 0x20000000 -#define NVIC_FLASH_VECTOR_ADDRESS 0x0 #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/flash_api.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/flash_api.c index 304219e8af..95d291010e 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/flash_api.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/flash_api.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010-2017 Analog Devices, Inc. + * Copyright (c) 2010-2018 Analog Devices, Inc. * * All rights reserved. * @@ -68,7 +68,7 @@ static const flash_algo_t flash_algo_config = { .erase_sector = 0x0000006F, .program_page = 0x000000AB, .static_base = 0x0000017C, - .algo_blob = FLASH_ALGO + .algo_blob = (uint32_t *)FLASH_ALGO }; static const sector_info_t sectors_info[] = { From 61bc05144e90a0058bf3dcc0104077d20724b2d9 Mon Sep 17 00:00:00 2001 From: Edmund Hsu Date: Fri, 20 Apr 2018 16:00:20 +1000 Subject: [PATCH 03/46] ADI: Enable bootloader for EV_COG_AD3029LZ and EV_COG_AD4050LZ --- .../TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c | 2 +- targets/targets.json | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c index 133fcc13c1..8bc0ae8289 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/TARGET_EV_COG_AD3029LZ/device/startup_ADuCM3029.c @@ -6,7 +6,7 @@ * @date: $Date: $ *----------------------------------------------------------------------------- * -Copyright (c) 2010-2017 Analog Devices, Inc. +Copyright (c) 2010-2018 Analog Devices, Inc. All rights reserved. diff --git a/targets/targets.json b/targets/targets.json index 87274af543..9ee12f7f14 100755 --- a/targets/targets.json +++ b/targets/targets.json @@ -636,7 +636,8 @@ "device_has": ["SERIAL", "STDIO_MESSAGES", "TRNG", "SLEEP", "INTERRUPTIN", "RTC", "SPI", "I2C", "FLASH", "ANALOGIN"], "device_name": "ADuCM4050", "detect_code": ["0603"], - "release_versions": ["5"] + "release_versions": ["5"], + "bootloader_supported": true }, "EV_COG_AD3029LZ": { "inherits": ["Target"], @@ -647,7 +648,8 @@ "device_has": ["SERIAL", "STDIO_MESSAGES", "TRNG", "SLEEP", "INTERRUPTIN", "RTC", "SPI", "I2C", "FLASH", "ANALOGIN"], "device_name": "ADuCM3029", "detect_code": ["0602"], - "release_versions": ["5"] + "release_versions": ["5"], + "bootloader_supported": true }, "MTS_GAMBIT": { "inherits": ["Target"], From 4574130022d31cef95cc806a7e8763b03488efc9 Mon Sep 17 00:00:00 2001 From: Keyur Hariya Date: Thu, 19 Apr 2018 13:15:38 -0500 Subject: [PATCH 04/46] Remove automatic I2C stop after each read Automatic stop prevents sending repeated start. --- targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c b/targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c index 5515750879..49a2706eb7 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c @@ -145,11 +145,6 @@ int i2c_byte_read(i2c_t *obj, int last) if (I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_RXDATA_NACK) != E_NO_ERROR) { goto byte_read_err; } - - // Send the stop condition - if (I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_STOP) != E_NO_ERROR) { - goto byte_read_err; - } } else { if (I2CM_WriteTxFifo(i2cm, fifo, MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT) != E_NO_ERROR) { goto byte_read_err; From d947139df34ee44342a32272a0ce6ba5c029c52e Mon Sep 17 00:00:00 2001 From: Ganesh Ramachandran Date: Thu, 19 Apr 2018 17:24:58 +0530 Subject: [PATCH 05/46] IAR export and page size fix for nvstore --- targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c | 3 ++- tools/export/iar/iar_definitions.json | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c index 6693e6a06d..7dd16b4a10 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/flash_api.c @@ -20,6 +20,7 @@ #define PROGRAM_WIRTE_MAX 16U /* Page program could be written 16 bytes/4 words once */ #define SECTOR_SIZE 0x8000 /* (512 * 8) sectors */ +#define PAGE_SIZE 16U /* Page program size is 16 bytes */ #if defined ( __ICCARM__ ) /* IAR Compiler */ #define FLASH_API_ROM ((uint32_t *)__section_begin("FLASH_CODE_ROM")) @@ -143,7 +144,7 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) #endif uint32_t flash_get_page_size(const flash_t *obj) { - return FLASH_PAGE_SIZE; + return PAGE_SIZE; } #if defined ( __ICCARM__ ) /* IAR Compiler */ diff --git a/tools/export/iar/iar_definitions.json b/tools/export/iar/iar_definitions.json index f8cc3042d3..b2ae9b1ac3 100644 --- a/tools/export/iar/iar_definitions.json +++ b/tools/export/iar/iar_definitions.json @@ -273,5 +273,10 @@ }, "ADuCM4050": { "OGChipSelectEditMenu": "ADuCM4050\tAnalogDevices ADuCM4050" + }, + "TMPM46BF10FG":{ + "OGChipSelectEditMenu": "TMPM46BF10FG\tToshiba TMPM46BF10FG", + "GFPUCoreSlave": 21, + "GBECoreSlave": 21 } } From 9b46b040e34102cb7b9baf5f8d4772ba2d87e13a Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Wed, 18 Apr 2018 14:40:17 +0100 Subject: [PATCH 06/46] make PR type box list "fancier" without making it a github tasklist --- .github/pull_request_template.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b6bd82bb4d..33855686f2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,18 +11,14 @@ + [ ] Fix [ ] Refactor [ ] New target [ ] Feature [ ] Breaking change ---> -[ ] Fix -[ ] Refactor -[ ] New target -[ ] Feature -[ ] Breaking change From f5aa8b33dc0d4b5e5e6bc8ed3ced0c48e76e9d95 Mon Sep 17 00:00:00 2001 From: bcostm Date: Thu, 29 Mar 2018 14:35:47 +0200 Subject: [PATCH 07/46] L0 ST CUBE V1.10.0 --- .../TOOLCHAIN_ARM_MICRO/startup_stm32l011xx.S | 5 +- .../TARGET_NUCLEO_L011K4/device/stm32l011xx.h | 8 +- .../TARGET_NUCLEO_L011K4/device/stm32l0xx.h | 14 +- .../device/system_stm32l0xx.h | 4 +- .../TOOLCHAIN_ARM_MICRO/startup_stm32l031xx.S | 5 +- .../TOOLCHAIN_ARM_STD/startup_stm32l031xx.S | 5 +- .../TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S | 2 - .../TOOLCHAIN_IAR/startup_stm32l031xx.S | 4 +- .../TARGET_NUCLEO_L031K6/device/stm32l031xx.h | 8 +- .../TARGET_NUCLEO_L031K6/device/stm32l0xx.h | 14 +- .../device/system_stm32l0xx.h | 4 +- .../TOOLCHAIN_ARM_MICRO/startup_stm32l073xx.S | 5 +- .../TOOLCHAIN_ARM_STD/startup_stm32l073xx.S | 5 +- .../TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S | 2 - .../TOOLCHAIN_IAR/startup_stm32l073xx.S | 4 +- .../TARGET_NUCLEO_L073RZ/device/stm32l073xx.h | 8 +- .../TARGET_NUCLEO_L073RZ/device/stm32l0xx.h | 14 +- .../device/system_stm32l0xx.h | 4 +- .../TOOLCHAIN_ARM_MICRO/startup_stm32l053xx.S | 5 +- .../TOOLCHAIN_ARM_STD/startup_stm32l053xx.S | 5 +- .../TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S | 2 - .../TOOLCHAIN_IAR/startup_stm32l053xx.S | 4 +- .../TARGET_STM32L053x8/device/stm32l053xx.h | 8 +- .../TARGET_STM32L053x8/device/stm32l0xx.h | 14 +- .../device/system_stm32l0xx.h | 4 +- .../TOOLCHAIN_GCC_ARM/startup_stm32l072xx.S | 2 - .../TARGET_STM32L072xZ/device/stm32l072xx.h | 2 - .../TARGET_STM32L072xZ/device/stm32l0xx.h | 14 +- .../device/system_stm32l0xx.h | 4 +- .../TARGET_STM32L0x2xZ/device/stm32l0xx.h | 14 +- .../device/system_stm32l0xx.h | 4 +- .../TARGET_STM32L0/device/stm32_hal_legacy.h | 193 +- .../TARGET_STM32L0/device/stm32l0xx_hal.c | 8 +- .../TARGET_STM32L0/device/stm32l0xx_hal.h | 6 +- .../TARGET_STM32L0/device/stm32l0xx_hal_adc.c | 603 ++-- .../TARGET_STM32L0/device/stm32l0xx_hal_adc.h | 544 ++-- .../device/stm32l0xx_hal_adc_ex.c | 119 +- .../device/stm32l0xx_hal_adc_ex.h | 35 +- .../device/stm32l0xx_hal_comp.c | 86 +- .../device/stm32l0xx_hal_comp.h | 4 +- .../device/stm32l0xx_hal_comp_ex.c | 32 +- .../device/stm32l0xx_hal_comp_ex.h | 2 - .../device/stm32l0xx_hal_conf.h | 8 +- .../device/stm32l0xx_hal_cortex.c | 2 - .../device/stm32l0xx_hal_cortex.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_crc.c | 7 +- .../TARGET_STM32L0/device/stm32l0xx_hal_crc.h | 2 - .../device/stm32l0xx_hal_crc_ex.c | 25 +- .../device/stm32l0xx_hal_crc_ex.h | 2 - .../device/stm32l0xx_hal_cryp.c | 2 - .../device/stm32l0xx_hal_cryp.h | 4 +- .../device/stm32l0xx_hal_cryp_ex.c | 2 - .../device/stm32l0xx_hal_cryp_ex.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_dac.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_dac.h | 6 +- .../device/stm32l0xx_hal_dac_ex.c | 2 - .../device/stm32l0xx_hal_dac_ex.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_def.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_dma.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_dma.h | 2 - .../device/stm32l0xx_hal_firewall.c | 2 - .../device/stm32l0xx_hal_firewall.h | 2 - .../device/stm32l0xx_hal_flash.c | 694 ++-- .../device/stm32l0xx_hal_flash.h | 364 +-- .../device/stm32l0xx_hal_flash_ex.c | 1147 ++++--- .../device/stm32l0xx_hal_flash_ex.h | 543 ++-- .../device/stm32l0xx_hal_flash_ramfunc.c | 306 +- .../device/stm32l0xx_hal_flash_ramfunc.h | 48 +- .../device/stm32l0xx_hal_gpio.c | 18 +- .../device/stm32l0xx_hal_gpio.h | 5 +- .../device/stm32l0xx_hal_gpio_ex.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_i2c.c | 833 ++--- .../TARGET_STM32L0/device/stm32l0xx_hal_i2c.h | 127 +- .../device/stm32l0xx_hal_i2c_ex.c | 28 +- .../device/stm32l0xx_hal_i2c_ex.h | 10 +- .../TARGET_STM32L0/device/stm32l0xx_hal_i2s.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_i2s.h | 2 - .../device/stm32l0xx_hal_irda.c | 2578 ++++++++++----- .../device/stm32l0xx_hal_irda.h | 885 ++--- .../device/stm32l0xx_hal_irda_ex.h | 112 +- .../device/stm32l0xx_hal_iwdg.c | 366 +-- .../device/stm32l0xx_hal_iwdg.h | 231 +- .../TARGET_STM32L0/device/stm32l0xx_hal_lcd.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_lcd.h | 11 +- .../device/stm32l0xx_hal_lptim.c | 2 - .../device/stm32l0xx_hal_lptim.h | 4 +- .../device/stm32l0xx_hal_lptim_ex.h | 4 +- .../TARGET_STM32L0/device/stm32l0xx_hal_pcd.c | 114 +- .../TARGET_STM32L0/device/stm32l0xx_hal_pcd.h | 20 +- .../device/stm32l0xx_hal_pcd_ex.c | 169 +- .../device/stm32l0xx_hal_pcd_ex.h | 31 +- .../TARGET_STM32L0/device/stm32l0xx_hal_pwr.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_pwr.h | 2 - .../device/stm32l0xx_hal_pwr_ex.c | 12 +- .../device/stm32l0xx_hal_pwr_ex.h | 3 +- .../TARGET_STM32L0/device/stm32l0xx_hal_rcc.c | 1234 +++---- .../TARGET_STM32L0/device/stm32l0xx_hal_rcc.h | 1821 ++++++----- .../device/stm32l0xx_hal_rcc_ex.c | 830 ++--- .../device/stm32l0xx_hal_rcc_ex.h | 2669 ++++++++------- .../TARGET_STM32L0/device/stm32l0xx_hal_rng.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_rng.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_rtc.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_rtc.h | 2 - .../device/stm32l0xx_hal_rtc_ex.c | 2 - .../device/stm32l0xx_hal_rtc_ex.h | 2 - .../device/stm32l0xx_hal_smartcard.c | 2853 +++++++++++------ .../device/stm32l0xx_hal_smartcard.h | 1036 +++--- .../device/stm32l0xx_hal_smartcard_ex.c | 151 +- .../device/stm32l0xx_hal_smartcard_ex.h | 194 +- .../device/stm32l0xx_hal_smbus.c | 1833 ++++++----- .../device/stm32l0xx_hal_smbus.h | 684 ++-- .../TARGET_STM32L0/device/stm32l0xx_hal_spi.c | 78 +- .../TARGET_STM32L0/device/stm32l0xx_hal_spi.h | 26 +- .../TARGET_STM32L0/device/stm32l0xx_hal_tim.c | 4 +- .../TARGET_STM32L0/device/stm32l0xx_hal_tim.h | 2 - .../device/stm32l0xx_hal_tim_ex.c | 2 - .../device/stm32l0xx_hal_tim_ex.h | 42 +- .../TARGET_STM32L0/device/stm32l0xx_hal_tsc.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_hal_tsc.h | 5 +- .../device/stm32l0xx_hal_uart.c | 2800 ++++++++++------ .../device/stm32l0xx_hal_uart.h | 1699 +++++----- .../device/stm32l0xx_hal_uart_ex.c | 504 +-- .../device/stm32l0xx_hal_uart_ex.h | 296 +- .../device/stm32l0xx_hal_usart.c | 2184 ++++++++----- .../device/stm32l0xx_hal_usart.h | 784 ++--- .../device/stm32l0xx_hal_usart_ex.h | 198 +- .../device/stm32l0xx_hal_wwdg.c | 360 +-- .../device/stm32l0xx_hal_wwdg.h | 236 +- .../TARGET_STM32L0/device/stm32l0xx_ll_adc.c | 12 +- .../TARGET_STM32L0/device/stm32l0xx_ll_adc.h | 82 +- .../TARGET_STM32L0/device/stm32l0xx_ll_bus.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_comp.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_comp.h | 62 +- .../device/stm32l0xx_ll_cortex.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_crc.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_crc.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_crs.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_crs.h | 9 +- .../TARGET_STM32L0/device/stm32l0xx_ll_dac.c | 6 +- .../TARGET_STM32L0/device/stm32l0xx_ll_dac.h | 66 +- .../TARGET_STM32L0/device/stm32l0xx_ll_dma.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_dma.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_exti.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_exti.h | 4 +- .../TARGET_STM32L0/device/stm32l0xx_ll_gpio.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_gpio.h | 3 - .../TARGET_STM32L0/device/stm32l0xx_ll_i2c.c | 11 +- .../TARGET_STM32L0/device/stm32l0xx_ll_i2c.h | 255 +- .../TARGET_STM32L0/device/stm32l0xx_ll_iwdg.h | 2 - .../device/stm32l0xx_ll_lptim.c | 4 +- .../device/stm32l0xx_ll_lptim.h | 2 - .../device/stm32l0xx_ll_lpuart.c | 2 - .../device/stm32l0xx_ll_lpuart.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_pwr.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_pwr.h | 79 +- .../TARGET_STM32L0/device/stm32l0xx_ll_rcc.c | 4 +- .../TARGET_STM32L0/device/stm32l0xx_ll_rcc.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_rng.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_rng.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_rtc.c | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_rtc.h | 2 - .../TARGET_STM32L0/device/stm32l0xx_ll_spi.c | 25 +- .../TARGET_STM32L0/device/stm32l0xx_ll_spi.h | 44 +- .../device/stm32l0xx_ll_system.h | 144 +- .../TARGET_STM32L0/device/stm32l0xx_ll_tim.c | 376 ++- .../TARGET_STM32L0/device/stm32l0xx_ll_tim.h | 939 +++--- .../device/stm32l0xx_ll_usart.c | 10 +- .../device/stm32l0xx_ll_usart.h | 2 - .../device/stm32l0xx_ll_utils.c | 2 - .../device/stm32l0xx_ll_utils.h | 11 +- .../TARGET_STM32L0/device/stm32l0xx_ll_wwdg.h | 2 - .../TARGET_STM32L0/device/system_stm32l0xx.c | 6 +- 172 files changed, 20248 insertions(+), 15075 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/TOOLCHAIN_ARM_MICRO/startup_stm32l011xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/TOOLCHAIN_ARM_MICRO/startup_stm32l011xx.S index f0ba3ff21f..bac2c1a396 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/TOOLCHAIN_ARM_MICRO/startup_stm32l011xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/TOOLCHAIN_ARM_MICRO/startup_stm32l011xx.S @@ -1,8 +1,8 @@ ;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l011xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32l011xx Devices vector table for MDK-ARM toolchain. ;* This module performs: ;* - Set the initial SP @@ -12,7 +12,6 @@ ;* calls main()). ;* After Reset the Cortex-M0+ processor is in Thread mode, ;* priority is Privileged, and the Stack is set to Main. -;* <<< Use Configuration Wizard in Context Menu >>> ;******************************************************************************* ;* ;* Redistribution and use in source and binary forms, with or without modification, diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/stm32l011xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/stm32l011xx.h index 0728b40f5b..5d1e8a8cb3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/stm32l011xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/stm32l011xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l011xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for stm32l011xx devices. @@ -16,7 +14,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -752,7 +750,7 @@ typedef struct /******************* Bits definition for ADC_CFGR2 register *****************/ #define ADC_CFGR2_TOVS_Pos (9U) -#define ADC_CFGR2_TOVS_Msk (0x400001U << ADC_CFGR2_TOVS_Pos) /*!< 0x80000200 */ +#define ADC_CFGR2_TOVS_Msk (0x1U << ADC_CFGR2_TOVS_Pos) /*!< 0x80000200 */ #define ADC_CFGR2_TOVS ADC_CFGR2_TOVS_Msk /*!< Triggered Oversampling */ #define ADC_CFGR2_OVSS_Pos (5U) #define ADC_CFGR2_OVSS_Msk (0xFU << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ @@ -5736,7 +5734,7 @@ typedef struct #define IS_COMP_ALL_INSTANCE(INSTANCE) (((INSTANCE) == COMP1) || \ ((INSTANCE) == COMP2)) -#define IS_COMP_COMMON_INSTANCE(INSTANCE) ((INSTANCE) == COMP12_COMMON) +#define IS_COMP_COMMON_INSTANCE(COMMON_INSTANCE) ((COMMON_INSTANCE) == COMP12_COMMON) /******************************* CRC Instances ********************************/ #define IS_CRC_ALL_INSTANCE(INSTANCE) ((INSTANCE) == CRC) diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/stm32l0xx.h index 37422f1567..d574d2fc57 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/stm32l0xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for STM32L0xx devices. @@ -20,7 +18,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -114,16 +112,16 @@ #endif /* USE_HAL_DRIVER */ /** - * @brief CMSIS Device version number V1.7.0 + * @brief CMSIS Device version number V1.7.1 */ #define __STM32L0xx_CMSIS_VERSION_MAIN (0x01) /*!< [31:24] main version */ #define __STM32L0xx_CMSIS_VERSION_SUB1 (0x07) /*!< [23:16] sub1 version */ -#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */ #define __STM32L0xx_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */ #define __STM32L0xx_CMSIS_VERSION ((__STM32L0xx_CMSIS_VERSION_MAIN << 24)\ - |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ - |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ - |(__STM32L0xx_CMSIS_VERSION_RC)) + |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ + |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ + |(__STM32L0xx_CMSIS_VERSION_RC)) /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_stm32l0xx.h index 7015debf51..8f3d7601be 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_stm32l0xx.h @@ -2,13 +2,11 @@ ****************************************************************************** * @file system_stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Header File. ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_ARM_MICRO/startup_stm32l031xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_ARM_MICRO/startup_stm32l031xx.S index 51ed9fc936..83190a4516 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_ARM_MICRO/startup_stm32l031xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_ARM_MICRO/startup_stm32l031xx.S @@ -1,8 +1,8 @@ ;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l053xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32l053xx Devices vector table for MDK-ARM toolchain. ;* This module performs: ;* - Set the initial SP @@ -12,7 +12,6 @@ ;* calls main()). ;* After Reset the Cortex-M0+ processor is in Thread mode, ;* priority is Privileged, and the Stack is set to Main. -;* <<< Use Configuration Wizard in Context Menu >>> ;******************************************************************************* ;* ;* Redistribution and use in source and binary forms, with or without modification, diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_ARM_STD/startup_stm32l031xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_ARM_STD/startup_stm32l031xx.S index 01380b68f9..6206c6b3fb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_ARM_STD/startup_stm32l031xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_ARM_STD/startup_stm32l031xx.S @@ -1,8 +1,8 @@ ;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l053xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32l053xx Devices vector table for MDK-ARM toolchain. ;* This module performs: ;* - Set the initial SP @@ -12,7 +12,6 @@ ;* calls main()). ;* After Reset the Cortex-M0+ processor is in Thread mode, ;* priority is Privileged, and the Stack is set to Main. -;* <<< Use Configuration Wizard in Context Menu >>> ;******************************************************************************* ;* ;* Redistribution and use in source and binary forms, with or without modification, diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S index 325c46fbcb..de2ba07180 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_GCC_ARM/startup_stm32l031xx.S @@ -2,8 +2,6 @@ ****************************************************************************** * @file startup_stm32l031xx.s * @author MCD Application Team - * @version V1.5.0 - * @date 8-January-2016 * @brief STM32L031xx Devices vector table for Atollic TrueSTUDIO toolchain. * This module performs: * - Set the initial SP diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_IAR/startup_stm32l031xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_IAR/startup_stm32l031xx.S index c9fbb7bf68..6b63abb0d2 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_IAR/startup_stm32l031xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/TOOLCHAIN_IAR/startup_stm32l031xx.S @@ -1,8 +1,8 @@ ;/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l031xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32L031xx Ultra Low Power Devices vector ;* This module performs: ;* - Set the initial SP diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/stm32l031xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/stm32l031xx.h index 63445fb605..2863d322cb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/stm32l031xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/stm32l031xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l031xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for stm32l031xx devices. @@ -16,7 +14,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -761,7 +759,7 @@ typedef struct /******************* Bits definition for ADC_CFGR2 register *****************/ #define ADC_CFGR2_TOVS_Pos (9U) -#define ADC_CFGR2_TOVS_Msk (0x400001U << ADC_CFGR2_TOVS_Pos) /*!< 0x80000200 */ +#define ADC_CFGR2_TOVS_Msk (0x1U << ADC_CFGR2_TOVS_Pos) /*!< 0x80000200 */ #define ADC_CFGR2_TOVS ADC_CFGR2_TOVS_Msk /*!< Triggered Oversampling */ #define ADC_CFGR2_OVSS_Pos (5U) #define ADC_CFGR2_OVSS_Msk (0xFU << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ @@ -5857,7 +5855,7 @@ typedef struct #define IS_COMP_ALL_INSTANCE(INSTANCE) (((INSTANCE) == COMP1) || \ ((INSTANCE) == COMP2)) -#define IS_COMP_COMMON_INSTANCE(INSTANCE) ((INSTANCE) == COMP12_COMMON) +#define IS_COMP_COMMON_INSTANCE(COMMON_INSTANCE) ((COMMON_INSTANCE) == COMP12_COMMON) /******************************* CRC Instances ********************************/ #define IS_CRC_ALL_INSTANCE(INSTANCE) ((INSTANCE) == CRC) diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/stm32l0xx.h index 4d938b97b6..25fb3c9971 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/stm32l0xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for STM32L0xx devices. @@ -20,7 +18,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -114,16 +112,16 @@ #endif /* USE_HAL_DRIVER */ /** - * @brief CMSIS Device version number V1.7.0 + * @brief CMSIS Device version number V1.7.1 */ #define __STM32L0xx_CMSIS_VERSION_MAIN (0x01) /*!< [31:24] main version */ #define __STM32L0xx_CMSIS_VERSION_SUB1 (0x07) /*!< [23:16] sub1 version */ -#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */ #define __STM32L0xx_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */ #define __STM32L0xx_CMSIS_VERSION ((__STM32L0xx_CMSIS_VERSION_MAIN << 24)\ - |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ - |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ - |(__STM32L0xx_CMSIS_VERSION_RC)) + |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ + |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ + |(__STM32L0xx_CMSIS_VERSION_RC)) /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_stm32l0xx.h index 7015debf51..8f3d7601be 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_stm32l0xx.h @@ -2,13 +2,11 @@ ****************************************************************************** * @file system_stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Header File. ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_ARM_MICRO/startup_stm32l073xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_ARM_MICRO/startup_stm32l073xx.S index e274266001..80bc3ca784 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_ARM_MICRO/startup_stm32l073xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_ARM_MICRO/startup_stm32l073xx.S @@ -1,8 +1,8 @@ ;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l073xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32l073xx Devices vector table for MDK-ARM toolchain. ;* This module performs: ;* - Set the initial SP @@ -12,7 +12,6 @@ ;* calls main()). ;* After Reset the Cortex-M0+ processor is in Thread mode, ;* priority is Privileged, and the Stack is set to Main. -;* <<< Use Configuration Wizard in Context Menu >>> ;******************************************************************************* ;* ;* Redistribution and use in source and binary forms, with or without modification, diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_ARM_STD/startup_stm32l073xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_ARM_STD/startup_stm32l073xx.S index cac4c7436e..b6fc856ea4 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_ARM_STD/startup_stm32l073xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_ARM_STD/startup_stm32l073xx.S @@ -1,8 +1,8 @@ ;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l073xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32l073xx Devices vector table for MDK-ARM toolchain. ;* This module performs: ;* - Set the initial SP @@ -12,7 +12,6 @@ ;* calls main()). ;* After Reset the Cortex-M0+ processor is in Thread mode, ;* priority is Privileged, and the Stack is set to Main. -;* <<< Use Configuration Wizard in Context Menu >>> ;******************************************************************************* ;* ;* Redistribution and use in source and binary forms, with or without modification, diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S index f2fecb6915..bff4028217 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l073xx.S @@ -2,8 +2,6 @@ ****************************************************************************** * @file startup_stm32l073xx.s * @author MCD Application Team - * @version V1.5.0 - * @date 8-January-2016 * @brief STM32L073xx Devices vector table for Atollic TrueSTUDIO toolchain. * This module performs: * - Set the initial SP diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_IAR/startup_stm32l073xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_IAR/startup_stm32l073xx.S index 1b186360ed..712035a55c 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_IAR/startup_stm32l073xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/TOOLCHAIN_IAR/startup_stm32l073xx.S @@ -1,8 +1,8 @@ ;/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l073xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32L073xx Ultra Low Power Devices vector ;* This module performs: ;* - Set the initial SP diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/stm32l073xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/stm32l073xx.h index b446f3ac53..fb5bb43dcc 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/stm32l073xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/stm32l073xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l073xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for stm32l073xx devices. @@ -16,7 +14,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -950,7 +948,7 @@ typedef struct /******************* Bits definition for ADC_CFGR2 register *****************/ #define ADC_CFGR2_TOVS_Pos (9U) -#define ADC_CFGR2_TOVS_Msk (0x400001U << ADC_CFGR2_TOVS_Pos) /*!< 0x80000200 */ +#define ADC_CFGR2_TOVS_Msk (0x1U << ADC_CFGR2_TOVS_Pos) /*!< 0x80000200 */ #define ADC_CFGR2_TOVS ADC_CFGR2_TOVS_Msk /*!< Triggered Oversampling */ #define ADC_CFGR2_OVSS_Pos (5U) #define ADC_CFGR2_OVSS_Msk (0xFU << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ @@ -7532,7 +7530,7 @@ typedef struct #define IS_COMP_ALL_INSTANCE(INSTANCE) (((INSTANCE) == COMP1) || \ ((INSTANCE) == COMP2)) -#define IS_COMP_COMMON_INSTANCE(INSTANCE) ((INSTANCE) == COMP12_COMMON) +#define IS_COMP_COMMON_INSTANCE(COMMON_INSTANCE) ((COMMON_INSTANCE) == COMP12_COMMON) /******************************* CRC Instances ********************************/ #define IS_CRC_ALL_INSTANCE(INSTANCE) ((INSTANCE) == CRC) diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/stm32l0xx.h index 9c87ac85b7..8946aed041 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/stm32l0xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for STM32L0xx devices. @@ -20,7 +18,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -114,16 +112,16 @@ #endif /* USE_HAL_DRIVER */ /** - * @brief CMSIS Device version number V1.7.0 + * @brief CMSIS Device version number V1.7.1 */ #define __STM32L0xx_CMSIS_VERSION_MAIN (0x01) /*!< [31:24] main version */ #define __STM32L0xx_CMSIS_VERSION_SUB1 (0x07) /*!< [23:16] sub1 version */ -#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */ #define __STM32L0xx_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */ #define __STM32L0xx_CMSIS_VERSION ((__STM32L0xx_CMSIS_VERSION_MAIN << 24)\ - |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ - |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ - |(__STM32L0xx_CMSIS_VERSION_RC)) + |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ + |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ + |(__STM32L0xx_CMSIS_VERSION_RC)) /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_stm32l0xx.h index fcf7649569..df958f5beb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_stm32l0xx.h @@ -2,13 +2,11 @@ ****************************************************************************** * @file system_stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Header File. ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_ARM_MICRO/startup_stm32l053xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_ARM_MICRO/startup_stm32l053xx.S index ff650e6752..35e90b1357 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_ARM_MICRO/startup_stm32l053xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_ARM_MICRO/startup_stm32l053xx.S @@ -1,8 +1,8 @@ ;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l053xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32l053xx Devices vector table for MDK-ARM toolchain. ;* This module performs: ;* - Set the initial SP @@ -12,7 +12,6 @@ ;* calls main()). ;* After Reset the Cortex-M0+ processor is in Thread mode, ;* priority is Privileged, and the Stack is set to Main. -;* <<< Use Configuration Wizard in Context Menu >>> ;******************************************************************************* ;* ;* Redistribution and use in source and binary forms, with or without modification, diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_ARM_STD/startup_stm32l053xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_ARM_STD/startup_stm32l053xx.S index 1457bb15fe..ab0d7758f5 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_ARM_STD/startup_stm32l053xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_ARM_STD/startup_stm32l053xx.S @@ -1,8 +1,8 @@ ;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l053xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32l053xx Devices vector table for MDK-ARM toolchain. ;* This module performs: ;* - Set the initial SP @@ -12,7 +12,6 @@ ;* calls main()). ;* After Reset the Cortex-M0+ processor is in Thread mode, ;* priority is Privileged, and the Stack is set to Main. -;* <<< Use Configuration Wizard in Context Menu >>> ;******************************************************************************* ;* ;* Redistribution and use in source and binary forms, with or without modification, diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S index 19ab5c6e41..d2cf3e2fbb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_GCC_ARM/startup_stm32l053xx.S @@ -2,8 +2,6 @@ ****************************************************************************** * @file startup_stm32l053xx.s * @author MCD Application Team - * @version V1.5.0 - * @date 8-January-2016 * @brief STM32L053xx Devices vector table for Atollic TrueSTUDIO toolchain. * This module performs: * - Set the initial SP diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_IAR/startup_stm32l053xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_IAR/startup_stm32l053xx.S index 5512752d86..46faa75241 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_IAR/startup_stm32l053xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/TOOLCHAIN_IAR/startup_stm32l053xx.S @@ -1,8 +1,8 @@ ;/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** ;* File Name : startup_stm32l053xx.s ;* Author : MCD Application Team -;* Version : V1.5.0 -;* Date : 8-January-2016 +;* Version : V1.7.1 +;* Date : 25-November-2016 ;* Description : STM32L053xx Ultra Low Power Devices vector ;* This module performs: ;* - Set the initial SP diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/stm32l053xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/stm32l053xx.h index 30fd888e28..a525cd5014 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/stm32l053xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/stm32l053xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l053xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for stm32l053xx devices. @@ -16,7 +14,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -921,7 +919,7 @@ typedef struct /******************* Bits definition for ADC_CFGR2 register *****************/ #define ADC_CFGR2_TOVS_Pos (9U) -#define ADC_CFGR2_TOVS_Msk (0x400001U << ADC_CFGR2_TOVS_Pos) /*!< 0x80000200 */ +#define ADC_CFGR2_TOVS_Msk (0x1U << ADC_CFGR2_TOVS_Pos) /*!< 0x80000200 */ #define ADC_CFGR2_TOVS ADC_CFGR2_TOVS_Msk /*!< Triggered Oversampling */ #define ADC_CFGR2_OVSS_Pos (5U) #define ADC_CFGR2_OVSS_Msk (0xFU << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ @@ -7235,7 +7233,7 @@ typedef struct #define IS_COMP_ALL_INSTANCE(INSTANCE) (((INSTANCE) == COMP1) || \ ((INSTANCE) == COMP2)) -#define IS_COMP_COMMON_INSTANCE(INSTANCE) ((INSTANCE) == COMP12_COMMON) +#define IS_COMP_COMMON_INSTANCE(COMMON_INSTANCE) ((COMMON_INSTANCE) == COMP12_COMMON) /******************************* CRC Instances ********************************/ #define IS_CRC_ALL_INSTANCE(INSTANCE) ((INSTANCE) == CRC) diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/stm32l0xx.h index ea576fe91b..f7266c762f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/stm32l0xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for STM32L0xx devices. @@ -20,7 +18,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -114,16 +112,16 @@ #endif /* USE_HAL_DRIVER */ /** - * @brief CMSIS Device version number V1.7.0 + * @brief CMSIS Device version number V1.7.1 */ #define __STM32L0xx_CMSIS_VERSION_MAIN (0x01) /*!< [31:24] main version */ #define __STM32L0xx_CMSIS_VERSION_SUB1 (0x07) /*!< [23:16] sub1 version */ -#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */ #define __STM32L0xx_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */ #define __STM32L0xx_CMSIS_VERSION ((__STM32L0xx_CMSIS_VERSION_MAIN << 24)\ - |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ - |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ - |(__STM32L0xx_CMSIS_VERSION_RC)) + |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ + |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ + |(__STM32L0xx_CMSIS_VERSION_RC)) /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/system_stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/system_stm32l0xx.h index 7015debf51..8f3d7601be 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/system_stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/device/system_stm32l0xx.h @@ -2,13 +2,11 @@ ****************************************************************************** * @file system_stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Header File. ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l072xx.S b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l072xx.S index 1aad893bcb..7725eed068 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l072xx.S +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/TOOLCHAIN_GCC_ARM/startup_stm32l072xx.S @@ -2,8 +2,6 @@ ****************************************************************************** * @file startup_stm32l072xx.s * @author MCD Application Team - * @version V1.7.1 - * @date 25-November-2016 * @brief STM32L072xx Devices vector table for Atollic TrueSTUDIO toolchain. * This module performs: * - Set the initial SP diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/stm32l072xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/stm32l072xx.h index a38c8690ef..fa5057ede6 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/stm32l072xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/stm32l072xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l072xx.h * @author MCD Application Team - * @version V1.7.1 - * @date 25-November-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for stm32l072xx devices. diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/stm32l0xx.h index 42ed24ead8..51afd8359a 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/stm32l0xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for STM32L0xx devices. @@ -20,7 +18,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -114,16 +112,16 @@ #endif /* USE_HAL_DRIVER */ /** - * @brief CMSIS Device version number V1.7.0 + * @brief CMSIS Device version number V1.7.1 */ #define __STM32L0xx_CMSIS_VERSION_MAIN (0x01) /*!< [31:24] main version */ #define __STM32L0xx_CMSIS_VERSION_SUB1 (0x07) /*!< [23:16] sub1 version */ -#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */ #define __STM32L0xx_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */ #define __STM32L0xx_CMSIS_VERSION ((__STM32L0xx_CMSIS_VERSION_MAIN << 24)\ - |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ - |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ - |(__STM32L0xx_CMSIS_VERSION_RC)) + |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ + |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ + |(__STM32L0xx_CMSIS_VERSION_RC)) /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/system_stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/system_stm32l0xx.h index fcf7649569..df958f5beb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/system_stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/device/system_stm32l0xx.h @@ -2,13 +2,11 @@ ****************************************************************************** * @file system_stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Header File. ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/device/stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/device/stm32l0xx.h index 884940fe67..a4ab0c0880 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/device/stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/device/stm32l0xx.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer Header File. * This file contains all the peripheral register's definitions, bits * definitions and memory mapping for STM32L0xx devices. @@ -20,7 +18,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -114,16 +112,16 @@ #endif /* USE_HAL_DRIVER */ /** - * @brief CMSIS Device version number V1.7.0 + * @brief CMSIS Device version number V1.7.1 */ #define __STM32L0xx_CMSIS_VERSION_MAIN (0x01) /*!< [31:24] main version */ #define __STM32L0xx_CMSIS_VERSION_SUB1 (0x07) /*!< [23:16] sub1 version */ -#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32L0xx_CMSIS_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */ #define __STM32L0xx_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */ #define __STM32L0xx_CMSIS_VERSION ((__STM32L0xx_CMSIS_VERSION_MAIN << 24)\ - |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ - |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ - |(__STM32L0xx_CMSIS_VERSION_RC)) + |(__STM32L0xx_CMSIS_VERSION_SUB1 << 16)\ + |(__STM32L0xx_CMSIS_VERSION_SUB2 << 8 )\ + |(__STM32L0xx_CMSIS_VERSION_RC)) /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/device/system_stm32l0xx.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/device/system_stm32l0xx.h index 7015debf51..8f3d7601be 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/device/system_stm32l0xx.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/device/system_stm32l0xx.h @@ -2,13 +2,11 @@ ****************************************************************************** * @file system_stm32l0xx.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Header File. ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32_hal_legacy.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32_hal_legacy.h index 48b38f6d3b..77647df28f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32_hal_legacy.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32_hal_legacy.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32_hal_legacy.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief This file contains aliases definition for the STM32Cube HAL constants * macros and functions maintained for legacy purpose. ****************************************************************************** @@ -138,6 +136,9 @@ #define COMP_EXTI_LINE_COMP5_EVENT COMP_EXTI_LINE_COMP5 #define COMP_EXTI_LINE_COMP6_EVENT COMP_EXTI_LINE_COMP6 #define COMP_EXTI_LINE_COMP7_EVENT COMP_EXTI_LINE_COMP7 +#if defined(STM32L0) +#define COMP_LPTIMCONNECTION_ENABLED ((uint32_t)0x00000003U) /*!< COMPX output generic naming: connected to LPTIM input 1 for COMP1, LPTIM input 2 for COMP2 */ +#endif #define COMP_OUTPUT_COMP6TIM2OCREFCLR COMP_OUTPUT_COMP6_TIM2OCREFCLR #if defined(STM32F373xC) || defined(STM32F378xx) #define COMP_OUTPUT_TIM3IC1 COMP_OUTPUT_COMP1_TIM3IC1 @@ -196,6 +197,7 @@ #define COMP_BLANKINGSRCE_TIM3OC4 COMP_BLANKINGSRC_TIM3_OC4_COMP2 #define COMP_BLANKINGSRCE_TIM8OC5 COMP_BLANKINGSRC_TIM8_OC5_COMP2 #define COMP_BLANKINGSRCE_TIM15OC1 COMP_BLANKINGSRC_TIM15_OC1_COMP2 +#define COMP_BLANKINGSRCE_NONE COMP_BLANKINGSRC_NONE #endif #if defined(STM32L0) @@ -263,7 +265,6 @@ #define HAL_REMAPDMA_TIM17_DMA_CH7 DMA_REMAP_TIM17_DMA_CH7 #define HAL_REMAPDMA_SPI2_DMA_CH67 DMA_REMAP_SPI2_DMA_CH67 #define HAL_REMAPDMA_USART2_DMA_CH67 DMA_REMAP_USART2_DMA_CH67 -#define HAL_REMAPDMA_USART3_DMA_CH32 DMA_REMAP_USART3_DMA_CH32 #define HAL_REMAPDMA_I2C1_DMA_CH76 DMA_REMAP_I2C1_DMA_CH76 #define HAL_REMAPDMA_TIM1_DMA_CH6 DMA_REMAP_TIM1_DMA_CH6 #define HAL_REMAPDMA_TIM2_DMA_CH7 DMA_REMAP_TIM2_DMA_CH7 @@ -354,6 +355,7 @@ #define OB_RDP_LEVEL0 OB_RDP_LEVEL_0 #define OB_RDP_LEVEL1 OB_RDP_LEVEL_1 #define OB_RDP_LEVEL2 OB_RDP_LEVEL_2 + /** * @} */ @@ -454,6 +456,78 @@ * @} */ +/** @defgroup HAL_JPEG_Aliased_Macros HAL JPEG Aliased Macros maintained for legacy purpose + * @{ + */ + +#if defined(STM32H7) + #define __HAL_RCC_JPEG_CLK_ENABLE __HAL_RCC_JPGDECEN_CLK_ENABLE + #define __HAL_RCC_JPEG_CLK_DISABLE __HAL_RCC_JPGDECEN_CLK_DISABLE + #define __HAL_RCC_JPEG_FORCE_RESET __HAL_RCC_JPGDECRST_FORCE_RESET + #define __HAL_RCC_JPEG_RELEASE_RESET __HAL_RCC_JPGDECRST_RELEASE_RESET + #define __HAL_RCC_JPEG_CLK_SLEEP_ENABLE __HAL_RCC_JPGDEC_CLK_SLEEP_ENABLE + #define __HAL_RCC_JPEG_CLK_SLEEP_DISABLE __HAL_RCC_JPGDEC_CLK_SLEEP_DISABLE + + #define DMA_REQUEST_DAC1 DMA_REQUEST_DAC1_CH1 + #define DMA_REQUEST_DAC2 DMA_REQUEST_DAC1_CH2 + + #define BDMA_REQUEST_LP_UART1_RX BDMA_REQUEST_LPUART1_RX + #define BDMA_REQUEST_LP_UART1_TX BDMA_REQUEST_LPUART1_TX + + #define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH0_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT + #define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH1_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT + #define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH2_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT + #define HAL_DMAMUX1_REQUEST_GEN_LPTIM1_OUT HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT + #define HAL_DMAMUX1_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT + #define HAL_DMAMUX1_REQUEST_GEN_LPTIM3_OUT HAL_DMAMUX1_REQ_GEN_LPTIM3_OUT + #define HAL_DMAMUX1_REQUEST_GEN_EXTI0 HAL_DMAMUX1_REQ_GEN_EXTI0 + #define HAL_DMAMUX1_REQUEST_GEN_TIM12_TRGO HAL_DMAMUX1_REQ_GEN_TIM12_TRGO + + #define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH0_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH0_EVT + #define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH1_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH1_EVT + #define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH2_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH2_EVT + #define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH3_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH3_EVT + #define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH4_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH4_EVT + #define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH5_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH5_EVT + #define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH6_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH6_EVT + #define HAL_DMAMUX2_REQUEST_GEN_LPUART1_RX_WKUP HAL_DMAMUX2_REQ_GEN_LPUART1_RX_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_LPUART1_TX_WKUP HAL_DMAMUX2_REQ_GEN_LPUART1_TX_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_LPTIM2_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM2_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT + #define HAL_DMAMUX2_REQUEST_GEN_LPTIM3_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM3_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_LPTIM3_OUT HAL_DMAMUX2_REQ_GEN_LPTIM3_OUT + #define HAL_DMAMUX2_REQUEST_GEN_LPTIM4_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM4_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_LPTIM5_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM5_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_I2C4_WKUP HAL_DMAMUX2_REQ_GEN_I2C4_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_SPI6_WKUP HAL_DMAMUX2_REQ_GEN_SPI6_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_COMP1_OUT HAL_DMAMUX2_REQ_GEN_COMP1_OUT + #define HAL_DMAMUX2_REQUEST_GEN_COMP2_OUT HAL_DMAMUX2_REQ_GEN_COMP2_OUT + #define HAL_DMAMUX2_REQUEST_GEN_RTC_WKUP HAL_DMAMUX2_REQ_GEN_RTC_WKUP + #define HAL_DMAMUX2_REQUEST_GEN_EXTI0 HAL_DMAMUX2_REQ_GEN_EXTI0 + #define HAL_DMAMUX2_REQUEST_GEN_EXTI2 HAL_DMAMUX2_REQ_GEN_EXTI2 + #define HAL_DMAMUX2_REQUEST_GEN_I2C4_IT_EVT HAL_DMAMUX2_REQ_GEN_I2C4_IT_EVT + #define HAL_DMAMUX2_REQUEST_GEN_SPI6_IT HAL_DMAMUX2_REQ_GEN_SPI6_IT + #define HAL_DMAMUX2_REQUEST_GEN_LPUART1_TX_IT HAL_DMAMUX2_REQ_GEN_LPUART1_TX_IT + #define HAL_DMAMUX2_REQUEST_GEN_LPUART1_RX_IT HAL_DMAMUX2_REQ_GEN_LPUART1_RX_IT + #define HAL_DMAMUX2_REQUEST_GEN_ADC3_IT HAL_DMAMUX2_REQ_GEN_ADC3_IT + #define HAL_DMAMUX2_REQUEST_GEN_ADC3_AWD1_OUT HAL_DMAMUX2_REQ_GEN_ADC3_AWD1_OUT + #define HAL_DMAMUX2_REQUEST_GEN_BDMA_CH0_IT HAL_DMAMUX2_REQ_GEN_BDMA_CH0_IT + #define HAL_DMAMUX2_REQUEST_GEN_BDMA_CH1_IT HAL_DMAMUX2_REQ_GEN_BDMA_CH1_IT + + #define HAL_DMAMUX_REQUEST_GEN_NO_EVENT HAL_DMAMUX_REQ_GEN_NO_EVENT + #define HAL_DMAMUX_REQUEST_GEN_RISING HAL_DMAMUX_REQ_GEN_RISING + #define HAL_DMAMUX_REQUEST_GEN_FALLING HAL_DMAMUX_REQ_GEN_FALLING + #define HAL_DMAMUX_REQUEST_GEN_RISING_FALLING HAL_DMAMUX_REQ_GEN_RISING_FALLING + + +#endif /* STM32H7 */ + + +/** + * @} + */ + + /** @defgroup HAL_HRTIM_Aliased_Macros HAL HRTIM Aliased Macros maintained for legacy purpose * @{ */ @@ -667,7 +741,6 @@ #define FORMAT_BCD RTC_FORMAT_BCD #define RTC_ALARMSUBSECONDMASK_None RTC_ALARMSUBSECONDMASK_NONE -#define RTC_TAMPERERASEBACKUP_ENABLED RTC_TAMPER_ERASE_BACKUP_ENABLE #define RTC_TAMPERERASEBACKUP_DISABLED RTC_TAMPER_ERASE_BACKUP_DISABLE #define RTC_TAMPERMASK_FLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE #define RTC_TAMPERMASK_FLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE @@ -675,9 +748,6 @@ #define RTC_MASKTAMPERFLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE #define RTC_MASKTAMPERFLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE #define RTC_TAMPERERASEBACKUP_ENABLED RTC_TAMPER_ERASE_BACKUP_ENABLE -#define RTC_TAMPERERASEBACKUP_DISABLED RTC_TAMPER_ERASE_BACKUP_DISABLE -#define RTC_MASKTAMPERFLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE -#define RTC_MASKTAMPERFLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE #define RTC_TAMPER1_2_INTERRUPT RTC_ALL_TAMPER_INTERRUPT #define RTC_TAMPER1_2_3_INTERRUPT RTC_ALL_TAMPER_INTERRUPT @@ -851,6 +921,8 @@ #define __DIVFRAQ_SAMPLING8 UART_DIVFRAQ_SAMPLING8 #define __UART_BRR_SAMPLING8 UART_BRR_SAMPLING8 +#define __DIV_LPUART UART_DIV_LPUART + #define UART_WAKEUPMETHODE_IDLELINE UART_WAKEUPMETHOD_IDLELINE #define UART_WAKEUPMETHODE_ADDRESSMARK UART_WAKEUPMETHOD_ADDRESSMARK @@ -941,9 +1013,12 @@ #define ETH_MAC_RXFIFO_BELOW_THRESHOLD ((uint32_t)0x00000100) /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */ #define ETH_MAC_RXFIFO_ABOVE_THRESHOLD ((uint32_t)0x00000200) /* Rx FIFO fill level: fill-level above flow-control activate threshold */ #define ETH_MAC_RXFIFO_FULL ((uint32_t)0x00000300) /* Rx FIFO fill level: full */ +#if defined(STM32F1) +#else #define ETH_MAC_READCONTROLLER_IDLE ((uint32_t)0x00000000) /* Rx FIFO read controller IDLE state */ #define ETH_MAC_READCONTROLLER_READING_DATA ((uint32_t)0x00000020) /* Rx FIFO read controller Reading frame data */ #define ETH_MAC_READCONTROLLER_READING_STATUS ((uint32_t)0x00000040) /* Rx FIFO read controller Reading frame status (or time-stamp) */ +#endif #define ETH_MAC_READCONTROLLER_FLUSHING ((uint32_t)0x00000060) /* Rx FIFO read controller Flushing the frame data and status */ #define ETH_MAC_RXFIFO_WRITE_ACTIVE ((uint32_t)0x00000010) /* Rx FIFO write controller active */ #define ETH_MAC_SMALL_FIFO_NOTACTIVE ((uint32_t)0x00000000) /* MAC small FIFO read / write controllers not active */ @@ -1304,7 +1379,6 @@ #define __HAL_ADC_CR1_SCANCONV ADC_CR1_SCANCONV #define __HAL_ADC_CR2_EOCSelection ADC_CR2_EOCSelection #define __HAL_ADC_CR2_DMAContReq ADC_CR2_DMAContReq -#define __HAL_ADC_GET_RESOLUTION ADC_GET_RESOLUTION #define __HAL_ADC_JSQR ADC_JSQR #define __HAL_ADC_CHSELR_CHANNEL ADC_CHSELR_CHANNEL @@ -1777,20 +1851,20 @@ #define HAL_RCC_CCSCallback HAL_RCC_CSSCallback #define HAL_RC48_EnableBuffer_Cmd(cmd) (((cmd)==ENABLE) ? HAL_RCCEx_EnableHSI48_VREFINT() : HAL_RCCEx_DisableHSI48_VREFINT()) -#define __ADC_CLK_DISABLE __HAL_RCC_ADC_CLK_DISABLE -#define __ADC_CLK_ENABLE __HAL_RCC_ADC_CLK_ENABLE -#define __ADC_CLK_SLEEP_DISABLE __HAL_RCC_ADC_CLK_SLEEP_DISABLE -#define __ADC_CLK_SLEEP_ENABLE __HAL_RCC_ADC_CLK_SLEEP_ENABLE -#define __ADC_FORCE_RESET __HAL_RCC_ADC_FORCE_RESET -#define __ADC_RELEASE_RESET __HAL_RCC_ADC_RELEASE_RESET -#define __ADC1_CLK_DISABLE __HAL_RCC_ADC1_CLK_DISABLE -#define __ADC1_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE -#define __ADC1_FORCE_RESET __HAL_RCC_ADC1_FORCE_RESET -#define __ADC1_RELEASE_RESET __HAL_RCC_ADC1_RELEASE_RESET -#define __ADC1_CLK_SLEEP_ENABLE __HAL_RCC_ADC1_CLK_SLEEP_ENABLE -#define __ADC1_CLK_SLEEP_DISABLE __HAL_RCC_ADC1_CLK_SLEEP_DISABLE -#define __ADC2_CLK_DISABLE __HAL_RCC_ADC2_CLK_DISABLE -#define __ADC2_CLK_ENABLE __HAL_RCC_ADC2_CLK_ENABLE +#define __ADC_CLK_DISABLE __HAL_RCC_ADC_CLK_DISABLE +#define __ADC_CLK_ENABLE __HAL_RCC_ADC_CLK_ENABLE +#define __ADC_CLK_SLEEP_DISABLE __HAL_RCC_ADC_CLK_SLEEP_DISABLE +#define __ADC_CLK_SLEEP_ENABLE __HAL_RCC_ADC_CLK_SLEEP_ENABLE +#define __ADC_FORCE_RESET __HAL_RCC_ADC_FORCE_RESET +#define __ADC_RELEASE_RESET __HAL_RCC_ADC_RELEASE_RESET +#define __ADC1_CLK_DISABLE __HAL_RCC_ADC1_CLK_DISABLE +#define __ADC1_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE +#define __ADC1_FORCE_RESET __HAL_RCC_ADC1_FORCE_RESET +#define __ADC1_RELEASE_RESET __HAL_RCC_ADC1_RELEASE_RESET +#define __ADC1_CLK_SLEEP_ENABLE __HAL_RCC_ADC1_CLK_SLEEP_ENABLE +#define __ADC1_CLK_SLEEP_DISABLE __HAL_RCC_ADC1_CLK_SLEEP_DISABLE +#define __ADC2_CLK_DISABLE __HAL_RCC_ADC2_CLK_DISABLE +#define __ADC2_CLK_ENABLE __HAL_RCC_ADC2_CLK_ENABLE #define __ADC2_FORCE_RESET __HAL_RCC_ADC2_FORCE_RESET #define __ADC2_RELEASE_RESET __HAL_RCC_ADC2_RELEASE_RESET #define __ADC3_CLK_DISABLE __HAL_RCC_ADC3_CLK_DISABLE @@ -1807,7 +1881,7 @@ #define __CRYP_CLK_SLEEP_DISABLE __HAL_RCC_CRYP_CLK_SLEEP_DISABLE #define __CRYP_CLK_ENABLE __HAL_RCC_CRYP_CLK_ENABLE #define __CRYP_CLK_DISABLE __HAL_RCC_CRYP_CLK_DISABLE -#define __CRYP_FORCE_RESET __HAL_RCC_CRYP_FORCE_RESET +#define __CRYP_FORCE_RESET __HAL_RCC_CRYP_FORCE_RESET #define __CRYP_RELEASE_RESET __HAL_RCC_CRYP_RELEASE_RESET #define __AFIO_CLK_DISABLE __HAL_RCC_AFIO_CLK_DISABLE #define __AFIO_CLK_ENABLE __HAL_RCC_AFIO_CLK_ENABLE @@ -2223,26 +2297,26 @@ #define __USART3_CLK_SLEEP_ENABLE __HAL_RCC_USART3_CLK_SLEEP_ENABLE #define __USART3_FORCE_RESET __HAL_RCC_USART3_FORCE_RESET #define __USART3_RELEASE_RESET __HAL_RCC_USART3_RELEASE_RESET -#define __USART4_CLK_DISABLE __HAL_RCC_USART4_CLK_DISABLE -#define __USART4_CLK_ENABLE __HAL_RCC_USART4_CLK_ENABLE -#define __USART4_CLK_SLEEP_ENABLE __HAL_RCC_USART4_CLK_SLEEP_ENABLE -#define __USART4_CLK_SLEEP_DISABLE __HAL_RCC_USART4_CLK_SLEEP_DISABLE -#define __USART4_FORCE_RESET __HAL_RCC_USART4_FORCE_RESET -#define __USART4_RELEASE_RESET __HAL_RCC_USART4_RELEASE_RESET -#define __USART5_CLK_DISABLE __HAL_RCC_USART5_CLK_DISABLE -#define __USART5_CLK_ENABLE __HAL_RCC_USART5_CLK_ENABLE -#define __USART5_CLK_SLEEP_ENABLE __HAL_RCC_USART5_CLK_SLEEP_ENABLE -#define __USART5_CLK_SLEEP_DISABLE __HAL_RCC_USART5_CLK_SLEEP_DISABLE -#define __USART5_FORCE_RESET __HAL_RCC_USART5_FORCE_RESET -#define __USART5_RELEASE_RESET __HAL_RCC_USART5_RELEASE_RESET -#define __USART7_CLK_DISABLE __HAL_RCC_USART7_CLK_DISABLE -#define __USART7_CLK_ENABLE __HAL_RCC_USART7_CLK_ENABLE -#define __USART7_FORCE_RESET __HAL_RCC_USART7_FORCE_RESET -#define __USART7_RELEASE_RESET __HAL_RCC_USART7_RELEASE_RESET -#define __USART8_CLK_DISABLE __HAL_RCC_USART8_CLK_DISABLE -#define __USART8_CLK_ENABLE __HAL_RCC_USART8_CLK_ENABLE -#define __USART8_FORCE_RESET __HAL_RCC_USART8_FORCE_RESET -#define __USART8_RELEASE_RESET __HAL_RCC_USART8_RELEASE_RESET +#define __USART4_CLK_DISABLE __HAL_RCC_UART4_CLK_DISABLE +#define __USART4_CLK_ENABLE __HAL_RCC_UART4_CLK_ENABLE +#define __USART4_CLK_SLEEP_ENABLE __HAL_RCC_UART4_CLK_SLEEP_ENABLE +#define __USART4_CLK_SLEEP_DISABLE __HAL_RCC_UART4_CLK_SLEEP_DISABLE +#define __USART4_FORCE_RESET __HAL_RCC_UART4_FORCE_RESET +#define __USART4_RELEASE_RESET __HAL_RCC_UART4_RELEASE_RESET +#define __USART5_CLK_DISABLE __HAL_RCC_UART5_CLK_DISABLE +#define __USART5_CLK_ENABLE __HAL_RCC_UART5_CLK_ENABLE +#define __USART5_CLK_SLEEP_ENABLE __HAL_RCC_UART5_CLK_SLEEP_ENABLE +#define __USART5_CLK_SLEEP_DISABLE __HAL_RCC_UART5_CLK_SLEEP_DISABLE +#define __USART5_FORCE_RESET __HAL_RCC_UART5_FORCE_RESET +#define __USART5_RELEASE_RESET __HAL_RCC_UART5_RELEASE_RESET +#define __USART7_CLK_DISABLE __HAL_RCC_UART7_CLK_DISABLE +#define __USART7_CLK_ENABLE __HAL_RCC_UART7_CLK_ENABLE +#define __USART7_FORCE_RESET __HAL_RCC_UART7_FORCE_RESET +#define __USART7_RELEASE_RESET __HAL_RCC_UART7_RELEASE_RESET +#define __USART8_CLK_DISABLE __HAL_RCC_UART8_CLK_DISABLE +#define __USART8_CLK_ENABLE __HAL_RCC_UART8_CLK_ENABLE +#define __USART8_FORCE_RESET __HAL_RCC_UART8_FORCE_RESET +#define __USART8_RELEASE_RESET __HAL_RCC_UART8_RELEASE_RESET #define __USB_CLK_DISABLE __HAL_RCC_USB_CLK_DISABLE #define __USB_CLK_ENABLE __HAL_RCC_USB_CLK_ENABLE #define __USB_FORCE_RESET __HAL_RCC_USB_FORCE_RESET @@ -2402,7 +2476,6 @@ #define __HAL_RCC_OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE #define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_ENABLED __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_ENABLED #define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_DISABLED __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_DISABLED -#define __CRYP_FORCE_RESET __HAL_RCC_CRYP_FORCE_RESET #define __SRAM3_CLK_SLEEP_ENABLE __HAL_RCC_SRAM3_CLK_SLEEP_ENABLE #define __CAN2_CLK_SLEEP_ENABLE __HAL_RCC_CAN2_CLK_SLEEP_ENABLE #define __CAN2_CLK_SLEEP_DISABLE __HAL_RCC_CAN2_CLK_SLEEP_DISABLE @@ -2435,8 +2508,6 @@ #define __ADC12_CLK_DISABLE __HAL_RCC_ADC12_CLK_DISABLE #define __ADC34_CLK_ENABLE __HAL_RCC_ADC34_CLK_ENABLE #define __ADC34_CLK_DISABLE __HAL_RCC_ADC34_CLK_DISABLE -#define __ADC12_CLK_ENABLE __HAL_RCC_ADC12_CLK_ENABLE -#define __ADC12_CLK_DISABLE __HAL_RCC_ADC12_CLK_DISABLE #define __DAC2_CLK_ENABLE __HAL_RCC_DAC2_CLK_ENABLE #define __DAC2_CLK_DISABLE __HAL_RCC_DAC2_CLK_DISABLE #define __TIM18_CLK_ENABLE __HAL_RCC_TIM18_CLK_ENABLE @@ -2458,8 +2529,6 @@ #define __ADC12_RELEASE_RESET __HAL_RCC_ADC12_RELEASE_RESET #define __ADC34_FORCE_RESET __HAL_RCC_ADC34_FORCE_RESET #define __ADC34_RELEASE_RESET __HAL_RCC_ADC34_RELEASE_RESET -#define __ADC12_FORCE_RESET __HAL_RCC_ADC12_FORCE_RESET -#define __ADC12_RELEASE_RESET __HAL_RCC_ADC12_RELEASE_RESET #define __DAC2_FORCE_RESET __HAL_RCC_DAC2_FORCE_RESET #define __DAC2_RELEASE_RESET __HAL_RCC_DAC2_RELEASE_RESET #define __TIM18_FORCE_RESET __HAL_RCC_TIM18_FORCE_RESET @@ -2644,10 +2713,22 @@ #define RCC_IT_HSI14 RCC_IT_HSI14RDY -#if defined(STM32L0) -#define RCC_IT_LSECSS RCC_IT_CSSLSE -#define RCC_IT_CSS RCC_IT_CSSHSE -#endif +#define RCC_IT_CSSLSE RCC_IT_LSECSS +#define RCC_IT_CSSHSE RCC_IT_CSS + +#define RCC_PLLMUL_3 RCC_PLL_MUL3 +#define RCC_PLLMUL_4 RCC_PLL_MUL4 +#define RCC_PLLMUL_6 RCC_PLL_MUL6 +#define RCC_PLLMUL_8 RCC_PLL_MUL8 +#define RCC_PLLMUL_12 RCC_PLL_MUL12 +#define RCC_PLLMUL_16 RCC_PLL_MUL16 +#define RCC_PLLMUL_24 RCC_PLL_MUL24 +#define RCC_PLLMUL_32 RCC_PLL_MUL32 +#define RCC_PLLMUL_48 RCC_PLL_MUL48 + +#define RCC_PLLDIV_2 RCC_PLL_DIV2 +#define RCC_PLLDIV_3 RCC_PLL_DIV3 +#define RCC_PLLDIV_4 RCC_PLL_DIV4 #define IS_RCC_MCOSOURCE IS_RCC_MCO1SOURCE #define __HAL_RCC_MCO_CONFIG __HAL_RCC_MCO1_CONFIG @@ -2672,7 +2753,10 @@ #define RCC_MCOSOURCE_PLLCLK_NODIV RCC_MCO1SOURCE_PLLCLK #define RCC_MCOSOURCE_PLLCLK_DIV2 RCC_MCO1SOURCE_PLLCLK_DIV2 +#if defined(STM32WB) || defined(STM32G0) +#else #define RCC_RTCCLKSOURCE_NONE RCC_RTCCLKSOURCE_NO_CLK +#endif #define RCC_USBCLK_PLLSAI1 RCC_USBCLKSOURCE_PLLSAI1 #define RCC_USBCLK_PLL RCC_USBCLKSOURCE_PLL @@ -2768,7 +2852,6 @@ #define RCC_DFSDMCLKSOURCE_SYSCLK RCC_DFSDM1CLKSOURCE_SYSCLK #define __HAL_RCC_DFSDM_CONFIG __HAL_RCC_DFSDM1_CONFIG #define __HAL_RCC_GET_DFSDM_SOURCE __HAL_RCC_GET_DFSDM1_SOURCE - /** * @} */ @@ -2785,8 +2868,10 @@ /** @defgroup HAL_RTC_Aliased_Macros HAL RTC Aliased Macros maintained for legacy purpose * @{ */ - +#if defined (STM32G0) +#else #define __HAL_RTC_CLEAR_FLAG __HAL_RTC_EXTI_CLEAR_FLAG +#endif #define __HAL_RTC_DISABLE_IT __HAL_RTC_EXTI_DISABLE_IT #define __HAL_RTC_ENABLE_IT __HAL_RTC_EXTI_ENABLE_IT diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal.c index 00ebc15bbc..bd160f0c30 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief HAL module driver. * This is the common part of the HAL initialization * @@ -86,11 +84,11 @@ __IO uint32_t uwTick; */ /** - * @brief STM32L0xx HAL Driver version number V1.7.0 + * @brief STM32L0xx HAL Driver version number */ #define __STM32L0xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */ -#define __STM32L0xx_HAL_VERSION_SUB1 (0x07U) /*!< [23:16] sub1 version */ -#define __STM32L0xx_HAL_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */ +#define __STM32L0xx_HAL_VERSION_SUB1 (0x08U) /*!< [23:16] sub1 version */ +#define __STM32L0xx_HAL_VERSION_SUB2 (0x02U) /*!< [15:8] sub2 version */ #define __STM32L0xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */ #define __STM32L0xx_HAL_VERSION ((__STM32L0xx_HAL_VERSION_MAIN << 24U)\ |(__STM32L0xx_HAL_VERSION_SUB1 << 16U)\ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal.h index 5e27c77b7a..f3c7367de7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief This file contains all the functions prototypes for the HAL * module driver. ****************************************************************************** @@ -346,7 +344,7 @@ * @arg SYSCFG_FASTMODEPLUS_PB9 */ #define __HAL_SYSCFG_FASTMODEPLUS_ENABLE(__FASTMODEPLUS__) do {assert_param(IS_SYSCFG_FASTMODEPLUS((__FASTMODEPLUS__))); \ - SET_BIT(SYSCFG->CFGR2, __FASTMODEPLUS__); \ + SET_BIT(SYSCFG->CFGR2, (__FASTMODEPLUS__)); \ }while(0) /** @brief Fast mode Plus driving capability disable macro * @param __FASTMODEPLUS__: This parameter can be a value of : @@ -356,7 +354,7 @@ * @arg SYSCFG_FASTMODEPLUS_PB9 */ #define __HAL_SYSCFG_FASTMODEPLUS_DISABLE(__FASTMODEPLUS__) do {assert_param(IS_SYSCFG_FASTMODEPLUS((__FASTMODEPLUS__))); \ - CLEAR_BIT(SYSCFG->CFGR2, __FASTMODEPLUS__); \ + CLEAR_BIT(SYSCFG->CFGR2, (__FASTMODEPLUS__)); \ }while(0) diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc.c index 575b3b930c..da7990a72f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc.c @@ -2,16 +2,14 @@ ****************************************************************************** * @file stm32l0xx_hal_adc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief This file provides firmware functions to manage the following * functionalities of the Analog to Digital Convertor (ADC) * peripheral: * + Initialization and de-initialization functions * ++ Initialization and Configuration of ADC * + Operation functions - * ++ Start, stop, get result of conversions of regular - * group, using 3 possible modes : polling, interruption or DMA. + * ++ Start, stop, get result of conversions of regular + * group, using 3 possible modes: polling, interruption or DMA. * + Control functions * ++ Channels configuration on regular group * ++ Analog Watchdog configuration @@ -20,38 +18,34 @@ * ++ Interrupts and flags management * Other functions (extended functions) are available in file * "stm32l0xx_hal_adc_ex.c". - * + * @verbatim ============================================================================== ##### ADC peripheral features ##### ============================================================================== - [..] - (+) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution - - (+) A built-in hardware oversampler can handle multiple conversions and average - them into a single data with increased data width, up to 16-bit. + [..] + (+) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution. (+) Interrupt generation at the end of regular conversion and in case of analog watchdog or overrun events. - + (+) Single and continuous conversion modes. (+) Scan mode for conversion of several channels sequentially. (+) Data alignment with in-built data coherency. - + (+) Programmable sampling time (common for all channels) - (+) ADC conversion of regular group. - (+) External trigger (timer or EXTI) with configurable polarity - + (+) DMA request generation for transfer of conversions data of regular group. (+) ADC calibration - - (+) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at - slower speed. + + (+) ADC conversion of regular group. + + (+) ADC supply requirements: 1.62 V to 3.6 V. (+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to Vdda or to an external voltage reference). @@ -65,13 +59,13 @@ ============================================================ [..] - (#) Enable the ADC interface - (++) As prerequisite, ADC clock must be configured at RCC top level. - Caution: On STM32L0, ADC clock frequency max is 16MHz (refer - to device datasheet). - Therefore, ADC clock prescaler must be configured in - function of ADC clock source frequency to remain below - this maximum frequency. + (#) Enable the ADC interface + (++) As prerequisite, ADC clock must be configured at RCC top level. + Caution: On STM32L0, ADC clock frequency max is 16MHz (refer + to device datasheet). + Therefore, ADC clock prescaler must be configured in + function of ADC clock source frequency to remain below + this maximum frequency. (++) Two clock settings are mandatory: (+++) ADC clock (core clock, also possibly conversion clock). @@ -87,9 +81,9 @@ (+++) Example: Into HAL_ADC_MspInit() (recommended code location) or with other device clock parameters configuration: - (+++) __HAL_RCC_ADC1_CLK_ENABLE(); (mandatory) + (+++) __HAL_RCC_ADC1_CLK_ENABLE(); (mandatory) - HSI16 enable : (optional: if asynchronous clock selected) + HSI enable (optional: if asynchronous clock selected) (+++) RCC_OscInitTypeDef RCC_OscInitStructure; (+++) RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI; (+++) RCC_OscInitStructure.HSI16CalibrationValue = RCC_HSICALIBRATION_DEFAULT; @@ -126,7 +120,7 @@ ================================================================ [..] - (#) Configure the ADC parameters (resolution, data alignment, oversampler, continuous mode, ...) + (#) Configure the ADC parameters (resolution, data alignment, ...) and regular group parameters (conversion trigger, sequencer, ...) using function HAL_ADC_Init(). @@ -186,9 +180,9 @@ destination variable address. (+++) Stop conversion and disable the ADC peripheral using function HAL_ADC_Stop_DMA() - - [..] - + + [..] + (@) Callback functions must be implemented in user program: (+@) HAL_ADC_ErrorCallback() (+@) HAL_ADC_LevelOutOfWindowCallback() (callback of analog watchdog) @@ -266,20 +260,20 @@ * @{ */ -#ifdef HAL_ADC_MODULE_ENABLED - -/** @addtogroup ADC - * @brief ADC driver modules - * @{ - */ - -/** @addtogroup ADC_Private +/** @defgroup ADC ADC + * @brief ADC HAL module driver * @{ */ - + +#ifdef HAL_ADC_MODULE_ENABLED + /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ +/** @defgroup ADC_Private_Constants ADC Private Constants + * @{ + */ + /* Delay for ADC stabilization time. */ /* Maximum delay is 1us (refer to device datasheet, parameter tSTART). */ /* Unit: us */ @@ -296,9 +290,9 @@ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ -/** @addtogroup ADC_Private +/** @defgroup ADC_Private_Functions ADC Private Functions * @{ - */ + */ static HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc); static HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef* hadc); static HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef* hadc); @@ -310,32 +304,32 @@ static void ADC_DelayMicroSecond(uint32_t microSecond); * @} */ -/** @addtogroup ADC_Exported_Functions - * @{ - */ +/* Exported functions ---------------------------------------------------------*/ -/** @addtogroup ADC_Exported_Functions_Group1 - * @brief Initialization and Configuration functions - * +/** @defgroup ADC_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief ADC Initialization and Configuration functions + * @verbatim =============================================================================== ##### Initialization and de-initialization functions ##### =============================================================================== [..] This section provides functions allowing to: (+) Initialize and configure the ADC. - (+) De-initialize the ADC. - + (+) De-initialize the ADC. @endverbatim * @{ */ - /** - * @brief Initializes the ADC peripheral and regular group according to + * @brief Initialize the ADC peripheral and regular group according to * parameters specified in structure "ADC_InitTypeDef". * @note As prerequisite, ADC clock must be configured at RCC top level - * depending on both possible clock sources: APB clock of HSI clock. - * See commented example code below that can be copied and uncommented + * depending on possible clock sources: APB clock of HSI clock. + * See commented example code below that can be copied and uncommented * into HAL_ADC_MspInit(). * @note Possibility to update parameters on the fly: * This function initializes the ADC MSP (HAL_ADC_MspInit()) only when @@ -371,18 +365,19 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc) assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler)); assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution)); - assert_param(IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTime)); - assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode)); - assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign)); + assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign)); + assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode)); assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); - assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv)); + assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); + assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection)); assert_param(IS_ADC_OVERRUN(hadc->Init.Overrun)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerAutoWait)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerFrequencyMode)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerAutoPowerOff)); + assert_param(IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTime)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.OversamplingMode)); /* As prerequisite, into HAL_ADC_MspInit(), ADC clock must be configured */ @@ -400,14 +395,14 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc) /* Allocate lock resource and initialize it */ hadc->Lock = HAL_UNLOCKED; - + /* Init the low level hardware */ HAL_ADC_MspInit(hadc); } /* Configuration of ADC parameters if previous preliminary actions are */ /* correctly completed. */ - /* and if there is no conversion on going on regular group (ADC can be */ + /* and if there is no conversion on going on regular group (ADC can be */ /* enabled anyway, in case of call of this function to update a parameter */ /* on the fly). */ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL) || @@ -473,20 +468,20 @@ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc) /* - Overrun */ /* - AutoDelay feature */ /* - Discontinuous mode */ - hadc->Instance->CFGR1 &= ~(ADC_CFGR1_ALIGN | - ADC_CFGR1_SCANDIR | - ADC_CFGR1_EXTSEL | - ADC_CFGR1_EXTEN | - ADC_CFGR1_CONT | - ADC_CFGR1_DMACFG | - ADC_CFGR1_OVRMOD | - ADC_CFGR1_AUTDLY | - ADC_CFGR1_AUTOFF | - ADC_CFGR1_DISCEN); + hadc->Instance->CFGR1 &= ~(ADC_CFGR1_ALIGN | + ADC_CFGR1_SCANDIR | + ADC_CFGR1_EXTSEL | + ADC_CFGR1_EXTEN | + ADC_CFGR1_CONT | + ADC_CFGR1_DMACFG | + ADC_CFGR1_OVRMOD | + ADC_CFGR1_AUTDLY | + ADC_CFGR1_AUTOFF | + ADC_CFGR1_DISCEN ); hadc->Instance->CFGR1 |= (hadc->Init.DataAlign | ADC_SCANDIR(hadc->Init.ScanConvMode) | - ADC_CONTINUOUS(hadc->Init.ContinuousConvMode) | + ADC_CONTINUOUS(hadc->Init.ContinuousConvMode) | ADC_DMACONTREQ(hadc->Init.DMAContinuousRequests) | hadc->Init.Overrun | __HAL_ADC_CFGR1_AutoDelay(hadc->Init.LowPowerAutoWait) | @@ -594,7 +589,7 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc) /* Check ADC handle */ if(hadc == NULL) { - return HAL_ERROR; + return HAL_ERROR; } /* Check the parameters */ @@ -618,7 +613,7 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc) /* Change ADC state */ hadc->State = HAL_ADC_STATE_READY; } - } + } /* Configuration of ADC parameters if previous preliminary actions are */ @@ -692,20 +687,19 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc) /* Set ADC error code to none */ ADC_CLEAR_ERRORCODE(hadc); - /* Set ADC state */ - hadc->State = HAL_ADC_STATE_RESET; + /* Set ADC state */ + hadc->State = HAL_ADC_STATE_RESET; } /* Process unlocked */ __HAL_UNLOCK(hadc); - + /* Return function status */ return tmp_hal_status; } - /** - * @brief Initializes the ADC MSP. + * @brief Initialize the ADC MSP. * @param hadc: ADC handle * @retval None */ @@ -714,13 +708,13 @@ __weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ADC_MspInit could be implemented in the user file + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADC_MspInit must be implemented in the user file. */ } /** - * @brief DeInitializes the ADC MSP. + * @brief DeInitialize the ADC MSP. * @param hadc: ADC handle * @retval None */ @@ -738,18 +732,18 @@ __weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) * @} */ -/** @addtogroup ADC_Exported_Functions_Group2 - * @brief I/O operation functions +/** @defgroup ADC_Exported_Functions_Group2 ADC Input and Output operation functions + * @brief ADC IO operation functions * @verbatim =============================================================================== - ##### IO operation functions ##### - =============================================================================== + ##### IO operation functions ##### + =============================================================================== [..] This section provides functions allowing to: (+) Start conversion of regular group. (+) Stop conversion of regular group. (+) Poll for conversion complete on regular group. - (+) poll for conversion event. + (+) Poll for conversion event. (+) Get result of regular channel conversion. (+) Start conversion of regular group and enable interruptions. (+) Stop conversion of regular group and disable interruptions. @@ -760,10 +754,9 @@ __weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) * @{ */ - /** - * @brief Enables ADC, starts conversion of regular group. - * Interruptions enabled in this function: None. + * @brief Enable ADC, start conversion of regular group. + * @note Interruptions enabled in this function: None. * @param hadc: ADC handle * @retval HAL status */ @@ -781,8 +774,8 @@ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc) __HAL_LOCK(hadc); /* Enable the ADC peripheral */ - /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ - /* performed automatically by hardware. */ + /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ + /* performed automatically by hardware. */ if (hadc->Init.LowPowerAutoPowerOff != ENABLE) { tmp_hal_status = ADC_Enable(hadc); @@ -800,11 +793,11 @@ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc) /* Reset ADC all error code fields */ ADC_CLEAR_ERRORCODE(hadc); - - /* Process unlocked */ + + /* Process unlocked */ /* Unlock before starting ADC conversions: in case of potential */ /* interruption, to let the process to ADC IRQ Handler. */ - __HAL_UNLOCK(hadc); + __HAL_UNLOCK(hadc); /* Clear regular group conversion flag and overrun flag */ /* (To ensure of no unknown state from potential previous ADC */ @@ -828,7 +821,8 @@ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc) } /** - * @brief Stop ADC conversion of regular group, disable ADC peripheral. + * @brief Stop ADC conversion of regular group (and injected channels in + * case of auto_injection mode), disable ADC peripheral. * @param hadc: ADC handle * @retval HAL status. */ @@ -842,7 +836,7 @@ HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc) /* Process locked */ __HAL_LOCK(hadc); - /* 1. Stop potential conversion on going, on regular group */ + /* 1. Stop potential conversion on going, on ADC group regular */ tmp_hal_status = ADC_ConversionStop(hadc); /* Disable ADC peripheral if conversions are effectively stopped */ @@ -859,7 +853,7 @@ HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc) HAL_ADC_STATE_REG_BUSY, HAL_ADC_STATE_READY); } - } + } /* Process unlocked */ __HAL_UNLOCK(hadc); @@ -888,19 +882,18 @@ HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc) */ HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout) { - uint32_t tickstart; - uint32_t tmp_Flag_EOC; - + uint32_t tickstart = 0; + uint32_t tmp_Flag_EOC = 0x00; + /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection)); - - /* If end of conversion selected to end of sequence */ + + /* If end of conversion selected to end of sequence conversions */ if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV) { tmp_Flag_EOC = ADC_FLAG_EOS; } - /* If end of conversion selected to end of each conversion */ + /* If end of conversion selected to end of unitary conversion */ else /* ADC_EOC_SINGLE_CONV */ { /* Verification that ADC configuration is compliant with polling for */ @@ -928,7 +921,7 @@ HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Ti /* Get tick count */ tickstart = HAL_GetTick(); - /* Wait until End of Conversion flag is raised */ + /* Wait until End of unitary conversion or sequence conversions flag is raised */ while(HAL_IS_BIT_CLR(hadc->Instance->ISR, tmp_Flag_EOC)) { /* Check if timeout is disabled (set to infinite wait) */ @@ -993,18 +986,24 @@ HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Ti __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS)); } - /* Return ADC state */ + /* Return function status */ return HAL_OK; } /** - * @brief Poll for conversion event. + * @brief Poll for ADC event. * @param hadc: ADC handle * @param EventType: the ADC event type. * This parameter can be one of the following values: * @arg ADC_AWD_EVENT: ADC Analog watchdog event * @arg ADC_OVR_EVENT: ADC Overrun event * @param Timeout: Timeout value in millisecond. + * @note The relevant flag is cleared if found to be set, except for ADC_FLAG_OVR. + * Indeed, the latter is reset only if hadc->Init.Overrun field is set + * to ADC_OVR_DATA_OVERWRITTEN. Otherwise, data register may be potentially overwritten + * by a new converted data as soon as OVR is cleared. + * To reset OVR flag once the preserved data is retrieved, the user can resort + * to macro __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout) @@ -1024,7 +1023,7 @@ HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventTy /* Check if timeout is disabled (set to infinite wait) */ if(Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + if((Timeout == 0U) ||((HAL_GetTick() - tickstart ) > Timeout)) { /* Update ADC state machine to timeout */ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); @@ -1068,25 +1067,32 @@ HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventTy break; } - /* Return ADC state */ + /* Return function status */ return HAL_OK; } /** - * @brief Enables ADC, starts conversion of regular group with interruption. - * Interruptions enabled in this function: - * - EOC (end of conversion of regular group) or EOS (end of - * sequence of regular group) depending on ADC initialization - * parameter "EOCSelection" - * - overrun (if available) + * @brief Enable ADC, start conversion of regular group with interruption. + * @note Interruptions enabled in this function according to initialization + * setting : EOC (end of conversion), EOS (end of sequence), + * OVR overrun. * Each of these interruptions has its dedicated callback function. + * @note To guarantee a proper reset of all interruptions once all the needed + * conversions are obtained, HAL_ADC_Stop_IT() must be called to ensure + * a correct stop of the IT-based conversions. + * @note By default, HAL_ADC_Start_IT() doesn't enable the End Of Sampling + * interruption. If required (e.g. in case of oversampling with trigger + * mode), the user must: + * 1. first clear the EOSMP flag if set with macro __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP) + * 2. then enable the EOSMP interrupt with macro __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOSMP) + * before calling HAL_ADC_Start_IT(). * @param hadc: ADC handle * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; - + /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); @@ -1097,8 +1103,8 @@ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc) __HAL_LOCK(hadc); /* Enable the ADC peripheral */ - /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ - /* performed automatically by hardware. */ + /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ + /* performed automatically by hardware. */ if (hadc->Init.LowPowerAutoPowerOff != ENABLE) { tmp_hal_status = ADC_Enable(hadc); @@ -1128,8 +1134,7 @@ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc) __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR)); /* Enable ADC end of conversion interrupt */ - /* Enable ADC overrun interrupt */ - assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection)); + /* Enable ADC overrun interrupt */ switch(hadc->Init.EOCSelection) { case ADC_EOC_SEQ_CONV: @@ -1153,13 +1158,14 @@ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc) { tmp_hal_status = HAL_BUSY; } - + /* Return function status */ return tmp_hal_status; } /** - * @brief Stop ADC conversion of regular group, disable interruption of + * @brief Stop ADC conversion of regular group (and injected group in + * case of auto_injection mode), disable interrution of * end-of-conversion, disable ADC peripheral. * @param hadc: ADC handle * @retval HAL status. @@ -1170,11 +1176,11 @@ HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc) /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - + /* Process locked */ __HAL_LOCK(hadc); - /* 1. Stop potential conversion on going, on regular group */ + /* 1. Stop potential conversion on going, on ADC group regular */ tmp_hal_status = ADC_ConversionStop(hadc); /* Disable ADC peripheral if conversions are effectively stopped */ @@ -1205,17 +1211,14 @@ HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc) } /** - * @brief Enables ADC, starts conversion of regular group and transfers result - * through DMA. - * Interruptions enabled in this function: - * - DMA transfer complete - * - DMA half transfer - * - overrun + * @brief Enable ADC, start conversion of regular group and transfer result through DMA. + * @note Interruptions enabled in this function: + * overrun (if applicable), DMA half transfer, DMA transfer complete. * Each of these interruptions has its dedicated callback function. * @param hadc: ADC handle - * @param pData: The destination Buffer address. - * @param Length: The length of data to be transferred from ADC peripheral to memory. - * @retval None + * @param pData: Destination Buffer address. + * @param Length: Length of data to be transferred from ADC peripheral to memory (in bytes) + * @retval HAL status. */ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) { @@ -1229,8 +1232,8 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, ui { /* Process locked */ __HAL_LOCK(hadc); - - /* Enable the ADC peripheral */ + + /* Enable the ADC peripheral */ /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ /* performed automatically by hardware. */ if (hadc->Init.LowPowerAutoPowerOff != ENABLE) @@ -1255,10 +1258,10 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, ui /* Unlock before starting ADC conversions: in case of potential */ /* interruption, to let the process to ADC IRQ Handler. */ __HAL_UNLOCK(hadc); - + /* Set the DMA transfer complete callback */ hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; - + /* Set the DMA half transfer complete callback */ hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt; @@ -1282,7 +1285,7 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, ui /* Start the DMA channel */ HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); - + /* Enable conversion of regular group. */ /* If software start has been selected, conversion starts immediately. */ /* If external trigger has been selected, conversion will start at next */ @@ -1300,7 +1303,8 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, ui } /** - * @brief Stop ADC conversion of regular group, disable ADC DMA transfer, disable + * @brief Stop ADC conversion of regular group (and injected group in + * case of auto_injection mode), disable ADC DMA transfer, disable * ADC peripheral. * Each of these interruptions has its dedicated callback function. * @param hadc: ADC handle @@ -1316,18 +1320,18 @@ HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc) /* Process locked */ __HAL_LOCK(hadc); - /* 1. Stop potential conversion on going, on regular group */ + /* 1. Stop potential ADC group regular conversion on going */ tmp_hal_status = ADC_ConversionStop(hadc); /* Disable ADC peripheral if conversions are effectively stopped */ if (tmp_hal_status == HAL_OK) { /* Disable ADC DMA (ADC DMA configuration ADC_CFGR_DMACFG is kept) */ - hadc->Instance->CFGR1 &= ~ADC_CFGR1_DMAEN; + CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN); - /* Disable the DMA channel (in case of DMA in circular mode or stop while */ + /* Disable the DMA channel (in case of DMA in circular mode or stop */ /* while DMA transfer is on going) */ - tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); + tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); /* Check if DMA channel effectively disabled */ if (tmp_hal_status != HAL_OK) @@ -1359,7 +1363,8 @@ HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc) HAL_ADC_STATE_REG_BUSY, HAL_ADC_STATE_READY); } - } + + } /* Process unlocked */ __HAL_UNLOCK(hadc); @@ -1370,9 +1375,9 @@ HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc) /** * @brief Get ADC regular group conversion result. - * @note Reading DR register automatically clears EOC (end of conversion of - * regular group) flag. - * @note This function does not clear ADC flag EOS + * @note Reading register DR automatically clears ADC flag EOC + * (ADC group regular end of unitary conversion). + * @note This function does not clear ADC flag EOS * (ADC group regular end of sequence conversion). * Occurrence of flag EOS rising: * - If sequencer is composed of 1 rank, flag EOS is equivalent @@ -1385,10 +1390,10 @@ HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc) * model polling: @ref HAL_ADC_PollForConversion() * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_EOS). * @param hadc: ADC handle - * @retval Converted value + * @retval ADC group regular conversion data */ uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc) -{ +{ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); @@ -1400,7 +1405,7 @@ uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc) } /** - * @brief Handles ADC interrupt request. + * @brief Handle ADC interrupt request. * @param hadc: ADC handle * @retval None */ @@ -1409,18 +1414,19 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection)); /* ========== Check End of Conversion flag for regular group ========== */ if( (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC)) || - (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOS)) ) + (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOS)) ) { /* Update state machine on conversion status if not in error state */ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL)) { /* Set ADC state */ - SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); } - + /* Determine whether any further conversion upcoming on group regular */ /* by external trigger, continuous mode or scan sequence on going. */ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && @@ -1430,9 +1436,9 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) ) { /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */ - /* ADSTART==0 (no conversion on going) */ + /* ADSTART==0 (no conversion on going) */ if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) - { + { /* Disable ADC end of single conversion interrupt on group regular */ /* Note: Overrun interrupt was enabled with EOC interrupt in */ /* HAL_Start_IT(), but is not disabled here because can be used */ @@ -1443,46 +1449,53 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_REG_BUSY, HAL_ADC_STATE_READY); - } - else - { - /* Change ADC state to error state */ + } + else + { + /* Change ADC state to error state */ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); - /* Set ADC error code to ADC IP internal error */ + /* Set ADC error code to ADC IP internal error */ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); } } - } - + } + /* Conversion complete callback */ /* Note: into callback, to determine if conversion has been triggered */ /* from EOC or EOS, possibility to use: */ /* " if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_EOS)) " */ HAL_ADC_ConvCpltCallback(hadc); - /* Clear regular group conversion flag */ /* Note: in case of overrun set to ADC_OVR_DATA_PRESERVED, end of */ /* conversion flags clear induces the release of the preserved data.*/ /* Therefore, if the preserved data value is needed, it must be */ /* read preliminarily into HAL_ADC_ConvCpltCallback(). */ - __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS) ); + /* Note: Management of low power auto-wait enabled: flags must be cleared */ + /* by user when fetching ADC conversion data. */ + /* This case is managed in IRQ handler, but this low-power mode */ + /* should not be used with programming model IT or DMA. */ + /* Refer to comment of parameter "LowPowerAutoWait". */ + if (hadc->Init.LowPowerAutoWait != ENABLE) + { + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS)); } + } - /* ========== Check Analog watchdog flags ========== */ + /* ========== Check analog watchdog 1 flag ========== */ if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD)) { - /* Set ADC state */ - SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); - /* Level out of window callback */ + /* Level out of window 1 callback */ HAL_ADC_LevelOutOfWindowCallback(hadc); /* Clear ADC Analog watchdog flag */ - __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); - } + } /* ========== Check Overrun flag ========== */ @@ -1510,10 +1523,11 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) /* Clear the Overrun flag */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); } + } /** - * @brief Conversion complete callback in non blocking mode + * @brief Conversion complete callback in non-blocking mode. * @param hadc: ADC handle * @retval None */ @@ -1528,7 +1542,7 @@ __weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) } /** - * @brief Conversion DMA half-transfer callback in non blocking mode + * @brief Conversion DMA half-transfer callback in non-blocking mode. * @param hadc: ADC handle * @retval None */ @@ -1539,11 +1553,11 @@ __weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) /* NOTE : This function should not be modified. When the callback is needed, function HAL_ADC_ConvHalfCpltCallback must be implemented in the user file. - */ + */ } /** - * @brief Analog watchdog callback in non blocking mode. + * @brief Analog watchdog 1 callback in non-blocking mode. * @param hadc: ADC handle * @retval None */ @@ -1553,13 +1567,19 @@ __weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc) UNUSED(hadc); /* NOTE : This function should not be modified. When the callback is needed, - function HAL_ADC_LevelOoutOfWindowCallback must be implemented in the user file. - */ + function HAL_ADC_LevelOutOfWindowCallback must be implemented in the user file. + */ } /** - * @brief ADC error callback in non blocking mode - * (ADC conversion with interruption or transfer by DMA) + * @brief ADC error callback in non-blocking mode + * (ADC conversion with interruption or transfer by DMA). + * @note In case of error due to overrun when using ADC with DMA transfer + * (HAL ADC handle paramater "ErrorCode" to state "HAL_ADC_ERROR_OVR"): + * - Reinitialize the DMA using function "HAL_ADC_Stop_DMA()". + * - If needed, restart a new ADC conversion using function + * "HAL_ADC_Start_DMA()" + * (this function is also clearing overrun flag) * @param hadc: ADC handle * @retval None */ @@ -1570,15 +1590,15 @@ __weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc) /* NOTE : This function should not be modified. When the callback is needed, function HAL_ADC_ErrorCallback must be implemented in the user file. - */ + */ } /** * @} */ -/** @addtogroup ADC_Exported_Functions_Group3 - * @brief Peripheral Control functions +/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions * @verbatim =============================================================================== @@ -1592,10 +1612,8 @@ __weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc) * @{ */ - /** - * @brief Configures the the selected channel to be linked to the regular - * group. + * @brief Configure a channel to be assigned to ADC group regular. * @note In case of usage of internal measurement channels: * VrefInt/Vlcd(STM32L0x3xx only)/TempSensor. * Sampling time constraints must be respected (sampling time can be @@ -1606,15 +1624,14 @@ __weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc) * These internal paths can be be disabled using function * HAL_ADC_DeInit(). * @note Possibility to update parameters on the fly: - * This function initializes channel into regular group, following - * calls to this function can be used to reconfigure some parameters - * of structure "ADC_ChannelConfTypeDef" on the fly, without reseting - * the ADC. - * The setting of these parameters is conditioned to ADC state. - * For parameters constraints, see comments of structure - * "ADC_ChannelConfTypeDef". + * This function initializes channel into ADC group regular, + * following calls to this function can be used to reconfigure + * some parameters of structure "ADC_ChannelConfTypeDef" on the fly, + * without resetting the ADC. + * The setting of these parameters is conditioned to ADC state: + * Refer to comments of structure "ADC_ChannelConfTypeDef". * @param hadc: ADC handle - * @param sConfig: Structure of ADC channel for regular group. + * @param sConfig: Structure of ADC channel assigned to ADC group regular. * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig) @@ -1625,7 +1642,7 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConf assert_param(IS_ADC_RANK(sConfig->Rank)); /* Process locked */ - __HAL_LOCK(hadc); + __HAL_LOCK(hadc); /* Parameters update conditioned to ADC state: */ /* Parameters that can be updated when ADC is disabled or enabled without */ @@ -1702,7 +1719,7 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConf } #endif } - + /* Process unlocked */ __HAL_UNLOCK(hadc); @@ -1711,15 +1728,23 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConf } /** - * @brief Configures the analog watchdog. + * @brief Configure the analog watchdog. * @note Possibility to update parameters on the fly: - * This function initializes the selected analog watchdog, following + * This function initializes the selected analog watchdog, successive * calls to this function can be used to reconfigure some parameters - * of structure "ADC_AnalogWDGConfTypeDef" on the fly, without reseting + * of structure "ADC_AnalogWDGConfTypeDef" on the fly, without resetting * the ADC. * The setting of these parameters is conditioned to ADC state. * For parameters constraints, see comments of structure * "ADC_AnalogWDGConfTypeDef". + * @note Analog watchdog thresholds can be modified while ADC conversion + * is on going. + * In this case, some constraints must be taken into account: + * the programmed threshold values are effective from the next + * ADC EOC (end of unitary conversion). + * Considering that registers write delay may happen due to + * bus activity, this might cause an uncertainty on the + * effective timing of the new programmed threshold values. * @param hadc: ADC handle * @param AnalogWDGConfig: Structure of ADC analog watchdog configuration * @retval HAL status @@ -1734,18 +1759,17 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDG /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(AnalogWDGConfig->WatchdogMode)); - assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode)); - /* Verify if threshold is within the selected ADC resolution */ - assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold)); - assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold)); - if(AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) { assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); } - + + /* Verify if threshold is within the selected ADC resolution */ + assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold)); + assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold)); + /* Process locked */ __HAL_LOCK(hadc); @@ -1767,7 +1791,7 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDG /* Disable the ADC Analog watchdog interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD); } - + /* Configuration of analog watchdog: */ /* - Set the analog watchdog mode */ /* - Set the Analog watchdog channel (is not used if watchdog */ @@ -1791,17 +1815,18 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDG /* Set the high threshold */ hadc->Instance->TR = ADC_TRX_HIGHTHRESHOLD (tmpAWDHighThresholdShifted); /* Set the low threshold */ - hadc->Instance->TR |= tmpAWDLowThresholdShifted; + hadc->Instance->TR |= tmpAWDLowThresholdShifted; } + /* If a conversion is on going on regular group, no update could be done */ + /* on neither of the AWD configuration structure parameters. */ else { /* Update ADC state machine to error */ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); - + tmp_hal_status = HAL_ERROR; } - /* Process unlocked */ __HAL_UNLOCK(hadc); @@ -1809,51 +1834,60 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDG return tmp_hal_status; } + /** * @} */ -/** @addtogroup ADC_Exported_Functions_Group4 - * @brief ADC Peripheral State functions +/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions + * @brief ADC Peripheral State functions * -@verbatim +@verbatim + =============================================================================== + ##### Peripheral state and errors functions ##### =============================================================================== - ##### ADC Peripheral State functions ##### - =============================================================================== [..] - This subsection provides functions allowing to - (+) Check the ADC state. - (+) handle ADC interrupt request. - + This subsection provides functions to get in run-time the status of the + peripheral. + (+) Check the ADC state + (+) Check the ADC error code + @endverbatim * @{ */ /** - * @brief return the ADC state + * @brief Return the ADC handle state. + * @note ADC state machine is managed by bitfields, ADC status must be + * compared with states bits. + * For example: + * " if (HAL_IS_BIT_SET(HAL_ADC_GetState(hadc1), HAL_ADC_STATE_REG_BUSY)) " + * " if (HAL_IS_BIT_SET(HAL_ADC_GetState(hadc1), HAL_ADC_STATE_AWD1) ) " * @param hadc: ADC handle - * @retval HAL state + * @retval ADC handle state (bitfield on 32 bits) */ uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc) { /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - /* Return ADC state */ + /* Return ADC handle state */ return hadc->State; } /** - * @brief Return the ADC error code + * @brief Return the ADC error code. * @param hadc: ADC handle - * @retval ADC Error Code + * @retval ADC error code (bitfield on 32 bits) */ uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc) { + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + return hadc->ErrorCode; } - /** * @} */ @@ -1862,8 +1896,7 @@ uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc) * @} */ - -/** @addtogroup ADC_Private +/** @defgroup ADC_Private_Functions ADC Private Functions * @{ */ @@ -1871,12 +1904,12 @@ uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc) * @brief Enable the selected ADC. * @note Prerequisite condition to use this function: ADC must be disabled * and voltage regulator must be enabled (done into HAL_ADC_Init()). - * @note If low power mode AutoPowerOff is enabled, power-on/off phases are - * performed automatically by hardware. - * In this mode, this function is useless and must not be called because - * flag ADC_FLAG_RDY is not usable. - * Therefore, this function must be called under condition of - * "if (hadc->Init.LowPowerAutoPowerOff != ENABLE)". + * @note If low power mode AutoPowerOff is enabled, power-on/off phases are + * performed automatically by hardware. + * In this mode, this function is useless and must not be called because + * flag ADC_FLAG_RDY is not usable. + * Therefore, this function must be called under condition of + * "if (hadc->Init.LowPowerAutoPowerOff != ENABLE)". * @param hadc: ADC handle * @retval HAL status. */ @@ -1909,23 +1942,22 @@ static HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc) ADC_DelayMicroSecond(ADC_STAB_DELAY_US); /* Get tick count */ - tickstart = HAL_GetTick(); + tickstart = HAL_GetTick(); /* Wait for ADC effectively enabled */ - while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == RESET) + while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == RESET) + { + if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT) { - if((HAL_GetTick() - tickstart ) > ADC_ENABLE_TIMEOUT) - { - /* Update ADC state machine to error */ - SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); - - /* Set ADC error code to ADC IP internal error */ - SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); - - return HAL_ERROR; - } - } - + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + return HAL_ERROR; + } + } } /* Return HAL status */ @@ -1945,8 +1977,8 @@ static HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef* hadc) /* Verification if ADC is not already disabled: */ /* Note: forbidden to disable ADC (set bit ADC_CR_ADDIS) if ADC is already */ - /* disabled. */ - if (ADC_IS_ENABLE(hadc) != RESET ) + /* disabled. */ + if (ADC_IS_ENABLE(hadc) != RESET) { /* Check if conditions to disable the ADC are fulfilled */ if (ADC_DISABLING_CONDITIONS(hadc) != RESET) @@ -1971,23 +2003,24 @@ static HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef* hadc) while(HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADEN)) { - if((HAL_GetTick() - tickstart ) > ADC_DISABLE_TIMEOUT) - { - /* Update ADC state machine to error */ + if((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT) + { + /* Update ADC state machine to error */ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); - + /* Set ADC error code to ADC IP internal error */ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); - - return HAL_ERROR; - } + + return HAL_ERROR; } } + } /* Return HAL status */ return HAL_OK; } + /** * @brief Stop ADC conversion. * @note Prerequisite condition to use this function: ADC conversions must be @@ -2026,7 +2059,7 @@ static HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef* hadc) { /* Update ADC state machine to error */ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); - + /* Set ADC error code to ADC IP internal error */ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); @@ -2040,21 +2073,22 @@ static HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef* hadc) return HAL_OK; } + /** * @brief DMA transfer complete callback. * @param hdma: pointer to DMA handle. * @retval None */ -static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) +static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) { /* Retrieve ADC handle corresponding to current DMA handle */ - ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* Update state machine on conversion status if not in error state */ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) { /* Set ADC state */ - SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); /* Determine whether any further conversion upcoming on group regular */ /* by external trigger, continuous mode or scan sequence on going. */ @@ -2089,16 +2123,15 @@ static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) } } } - + /* Conversion complete callback */ - HAL_ADC_ConvCpltCallback(hadc); -} + HAL_ADC_ConvCpltCallback(hadc); + } else { /* Call DMA error callback */ hadc->DMA_Handle->XferErrorCallback(hdma); } - } /** @@ -2106,29 +2139,29 @@ static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) * @param hdma: pointer to DMA handle. * @retval None */ -static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma) -{ - /* Retrieve ADC handle corresponding to current DMA handle */ - ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - /* Half conversion callback */ - HAL_ADC_ConvHalfCpltCallback(hadc); -} - -/** - * @brief DMA error callback - * @param hdma: pointer to DMA handle. - * @retval None - */ -static void ADC_DMAError(DMA_HandleTypeDef *hdma) +static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma) { /* Retrieve ADC handle corresponding to current DMA handle */ ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Half conversion callback */ + HAL_ADC_ConvHalfCpltCallback(hadc); +} +/** + * @brief DMA error callback. + * @param hdma: pointer to DMA handle. + * @retval None + */ +static void ADC_DMAError(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* Set ADC state */ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA); - /* Set ADC error code to DMA error */ + /* Set ADC error code to DMA error */ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA); /* Error callback */ @@ -2151,17 +2184,13 @@ static void ADC_DelayMicroSecond(uint32_t microSecond) } } -/** - * @} - */ - -/** - * @} - */ - #endif /* HAL_ADC_MODULE_ENABLED */ /** * @} - */ + */ + +/** + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc.h index 4021cf7cc9..b68e202e7d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc.h @@ -2,10 +2,7 @@ ****************************************************************************** * @file stm32l0xx_hal_adc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief This file contains all the functions prototypes for the ADC firmware - * library. + * @brief Header file of ADC HAL module. ****************************************************************************** * @attention * @@ -37,8 +34,8 @@ */ /* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L0xx_ADC_H -#define __STM32L0xx_ADC_H +#ifndef __STM32L0xx_HAL_ADC_H +#define __STM32L0xx_HAL_ADC_H #ifdef __cplusplus extern "C" { @@ -46,150 +43,242 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal_def.h" - + /** @addtogroup STM32L0xx_HAL_Driver * @{ */ -/** @defgroup ADC ADC +/** @addtogroup ADC * @{ - */ + */ +/* Exported types ------------------------------------------------------------*/ /** @defgroup ADC_Exported_Types ADC Exported Types * @{ */ -/* Exported types ------------------------------------------------------------*/ /** - * @brief HAL ADC state machine: ADC states definition (bitfields) - */ -/* States of ADC global scope */ -#define HAL_ADC_STATE_RESET ((uint32_t)0x00000000U) /*!< ADC not yet initialized or disabled */ -#define HAL_ADC_STATE_READY ((uint32_t)0x00000001U) /*!< ADC peripheral ready for use */ -#define HAL_ADC_STATE_BUSY_INTERNAL ((uint32_t)0x00000002U) /*!< ADC is busy to internal process (initialization, calibration) */ -#define HAL_ADC_STATE_TIMEOUT ((uint32_t)0x00000004U) /*!< TimeOut occurrence */ - -/* States of ADC errors */ -#define HAL_ADC_STATE_ERROR_INTERNAL ((uint32_t)0x00000010U) /*!< Internal error occurrence */ -#define HAL_ADC_STATE_ERROR_CONFIG ((uint32_t)0x00000020U) /*!< Configuration error occurrence */ -#define HAL_ADC_STATE_ERROR_DMA ((uint32_t)0x00000040U) /*!< DMA error occurrence */ - -/* States of ADC group regular */ -#define HAL_ADC_STATE_REG_BUSY ((uint32_t)0x00000100U) /*!< A conversion on group regular is ongoing or can occur (either by continuous mode, - external trigger, low power auto power-on, multimode ADC master control) */ -#define HAL_ADC_STATE_REG_EOC ((uint32_t)0x00000200U) /*!< Conversion data available on group regular */ -#define HAL_ADC_STATE_REG_OVR ((uint32_t)0x00000400U) /*!< Overrun occurrence */ -#define HAL_ADC_STATE_REG_EOSMP ((uint32_t)0x00000800U) /*!< Not available on STM32F0 device: End Of Sampling flag raised */ - -/* States of ADC group injected */ -#define HAL_ADC_STATE_INJ_BUSY ((uint32_t)0x00001000U) /*!< Not available on STM32F0 device: A conversion on group injected is ongoing or can occur (either by auto-injection mode, - external trigger, low power auto power-on, multimode ADC master control) */ -#define HAL_ADC_STATE_INJ_EOC ((uint32_t)0x00002000U) /*!< Not available on STM32F0 device: Conversion data available on group injected */ -#define HAL_ADC_STATE_INJ_JQOVF ((uint32_t)0x00004000U) /*!< Not available on STM32F0 device: Not available on STM32F0 device: Injected queue overflow occurrence */ - -/* States of ADC analog watchdogs */ -#define HAL_ADC_STATE_AWD1 ((uint32_t)0x00010000U) /*!< Out-of-window occurrence of analog watchdog 1 */ -#define HAL_ADC_STATE_AWD2 ((uint32_t)0x00020000U) /*!< Not available on STM32F0 device: Out-of-window occurrence of analog watchdog 2 */ -#define HAL_ADC_STATE_AWD3 ((uint32_t)0x00040000U) /*!< Not available on STM32F0 device: Out-of-window occurrence of analog watchdog 3 */ - -/* States of ADC multi-mode */ -#define HAL_ADC_STATE_MULTIMODE_SLAVE ((uint32_t)0x00100000U) /*!< Not available on STM32F0 device: ADC in multimode slave state, controlled by another ADC master ( */ - - -/** - * @brief ADC Oversampler structure definition + * @brief ADC group regular oversampling structure definition */ typedef struct { uint32_t Ratio; /*!< Configures the oversampling ratio. This parameter can be a value of @ref ADC_Oversampling_Ratio */ + uint32_t RightBitShift; /*!< Configures the division coefficient for the Oversampler. This parameter can be a value of @ref ADC_Right_Bit_Shift */ - uint32_t TriggeredMode; /*!< Selects the regular triggered oversampling mode + + uint32_t TriggeredMode; /*!< Selects the regular triggered oversampling mode. This parameter can be a value of @ref ADC_Triggered_Oversampling_Mode */ - }ADC_OversamplingTypeDef; /** - * @brief ADC Init structure definition - * @note The setting of these parameters with function HAL_ADC_Init() is conditioned by the ADC state. + * @brief Structure definition of ADC instance and ADC group regular. + * @note Parameters of this structure are shared within 2 scopes: + * - Scope entire ADC (differentiation done for compatibility with some other STM32 series featuring ADC groups regular and injected): ClockPrescaler, Resolution, DataAlign, + * ScanConvMode, EOCSelection, LowPowerAutoWait. + * - Scope ADC group regular: ContinuousConvMode, NbrOfConversion, DiscontinuousConvMode, + * ExternalTrigConv, ExternalTrigConvEdge, DMAContinuousRequests, Overrun, OversamplingMode, Oversampling. + * @note The setting of these parameters by function HAL_ADC_Init() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled + * - For all parameters except 'ClockPrescaler' and 'Resolution': ADC enabled without conversion on going on group regular. * If ADC is not in the appropriate state to modify some parameters, these parameters setting is bypassed - * without error reporting (as it can be the expected behavior in case of intended action to update antother parameter (which fullfills the ADC state condition) on the fly). + * without error reporting (as it can be the expected behavior in case of intended action to update another parameter + * (which fulfills the ADC state condition) on the fly). */ typedef struct { - uint32_t OversamplingMode; /*!< Specifies whether the oversampling feature is enabled or disabled - This parameter can be set to ENABLE or DISABLE. - Note: This parameter can be modified only if there is no conversion is ongoing. */ - ADC_OversamplingTypeDef Oversample; /*!< Specifies the Oversampling parameters - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t ClockPrescaler; /*!< Selects the ADC clock frequency. - This parameter can be a value of @ref ADC_ClockPrescaler - Note: This parameter can be modified only if ADC is disabled. - Note: In case of Synchronous clock mode divided by 1, this configuration must be enabled only - if PCLK has a 50% duty clock cycle (APB prescaler configured inside the RCC - must be bypassed and the system clock must by 50% duty cycle). Refer to reference manual for details */ - uint32_t Resolution; /*!< Configures the ADC resolution mode. - This parameter can be a value of @ref ADC_Resolution - Note: This parameter can be modified only if ADC is disabled. */ - uint32_t SamplingTime; /*!< The sample time value to be set for all channels. + uint32_t ClockPrescaler; /*!< Select ADC clock source (synchronous clock derived from APB clock or asynchronous clock derived from ADC dedicated HSI RC oscillator) and clock prescaler. + This parameter can be a value of @ref ADC_ClockPrescaler. + Note: In case of synchronous clock mode based on HCLK/1, the configuration must be enabled only + if the system clock has a 50% duty clock cycle (APB prescaler configured inside RCC + must be bypassed and PCLK clock must have 50% duty cycle). Refer to reference manual for details. + Note: In case of usage of the ADC dedicated HSI RC oscillator, it must be preliminarily enabled at RCC top level. + Note: This parameter can be modified only if the ADC is disabled. */ + + uint32_t Resolution; /*!< Configure the ADC resolution. + This parameter can be a value of @ref ADC_Resolution */ + + uint32_t DataAlign; /*!< Specify ADC data alignment in conversion data register (right or left). + Refer to reference manual for alignments formats versus resolutions. + This parameter can be a value of @ref ADC_Data_align */ + + uint32_t ScanConvMode; /*!< Configure the sequencer of regular group. + This parameter can be associated to parameter 'DiscontinuousConvMode' to have main sequence subdivided in successive parts. + Sequencer is automatically enabled if several channels are set (sequencer cannot be disabled, as it can be the case on other STM32 devices): + If only 1 channel is set: Conversion is performed in single mode. + If several channels are set: Conversions are performed in sequence mode (ranks defined by each channel number: channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + Scan direction can be set to forward (from channel 0 to channel 18) or backward (from channel 18 to channel 0). + This parameter can be a value of @ref ADC_Scan_mode */ + + uint32_t EOCSelection; /*!< Specify which EOC (End Of Conversion) flag is used for conversion by polling and interruption: end of unitary conversion or end of sequence conversions. + This parameter can be a value of @ref ADC_EOCSelection. */ + + uint32_t LowPowerAutoWait; /*!< Select the dynamic low power Auto Delay: new conversion start only when the previous + conversion (for ADC group regular) has been retrieved by user software, + using function HAL_ADC_GetValue(). + This feature automatically adapts the frequency of ADC conversions triggers to the speed of the system that reads the data. Moreover, this avoids risk of overrun + for low frequency applications. + This parameter can be set to ENABLE or DISABLE. + Note: Do not use with interruption or DMA (HAL_ADC_Start_IT(), HAL_ADC_Start_DMA()) since they clear immediately the EOC flag + to free the IRQ vector sequencer. + Do use with polling: 1. Start conversion with HAL_ADC_Start(), 2. Later on, when ADC conversion data is needed: + use HAL_ADC_PollForConversion() to ensure that conversion is completed and HAL_ADC_GetValue() to retrieve conversion result and trig another conversion start. */ + + uint32_t LowPowerAutoPowerOff; /*!< Select the auto-off mode: the ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered (with startup time between trigger and start of sampling). + This feature can be combined with automatic wait mode (parameter 'LowPowerAutoWait'). + This parameter can be set to ENABLE or DISABLE. + Note: If enabled, this feature also turns off the ADC dedicated 14 MHz RC oscillator (HSI14) */ + + uint32_t ContinuousConvMode; /*!< Specify whether the conversion is performed in single mode (one conversion) or continuous mode for ADC group regular, + after the first ADC conversion start trigger occurred (software start or external trigger). + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t DiscontinuousConvMode; /*!< Specify whether the conversions sequence of ADC group regular is performed in Complete-sequence/Discontinuous-sequence + (main sequence subdivided in successive parts). + Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded. + Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded. + This parameter can be set to ENABLE or DISABLE. + Note: On this STM32 serie, ADC group regular number of discontinuous ranks increment is fixed to one-by-one. */ + + uint32_t ExternalTrigConv; /*!< Select the external event source used to trigger ADC group regular conversion start. + If set to ADC_SOFTWARE_START, external triggers are disabled and software trigger is used instead. + This parameter can be a value of @ref ADC_regular_external_trigger_source. + Caution: external trigger source is common to all ADC instances. */ + + uint32_t ExternalTrigConvEdge; /*!< Select the external event edge used to trigger ADC group regular conversion start. + If trigger source is set to ADC_SOFTWARE_START, this parameter is discarded. + This parameter can be a value of @ref ADC_regular_external_trigger_edge */ + + uint32_t DMAContinuousRequests; /*!< Specify whether the DMA requests are performed in one shot mode (DMA transfer stops when number of conversions is reached) + or in continuous mode (DMA transfer unlimited, whatever number of conversions). + This parameter can be set to ENABLE or DISABLE. + Note: In continuous mode, DMA must be configured in circular mode. Otherwise an overrun will be triggered when DMA buffer maximum pointer is reached. */ + + uint32_t Overrun; /*!< Select the behavior in case of overrun: data overwritten or preserved (default). + This parameter can be a value of @ref ADC_Overrun. + Note: In case of overrun set to data preserved and usage with programming model with interruption (HAL_Start_IT()): ADC IRQ handler has to clear + end of conversion flags, this induces the release of the preserved data. If needed, this data can be saved in function + HAL_ADC_ConvCpltCallback(), placed in user program code (called before end of conversion flags clear). + Note: Error reporting with respect to the conversion mode: + - Usage with ADC conversion by polling for event or interruption: Error is reported only if overrun is set to data preserved. If overrun is set to data + overwritten, user can willingly not read all the converted data, this is not considered as an erroneous case. + - Usage with ADC conversion by DMA: Error is reported whatever overrun setting (DMA is expected to process all data from data register). */ + + uint32_t LowPowerFrequencyMode; /*!< When selecting an analog ADC clock frequency lower than 2.8MHz, + it is mandatory to first enable the Low Frequency Mode. + This parameter can be set to ENABLE or DISABLE. + Note: This parameter can be modified only if there is no conversion is ongoing. */ + + + uint32_t SamplingTime; /*!< The sample time common to all channels. + Unit: ADC clock cycles This parameter can be a value of @ref ADC_sampling_times Note: This parameter can be modified only if there is no conversion ongoing. */ - uint32_t ScanConvMode; /*!< The scan sequence direction. - If several channels are set: Conversions are performed in sequence mode - (ranks defined by each channel number: channel 0 fixed on rank 0, - channel 1 fixed on rank1, ...). - This parameter can be a value of @ref ADC_Scan_mode - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t DataAlign; /*!< Specifies whether the ADC data alignment is left or right. - This parameter can be a value of @ref ADC_data_align - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t ContinuousConvMode; /*!< Specifies whether the conversion is performed in Continuous or Single mode. - This parameter can be set to ENABLE or DISABLE. - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t DiscontinuousConvMode; /*!< Specifies whether the conversion is performed - in Complete-sequence/Discontinuous-sequence. - Discontinuous mode can be enabled only if continuous mode is disabled. - This parameter can be set to ENABLE or DISABLE. - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t ExternalTrigConv; /*!< Select the external event used to trigger the start of conversion. - If set to ADC_SOFTWARE_START, external triggers are disabled. - This parameter can be a value of @ref ADC_External_trigger_Source - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t ExternalTrigConvEdge; /*!< Select the external trigger edge and enable the trigger. - If trigger is set to ADC_SOFTWARE_START, this parameter is discarded. - This parameter can be a value of @ref ADC_Regular_External_Trigger_Source_Edge - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t DMAContinuousRequests; /*!< Specifies whether the DMA requests are performed in one shot mode (DMA transfer stop when number of conversions is reached) - or in Continuous mode (DMA transfer unlimited, whatever number of conversions). - Note: In continuous mode, DMA must be configured in circular mode. Otherwise an overrun will be triggered when DMA buffer max pointer is reached. - This parameter can be set to ENABLE or DISABLE. - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t EOCSelection; /*!< Specifies what EOC (End Of Conversion) flag is used for conversion polling and interruption: - end of single channel conversion or end of channels conversions sequence. - This parameter can be a value of @ref ADC_EOCSelection */ - uint32_t Overrun; /*!< Select the behaviour in case of overrun: data preserved or overwritten - This parameter has an effect on regular channels only, including in DMA mode. - This parameter can be a value of @ref ADC_Overrun - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t LowPowerAutoWait; /*!< Specifies the usage of dynamic low power Auto Delay: new conversion start only - when the previous conversion (for regular channel) is completed. - This avoids risk of overrun for low frequency application. - This parameter can be set to ENABLE or DISABLE. - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t LowPowerFrequencyMode; /*!< When selecting an analog ADC clock frequency lower than 2.8MHz, - it is mandatory to first enable the Low Frequency Mode. - This parameter can be set to ENABLE or DISABLE. - Note: This parameter can be modified only if there is no conversion is ongoing. */ - uint32_t LowPowerAutoPowerOff; /*!< When setting the AutoOff feature, the ADC is always powered off when not converting and automatically - wakes-up when a conversion is started (by software or hardware trigger). - This parameter can be set to ENABLE or DISABLE. - Note: This parameter can be modified only if there is no conversion is ongoing. */ + + uint32_t OversamplingMode; /*!< Specify whether the oversampling feature is enabled or disabled. + This parameter can be set to ENABLE or DISABLE. + Note: This parameter can be modified only if there is no conversion is ongoing on ADC group regular. */ + + + ADC_OversamplingTypeDef Oversample; /*!< Specify the Oversampling parameters + Caution: this setting overwrites the previous oversampling configuration if oversampling is already enabled. */ }ADC_InitTypeDef; +/** + * @brief Structure definition of ADC channel for regular group + * @note The setting of these parameters by function HAL_ADC_ConfigChannel() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled or enabled without conversion on going on regular group. + * If ADC is not in the appropriate state to modify some parameters, these parameters setting is bypassed + * without error reporting (as it can be the expected behavior in case of intended action to update another parameter (which fulfills the ADC state condition) on the fly). + */ +typedef struct +{ + uint32_t Channel; /*!< Specify the channel to configure into ADC regular group. + This parameter can be a value of @ref ADC_channels + Note: Depending on devices, some channels may not be available on device package pins. Refer to device datasheet for channels availability. */ + + uint32_t Rank; /*!< Add or remove the channel from ADC regular group sequencer. + On STM32L0 devices, number of ranks in the sequence is defined by number of channels enabled, rank of each channel is defined by channel number + (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + Despite the channel rank is fixed, this parameter allow an additional possibility: to remove the selected rank (selected channel) from sequencer. + This parameter can be a value of @ref ADC_rank */ +}ADC_ChannelConfTypeDef; + +/** + * @brief Structure definition of ADC analog watchdog + * @note The setting of these parameters by function HAL_ADC_AnalogWDGConfig() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled or ADC enabled without conversion on going on ADC group regular + * - For parameters 'HighThreshold' and 'LowThreshold': ADC enabled with conversion on going on regular group (AWD thresholds can be modify on the fly while ADC conversion is on going) + */ +typedef struct +{ + uint32_t WatchdogMode; /*!< Configure the ADC analog watchdog mode: single/all channels. + This parameter can be a value of @ref ADC_analog_watchdog_mode */ + + uint32_t Channel; /*!< Select which ADC channel to monitor by analog watchdog. + This parameter has an effect only if watchdog mode is configured on single channel (parameter WatchdogMode) + This parameter can be a value of @ref ADC_channels */ + + uint32_t ITMode; /*!< Specify whether the analog watchdog is configured in interrupt or polling mode. + This parameter can be set to ENABLE or DISABLE */ + uint32_t HighThreshold; /*!< Configures the ADC analog watchdog High threshold value. + Depending of ADC resolution selected (12, 10, 8 or 6 bits), + this parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */ + + uint32_t LowThreshold; /*!< Configures the ADC analog watchdog High threshold value. + Depending of ADC resolution selected (12, 10, 8 or 6 bits), + this parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */ +}ADC_AnalogWDGConfTypeDef; + +/** + * @brief HAL ADC state machine: ADC states definition (bitfields) + * @note ADC state machine is managed by bitfields, state must be compared + * with bit by bit. + * For example: + * " if (HAL_IS_BIT_SET(HAL_ADC_GetState(hadc1), HAL_ADC_STATE_REG_BUSY)) " + * " if (HAL_IS_BIT_SET(HAL_ADC_GetState(hadc1), HAL_ADC_STATE_AWD1) ) " + */ +/* States of ADC global scope */ +#define HAL_ADC_STATE_RESET ((uint32_t)0x00000000) /*!< ADC not yet initialized or disabled */ +#define HAL_ADC_STATE_READY ((uint32_t)0x00000001) /*!< ADC peripheral ready for use */ +#define HAL_ADC_STATE_BUSY_INTERNAL ((uint32_t)0x00000002) /*!< ADC is busy due to an internal process (initialization, calibration) */ +#define HAL_ADC_STATE_TIMEOUT ((uint32_t)0x00000004) /*!< TimeOut occurrence */ + +/* States of ADC errors */ +#define HAL_ADC_STATE_ERROR_INTERNAL ((uint32_t)0x00000010) /*!< Internal error occurrence */ +#define HAL_ADC_STATE_ERROR_CONFIG ((uint32_t)0x00000020) /*!< Configuration error occurrence */ +#define HAL_ADC_STATE_ERROR_DMA ((uint32_t)0x00000040) /*!< DMA error occurrence */ + +/* States of ADC group regular */ +#define HAL_ADC_STATE_REG_BUSY ((uint32_t)0x00000100) /*!< A conversion on ADC group regular is ongoing or can occur (either by continuous mode, + external trigger, low power auto power-on (if feature available), multimode ADC master control (if feature available)) */ +#define HAL_ADC_STATE_REG_EOC ((uint32_t)0x00000200) /*!< Conversion data available on group regular */ +#define HAL_ADC_STATE_REG_OVR ((uint32_t)0x00000400) /*!< Overrun occurrence */ +#define HAL_ADC_STATE_REG_EOSMP ((uint32_t)0x00000800) /*!< Not available on this STM32 serie: End Of Sampling flag raised */ + +/* States of ADC group injected */ +#define HAL_ADC_STATE_INJ_BUSY ((uint32_t)0x00001000) /*!< Not available on this STM32 serie: A conversion on group injected is ongoing or can occur (either by auto-injection mode, + external trigger, low power auto power-on (if feature available), multimode ADC master control (if feature available)) */ +#define HAL_ADC_STATE_INJ_EOC ((uint32_t)0x00002000) /*!< Not available on this STM32 serie: Conversion data available on group injected */ +#define HAL_ADC_STATE_INJ_JQOVF ((uint32_t)0x00004000) /*!< Not available on this STM32 serie: Injected queue overflow occurrence */ + +/* States of ADC analog watchdogs */ +#define HAL_ADC_STATE_AWD1 ((uint32_t)0x00010000) /*!< Out-of-window occurrence of ADC analog watchdog 1 */ +#define HAL_ADC_STATE_AWD2 ((uint32_t)0x00020000) /*!< Not available on this STM32 serie: Out-of-window occurrence of ADC analog watchdog 2 */ +#define HAL_ADC_STATE_AWD3 ((uint32_t)0x00040000) /*!< Not available on this STM32 serie: Out-of-window occurrence of ADC analog watchdog 3 */ + +/* States of ADC multi-mode */ +#define HAL_ADC_STATE_MULTIMODE_SLAVE ((uint32_t)0x00100000) /*!< Not available on this STM32 serie: ADC in multimode slave state, controlled by another ADC master (when feature available) */ + + + /** - * @brief ADC handle Structure definition - */ + * @brief ADC handle Structure definition + */ typedef struct { ADC_TypeDef *Instance; /*!< Register base address */ @@ -204,43 +293,6 @@ typedef struct __IO uint32_t ErrorCode; /*!< ADC Error code */ }ADC_HandleTypeDef; - -/** - * @brief ADC Configuration regular Channel structure definition - */ -typedef struct -{ - uint32_t Channel; /*!< the ADC channel to configure - This parameter can be a value of @ref ADC_channels */ - - uint32_t Rank; /*!< Add or remove the channel from ADC regular group sequencer. - On STM32L0 devices, number of ranks in the sequence is defined by number of channels enabled, rank of each channel is defined by channel number - (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). - Despite the channel rank is fixed, this parameter allow an additional possibility: to remove the selected rank (selected channel) from sequencer. - This parameter can be a value of @ref ADC_rank */ -}ADC_ChannelConfTypeDef; - - -/** - * @brief ADC Configuration analog watchdog definition - */ -typedef struct -{ - uint32_t WatchdogMode; /*!< Configures the ADC analog watchdog mode: single/all channels. - This parameter can be a value of @ref ADC_analog_watchdog_mode */ - uint32_t Channel; /*!< Selects which ADC channel to monitor by analog watchdog. - This parameter has an effect only if watchdog mode is configured on single channel (parameter WatchdogMode) - This parameter can be a value of @ref ADC_channels */ - uint32_t ITMode; /*!< Specifies whether the analog watchdog is configured in interrupt or polling mode. - This parameter can be set to ENABLE or DISABLE */ - uint32_t HighThreshold; /*!< Configures the ADC analog watchdog High threshold value. - Depending of ADC resolution selected (12, 10, 8 or 6 bits), - this parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */ - uint32_t LowThreshold; /*!< Configures the ADC analog watchdog High threshold value. - Depending of ADC resolution selected (12, 10, 8 or 6 bits), - this parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */ -}ADC_AnalogWDGConfTypeDef; - /** * @} */ @@ -254,19 +306,19 @@ typedef struct /** @defgroup ADC_Error_Code ADC Error Code * @{ - */ -#define HAL_ADC_ERROR_NONE ((uint32_t)0x00U) /*!< No error */ -#define HAL_ADC_ERROR_INTERNAL ((uint32_t)0x01U) /*!< ADC IP internal error: if problem of clocking, - enable/disable, erroneous state */ -#define HAL_ADC_ERROR_OVR ((uint32_t)0x02U) /*!< OVR error */ -#define HAL_ADC_ERROR_DMA ((uint32_t)0x04U) /*!< DMA transfer error */ + */ +#define HAL_ADC_ERROR_NONE ((uint32_t)0x00U) /*!< No error */ +#define HAL_ADC_ERROR_INTERNAL ((uint32_t)0x01U) /*!< ADC IP internal error (problem of clocking, + enable/disable, erroneous state, ...) */ +#define HAL_ADC_ERROR_OVR ((uint32_t)0x02U) /*!< Overrun error */ +#define HAL_ADC_ERROR_DMA ((uint32_t)0x04U) /*!< DMA transfer error */ /** * @} - */ + */ /** @defgroup ADC_TimeOut_Values ADC TimeOut Values * @{ - */ + */ /* Fixed timeout values for ADC calibration, enable settling time, disable */ /* settling time. */ @@ -313,28 +365,27 @@ typedef struct /** @defgroup ADC_Resolution ADC Resolution * @{ - */ -#define ADC_RESOLUTION_12B ((uint32_t)0x00000000U) /*!< ADC 12-bit resolution */ -#define ADC_RESOLUTION_10B ((uint32_t)ADC_CFGR1_RES_0) /*!< ADC 10-bit resolution */ -#define ADC_RESOLUTION_8B ((uint32_t)ADC_CFGR1_RES_1) /*!< ADC 8-bit resolution */ -#define ADC_RESOLUTION_6B ((uint32_t)ADC_CFGR1_RES) /*!< ADC 6-bit resolution */ + */ +#define ADC_RESOLUTION_12B ((uint32_t)0x00000000U) /*!< ADC 12-bit resolution */ +#define ADC_RESOLUTION_10B ((uint32_t)ADC_CFGR1_RES_0) /*!< ADC 10-bit resolution */ +#define ADC_RESOLUTION_8B ((uint32_t)ADC_CFGR1_RES_1) /*!< ADC 8-bit resolution */ +#define ADC_RESOLUTION_6B ((uint32_t)ADC_CFGR1_RES) /*!< ADC 6-bit resolution */ /** * @} - */ + */ -/** @defgroup ADC_data_align ADC Data Align +/** @defgroup ADC_Data_align ADC conversion data alignment * @{ - */ + */ #define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) #define ADC_DATAALIGN_LEFT ((uint32_t)ADC_CFGR1_ALIGN) - /** * @} - */ + */ -/** @defgroup ADC_Regular_External_Trigger_Source_Edge ADC External Trigger Source Edge for Regular Group +/** @defgroup ADC_regular_external_trigger_edge ADC External Trigger Source Edge for Regular Group * @{ - */ + */ #define ADC_EXTERNALTRIGCONVEDGE_NONE ((uint32_t)0x00000000U) #define ADC_EXTERNALTRIGCONVEDGE_RISING ((uint32_t)ADC_CFGR1_EXTEN_0) #define ADC_EXTERNALTRIGCONVEDGE_FALLING ((uint32_t)ADC_CFGR1_EXTEN_1) @@ -360,12 +411,12 @@ typedef struct #define ADC_OVR_DATA_OVERWRITTEN ((uint32_t)ADC_CFGR1_OVRMOD) /** * @} - */ + */ /** @defgroup ADC_rank ADC rank * @{ - */ + */ #define ADC_RANK_CHANNEL_NUMBER ((uint32_t)0x00001000U) /*!< Enable the rank of the selected channels. Number of ranks in the sequence is defined by number of channels enabled, rank of each channel is defined by channel number (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...) */ #define ADC_RANK_NONE ((uint32_t)0x00001001U) /*!< Disable the selected rank (selected channel) from sequencer */ /** @@ -417,24 +468,21 @@ typedef struct * @} */ - /** @defgroup ADC_sampling_times ADC Sampling Cycles * @{ */ - #define ADC_SAMPLETIME_1CYCLE_5 ((uint32_t)0x00000000U) /*!< ADC sampling time 1.5 cycle */ -#define ADC_SAMPLETIME_7CYCLES_5 ((uint32_t)ADC_SMPR_SMPR_0) /*!< ADC sampling time 7.5 CYCLES */ -#define ADC_SAMPLETIME_13CYCLES_5 ((uint32_t)ADC_SMPR_SMPR_1) /*!< ADC sampling time 13.5 CYCLES */ -#define ADC_SAMPLETIME_28CYCLES_5 ((uint32_t)(ADC_SMPR_SMPR_1 | ADC_SMPR_SMPR_0)) /*!< ADC sampling time 28.5 CYCLES */ -#define ADC_SAMPLETIME_41CYCLES_5 ((uint32_t)ADC_SMPR_SMPR_2) /*!< ADC sampling time 41.5 CYCLES */ -#define ADC_SAMPLETIME_55CYCLES_5 ((uint32_t)(ADC_SMPR_SMPR_2 | ADC_SMPR_SMPR_0)) /*!< ADC sampling time 55.5 CYCLES */ -#define ADC_SAMPLETIME_71CYCLES_5 ((uint32_t)(ADC_SMPR_SMPR_2 | ADC_SMPR_SMPR_1)) /*!< ADC sampling time 71.5 CYCLES */ -#define ADC_SAMPLETIME_239CYCLES_5 ((uint32_t)ADC_SMPR_SMPR) /*!< ADC sampling time 239.5 CYCLES */ +#define ADC_SAMPLETIME_3CYCLES_5 ((uint32_t)ADC_SMPR_SMPR_0) /*!< ADC sampling time 3.5 CYCLES */ +#define ADC_SAMPLETIME_7CYCLES_5 ((uint32_t)ADC_SMPR_SMPR_1) /*!< ADC sampling time 7.5 CYCLES */ +#define ADC_SAMPLETIME_12CYCLES_5 ((uint32_t)(ADC_SMPR_SMPR_1 | ADC_SMPR_SMPR_0)) /*!< ADC sampling time 12.5 CYCLES */ +#define ADC_SAMPLETIME_19CYCLES_5 ((uint32_t)ADC_SMPR_SMPR_2) /*!< ADC sampling time 19.5 CYCLES */ +#define ADC_SAMPLETIME_39CYCLES_5 ((uint32_t)(ADC_SMPR_SMPR_2 | ADC_SMPR_SMPR_0)) /*!< ADC sampling time 39.5 CYCLES */ +#define ADC_SAMPLETIME_79CYCLES_5 ((uint32_t)(ADC_SMPR_SMPR_2 | ADC_SMPR_SMPR_1)) /*!< ADC sampling time 79.5 CYCLES */ +#define ADC_SAMPLETIME_160CYCLES_5 ((uint32_t)ADC_SMPR_SMPR) /*!< ADC sampling time 160.5 CYCLES */ /** * @} */ - /** @defgroup ADC_Scan_mode ADC Scan mode * @{ */ @@ -518,7 +566,7 @@ typedef struct /** @defgroup ADC_Event_type ADC Event * @{ - */ + */ #define ADC_AWD_EVENT ((uint32_t)ADC_FLAG_AWD) #define ADC_OVR_EVENT ((uint32_t)ADC_FLAG_OVR) /** @@ -537,14 +585,12 @@ typedef struct #define ADC_IT_EOCAL ADC_IER_EOCALIE /*!< ADC End of Calibration interrupt source */ /** * @} - */ + */ - - -/** @defgroup ADC_flags_definition ADC Flags Definition +/** @defgroup ADC_flags_definition ADC flags definition * @{ */ -#define ADC_FLAG_RDY ADC_ISR_ADRDY /*!< ADC Ready (ADRDY) flag */ +#define ADC_FLAG_RDY ADC_ISR_ADRDY /*!< ADC Ready flag */ #define ADC_FLAG_EOSMP ADC_ISR_EOSMP /*!< ADC End of Sampling flag */ #define ADC_FLAG_EOC ADC_ISR_EOC /*!< ADC End of Regular Conversion flag */ #define ADC_FLAG_EOS ADC_ISR_EOSEQ /*!< ADC End of Regular sequence of Conversions flag */ @@ -562,9 +608,11 @@ typedef struct /** * @} */ + + /* Exported macro ------------------------------------------------------------*/ - -/** @defgroup ADC_Exported_Macro ADC Exported Macro + +/** @defgroup ADC_Exported_Macros ADC Exported Macros * @{ */ /** @brief Reset ADC handle state @@ -648,7 +696,7 @@ typedef struct #define ADC_IS_CONVERSION_ONGOING_REGULAR(__HANDLE__) \ (( (((__HANDLE__)->Instance->CR) & ADC_CR_ADSTART) == RESET \ ) ? RESET : SET) - + /** * @brief Enable ADC continuous conversion mode. * @param _CONTINUOUS_MODE_: Continuous mode. @@ -693,7 +741,7 @@ typedef struct * @retval None */ #define __HAL_ADC_CFGR1_AUTOFF(_AUTOFF_) ((_AUTOFF_) << 15U) - + /** * @brief Configure the analog watchdog high threshold into registers TR1, TR2 or TR3. * @param _Threshold_: Threshold value @@ -707,7 +755,7 @@ typedef struct * @retval None */ #define __HAL_ADC_CCR_LOWFREQUENCY(_LOW_FREQUENCY_MODE_) ((_LOW_FREQUENCY_MODE_) << 25U) - + /** * @brief Shift the offset in function of the selected ADC resolution. * Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 @@ -737,7 +785,7 @@ typedef struct */ #define ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(__HANDLE__, _Threshold_) \ ((_Threshold_) << ((((__HANDLE__)->Instance->CFGR1 & ADC_CFGR1_RES) >> 3U)*2U)) - + /** * @brief Shift the value on the left, less significant are set to 0. * @param _Value_: Value to be shifted @@ -813,8 +861,6 @@ typedef struct ((__HANDLE__)->ErrorCode = HAL_ADC_ERROR_NONE) - - /** * @brief Configuration of ADC clock & prescaler: clock source PCLK or Asynchronous with selectable prescaler * @param __HANDLE__: ADC handle @@ -925,13 +971,13 @@ typedef struct #endif #define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SAMPLETIME_1CYCLE_5 ) || \ + ((TIME) == ADC_SAMPLETIME_3CYCLES_5 ) || \ ((TIME) == ADC_SAMPLETIME_7CYCLES_5 ) || \ - ((TIME) == ADC_SAMPLETIME_13CYCLES_5 ) || \ - ((TIME) == ADC_SAMPLETIME_28CYCLES_5 ) || \ - ((TIME) == ADC_SAMPLETIME_41CYCLES_5 ) || \ - ((TIME) == ADC_SAMPLETIME_55CYCLES_5 ) || \ - ((TIME) == ADC_SAMPLETIME_71CYCLES_5 ) || \ - ((TIME) == ADC_SAMPLETIME_239CYCLES_5)) + ((TIME) == ADC_SAMPLETIME_12CYCLES_5 ) || \ + ((TIME) == ADC_SAMPLETIME_19CYCLES_5 ) || \ + ((TIME) == ADC_SAMPLETIME_39CYCLES_5 ) || \ + ((TIME) == ADC_SAMPLETIME_79CYCLES_5 ) || \ + ((TIME) == ADC_SAMPLETIME_160CYCLES_5)) #define IS_ADC_SCAN_MODE(SCAN_MODE) (((SCAN_MODE) == ADC_SCAN_DIRECTION_FORWARD) || \ ((SCAN_MODE) == ADC_SCAN_DIRECTION_BACKWARD)) @@ -971,7 +1017,7 @@ typedef struct /** @defgroup ADC_range_verification ADC Range Verification * in function of ADC resolution selected (12, 10, 8 or 6 bits) * @{ - */ + */ #define IS_ADC_RANGE(RESOLUTION, ADC_VALUE) \ ((((RESOLUTION) == ADC_RESOLUTION_12B) && ((ADC_VALUE) <= ((uint32_t)0x0FFFU))) || \ (((RESOLUTION) == ADC_RESOLUTION_10B) && ((ADC_VALUE) <= ((uint32_t)0x03FFU))) || \ @@ -979,61 +1025,64 @@ typedef struct (((RESOLUTION) == ADC_RESOLUTION_6B) && ((ADC_VALUE) <= ((uint32_t)0x003FU)))) /** * @} - */ + */ /** @defgroup ADC_regular_nb_conv_verification ADC Regular Nb Conversion Verification * @{ - */ + */ #define IS_ADC_REGULAR_NB_CONV(LENGTH) (((LENGTH) >= ((uint32_t)1U)) && ((LENGTH) <= ((uint32_t)16U))) /** * @} */ - - /** + +/** * @} */ - -/* Include ADC HAL Extension module */ + +/* Include ADC HAL Extended module */ #include "stm32l0xx_hal_adc_ex.h" - -/* Exported functions --------------------------------------------------------*/ -/** @defgroup ADC_Exported_Functions ADC Exported Functions + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADC_Exported_Functions * @{ - */ -/* Initialization and de-initialization functions **********************************/ -/** @defgroup ADC_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and de-initialization functions - * @{ */ + +/** @addtogroup ADC_Exported_Functions_Group1 + * @brief Initialization and Configuration functions + * @{ + */ +/* Initialization and de-initialization functions ****************************/ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc); HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc); void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc); void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc); /** * @} - */ + */ -/* IO operation functions *****************************************************/ -/** @defgroup ADC_Exported_Functions_Group2 I/O operation functions +/** @addtogroup ADC_Exported_Functions_Group2 + * @brief IO operation functions * @{ */ +/* IO operation functions *****************************************************/ + /* Blocking mode: Polling */ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc); -HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); +HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout); - + /* Non-blocking mode: Interruption */ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc); HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc); - + /* Non-blocking mode: DMA */ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length); HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc); - + /* ADC retrieve conversion value intended to be used with polling or interruption */ uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc); - + /* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption and DMA) */ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc); void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc); @@ -1042,46 +1091,37 @@ void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc); void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc); /** * @} - */ - -/* Peripheral Control functions ***********************************************/ -/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions - * @{ */ + +/** @addtogroup ADC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ +/* Peripheral Control functions ***********************************************/ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig); HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig); /** * @} - */ + */ /* Peripheral State functions *************************************************/ -/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions +/** @addtogroup ADC_Exported_Functions_Group4 * @{ */ uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc); uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc); /** * @} - */ - - -/** - * @} - */ - -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup ADC_Private ADC Private - * @{ */ + + /** * @} */ -/**************************************************************/ /** * @} - */ + */ /** * @} @@ -1091,7 +1131,7 @@ uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc); } #endif -#endif /*__STM32L0xx_ADC_H */ +#endif /*__STM32L0xx_HAL_ADC_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc_ex.c index d9758db350..1f260e1466 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc_ex.c @@ -2,34 +2,22 @@ ****************************************************************************** * @file stm32l0xx_hal_adc_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief This file provides firmware functions to manage the following * functionalities of the Analog to Digital Convertor (ADC) * peripheral: - * + Start calibration. - * + Read the calibration factor. - * + Set a calibration factor. - * + * + Operation functions + * ++ Calibration + * +++ ADC automatic self-calibration + * +++ Calibration factors get or set + * Other functions (generic functions) are available in file + * "stm32l0xx_hal_adc.c". + * @verbatim - ============================================================================== - ##### ADC specific features ##### - ============================================================================== [..] - (#) Self calibration. - - - ##### How to use this driver ##### - ============================================================================== - [..] - - (#) Call HAL_ADCEx_Calibration_Start() to start calibration - - (#) Read the calibration factor using HAL_ADCEx_Calibration_GetValue() - - (#) User can set a his calibration factor using HAL_ADCEx_Calibration_SetValue() - - @endverbatim + (@) Sections "ADC peripheral features" and "How to use this driver" are + available in file of generic functions "stm32l0xx_hal_adc.c". + [..] + @endverbatim ****************************************************************************** * @attention * @@ -57,7 +45,7 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -67,18 +55,21 @@ * @{ */ +/** @defgroup ADCEx ADCEx + * @brief ADC Extended HAL module driver + * @{ + */ + #ifdef HAL_ADC_MODULE_ENABLED -/** @addtogroup ADCEx - * @brief ADC driver modules - * @{ - */ - /* Private typedef -----------------------------------------------------------*/ - /* Private define ------------------------------------------------------------*/ -/* Fixed timeout values for ADC calibration, enable settling time, disable */ +/** @defgroup ADCEx_Private_Constants ADC Extended Private Constants + * @{ + */ + + /* Fixed timeout values for ADC calibration, enable settling time, disable */ /* settling time. */ /* Values defined to be higher than worst cases: low clock frequency, */ /* maximum prescaler. */ @@ -98,38 +89,32 @@ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Functions ADC Extended Exported Functions + * @{ + */ -/** @addtogroup ADCEx_Exported_Functions - * @brief ADC Extended features functions - * -@verbatim +/** @defgroup ADCEx_Exported_Functions_Group1 Extended Input and Output operation functions + * @brief Extended IO operation functions + * +@verbatim =============================================================================== - ##### ADC Extended features functions ##### - =============================================================================== - [..] -This subsection provides functions allowing to: - (+) Start calibration. - (+) Get calibration factor. - (+) Set calibration factor. - (+) Enable VREFInt. - (+) Disable VREFInt. - (+) Enable VREFInt TempSensor. - (+) Disable VREFInt TempSensor. - + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Perform the ADC calibration. @endverbatim * @{ */ -/** @addtogroup ADCEx_Exported_Functions_Group3 - * @{ - */ - /** - * @brief Start an automatic calibration - * @param hadc: pointer to a ADC_HandleTypeDef structure that contains - * the configuration information for the specified ADC. + * @brief Perform an ADC automatic self-calibration + * Calibration prerequisite: ADC must be disabled (execute this + * function before HAL_ADC_Start() or after HAL_ADC_Stop() ). + * @note Calibration factor can be read after calibration, using function + * HAL_ADC_GetValue() (value on 7 bits: from DR[6;0]). + * @param hadc ADC handle * @param SingleDiff: Selection of single-ended or differential input * This parameter can be only of the following values: * @arg ADC_SINGLE_ENDED: Channel in mode input single ended @@ -138,7 +123,8 @@ This subsection provides functions allowing to: HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc, uint32_t SingleDiff) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; - uint32_t tickstart=0U; + uint32_t tickstart = 0U; + uint32_t backup_setting_adc_dma_transfer = 0U; /* Note: Variable not declared as volatile because register read is already declared as volatile */ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); @@ -154,11 +140,20 @@ HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc, uint32_t HAL_ADC_STATE_REG_BUSY, HAL_ADC_STATE_BUSY_INTERNAL); + /* Disable ADC DMA transfer request during calibration */ + /* Note: Specificity of this STM32 serie: Calibration factor is */ + /* available in data register and also transfered by DMA. */ + /* To not insert ADC calibration factor among ADC conversion data */ + /* in array variable, DMA transfer must be disabled during */ + /* calibration. */ + backup_setting_adc_dma_transfer = READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG); + CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG); + /* Start ADC calibration */ hadc->Instance->CR |= ADC_CR_ADCAL; - + tickstart = HAL_GetTick(); - + /* Wait for calibration completion */ while(HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADCAL)) { @@ -176,6 +171,9 @@ HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc, uint32_t } } + /* Restore ADC DMA transfer request after calibration */ + SET_BIT(hadc->Instance->CFGR1, backup_setting_adc_dma_transfer); + /* Set ADC state */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, @@ -196,7 +194,6 @@ HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc, uint32_t return tmp_hal_status; } - /** * @brief Get the calibration factor. * @param hadc: ADC handle. @@ -352,13 +349,13 @@ void HAL_ADCEx_DisableVREFINTTempSensor(void) * @} */ +#endif /* HAL_ADC_MODULE_ENABLED */ /** * @} */ -#endif /* HAL_ADC_MODULE_ENABLED */ /** * @} - */ + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc_ex.h index e886b9d759..c88aeb83cb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_adc_ex.h @@ -2,10 +2,7 @@ ****************************************************************************** * @file stm32l0xx_hal_adc_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief This file contains all the functions prototypes for the ADC firmware - * library. + * @brief Header file of ADC HAL extended module. ****************************************************************************** * @attention * @@ -37,8 +34,8 @@ */ /* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L0xx_ADC_EX_H -#define __STM32L0xx_ADC_EX_H +#ifndef __STM32L0xx_HAL_ADC_EX_H +#define __STM32L0xx_HAL_ADC_EX_H #ifdef __cplusplus extern "C" { @@ -46,19 +43,19 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal_def.h" - + /** @addtogroup STM32L0xx_HAL_Driver * @{ */ -/** @defgroup ADCEx ADCEx - * @brief ADC driver modules +/** @addtogroup ADCEx * @{ */ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ -/** @defgroup ADCEx_Exported_Constants ADCEx Exported Constants + +/** @defgroup ADCEx_Exported_Constants ADC Extended Exported Constants * @{ */ @@ -70,7 +67,7 @@ * @} */ -/** @defgroup ADC_External_trigger_Source ADC External Trigger Source +/** @defgroup ADC_regular_external_trigger_source ADC External Trigger Source * @{ */ #define ADC_EXTERNALTRIGCONV_T6_TRGO ((uint32_t)0x00000000U) @@ -185,18 +182,22 @@ * @} */ -/** @defgroup ADCEx_Exported_Functions ADCEx Exported Functions +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADCEx_Exported_Functions * @{ */ -/** @defgroup ADCEx_Exported_Functions_Group3 Peripheral Control functions +/** @addtogroup ADCEx_Exported_Functions_Group1 * @{ */ -/* Exported functions --------------------------------------------------------*/ -/* Peripheral Control functions ***********************************************/ +/* IO operation functions *****************************************************/ + +/* ADC calibration */ HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc, uint32_t SingleDiff); uint32_t HAL_ADCEx_Calibration_GetValue(ADC_HandleTypeDef* hadc, uint32_t SingleDiff); HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef* hadc, uint32_t SingleDiff, uint32_t CalibrationFactor); + +/* ADC VrefInt and Temperature sensor functions specific to this STM32 serie */ HAL_StatusTypeDef HAL_ADCEx_EnableVREFINT(void); void HAL_ADCEx_DisableVREFINT(void); HAL_StatusTypeDef HAL_ADCEx_EnableVREFINTTempSensor(void); @@ -209,6 +210,7 @@ void HAL_ADCEx_DisableVREFINTTempSensor(void); * @} */ + /** * @} */ @@ -221,8 +223,7 @@ void HAL_ADCEx_DisableVREFINTTempSensor(void); } #endif -#endif /*__STM32L0xx_ADC_H */ +#endif /*__STM32L0xx_HAL_ADC_EX_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp.c index 0c6748bf20..a72be7d4c5 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_comp.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief COMP HAL module driver. * This file provides firmware functions to manage the following * functionalities of the COMP peripheral: @@ -320,45 +318,49 @@ HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp) { /* Note : COMP1 can be connected to the input 1 of LPTIM if requested */ assert_param(IS_COMP1_LPTIMCONNECTION(hcomp->Init.LPTIMConnection)); - if (hcomp->Init.LPTIMConnection == COMP_LPTIMCONNECTION_IN1_ENABLED) - { + + /* Note: Compatibility with previous driver version using */ + /* generic literal COMP_LPTIMCONNECTION_ENABLED corresponding */ + /* to LPTIM input 1 for COMP1. */ tmp_csr |= (COMP_CSR_COMP1LPTIM1IN1); } - } else { - /* Check the MCU_ID in order to allow or not the COMP2 connection to LPTIM-input2 */ - if (((HAL_GetDEVID() == C_DEV_ID_L073) && (HAL_GetREVID() == C_REV_ID_A)) - || - ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_A)) - || - ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_Z))) + /* Note : COMP2 can be connected to input 1 or input 2 of LPTIM if requested */ + assert_param(IS_COMP2_LPTIMCONNECTION(hcomp->Init.LPTIMConnection)); + + switch (hcomp->Init.LPTIMConnection) { - /* Note : COMP2 can be connected only to input 1 of LPTIM if requested */ - assert_param(IS_COMP2_LPTIMCONNECTION_RESTRICTED(hcomp->Init.LPTIMConnection)); - + case COMP_LPTIMCONNECTION_IN1_ENABLED : tmp_csr |= (COMP_CSR_COMP2LPTIM1IN1); - } - /* LPTIM connexion requested on COMP2 */ - else - { - /* Note : COMP2 can be connected to input 1 or input2 of LPTIM if requested */ - assert_param(IS_COMP2_LPTIMCONNECTION(hcomp->Init.LPTIMConnection)); - switch (hcomp->Init.LPTIMConnection) + break; + case COMP_LPTIMCONNECTION_IN2_ENABLED : + default : + /* Note: Default case for compatibility with previous driver version*/ + /* using generic literal COMP_LPTIMCONNECTION_ENABLED corresponding */ + /* to LPTIM input 2 for COMP2. */ + + /* Check the MCU_ID in order to allow or not the COMP2 connection to LPTIM input 2 */ + if (((HAL_GetDEVID() == C_DEV_ID_L073) && (HAL_GetREVID() == C_REV_ID_A)) + || + ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_A)) + || + ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_Z))) { - case COMP_LPTIMCONNECTION_IN1_ENABLED : - tmp_csr |= (COMP_CSR_COMP2LPTIM1IN1); - break; - case COMP_LPTIMCONNECTION_IN2_ENABLED : - tmp_csr |= (COMP_CSR_COMP2LPTIM1IN2); - break; - default : - break; + assert_param(IS_COMP2_LPTIMCONNECTION_RESTRICTED(hcomp->Init.LPTIMConnection)); + + /* Error: On the selected device, COMP2 cannot be connected to LPTIM input 2 */ + status = HAL_ERROR; } + else + { + tmp_csr |= (COMP_CSR_COMP2LPTIM1IN2); + } + break; } } } - + /* Update comparator register */ if ((hcomp->Instance) == COMP1) { @@ -442,8 +444,11 @@ HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp) } else { - /* Disable EXTI event generation */ + /* Disable EXTI event mode */ CLEAR_BIT(EXTI->EMR, exti_line); + + /* Disable EXTI interrupt mode */ + CLEAR_BIT(EXTI->IMR, exti_line); } /* Set HAL COMP handle state */ @@ -641,8 +646,23 @@ void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp) /* Check COMP EXTI flag */ if(READ_BIT(EXTI->PR, exti_line) != RESET) { - /* Clear COMP EXTI pending bit */ - WRITE_REG(EXTI->PR, exti_line); + /* Check whether comparator is in independent or window mode */ + if(READ_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE) != 0) + { + /* Clear COMP EXTI line pending bit of the pair of comparators */ + /* in window mode. */ + /* Note: Pair of comparators in window mode can both trig IRQ when */ + /* input voltage is changing from "out of window" area */ + /* (low or high ) to the other "out of window" area (high or low).*/ + /* Both flags must be cleared to call comparator trigger */ + /* callback is called once. */ + WRITE_REG(EXTI->PR, (COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2)); + } + else + { + /* Clear COMP EXTI line pending bit */ + WRITE_REG(EXTI->PR, exti_line); + } /* COMP trigger user callback */ HAL_COMP_TriggerCallback(hcomp); diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp.h index d2ba7e2141..8e90a409a1 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_comp.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of COMP HAL module. ****************************************************************************** * @attention @@ -586,7 +584,7 @@ typedef struct ((LPTIMCONNECTION) == COMP_LPTIMCONNECTION_IN2_ENABLED)) #define IS_COMP2_LPTIMCONNECTION_RESTRICTED(LPTIMCONNECTION) (((LPTIMCONNECTION) == COMP_LPTIMCONNECTION_DISABLED) || \ - ((LPTIMCONNECTION) == COMP_LPTIMCONNECTION_IN2_ENABLED)) + ((LPTIMCONNECTION) == COMP_LPTIMCONNECTION_IN1_ENABLED)) #define IS_COMP_OUTPUTPOL(POL) (((POL) == COMP_OUTPUTPOL_NONINVERTED) || \ ((POL) == COMP_OUTPUTPOL_INVERTED)) diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp_ex.c index 98fc39e07b..eb966bf428 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_comp_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Extended COMP HAL module driver. * @brief This file provides firmware functions to manage voltage reference * VrefInt that must be specifically controled for comparator @@ -65,6 +63,23 @@ * @{ */ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup COMP_Private_Constants + * @{ + */ + +/* Delay for COMP voltage scaler stabilization time (voltage from VrefInt, */ +/* delay based on VrefInt startup time). */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "TVREFINT"). */ +/* Unit: us */ +#define COMP_DELAY_VOLTAGE_SCALER_STAB_US ((uint32_t)3000U) /*!< Delay for COMP voltage scaler stabilization time */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ /** @addtogroup COMPEx_Exported_Functions * @{ */ @@ -82,12 +97,25 @@ * using function "HAL_COMP_Init()". * @note VrefInt requires a startup time * (refer to device datasheet, parameter "TVREFINT"). + * This function waits for the startup time + * (alternative solution: poll for bit SYSCFG_CFGR3_VREFINT_RDYF set). * @retval None */ void HAL_COMPEx_EnableVREFINT(void) { + __IO uint32_t wait_loop_index = 0U; + /* Enable the Buffer for the COMP by setting ENBUFLP_VREFINT_COMP bit in the CFGR3 register */ SYSCFG->CFGR3 |= (SYSCFG_CFGR3_ENBUFLP_VREFINT_COMP); + + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles. */ + wait_loop_index = (COMP_DELAY_VOLTAGE_SCALER_STAB_US * (SystemCoreClock / (1000000U * 2U))); + while(wait_loop_index != 0U) + { + wait_loop_index--; + } } /** diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp_ex.h index 4aef262655..4b4fa0a97f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_comp_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_comp_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of COMP HAL Extended module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_conf.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_conf.h index 0cc95650be..b157dc88ee 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_conf.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_conf.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_conf.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief HAL configuration file. ****************************************************************************** * @attention @@ -146,10 +144,12 @@ #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ - +/** + * @brief Time out for LSE start up value in ms. + */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ -#endif /* HSE_STARTUP_TIMEOUT */ +#endif /* LSE_STARTUP_TIMEOUT */ /* Tip: To avoid modifying this file each time you need to use different HSE, diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cortex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cortex.c index 04cdf09992..047d0bc67d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cortex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cortex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_cortex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CORTEX HAL module driver. * This file provides firmware functions to manage the following * functionalities of the CORTEX: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cortex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cortex.h index 69f00d4f1c..effe21fc5f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cortex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cortex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_cortex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of CORTEX HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc.c index 80532e08f1..98e0cc21a3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_crc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CRC HAL module driver. * * This file provides firmware functions to manage the following @@ -228,13 +226,16 @@ HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc) /* Reset CRC calculation unit */ __HAL_CRC_DR_RESET(hcrc); + + /* Reset IDR register content */ + CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR) ; /* DeInit the low level hardware */ HAL_CRC_MspDeInit(hcrc); /* Change CRC peripheral state */ hcrc->State = HAL_CRC_STATE_RESET; - + /* Process unlocked */ __HAL_UNLOCK(hcrc); diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc.h index 61a817c371..fffdac0a7d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_crc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of CRC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc_ex.c index 91e899f15f..1f29160005 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_crc_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Extended CRC HAL module driver. * * This file provides firmware functions to manage the following @@ -120,24 +118,33 @@ HAL_StatusTypeDef HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef *hcrc, uint32_t Pol * Look for MSB position: msb will contain the degree of * the second to the largest polynomial member. E.g., for * X^7 + X^6 + X^5 + X^2 + 1, msb = 6. */ - while (((Pol & ((uint32_t)(0x1U) << msb)) == 0U) && (msb-- > 0U)); + while (((Pol & (1U << msb)) == 0) && (msb-- > 0)){} switch (PolyLength) { case CRC_POLYLENGTH_7B: - if (msb >= HAL_CRC_LENGTH_7B) return HAL_ERROR; + if (msb >= HAL_CRC_LENGTH_7B) + { + return HAL_ERROR; + } break; case CRC_POLYLENGTH_8B: - if (msb >= HAL_CRC_LENGTH_8B) return HAL_ERROR; + if (msb >= HAL_CRC_LENGTH_8B) + { + return HAL_ERROR; + } break; case CRC_POLYLENGTH_16B: - if (msb >= HAL_CRC_LENGTH_16B) return HAL_ERROR; + if (msb >= HAL_CRC_LENGTH_16B) + { + return HAL_ERROR; + } break; case CRC_POLYLENGTH_32B: /* no polynomial definition vs. polynomial length issue possible */ - break; - default: - break; + break; + default: + break; } /* set generating polynomial */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc_ex.h index e8a203d177..7cef231b60 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_crc_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_crc_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of CRC HAL extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp.c index 46c5516627..2e23f51bff 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_cryp.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CRYP HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp.h index 280b6a248c..f20a7c1d55 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_cryp.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of CRYP HAL module. ****************************************************************************** * @attention @@ -43,7 +41,7 @@ extern "C" { #endif -#if defined (STM32L021xx) || (STM32L041xx) || defined (STM32L061xx) || defined (STM32L062xx) || defined (STM32L063xx) || defined (STM32L081xx) || defined (STM32L082xx) || defined (STM32L083xx) +#if defined (STM32L021xx) || defined (STM32L041xx) || defined (STM32L061xx) || defined (STM32L062xx) || defined (STM32L063xx) || defined (STM32L081xx) || defined (STM32L082xx) || defined (STM32L083xx) /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal_def.h" diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp_ex.c index 88872c064a..4ff7316ae1 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_cryp_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CRYPEx HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp_ex.h index 959eabf100..4678d47a76 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_cryp_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_cryp_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of CRYPEx HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac.c index 375384a140..80e625237e 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_dac.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief DAC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Digital to Analog Converter (DAC) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac.h index 42ab17c5c4..535ca574bb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_dac.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of DAC HAL module. ****************************************************************************** * @attention @@ -280,7 +278,7 @@ CLEAR_BIT((__HANDLE__)->Instance->CR, (DAC_CR_EN1 << (__DAC_CHANNEL__))) #define __HAL_DAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ -SET_BIT((__HANDLE__)->Instance->CR, __INTERRUPT__) +SET_BIT((__HANDLE__)->Instance->CR, (__INTERRUPT__)) /** @brief Disable the DAC interrupt @@ -289,7 +287,7 @@ SET_BIT((__HANDLE__)->Instance->CR, __INTERRUPT__) * @retval None */ #define __HAL_DAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ -CLEAR_BIT((__HANDLE__)->Instance->CR, __INTERRUPT__) +CLEAR_BIT((__HANDLE__)->Instance->CR, (__INTERRUPT__)) /** @brief Check whether the specified DAC interrupt source is enabled or not. * @param __HANDLE__: DAC handle diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac_ex.c index b1f4e4cc8b..bbf782fce7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_dac_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Extended DAC HAL module driver. * This file provides firmware functions to manage the following * functionalities of DAC extension peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac_ex.h index 0772beb06b..3b65bfde87 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dac_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_dac_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of DAC HAL Extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_def.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_def.h index 2893f201c7..01f5b99771 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_def.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_def.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_def.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief This file contains HAL common defines, enumeration, macros and * structures definitions. ****************************************************************************** diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dma.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dma.c index c4dc9ced10..aae8a07573 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dma.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dma.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_dma.c * @author MCD Application Team - * @version $VERSION$ - * @date $DATE$ * @brief DMA HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dma.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dma.h index 2f657362c7..db45676c84 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dma.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_dma.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_dma.h * @author MCD Application Team - * @version $VERSION$ - * @date $DATE$ * @brief Header file of DMA HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_firewall.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_firewall.c index 9c85825034..fccaf00ea5 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_firewall.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_firewall.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_firewall.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief FIREWALL HAL module driver. * This file provides firmware functions to manage the Firewall * Peripheral initialization and enabling. diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_firewall.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_firewall.h index 197de1c285..c528970cf9 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_firewall.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_firewall.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_firewall.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of FIREWALL HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash.c index ee51155216..5d8dbfe7f1 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash.c @@ -2,28 +2,23 @@ ****************************************************************************** * @file stm32l0xx_hal_flash.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief FLASH HAL module driver. * This file provides firmware functions to manage the following * functionalities of the internal FLASH memory: - * + FLASH Interface configuration - * + FLASH Memory Programming - * + DATA EEPROM Programming - * + Option Bytes Programming - * + Interrupts and flags management - * - * @verbatim - + * + Program operations functions + * + Memory Control functions + * + Peripheral State functions + * + @verbatim ============================================================================== ##### FLASH peripheral features ##### ============================================================================== - [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses to the Flash memory. It implements the erase and program Flash memory operations and the read and write protection mechanisms. - [..] The Flash memory interface accelerates code execution with a system of instruction prefetch. + [..] The Flash memory interface accelerates code execution with a system of instruction + prefetch. [..] The FLASH main features are: (+) Flash memory read operations @@ -31,46 +26,48 @@ (+) Read / write protections (+) Prefetch on I-Code (+) Option Bytes programming - + + ##### How to use this driver ##### ============================================================================== - [..] This driver provides functions to configure and program the Flash - memory of all STM32L0xx devices. + [..] + This driver provides functions and macros to configure and program the FLASH + memory of all STM32L0xx devices. - (#) 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 + (#) FLASH Memory I/O 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. - (++) Program 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. + (#) 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 manage the Option Bytes: + (++) Lock and Unlock the Option Bytes + (++) Set/Reset the write protection + (++) Set the Read protection Level + (++) Program the user Option Bytes + (++) Launch the Option Bytes loader + (++) Set/Get the Read protection Level. + (++) Set/Get the BOR level. + (++) Get the Write protection. + (++) Get the user option bytes. - (#) Interrupts and flags management functions : - (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler() - (++) Wait for last FLASH operation according to its status - (++) Get error flag status by calling HAL_GetErrorCode() + (#) Interrupts and flags management functions : this group + includes all needed functions to: + (++) Handle FLASH interrupts + (++) Wait for last FLASH operation according to its status + (++) Get error flag status (#) FLASH Interface configuration functions: this group includes the management of following features: @@ -80,68 +77,65 @@ (#) FLASH Peripheral State methods: this group includes the management of following features: (++) Wait for the FLASH operation - (++) Get the specific FLASH error flag + (++) Get the specific FLASH error flag [..] In addition to these function, this driver includes a set of macros allowing - to handle the following operations: + to handle the following operations: - (+) Set/Get the latency - (+) Enable/Disable the prefetch buffer - (+) Enable/Disable the preread buffer - (+) Enable/Disable the Flash power-down - (+) Enable/Disable the FLASH interrupts - (+) Monitor the FLASH flags status - - =============================================================================== - ##### Programming operation functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to manage the FLASH - program operations. - - [..] The FLASH Memory Programming functions, includes the following functions: - (+) HAL_FLASH_Unlock(void); - (+) HAL_FLASH_Lock(void); - (+) HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data) - (+) HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t Data) - - [..] Any operation of erase or program should follow these steps: - (#) Call the HAL_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 HAL_FLASH_Lock() to disable the flash program memory access - (recommended to protect the FLASH memory against possible unwanted operation). - - ============================================================================== - ##### Option Bytes Programming functions ##### - ============================================================================== - - [..] The FLASH_Option Bytes Programming_functions, includes the following functions: - (+) HAL_FLASH_OB_Unlock(void); - (+) HAL_FLASH_OB_Lock(void); - (+) HAL_FLASH_OB_Launch(void); - (+) HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit); - (+) HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit); - - [..] Any operation of erase or program should follow these steps: - (#) Call the HAL_FLASH_OB_Unlock() function to enable the Flash option control - register access. - (#) Call the following functions to program the desired option bytes. - (++) HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit); - (#) Once all needed option bytes to be programmed are correctly written, call the - HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process. - (#) Call the HAL_FLASH_OB_Lock() to disable the Flash option control register access (recommended - to protect the option Bytes against possible unwanted operations). - + (+) Set/Get the latency + (+) Enable/Disable the prefetch buffer + (+) Enable/Disable the preread buffer + (+) Enable/Disable the Flash power-down + (+) Enable/Disable the FLASH interrupts + (+) Monitor the FLASH flags status + + ##### Programming operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the FLASH + program operations. + + [..] The FLASH Memory Programming functions, includes the following functions: + (+) HAL_FLASH_Unlock(void); + (+) HAL_FLASH_Lock(void); + (+) HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data) + (+) HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t Data) + + [..] Any operation of erase or program should follow these steps: + (#) Call the HAL_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 HAL_FLASH_Lock() to disable the flash program memory access + (recommended to protect the FLASH memory against possible unwanted operation). + + ##### Option Bytes Programming functions ##### + ============================================================================== + + [..] The FLASH_Option Bytes Programming_functions, includes the following functions: + (+) HAL_FLASH_OB_Unlock(void); + (+) HAL_FLASH_OB_Lock(void); + (+) HAL_FLASH_OB_Launch(void); + (+) HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit); + (+) HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit); + + [..] Any operation of erase or program should follow these steps: + (#) Call the HAL_FLASH_OB_Unlock() function to enable the Flash option control + register access. + (#) Call the following functions to program the desired option bytes. + (++) HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit); + (#) Once all needed option bytes to be programmed are correctly written, call the + HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process. + (#) Call the HAL_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. As a result, these 2 options are exclusive each other. (#) To activate PCROP mode for Flash sectors(s), you need to follow the sequence below: (++) Use this function HAL_FLASHEx_AdvOBProgram with PCROPState = OB_PCROP_STATE_ENABLE. - * @endverbatim - * - ****************************************************************************** + @endverbatim + ****************************************************************************** * @attention * *

© COPYRIGHT(c) 2016 STMicroelectronics

@@ -168,7 +162,7 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -180,57 +174,73 @@ #ifdef HAL_FLASH_MODULE_ENABLED -/** @addtogroup FLASH FLASH - * @brief FLASH driver modules +/** @defgroup FLASH FLASH + * @brief FLASH HAL module driver * @{ - */ - + */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/** @addtogroup FLASH_Private +/** @defgroup FLASH_Private_Constants FLASH Private Constants * @{ */ - -/** - * @brief Variable used for Program/Erase sectors under interruption - */ -FLASH_ProcessTypeDef ProcFlash; - - -/* Private function prototypes -----------------------------------------------*/ -static void FLASH_SetErrorCode(void); -static void FLASH_Program_Word(uint32_t Address, uint32_t Data); - /** * @} */ -/* functions -----------------------------------------------------------------*/ - -/** @addtogroup FLASH_Exported_Functions +/* Private macro ---------------------------- ---------------------------------*/ +/** @defgroup FLASH_Private_Macros FLASH Private Macros * @{ - */ + */ + +/** + * @} + */ -/** @addtogroup FLASH_Exported_Functions_Group1 - * @brief Programming operation functions - * +/* Private variables ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Variables FLASH Private Variables + * @{ + */ +/* Variables used for Erase pages under interruption*/ +FLASH_ProcessTypeDef pFlash; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASH_Private_Functions FLASH Private Functions + * @{ + */ +static void FLASH_SetErrorCode(void); +extern void FLASH_PageErase(uint32_t PageAddress); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Functions FLASH Exported Functions + * @{ + */ + +/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions + * @brief Programming operation functions + * @verbatim @endverbatim * @{ */ + /** * @brief Program word at a specified address * @note To correctly run this function, the HAL_FLASH_Unlock() function * must be called before. * Call the HAL_FLASH_Lock() to disable the flash memory access * (recommended to protect the FLASH memory against possible unwanted operation). - * @param TypeProgram: Indicate the way to program at a specified address. - * This parameter can be a value of @ref FLASH_Type_Program - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed + * + * @param TypeProgram Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASH_Type_Program + * @param Address Specifie the address to be programmed. + * @param Data Specifie the data to be programmed * * @retval HAL_StatusTypeDef HAL Status */ @@ -239,35 +249,40 @@ HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint HAL_StatusTypeDef status = HAL_ERROR; /* Process Locked */ - __HAL_LOCK(&ProcFlash); + __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { - /* Program word (32-bit) at a specified address */ - FLASH_Program_Word(Address, (uint32_t) Data); + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /*Program word (32-bit) at a specified address.*/ + *(__IO uint32_t *)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); } /* Process Unlocked */ - __HAL_UNLOCK(&ProcFlash); + __HAL_UNLOCK(&pFlash); - return status; + return status; } /** * @brief Program word at a specified address with interrupt enabled. - * @param TypeProgram: Indicate the way to program at a specified address. - * This parameter can be a value of @ref FLASH_Type_Program - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed + * + * @param TypeProgram Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASH_Type_Program + * @param Address Specifie the address to be programmed. + * @param Data Specifie the data to be programmed * * @retval HAL_StatusTypeDef HAL Status */ @@ -276,31 +291,25 @@ HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, u HAL_StatusTypeDef status = HAL_OK; /* Process Locked */ - __HAL_LOCK(&ProcFlash); + __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + /* Enable End of FLASH Operation and Error source interrupts */ + __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); - if(status == HAL_OK) + pFlash.Address = Address; + pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM; + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + if(TypeProgram == FLASH_TYPEPROGRAM_WORD) { - /* Enable End of FLASH Operation interrupt */ - __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP); - - /* Enable Error source interrupt */ - __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR); - - ProcFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM; - ProcFlash.Address = Address; - - if(TypeProgram == FLASH_TYPEPROGRAM_WORD) - { - /* Program word (32-bit) at a specified address */ - FLASH_Program_Word(Address, (uint32_t) Data); - } - } + /* Program word (32-bit) at a specified address. */ + *(__IO uint32_t *)Address = Data; + } return status; } @@ -310,8 +319,8 @@ HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, u */ void HAL_FLASH_IRQHandler(void) { - uint32_t temp; - + uint32_t addresstmp = 0; + /* Check FLASH operation error flags */ /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices, @@ -325,108 +334,110 @@ void HAL_FLASH_IRQHandler(void) * */ - if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | FLASH_FLAG_OPTVERR | \ - FLASH_FLAG_RDERR | FLASH_FLAG_FWWERR | FLASH_FLAG_NOTZEROERR) != RESET) + if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) ) { - if(ProcFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) + if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) { /* Return the faulty sector */ - temp = ProcFlash.Page; - ProcFlash.Page = 0xFFFFFFFFU; + addresstmp = pFlash.Page; + pFlash.Page = 0xFFFFFFFFU; } else { /* Return the faulty address */ - temp = ProcFlash.Address; + addresstmp = pFlash.Address; } - /* Save the Error code */ FLASH_SetErrorCode(); - + /* FLASH error interrupt user callback */ - HAL_FLASH_OperationErrorCallback(temp); + HAL_FLASH_OperationErrorCallback(addresstmp); /* Stop the procedure ongoing */ - ProcFlash.ProcedureOnGoing = FLASH_PROC_NONE; + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } - - /* Check FLASH End of Operation flag */ - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET) + + /* Check FLASH End of Operation flag */ + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); - + /* Process can continue only if no error detected */ - if(ProcFlash.ProcedureOnGoing != FLASH_PROC_NONE) + if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE) { - if(ProcFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) + if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) { - /* Nb of sector to erased can be decreased */ - ProcFlash.NbPagesToErase--; - - /* Check if there are still sectors to erase */ - if(ProcFlash.NbPagesToErase != 0U) + /* Nb of pages to erased can be decreased */ + pFlash.NbPagesToErase--; + + /* Check if there are still pages to erase */ + if(pFlash.NbPagesToErase != 0U) { - temp = ProcFlash.Page; - /* Indicate user which sector has been erased */ - HAL_FLASH_EndOfOperationCallback(temp); - - /* Increment sector number */ - temp = ProcFlash.Page + FLASH_PAGE_SIZE; - ProcFlash.Page = ProcFlash.Page + FLASH_PAGE_SIZE; - + addresstmp = pFlash.Page; + /*Indicate user which sector has been erased */ + HAL_FLASH_EndOfOperationCallback(addresstmp); + + /*Increment sector number*/ + addresstmp = pFlash.Page + FLASH_PAGE_SIZE; + pFlash.Page = addresstmp; + /* If the erase operation is completed, disable the ERASE Bit */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE); - - FLASH_ErasePage(temp); + + FLASH_PageErase(addresstmp); } else { - /* No more sectors to Erase, user callback can be called */ - /* Reset Sector and stop Erase sectors procedure */ - ProcFlash.Page = temp = 0xFFFFFFFFU; - ProcFlash.ProcedureOnGoing = FLASH_PROC_NONE; + /* No more pages to Erase, user callback can be called. */ + /* Reset Sector and stop Erase pages procedure */ + pFlash.Page = addresstmp = 0xFFFFFFFFU; + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* FLASH EOP interrupt user callback */ - HAL_FLASH_EndOfOperationCallback(temp); + HAL_FLASH_EndOfOperationCallback(addresstmp); } } - else + else { - if(ProcFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM) - { /* If the program operation is completed, disable the PROG Bit */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG); + /* Program ended. Return the selected address */ /* FLASH EOP interrupt user callback */ - HAL_FLASH_EndOfOperationCallback(ProcFlash.Address); - } - ProcFlash.ProcedureOnGoing = FLASH_PROC_NONE; + HAL_FLASH_EndOfOperationCallback(pFlash.Address); + + /* Reset Address and stop Program procedure */ + pFlash.Address = 0xFFFFFFFFU; + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } } } + - if(ProcFlash.ProcedureOnGoing == FLASH_PROC_NONE) + if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) { - /* Operation is completed, disable the PG and PER Bits */ - CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE | FLASH_PECR_PROG); + /* Operation is completed, disable the PROG and ERASE */ + CLEAR_BIT(FLASH->PECR, (FLASH_PECR_ERASE | FLASH_PECR_PROG)); - /* Disable End of FLASH Operation interrupt */ - __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP); - - /* Disable Error source interrupt */ - __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR); + /* Disable End of FLASH Operation and Error source interrupts */ + __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); /* Process Unlocked */ - __HAL_UNLOCK(&ProcFlash); + __HAL_UNLOCK(&pFlash); } - -} +} /** * @brief FLASH end of operation interrupt callback * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure - * - Pages Erase: Sector which has been erased - * (if 0xFFFFFFFF, it means that all the selected sectors have been erased) + * - Pages Erase: Address of the page which has been erased + * (if 0xFFFFFFFF, it means that all the selected pages have been erased) * - Program: Address which was selected for data program * @retval none */ @@ -443,7 +454,7 @@ __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue) /** * @brief FLASH operation error interrupt callback * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure - * - Pagess Erase: Sector number which returned an error + * - Pages Erase: Address of the page which returned an error * - Program: Address which was selected for data program * @retval none */ @@ -461,7 +472,7 @@ __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue) * @} */ -/** @addtogroup FLASH_Exported_Functions_Group2 +/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions * @brief management functions * @verbatim @@ -474,116 +485,114 @@ __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue) @endverbatim * @{ - */ + */ /** * @brief Unlock the FLASH control register access - * @retval HAL_StatusTypeDef HAL Status + * @retval HAL Status */ -HAL_StatusTypeDef HAL_FLASH_Unlock(void) +HAL_StatusTypeDef HAL_FLASH_Unlock(void) { - if((FLASH->PECR & FLASH_PECR_PRGLOCK) != RESET) + if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PRGLOCK)) { - /* Unlocking FLASH_PECR register access */ - if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET) - { - FLASH->PEKEYR = FLASH_PEKEY1; - FLASH->PEKEYR = FLASH_PEKEY2; - } - + /* Unlocking FLASH_PECR register access*/ + if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK)) + { + WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1); + WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2); + } + /* Unlocking the program memory access */ - FLASH->PRGKEYR = FLASH_PRGKEY1; - FLASH->PRGKEYR = FLASH_PRGKEY2; + WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY1); + WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY2); } else { return HAL_ERROR; } - + return HAL_OK; } /** * @brief Locks the FLASH control register access - * @retval HAL_StatusTypeDef HAL Status + * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASH_Lock(void) { - /* Set the PRGLOCK Bit to lock the program memory access */ + /* Set the PRGLOCK Bit to lock the FLASH Registers access */ SET_BIT(FLASH->PECR, FLASH_PECR_PRGLOCK); - return HAL_OK; + return HAL_OK; } /** * @brief Unlock the FLASH Option Control Registers access. - * @retval HAL_StatusTypeDef HAL Status + * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void) { - if((FLASH->PECR & FLASH_PECR_OPTLOCK) != RESET) + if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_OPTLOCK)) { - /* Unlocking FLASH_PECR register access */ - if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET) - { - FLASH->PEKEYR = FLASH_PEKEY1; - FLASH->PEKEYR = FLASH_PEKEY2; - } - + /* Unlocking FLASH_PECR register access*/ + if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK)) + { + /* Unlocking FLASH_PECR register access*/ + WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1); + WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2); + } + /* Unlocking the option bytes block access */ - FLASH->OPTKEYR = FLASH_OPTKEY1; - FLASH->OPTKEYR = FLASH_OPTKEY2; + WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1); + WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2); } else { return HAL_ERROR; } - return HAL_OK; + return HAL_OK; } /** * @brief Lock the FLASH Option Control Registers access. - * @retval HAL_StatusTypeDef HAL Status + * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASH_OB_Lock(void) { /* Set the OPTLOCK Bit to lock the option bytes block access */ SET_BIT(FLASH->PECR, FLASH_PECR_OPTLOCK); - + return HAL_OK; } - + /** * @brief Launch the option byte loading. - * @retval HAL_StatusTypeDef HAL Status + * @note This function will reset automatically the MCU. + * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASH_OB_Launch(void) { - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - - /* Set the OBL_Launch bit to lauch the option byte loading */ + /* Set the OBL_Launch bit to launch the option byte loading */ SET_BIT(FLASH->PECR, FLASH_PECR_OBL_LAUNCH); /* Wait for last operation to be completed */ - return(FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE -)); + return(FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE)); } /** * @} - */ + */ -/** @addtogroup FLASH_Exported_Functions_Group3 - * @brief Peripheral Errors functions +/** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions + * @brief Peripheral errors functions * @verbatim =============================================================================== - ##### Peripheral Errors functions ##### + ##### Peripheral Errors functions ##### =============================================================================== [..] - This subsection permit to get in run-time Errors of the FLASH peripheral. + This subsection permit to get in run-time errors of the FLASH peripheral. @endverbatim * @{ @@ -591,18 +600,12 @@ HAL_StatusTypeDef HAL_FLASH_OB_Launch(void) /** * @brief Get the specific FLASH error flag. - * @retval uint32_t: The returned value can be a mixed of : - * @arg HAL_FLASH_ERROR_RD: FLASH Read Protection error flag (PCROP) - * @arg HAL_FLASH_ERROR_SIZE: FLASH Programming Parallelism error flag - * @arg HAL_FLASH_ERROR_PGA: FLASH Programming Alignment error flag - * @arg HAL_FLASH_ERROR_WRP: FLASH Write protected error flag - * @arg HAL_FLASH_ERROR_OPTV: FLASH Option valid error flag - * @arg HAL_FLASH_ERROR_FWWERR: FLASH Write or Errase operation aborted - * @arg HAL_FLASH_ERROR_NOTZERO: FLASH Write operation is done in a not-erased region + * @retval FLASH_ErrorCode The returned value can be: + * @ref FLASH_Error_Codes */ uint32_t HAL_FLASH_GetError(void) -{ - return ProcFlash.ErrorCode; +{ + return pFlash.ErrorCode; } /** @@ -613,34 +616,34 @@ uint32_t HAL_FLASH_GetError(void) * @} */ -/** @addtogroup FLASH_Private - * @{ - */ +/** @addtogroup FLASH_Private_Functions + * @{ + */ /** * @brief Wait for a FLASH operation to complete. - * @param Timeout: maximum flash operationtimeout - * @retval HAL status + * @param Timeout maximum flash operation timeout + * @retval HAL Status */ HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) { /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. Even if the FLASH operation fails, the BUSY flag will be reset and an error flag will be set */ - - uint32_t tickstart = HAL_GetTick(); - while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET) + uint32_t tickstart = HAL_GetTick(); + + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { - if(Timeout != HAL_MAX_DELAY) + if (Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) { return HAL_TIMEOUT; } - } + } } - + /* Check FLASH End of Operation flag */ if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { @@ -648,13 +651,15 @@ HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); } - - if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET) || \ - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) != RESET) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) != RESET) || \ - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR) != RESET) || \ - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) != RESET)) + if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) ) { - /* Save the error code */ + /*Save the error code*/ /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices, * (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving @@ -666,118 +671,81 @@ HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) */ FLASH_SetErrorCode(); return HAL_ERROR; - } + } /* There is no error flag set */ - return HAL_OK; + return HAL_OK; } + /** * @brief Set the specific FLASH error flag. * @retval None */ static void FLASH_SetErrorCode(void) -{ +{ + uint32_t flags = 0; + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) - { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; + flags |= FLASH_FLAG_WRPERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) - { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_PGA; + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA; + flags |= FLASH_FLAG_PGAERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE; + pFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE; + flags |= FLASH_FLAG_SIZERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)) - { - /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices, - * (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving - * as expected. If the user run an application using the first - * cut of the STM32L031xx device or the first cut of the STM32L041xx - * device, this error should be ignored. The revId of the device - * can be retrieved via the HAL_GetREVID() function. - * - */ - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV; + { + /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices, + * (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving + * as expected. If the user run an application using the first + * cut of the STM32L031xx device or the first cut of the STM32L041xx + * device, this error should be ignored. The revId of the device + * can be retrieved via the HAL_GetREVID() function. + * + */ + pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV; + flags |= FLASH_FLAG_OPTVERR; } + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)) - { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_RD; + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_RD; + flags |= FLASH_FLAG_RDERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR)) { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_FWWERR; + pFlash.ErrorCode |= HAL_FLASH_ERROR_FWWERR; + flags |= HAL_FLASH_ERROR_FWWERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR)) { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_NOTZERO; + pFlash.ErrorCode |= HAL_FLASH_ERROR_NOTZERO; + flags |= FLASH_FLAG_NOTZEROERR; } - - /* Errors are now stored, clear errors flags */ - - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | - FLASH_FLAG_OPTVERR | FLASH_FLAG_RDERR | FLASH_FLAG_FWWERR | - FLASH_FLAG_NOTZEROERR); -} + /* Clear FLASH error pending bits */ + __HAL_FLASH_CLEAR_FLAG(flags); +} /** - * @brief Erases a specified page in program memory. - * @note To correctly run this function, the HAL_FLASH_Unlock() function - * must be called before. - * Call the HAL_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 128 bytes). - * @retval HAL_StatusTypeDef HAL Status + * @} */ -void FLASH_ErasePage(uint32_t Page_Address) -{ - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - - /* Set the ERASE bit */ - SET_BIT(FLASH->PECR, FLASH_PECR_ERASE); - - /* Set PROG bit */ - SET_BIT(FLASH->PECR, FLASH_PECR_PROG); - - /* Write 00000000h to the first word of the program page to erase */ - *(__IO uint32_t *)Page_Address = 0x00000000U; -} - -/** - * @brief Program word (32-bit) at a specified address. - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed. - * @retval None - */ -static void FLASH_Program_Word(uint32_t Address, uint32_t Data) -{ - /* Check the parameters */ - assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); - - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - - *(__IO uint32_t*)Address = Data; -} /** * @} */ -#endif /* HAL_FLASH_MODULE_ENABLED */ +#endif /* HAL_FLASH_MODULE_ENABLED */ -/** - * @} - */ - /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash.h index 96afb4a1b7..e9712cf8c6 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_flash.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of Flash HAL module. ****************************************************************************** * @attention @@ -32,12 +30,12 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L0XX_HAL_FLASH_H -#define __STM32L0XX_HAL_FLASH_H +#ifndef __STM32L0xx_HAL_FLASH_H +#define __STM32L0xx_HAL_FLASH_H #ifdef __cplusplus extern "C" { @@ -45,15 +43,38 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal_def.h" - + /** @addtogroup STM32L0xx_HAL_Driver * @{ */ -/** @defgroup FLASH FLASH +/** @addtogroup FLASH + * @{ + */ + +/** @addtogroup FLASH_Private_Constants + * @{ + */ +#define FLASH_TIMEOUT_VALUE (50000U) /* 50 s */ +#define FLASH_SIZE_DATA_REGISTER FLASHSIZE_BASE +/** + * @} + */ + +/** @addtogroup FLASH_Private_Macros * @{ */ +#define IS_FLASH_TYPEPROGRAM(_VALUE_) ((_VALUE_) == FLASH_TYPEPROGRAM_WORD) + +#define IS_FLASH_LATENCY(__LATENCY__) (((__LATENCY__) == FLASH_LATENCY_0) || \ + ((__LATENCY__) == FLASH_LATENCY_1)) + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ /** @defgroup FLASH_Exported_Types FLASH Exported Types * @{ */ @@ -63,90 +84,82 @@ */ typedef enum { - FLASH_PROC_NONE = 0U, - FLASH_PROC_PAGEERASE, - FLASH_PROC_PROGRAM + FLASH_PROC_NONE = 0, + FLASH_PROC_PAGEERASE = 1, + FLASH_PROC_PROGRAM = 2, } FLASH_ProcedureTypeDef; -/** - * @brief FLASH Erase structure definition - */ - typedef struct - { - uint32_t TypeErase; /*!< TypeErase: Page Erase only. - This parameter can be a value of @ref FLASHEx_Type_Erase */ - - uint32_t PageAddress ; /*!< PageAddress : Initial FLASH address to be erased - This parameter must be a value belonging to FLASH Programm address (depending on the devices) */ - - uint32_t NbPages; /*!< NbPages: Number of pages to be erased. - This parameter must be a value between 1 and (max number of pages - value of Initial page)*/ - - } FLASH_EraseInitTypeDef; - /** * @brief FLASH handle Structure definition */ typedef struct { - __IO FLASH_ProcedureTypeDef ProcedureOnGoing; /* Internal variable to indicate which procedure is ongoing or not in IT context */ + __IO FLASH_ProcedureTypeDef ProcedureOnGoing; /*!< Internal variable to indicate which procedure is ongoing or not in IT context */ - __IO uint32_t NbPagesToErase; /* Internal variable to save the remaining sectors to erase in IT context */ - - __IO uint32_t Page; /* Internal variable to define the current sector which is erasing */ - - __IO uint32_t Address; /* Internal variable to save address selected for program */ - - HAL_LockTypeDef Lock; /* FLASH locking object */ + __IO uint32_t NbPagesToErase; /*!< Internal variable to save the remaining sectors to erase in IT context*/ - __IO uint32_t ErrorCode; /* FLASH error code */ + __IO uint32_t Address; /*!< Internal variable to save address selected for program or erase */ + + __IO uint32_t Page; /*!< Internal variable to define the current page which is erasing */ + + HAL_LockTypeDef Lock; /*!< FLASH locking object */ + + __IO uint32_t ErrorCode; /*!< FLASH error code + This parameter can be a value of @ref FLASH_Error_Codes */ +} FLASH_ProcessTypeDef; -}FLASH_ProcessTypeDef; /** * @} - */ + */ -/** @addtogroup FLASH_Private +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Constants FLASH Exported Constants * @{ */ -/** - * @brief Variable used for Program/Erase sectors under interruption. - * Put as extern as used also in flash_ex.c. +/** @defgroup FLASH_Error_Codes FLASH Error Codes + * @{ */ -extern FLASH_ProcessTypeDef ProcFlash; +#define HAL_FLASH_ERROR_NONE 0x00U /*!< No error */ +#define HAL_FLASH_ERROR_PGA 0x01U /*!< Programming alignment error */ +#define HAL_FLASH_ERROR_WRP 0x02U /*!< Write protection error */ +#define HAL_FLASH_ERROR_OPTV 0x04U /*!< Option validity error */ +#define HAL_FLASH_ERROR_SIZE 0x08U /*!< */ +#define HAL_FLASH_ERROR_RD 0x10U /*!< Read protected error */ +#define HAL_FLASH_ERROR_FWWERR 0x20U /*!< FLASH Write or Erase operation aborted */ +#define HAL_FLASH_ERROR_NOTZERO 0x40U /*!< FLASH Write operation is done in a not-erased region */ -#define FLASH_TIMEOUT_VALUE ((uint32_t)50000U) /* 50 s */ -#define FLASH_SIZE_DATA_REGISTER ((uint32_t)0x1FF8007CU) /** * @} */ - -/** @defgroup FLASH_Exported_Constants FLASH Public Constants +/** @defgroup FLASH_Page_Size FLASH size information * @{ + */ + +#define FLASH_SIZE (uint32_t)((*((uint32_t *)FLASHSIZE_BASE)&0xFFFF) * 1024U) +#define FLASH_PAGE_SIZE ((uint32_t)128U) /*!< FLASH Page Size in bytes */ + +/** + * @} */ - - /** - * @brief FLASH size information - */ -#define FLASH_SIZE (uint32_t)(*((uint16_t *)FLASH_SIZE_DATA_REGISTER) * 1024U) -#define FLASH_PAGE_SIZE ((uint32_t)128U) /** @defgroup FLASH_Type_Program FLASH Type Program * @{ - */ -#define FLASH_TYPEPROGRAM_WORD ((uint32_t)0x02U) /*!PECR) |= (__INTERRUPT__)) + */ +#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) SET_BIT((FLASH->PECR), (__INTERRUPT__)) /** * @brief Disable the specified FLASH interrupt. - * @param __INTERRUPT__ : FLASH interrupt - * This parameter can be any combination of the following values: - * @arg FLASH_IT_EOP: End of FLASH Operation Interrupt - * @arg FLASH_IT_ERR: Error Interrupt + * @param __INTERRUPT__ FLASH interrupt + * This parameter can be any combination of the following values: + * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt + * @arg @ref FLASH_IT_ERR Error Interrupt * @retval none - */ -#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) ((FLASH->PECR) &= ~(uint32_t)(__INTERRUPT__)) + */ +#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) CLEAR_BIT((FLASH->PECR), (uint32_t)(__INTERRUPT__)) /** * @brief Get the specified FLASH flag status. - * @param __FLAG__: specifies the FLASH flag to check. - * This parameter can be one of the following values: - * @arg FLASH_FLAG_BSY : FLASH Busy 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 (not valid with STM32L031xx/STM32L041xx) - * @arg FLASH_FLAG_SIZERR: FLASH Size error flag - * @arg FLASH_FLAG_OPTVERR: FLASH Option validity error flag (not valid with STM32L031xx/STM32L041xx) - * @arg FLASH_FLAG_RDERR: FLASH Read protected error flag - * @arg FLASH_FLAG_FWWERR: FLASH Fetch While Write Error flag - * @arg FLASH_FLAG_NOTZEROERR: Not Zero area error flag + * @param __FLAG__ specifies the FLASH flag to check. + * This parameter can be one of the following values: + * @arg @ref FLASH_FLAG_BSY FLASH Busy flag + * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag + * @arg @ref FLASH_FLAG_ENDHV FLASH End of High Voltage flag + * @arg @ref FLASH_FLAG_READY FLASH Ready flag after low power mode + * @arg @ref FLASH_FLAG_PGAERR FLASH Programming Alignment error flag + * @arg @ref FLASH_FLAG_SIZERR FLASH Size error flag + * @arg @ref FLASH_FLAG_OPTVERR FLASH Option validity error flag (not valid with STM32L031xx/STM32L041xx) + * @arg @ref FLASH_FLAG_RDERR FLASH Read protected error flag + * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag + * @arg @ref FLASH_FLAG_FWWERR FLASH Fetch While Write Error flag + * @arg @ref FLASH_FLAG_NOTZEROERR Not Zero area error flag * @retval The new state of __FLAG__ (SET or RESET). */ #define __HAL_FLASH_GET_FLAG(__FLAG__) (((FLASH->SR) & (__FLAG__)) == (__FLAG__)) /** * @brief Clear the specified FLASH flag. - * @param __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 (not valid with STM32L031xx/STM32L041xx) - * @arg FLASH_FLAG_SIZERR: FLASH size error flag - * @arg FLASH_FLAG_OPTVERR: FLASH Option validity error flag (not valid with STM32L031xx/STM32L041xx) - * @arg FLASH_FLAG_RDERR: FLASH Read protected error flag - * @arg FLASH_FLAG_FWWERR: FLASH Fetch While Write Error flag - * @arg FLASH_FLAG_NOTZEROERR: Not Zero area error flag - * @retval None + * @param __FLAG__ specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag + * @arg @ref FLASH_FLAG_PGAERR FLASH Programming Alignment error flag + * @arg @ref FLASH_FLAG_SIZERR FLASH Size error flag + * @arg @ref FLASH_FLAG_OPTVERR FLASH Option validity error flag (not valid with STM32L031xx/STM32L041xx) + * @arg @ref FLASH_FLAG_RDERR FLASH Read protected error flag + * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag + * @arg @ref FLASH_FLAG_FWWERR FLASH Fetch While Write Error flag + * @arg @ref FLASH_FLAG_NOTZEROERR Not Zero area error flag + * @retval none */ -#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) (FLASH->SR = (__FLAG__)) +#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) ((FLASH->SR) = (__FLAG__)) /** * @} @@ -298,101 +304,73 @@ extern FLASH_ProcessTypeDef ProcFlash; * @} */ -/* Include FLASH HAL Extension module */ -#include "stm32l0xx_hal_flash_ex.h" -#include "stm32l0xx_hal_flash_ramfunc.h" +/* Include FLASH HAL Extended module */ +#include "stm32l0xx_hal_flash_ex.h" +#include "stm32l0xx_hal_flash_ramfunc.h" -/* Exported functions ------------------------------------------------------- */ - -/** @defgroup FLASH_Exported_Functions FLASH Exported functions +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FLASH_Exported_Functions * @{ */ - -/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions + +/** @addtogroup FLASH_Exported_Functions_Group1 * @{ */ - -/** - * @brief FLASH memory functions that can be executed from FLASH. - */ -/* Program operation functions ***********************************************/ +/* IO operation functions *****************************************************/ HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data); HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t Data); -/* FLASH IRQ handler function ***********************************************/ -void HAL_FLASH_IRQHandler(void); +/* FLASH IRQ handler function */ +void HAL_FLASH_IRQHandler(void); +/* Callbacks in non blocking modes */ +void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue); +void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue); -/* Callbacks in non blocking modes ******************************************/ -void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue); -void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue); - /** * @} - */ - -/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions - * @{ */ -/* FLASH Memory Programming functions *****************************************/ +/** @addtogroup FLASH_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions ***********************************************/ HAL_StatusTypeDef HAL_FLASH_Unlock(void); HAL_StatusTypeDef HAL_FLASH_Lock(void); - -/* Option Bytes Programming functions *****************************************/ HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void); HAL_StatusTypeDef HAL_FLASH_OB_Lock(void); HAL_StatusTypeDef HAL_FLASH_OB_Launch(void); /** * @} - */ + */ -/** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions +/** @addtogroup FLASH_Exported_Functions_Group3 * @{ */ -/* Peripheral State methods **************************************************/ +/* Peripheral State and Error functions ***************************************/ uint32_t HAL_FLASH_GetError(void); /** * @} - */ - -/** - * @} - */ - -/** @addtogroup FLASH_Private - * @{ - */ - -#define IS_FLASH_TYPEPROGRAM(VALUE) ((VALUE) == FLASH_TYPEPROGRAM_WORD) - -#define IS_FLASH_LATENCY(__LATENCY__) (((__LATENCY__) == FLASH_LATENCY_0) || \ - ((__LATENCY__) == FLASH_LATENCY_1)) - -/** - * @brief Function used internally by HAL FLASH driver. - */ -HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); -void FLASH_ErasePage(uint32_t Page_Address); -/** - * @} - */ - -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup FLASH_Private FLASH Private - * @{ */ /** * @} */ -/**************************************************************/ + +/* Private function -------------------------------------------------*/ +/** @addtogroup FLASH_Private_Functions + * @{ + */ +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); /** * @} - */ + */ + +/** + * @} + */ /** * @} @@ -402,7 +380,7 @@ void FLASH_ErasePage(uint32_t Page_Address); } #endif -#endif /* __STM32L0XX_HAL_FLASH_H */ +#endif /* __STM32L0xx_HAL_FLASH_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ex.c index 4fb4ada6e3..413eaad701 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ex.c @@ -2,9 +2,8 @@ ****************************************************************************** * @file stm32l0xx_hal_flash_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief FLASH HAL module driver. + * @brief Extended FLASH HAL module driver. + * * This file provides firmware functions to manage the following * functionalities of the internal FLASH memory: * + FLASH Interface configuration @@ -12,8 +11,8 @@ * + DATA EEPROM Programming/Erasing * + Option Bytes Programming * + Interrupts management - * - * @verbatim + * + @verbatim ============================================================================== ##### Flash peripheral Extended features ##### ============================================================================== @@ -28,10 +27,10 @@ ##### How to use this driver ##### ============================================================================== [..] This driver provides functions to configure and program the FLASH memory - of all STM32L0xx. It includes: + of all STM32L0xx. It includes: (+) Full DATA_EEPROM erase and program management (+) Boot activation - (+) PCROP protection configuration and control for all sectors + (+) PCROP protection configuration and control for all pages @endverbatim ****************************************************************************** @@ -61,7 +60,7 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -70,54 +69,83 @@ /** @addtogroup STM32L0xx_HAL_Driver * @{ */ - #ifdef HAL_FLASH_MODULE_ENABLED -/** @addtogroup FLASHEx +/** @addtogroup FLASH + * @{ + */ +/** @addtogroup FLASH_Private_Variables + * @{ + */ +/* Variables used for Erase pages under interruption*/ +extern FLASH_ProcessTypeDef pFlash; +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FLASHEx FLASHEx * @brief FLASH HAL Extension module driver * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/** @addtogroup FLASHEx_Private - * @{ - */ -static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP); -static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR); -static uint8_t FLASH_OB_GetUser(void); -static uint8_t FLASH_OB_GetRDP(void); -static uint8_t FLASH_OB_GetBOR(void); -static uint8_t FLASH_OB_GetBOOTBit1(void); -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) -static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t Sector2, uint32_t NewState); -#else -static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t NewState); -#endif -static HAL_StatusTypeDef FLASH_OB_PCROPSelectionConfig(uint32_t WPRMOD); -static uint32_t FLASH_OB_GetWRP(void); -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) -static uint32_t FLASH_OB_GetWRP2(void); -#endif -static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY); -static HAL_StatusTypeDef FLASH_OB_BOOTBit1Config(uint8_t OB_BOOT_BIT1); -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) -static HAL_StatusTypeDef FLASH_OB_BFB2Config(uint8_t OB_BFB2); -#endif +/** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants + * @{ + */ /** * @} */ - -/* Exported functions ---------------------------------------------------------*/ -/** @addtogroup FLASHEx_Exported_Functions +/* Private macro -------------------------------------------------------------*/ +/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros + * @{ + */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions + * @{ + */ +void FLASH_PageErase(uint32_t PageAddress); +#if defined(FLASH_OPTR_BFB2) +static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t OB_BOOT); +#endif /* FLASH_OPTR_BFB2 */ +static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP); +static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY); +static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR); +static uint8_t FLASH_OB_GetRDP(void); +static uint8_t FLASH_OB_GetUser(void); +static uint8_t FLASH_OB_GetBOR(void); +static uint8_t FLASH_OB_GetBOOTBit1(void); +static HAL_StatusTypeDef FLASH_OB_BOOTBit1Config(uint8_t OB_BootBit1); +#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) +static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t Sector2, uint32_t NewState); +#else +static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t NewState); +#endif +static uint32_t FLASH_OB_GetWRP(void); +#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) +static uint32_t FLASH_OB_GetWRP2(void); +#endif + +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions * @{ */ -/** @addtogroup FLASHEx_Exported_Functions_Group1 +/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions * @brief FLASH Memory Erasing functions * @verbatim @@ -126,134 +154,140 @@ static HAL_StatusTypeDef FLASH_OB_BFB2Config(uint8_t OB_BFB2); ============================================================================== [..] The FLASH Memory Erasing functions, includes the following functions: - (+) HAL_FLASHEx_Erase: return only when erase has been done - (+) HAL_FLASHEx_Erase_IT: end of erase is done when HAL_FLASH_EndOfOperationCallback is called with parameter - 0xFFFFFFFF + (+) @ref HAL_FLASHEx_Erase: return only when erase has been done + (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback + is called with parameter 0xFFFFFFFF [..] Any operation of erase should follow these steps: - (#) Call the HAL_FLASH_Unlock() function to enable the flash control register and + (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and program memory access. (#) Call the desired function to erase page. - (#) Call the HAL_FLASH_Lock() to disable the flash program memory access + (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access (recommended to protect the FLASH memory against possible unwanted operation). @endverbatim * @{ */ - + /** * @brief Erase the specified FLASH memory Pages - * @note To correctly run this function, the HAL_FLASH_Unlock() function + * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function * must be called before. - * Call the HAL_FLASH_Lock() to disable the flash memory access + * Call the @ref HAL_FLASH_Lock() to disable the flash memory access * (recommended to protect the FLASH memory against possible unwanted operation) - * @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that + * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * - * @param[out] PageError: pointer to variable that - * contains the configuration information on faulty sector in case of error - * (0xFFFFFFFF means that all the sectors have been correctly erased) + * @param[out] PageError pointer to variable that + * contains the configuration information on faulty page in case of error + * (0xFFFFFFFF means that all the pages have been correctly erased) * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError) { HAL_StatusTypeDef status = HAL_ERROR; - uint32_t index = 0U; + uint32_t address = 0U; /* Process Locked */ - __HAL_LOCK(&ProcFlash); + __HAL_LOCK(&pFlash); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); if (status == HAL_OK) { - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - /*Initialization of PageError variable*/ *PageError = 0xFFFFFFFFU; - + /* Check the parameters */ assert_param(IS_NBPAGES(pEraseInit->NbPages)); assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); - assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U)); + assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U)); - /* Erase by sector by sector to be done*/ - for(index = pEraseInit->PageAddress; index < ((pEraseInit->NbPages * FLASH_PAGE_SIZE)+ pEraseInit->PageAddress); index += FLASH_PAGE_SIZE) - { - FLASH_ErasePage(index); + /* Erase page by page to be done*/ + for(address = pEraseInit->PageAddress; + address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress); + address += FLASH_PAGE_SIZE) + { + FLASH_PageErase(address); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - + /* If the erase operation is completed, disable the ERASE Bit */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG); CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE); if (status != HAL_OK) { - /* In case of error, stop erase procedure and return the faulty sector*/ - *PageError = index; + /* In case of error, stop erase procedure and return the faulty address */ + *PageError = address; break; } } } /* Process Unlocked */ - __HAL_UNLOCK(&ProcFlash); + __HAL_UNLOCK(&pFlash); return status; } /** * @brief Perform a page erase of the specified FLASH memory pages with interrupt enabled - * @note To correctly run this function, the HAL_FLASH_Unlock() function + * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function * must be called before. - * Call the HAL_FLASH_Lock() to disable the flash memory access - * (recommended to protect the FLASH memory against possible unwanted operation). - End of erase is done when HAL_FLASH_EndOfOperationCallback is called with parameter - 0xFFFFFFFF - * @param pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that + * Call the @ref HAL_FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation) + * End of erase is done when @ref HAL_FLASH_EndOfOperationCallback is called with parameter + * 0xFFFFFFFF + * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) { - HAL_StatusTypeDef status = HAL_OK; + HAL_StatusTypeDef status = HAL_ERROR; + + /* If procedure already ongoing, reject the next one */ + if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_NBPAGES(pEraseInit->NbPages)); + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); + assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1)); /* Process Locked */ - __HAL_LOCK(&ProcFlash); + __HAL_LOCK(&pFlash); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - + if (status == HAL_OK) { - /* Enable End of FLASH Operation interrupt */ - __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP); + /* Enable End of FLASH Operation and Error source interrupts */ + __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); - /* Enable Error source interrupt */ - __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR); - - /* Check the parameters */ - assert_param(IS_NBPAGES(pEraseInit->NbPages)); - assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); - assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); - assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U)); - - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - ProcFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE; - ProcFlash.NbPagesToErase = pEraseInit->NbPages; - ProcFlash.Page = pEraseInit->PageAddress; - - /* Erase 1st page and wait for IT */ - FLASH_ErasePage(pEraseInit->PageAddress); + pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE; + pFlash.NbPagesToErase = pEraseInit->NbPages; + pFlash.Page = pEraseInit->PageAddress; + + /*Erase 1st page and wait for IT*/ + FLASH_PageErase(pEraseInit->PageAddress); } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } + return status; } @@ -261,9 +295,8 @@ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) * @} */ - -/** @addtogroup FLASHEx_Exported_Functions_Group2 - * @brief Option Bytes Programming functions +/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions + * @brief Option Bytes Programming functions * @verbatim ============================================================================== @@ -271,20 +304,20 @@ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) ============================================================================== [..] Any operation of erase or program should follow these steps: - (#) Call the HAL_FLASH_OB_Unlock() function to enable the Flash option control + (#) Call the @ref HAL_FLASH_OB_Unlock() function to enable the Flash option control register access. (#) Call following function to program the desired option bytes. - (++) HAL_FLASHEx_OBProgram: + (++) @ref HAL_FLASHEx_OBProgram: - To Enable/Disable the desired sector write protection. - To set the desired read Protection Level. - To configure the user option Bytes: IWDG, STOP and the Standby. - To Set the BOR level. (#) Once all needed option bytes to be programmed are correctly written, call the - HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process. - (#) Call the HAL_FLASH_OB_Lock() to disable the Flash option control register access (recommended + @ref HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process. + (#) Call the @ref HAL_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): + [..] 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), @@ -293,15 +326,16 @@ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) means: if WPRMOD = 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 call the following function: - (++) HAL_FLASHEx_AdvOBProgram in selecting sectors to be read/write protected - (++) HAL_FLASHEx_OB_SelectPCROP to enable the read/write protection + (++) @ref HAL_FLASHEx_AdvOBProgram in selecting sectors to be read/write protected + (++) @ref HAL_FLASHEx_OB_SelectPCROP to enable the read/write protection + @endverbatim * @{ */ /** * @brief Program option bytes - * @param pOBInit: pointer to an FLASH_OBInitStruct structure that + * @param pOBInit pointer to an FLASH_OBInitStruct structure that * contains the configuration information for the programming. * * @retval HAL_StatusTypeDef HAL Status @@ -311,12 +345,12 @@ HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) HAL_StatusTypeDef status = HAL_ERROR; /* Process Locked */ - __HAL_LOCK(&ProcFlash); + __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); - /* Write protection configuration */ + /*Write protection configuration*/ if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP) { assert_param(IS_WRPSTATE(pOBInit->WRPState)); @@ -324,28 +358,28 @@ HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) status = FLASH_OB_ProtectedSectorsConfig(pOBInit->WRPSector, pOBInit->WRPSector2, pOBInit->WRPState); #else status = FLASH_OB_ProtectedSectorsConfig(pOBInit->WRPSector, pOBInit->WRPState); -#endif +#endif if (status != HAL_OK) { /* Process Unlocked */ - __HAL_UNLOCK(&ProcFlash); + __HAL_UNLOCK(&pFlash); return status; } } - - /* Read protection configuration */ + + /* Read protection configuration*/ if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP) { status = FLASH_OB_RDPConfig(pOBInit->RDPLevel); if (status != HAL_OK) { /* Process Unlocked */ - __HAL_UNLOCK(&ProcFlash); + __HAL_UNLOCK(&pFlash); return status; } } - - /* USER configuration */ + + /* USER configuration*/ if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER) { status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_IWDG_SW, @@ -354,31 +388,37 @@ HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) if (status != HAL_OK) { /* Process Unlocked */ - __HAL_UNLOCK(&ProcFlash); + __HAL_UNLOCK(&pFlash); return status; } } - /* BOR Level configuration */ + /* BOR Level configuration*/ if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR) { status = FLASH_OB_BORConfig(pOBInit->BORLevel); - } + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } + } /* Program BOOT Bit1 config option byte */ if ((pOBInit->OptionType & OPTIONBYTE_BOOT_BIT1) == OPTIONBYTE_BOOT_BIT1) { status = FLASH_OB_BOOTBit1Config(pOBInit->BOOTBit1Config); } - /* Process Unlocked */ - __HAL_UNLOCK(&ProcFlash); + __HAL_UNLOCK(&pFlash); + return status; } /** * @brief Get the Option byte configuration - * @param pOBInit: pointer to an FLASH_OBInitStruct structure that + * @param pOBInit pointer to an FLASH_OBInitStruct structure that * contains the configuration information for the programming. * * @retval None @@ -394,23 +434,24 @@ void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) pOBInit->WRPSector2 = FLASH_OB_GetWRP2(); #endif - /* Get RDP Level */ - pOBInit->RDPLevel = FLASH_OB_GetRDP(); + /*Get RDP Level*/ + pOBInit->RDPLevel = FLASH_OB_GetRDP(); - /* Get USER */ + /*Get USER*/ pOBInit->USERConfig = FLASH_OB_GetUser(); - /* Get BOR Level */ - pOBInit->BORLevel = FLASH_OB_GetBOR(); - + /*Get BOR Level*/ + pOBInit->BORLevel = FLASH_OB_GetBOR(); + /* Get BOOT bit 1 config OB */ pOBInit->BOOTBit1Config = FLASH_OB_GetBOOTBit1(); - } +#if defined(FLASH_OPTR_WPRMOD) || defined(FLASH_OPTR_BFB2) + /** * @brief Program option bytes - * @param pAdvOBInit: pointer to an FLASH_AdvOBProgramInitTypeDef structure that + * @param pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that * contains the configuration information for the programming. * * @retval HAL_StatusTypeDef HAL Status @@ -422,7 +463,9 @@ HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram (FLASH_AdvOBProgramInitTypeDef *pAdvO /* Check the parameters */ assert_param(IS_OBEX(pAdvOBInit->OptionType)); - /* Program PCROP option byte */ +#if defined(FLASH_OPTR_WPRMOD) + + /* Program PCROP option byte*/ if ((pAdvOBInit->OptionType & OPTIONBYTE_PCROP) == OPTIONBYTE_PCROP) { /* Check the parameters */ @@ -433,44 +476,63 @@ HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram (FLASH_AdvOBProgramInitTypeDef *pAdvO status = FLASH_OB_ProtectedSectorsConfig(pAdvOBInit->PCROPSector, pAdvOBInit->PCROPState); #endif } -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) + +#endif /* FLASH_OPTR_WPRMOD */ + +#if defined(FLASH_OPTR_BFB2) + + /* Program BOOT config option byte */ if ((pAdvOBInit->OptionType & OPTIONBYTE_BOOTCONFIG) == OPTIONBYTE_BOOTCONFIG) { - status = FLASH_OB_BFB2Config(pAdvOBInit->BootConfig); + status = FLASH_OB_BootConfig(pAdvOBInit->BootConfig); } -#endif + +#endif /* FLASH_OPTR_BFB2 */ return status; } /** - * @brief Get the OBEX byte configuration - * @param pAdvOBInit: pointer to an FLASH_AdvOBProgramInitTypeDef structure that + * @brief Get the OBEX byte configuration + * @param pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that * contains the configuration information for the programming. * * @retval None */ void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit) { -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) - pAdvOBInit->OptionType = OPTIONBYTE_PCROP| OPTIONBYTE_BOOTCONFIG; -#else - pAdvOBInit->OptionType = OPTIONBYTE_PCROP; -#endif + pAdvOBInit->OptionType = 0; + +#if defined(FLASH_OPTR_WPRMOD) + + pAdvOBInit->OptionType |= OPTIONBYTE_PCROP; + + /* Get PCROP state */ - pAdvOBInit->PCROPState = (FLASH->OPTR & FLASH_OPTR_WPRMOD) >> 8U; + pAdvOBInit->PCROPState = (FLASH->OPTR & FLASH_OPTR_WPRMOD) >> FLASH_OPTR_WPRMOD_Pos; /* Get PCROP protected sector */ pAdvOBInit->PCROPSector = FLASH->WRPR; #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) /* Get PCROP protected sector */ pAdvOBInit->PCROPSector2 = FLASH->WRPR2; - - /* Get boot bank config */ - pAdvOBInit->BootConfig = (FLASH->OPTR & FLASH_OPTR_BFB2) >> 23U; #endif +#endif /* FLASH_OPTR_WPRMOD */ + +#if defined(FLASH_OPTR_BFB2) + + pAdvOBInit->OptionType |= OPTIONBYTE_BOOTCONFIG; + + /* Get Boot config OB */ + pAdvOBInit->BootConfig = (FLASH->OPTR & FLASH_OPTR_BFB2) >> 16U; + +#endif /* FLASH_OPTR_BFB2 */ } +#endif /* FLASH_OPTR_WPRMOD || FLASH_OPTR_BFB2 */ + +#if defined(FLASH_OPTR_WPRMOD) + /** * @brief Select the Protection Mode (WPRMOD). * @note Once WPRMOD bit is active, unprotection of a protected sector is not possible @@ -479,7 +541,38 @@ void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit) */ HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void) { - return (FLASH_OB_PCROPSelectionConfig(1U)); + HAL_StatusTypeDef status = HAL_OK; + uint16_t tmp1 = 0; + uint32_t tmp2 = 0; + uint8_t optiontmp = 0; + uint16_t optiontmp2 = 0; + + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + /* Mask RDP Byte */ + optiontmp = (uint8_t)(*(__IO uint8_t *)(OB_BASE)); + + /* Update Option Byte */ + optiontmp2 = (uint16_t)(OB_PCROP_SELECTED | optiontmp); + + /* calculate the option byte to write */ + tmp1 = (uint16_t)(~(optiontmp2 )); + tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2)); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* program PCRop */ + OB->RDP = tmp2; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + + /* Return the Read protection operation Status */ + return status; } /** @@ -490,14 +583,47 @@ HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void) */ HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void) { - return (FLASH_OB_PCROPSelectionConfig(0U)); + HAL_StatusTypeDef status = HAL_OK; + uint16_t tmp1 = 0; + uint32_t tmp2 = 0; + uint8_t optiontmp = 0; + uint16_t optiontmp2 = 0; + + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + /* Mask RDP Byte */ + optiontmp = (uint8_t)(*(__IO uint8_t *)(OB_BASE)); + + /* Update Option Byte */ + optiontmp2 = (uint16_t)(OB_PCROP_DESELECTED | optiontmp); + + /* calculate the option byte to write */ + tmp1 = (uint16_t)(~(optiontmp2 )); + tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2)); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* program PCRop */ + OB->RDP = tmp2; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + + /* Return the Read protection operation Status */ + return status; } +#endif /* FLASH_OPTR_WPRMOD */ + /** * @} */ - -/** @addtogroup FLASHEx_Exported_Functions_Group3 + +/** @defgroup FLASHEx_Exported_Functions_Group3 DATA EEPROM Programming functions * @brief DATA EEPROM Programming functions * @verbatim @@ -505,23 +631,18 @@ HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void) ##### DATA EEPROM Programming functions ##### =============================================================================== - [..] The FLASH_DATAEEPROM Programming_Functions, includes the following functions: - (+) HAL_FLASHEx_DATAEEPROM_Unlock(void); - (+) HAL_FLASHEx_DATAEEPROM_Lock(void); - (+) HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address) - (+) HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data) - [..] Any operation of erase or program should follow these steps: - (#) Call the HAL_FLASHEx_DATAEEPROM_Unlock() function to enable the data EEPROM access + (#) Call the @ref HAL_FLASHEx_DATAEEPROM_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 HAL_FLASHEx_DATAEEPROM_Lock() to disable the data EEPROM access + (#) Call the @ref HAL_FLASHEx_DATAEEPROM_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. * @retval HAL_StatusTypeDef HAL Status @@ -530,15 +651,15 @@ HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Unlock(void) { if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET) { - /* Unlocking the Data memory and FLASH_PECR register access */ + /* Unlocking the Data memory and FLASH_PECR register access*/ FLASH->PEKEYR = FLASH_PEKEY1; FLASH->PEKEYR = FLASH_PEKEY2; - return HAL_OK; } else { return HAL_ERROR; } + return HAL_OK; } /** @@ -548,19 +669,20 @@ HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Unlock(void) HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Lock(void) { /* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */ - SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK); + SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK); + return HAL_OK; } - + /** * @brief Erase a word in data memory. - * @param Address: specifies the address to be erased. - * @note To correctly run this function, the HAL_FLASHEx_DATAEEPROM_Unlock() function + * @param Address specifies the address to be erased. + * @note To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function * must be called before. - * Call the HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access + * Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access * and Flash program erase control register access(recommended to protect * the DATA_EEPROM against possible unwanted operation). - * @retval HAL status + * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address) { @@ -575,59 +697,67 @@ HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address) if(status == HAL_OK) { /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - /* Write "00000000h" to valid address in the data memory" */ + /* Write 00000000h to valid address in the data memory */ *(__IO uint32_t *) Address = 0x00000000U; status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); } - + + /* Return the erase status */ return status; } /** * @brief Program word at a specified address - * @param TypeProgram: Indicate the way to program at a specified address. - * This parameter can be a value of @ref FLASHEx_Type_Program_Data - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed + * @note To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function + * must be called before. + * Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() 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 @ref HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram() can be called before + * this function to configure the Fixed Time Programming. + * @param TypeProgram Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASHEx_Type_Program_Data + * @param Address specifie the address to be programmed. + * @param Data specifie the data to be programmed * * @retval HAL_StatusTypeDef HAL Status */ -HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data) +HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data) { HAL_StatusTypeDef status = HAL_ERROR; /* Process Locked */ - __HAL_LOCK(&ProcFlash); + __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_TYPEPROGRAMDATA(TypeProgram)); assert_param(IS_FLASH_DATA_ADDRESS(Address)); - + /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; if(TypeProgram == FLASH_TYPEPROGRAMDATA_WORD) { - /* Program word (32-bit) at a specified address */ + /* Program word (32-bit) at a specified address.*/ *(__IO uint32_t *)Address = Data; } else if(TypeProgram == FLASH_TYPEPROGRAMDATA_HALFWORD) { - /* Program word (16-bit) at a specified address */ + /* Program halfword (16-bit) at a specified address.*/ *(__IO uint16_t *)Address = (uint16_t) Data; } else if(TypeProgram == FLASH_TYPEPROGRAMDATA_BYTE) { - /*Program word (8-bit) at a specified address */ + /* Program byte (8-bit) at a specified address.*/ *(__IO uint8_t *)Address = (uint8_t) Data; } else @@ -635,11 +765,16 @@ HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t status = HAL_ERROR; } - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + if (status != HAL_OK) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } } + /* Process Unlocked */ - __HAL_UNLOCK(&ProcFlash); + __HAL_UNLOCK(&pFlash); + return status; } @@ -669,9 +804,152 @@ void HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void) * @} */ -/** @addtogroup FLASHEx_Private - * @{ - */ +/** @addtogroup FLASHEx_Private_Functions + * @{ + */ + +/* +============================================================================== + OPTIONS BYTES +============================================================================== +*/ +/** + * @brief Enables or disables the read out protection. + * @note To correctly run this function, the @ref HAL_FLASH_OB_Unlock() function + * must be called before. + * @param OB_RDP specifies the read protection level. + * This parameter can be: + * @arg @ref OB_RDP_LEVEL_0 No protection + * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory + * @arg @ref 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 HAL status + */ +static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U; + + /* Check the parameters */ + assert_param(IS_OB_RDP(OB_RDP)); + + tmp1 = (uint32_t)(OB->RDP & FLASH_OPTR_RDPROT); + +#if defined(FLASH_OPTR_WPRMOD) + /* Mask WPRMOD bit */ + tmp3 = (uint32_t)(OB->RDP & FLASH_OPTR_WPRMOD); +#endif + + /* calculate the option byte to write */ + tmp1 = (~((uint32_t)(OB_RDP | tmp3))); + tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)(OB_RDP | tmp3))); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* program read protection level */ + OB->RDP = tmp2; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + + /* Return the Read protection operation 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 @ref 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 @ref OB_BOR_LEVEL1 BOR Reset threshold levels for 1.7V - 1.8V VDD power supply + * @arg @ref OB_BOR_LEVEL2 BOR Reset threshold levels for 1.9V - 2.0V VDD power supply + * @arg @ref OB_BOR_LEVEL3 BOR Reset threshold levels for 2.3V - 2.4V VDD power supply + * @arg @ref OB_BOR_LEVEL4 BOR Reset threshold levels for 2.55V - 2.65V VDD power supply + * @arg @ref OB_BOR_LEVEL5 BOR Reset threshold levels for 2.8V - 2.9V VDD power supply + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmp = 0, tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_OB_BOR_LEVEL(OB_BOR)); + + /* Get the User Option byte register */ + tmp1 = OB->USER & ((~FLASH_OPTR_BOR_LEV) >> 16U); + + /* Calculate the option byte to write - [0xFF | nUSER | 0x00 | USER]*/ + tmp = (uint32_t)~((OB_BOR | tmp1)) << 16U; + tmp |= (OB_BOR | tmp1); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Write the BOR Option Byte */ + OB->USER = tmp; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + + /* Return the Option Byte BOR programmation Status */ + return status; +} + +/** + * @brief Sets or resets the BOOT bit1 option bit. + * @param OB_BootBit1 Set or Reset the BOOT bit1 option bit. + * This parameter can be one of the following values: + * @arg @ref OB_BOOT_BIT1_RESET BOOT1 option bit reset + * @arg @ref OB_BOOT_BIT1_SET BOOT1 option bit set + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_BOOTBit1Config(uint8_t OB_BootBit1) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmp = 0, tmp1 = 0, OB_Bits = ((uint32_t) OB_BootBit1) << 15; + + /* Check the parameters */ + assert_param(IS_OB_BOOT1(OB_BootBit1)); + + /* Get the User Option byte register */ + tmp1 = OB->USER & ((~FLASH_OPTR_BOOT1) >> 16U); + + /* Calculate the user option byte to write */ + tmp = (~(OB_Bits | tmp1)) << 16U; + tmp |= OB_Bits | tmp1; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + /* Program OB */ + OB->USER = tmp; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + + return status; +} /** * @brief Returns the FLASH User Option Bytes values. @@ -684,8 +962,12 @@ static uint8_t FLASH_OB_GetUser(void) } /** - * @brief Returns the FLASH Read out Protection Level. - * @retval FLASH RDP level. + * @brief Returns the FLASH Read Protection level. + * @retval FLASH RDP level + * This parameter can be one of the following values: + * @arg @ref OB_RDP_LEVEL_0 No protection + * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory + * @arg @ref OB_RDP_LEVEL_2 Full chip protection */ static uint8_t FLASH_OB_GetRDP(void) { @@ -709,7 +991,7 @@ static uint8_t FLASH_OB_GetBOR(void) static uint8_t FLASH_OB_GetBOOTBit1(void) { /* Return the BOR level */ - return (FLASH->OPTR & FLASH_OPTR_BOOT1) >> 31U; + return (FLASH->OPTR & FLASH_OPTR_BOOT1) >> FLASH_OPTR_BOOT1_Pos; } @@ -735,338 +1017,95 @@ static uint32_t FLASH_OB_GetWRP2(void) } #endif /* STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */ -/** - * @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 HAL status - */ -static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) -{ - HAL_StatusTypeDef status = HAL_OK; - uint32_t tmp = 0U, tmp1 = 0U, OB_Bits = (uint32_t) (OB_IWDG | OB_STOP | OB_STDBY); - - /* 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)); - - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - - /* Get the User Option byte register */ - tmp1 = OB->USER & ((~FLASH_OPTR_USER) >> 16U); - - /* Calculate the user option byte to write */ - tmp = (~(OB_Bits | tmp1)) << 16U; - tmp |= OB_Bits | tmp1; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - - if(status == HAL_OK) - { - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - /* Program OB */ - OB->USER = tmp; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - } - 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 OB_RDP: 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 HAL status - */ -static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP) -{ - HAL_StatusTypeDef status; - uint32_t tmp = 0U, tmp1 = 0U, OB_Bits = (uint32_t) OB_RDP; - - /* Check the parameters */ - assert_param(IS_OB_RDP(OB_RDP)); - - /* Calculate the option byte to write */ - tmp = (OB->RDP & ((~FLASH_OPTR_RDPROT) & 0x0000FFFFU)) | OB_Bits; - tmp1 = (~tmp << 16U) | tmp; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - - if(status == HAL_OK) - { - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - /* Program OB */ - OB->RDP = tmp1; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - } - 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 HAL status - */ -static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR) -{ - HAL_StatusTypeDef status = HAL_OK; - uint32_t tmp = 0U, tmp1 = 0U, OB_Bits = (uint32_t) OB_BOR; - - /* Check the parameters */ - assert_param(IS_OB_BOR_LEVEL(OB_BOR)); - - /* Get the User Option byte register */ - tmp1 = OB->USER & ((~FLASH_OPTR_BOR_LEV) >> 16U); - - /* Calculate the user option byte to write */ - tmp = (~(OB_Bits | tmp1)) << 16U; - tmp |= OB_Bits | tmp1; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - - if(status == HAL_OK) - { - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - /* Program OB */ - OB->USER = tmp; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - } - - return status; -} - -/** - * @brief Sets or resets the BOOT bit1 option bit. - * @param OB_BOOT_BIT1: Set or Reset the BOOT bit1 option bit. - * This parameter can be one of the following values: - * @arg OB_BOOT_BIT1_RESET: BOOT1 option bit reset - * @arg OB_BOOT_BIT1_SET: BOOT1 option bit set - * @retval HAL status - */ -static HAL_StatusTypeDef FLASH_OB_BOOTBit1Config(uint8_t OB_BOOT_BIT1) -{ - HAL_StatusTypeDef status = HAL_OK; - uint32_t tmp = 0U, tmp1 = 0U, OB_Bits = ((uint32_t) OB_BOOT_BIT1) << 15U; - - /* Check the parameters */ - assert_param(IS_OB_BOOT1(OB_BOOT_BIT1)); - - /* Get the User Option byte register */ - tmp1 = OB->USER & ((~FLASH_OPTR_BOOT1) >> 16U); - - /* Calculate the user option byte to write */ - tmp = (~(OB_Bits | tmp1)) << 16U; - tmp |= OB_Bits | tmp1; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - - if(status == HAL_OK) - { - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - /* Program OB */ - OB->USER = tmp; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - } - - return status; -} - -/** - * @brief Select the Protection Mode (WPRMOD). - * @note Once WPRMOD 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 WPRMOD: Select the Protection Mode of WPR bits. - * This parameter can be: - * @arg OB_PCROP_SELECTED: nWRP control the read&write protection (PcROP) of respective user sectors. - * @arg OB_PCROP_DESELECTED: nWRP control the write protection of respective user sectors. - * @retval HAL status - */ -static HAL_StatusTypeDef FLASH_OB_PCROPSelectionConfig(uint32_t WPRMOD) -{ - HAL_StatusTypeDef status; - uint32_t tmp = 0U, tmp1 = 0U, OB_Bits = ((uint32_t) WPRMOD) << 8U; - - /* Get the User Option byte register */ - tmp1 = OB->USER & ((~FLASH_OPTR_WPRMOD) >> 16U); - - /* Calculate the user option byte to write */ - tmp = (~(OB_Bits | tmp1)) << 16U; - tmp |= OB_Bits | tmp1; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - - if(status == HAL_OK) - { - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - /* Program OB */ - OB->RDP = tmp; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - } - - return status; -} - -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) -/** - * @brief Sets or resets the BFB2 option bit. - * @param OB_BFB2: Set or Reset the BFB2 option bit. - * This parameter can be one of the following values: - * @arg OB_BOOT_BANK1: BFB2 option bit reset - * @arg OB_BOOT_BANK2: BFB2 option bit set - * @retval None - */ -static HAL_StatusTypeDef FLASH_OB_BFB2Config(uint8_t OB_BFB2) -{ - HAL_StatusTypeDef status = HAL_OK; - uint32_t tmp = 0U, tmp1 = 0U, OB_Bits = ((uint32_t) OB_BFB2) << 7U; - - /* Check the parameters */ - assert_param(IS_OB_BOOT_BANK(OB_BFB2)); - - /* Get the User Option byte register */ - tmp1 = OB->USER & ((~FLASH_OPTR_BFB2) >> 16U); - - /* Calculate the user option byte to write */ - tmp = (~(OB_Bits | tmp1)) << 16U; - tmp |= OB_Bits | tmp1; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - - if(status == HAL_OK) - { - /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - - /* Program OB */ - OB->USER = tmp; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - } - return status; -} -#endif - - #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) /** * @brief Write Option Byte of the desired pages of the Flash. - * @param Sector: specifies the sectors to be write protected. - * @param Sector2: specifies the sectors to be write protected (only stm32l07xxx and stm32l08xxx devices) - * @param NewState: new state of the specified FLASH Pages Wite protection. - * This parameter can be: ENABLE or DISABLE. + * @param Sector specifies the sectors to be write protected. + * @param Sector2 specifies the sectors to be write protected (only stm32l07xxx and stm32l08xxx devices) + * @param NewState new state of the specified FLASH Pages Write protection. + * This parameter can be: + * @arg @ref OB_WRPSTATE_ENABLE + * @arg @ref OB_WRPSTATE_DISABLE * @retval HAL_StatusTypeDef */ static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t Sector2, uint32_t NewState) #else /** * @brief Write Option Byte of the desired pages of the Flash. - * @param Sector: specifies the sectors to be write protected. - * @param NewState: new state of the specified FLASH Pages Wite protection. - * This parameter can be: ENABLE or DISABLE. + * @param Sector specifies the sectors to be write protected. + * @param NewState new state of the specified FLASH Pages Write protection. + * This parameter can be: + * @arg @ref OB_WRPSTATE_ENABLE + * @arg @ref OB_WRPSTATE_DISABLE * @retval HAL_StatusTypeDef */ static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t NewState) #endif { HAL_StatusTypeDef status = HAL_OK; - uint32_t WRP_Data = 0U; + uint32_t WRP_Data = 0; uint32_t OB_WRP = Sector; - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - + if(status == HAL_OK) { /* Clean the error context */ - ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - if (OB_WRP & 0x0000FFFFU) + /* Update WRP only if at least 1 selected sector */ + if (OB_WRP != 0x00000000U) { - if (NewState != OB_WRPSTATE_DISABLE) + if ((OB_WRP & WRP_MASK_LOW) != 0x00000000U) { - WRP_Data = (uint16_t)(((OB_WRP & WRP_MASK_LOW) | OB->WRP01)); - OB->WRP01 = (uint32_t)(~(WRP_Data) << 16U) | (WRP_Data); - } - else - { - WRP_Data = (uint16_t)(~OB_WRP & (WRP_MASK_LOW & OB->WRP01)); - OB->WRP01 = (uint32_t)((~WRP_Data) << 16U) | (WRP_Data); + if (NewState != OB_WRPSTATE_DISABLE) + { + WRP_Data = (uint16_t)(((OB_WRP & WRP_MASK_LOW) | OB->WRP01)); + OB->WRP01 = (uint32_t)(~(WRP_Data) << 16U) | (WRP_Data); + } + else + { + WRP_Data = (uint16_t)(~OB_WRP & (WRP_MASK_LOW & OB->WRP01)); + OB->WRP01 = (uint32_t)((~WRP_Data) << 16U) | (WRP_Data); + } } } #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) - if (OB_WRP & 0xFFFF0000U) + /* Update WRP only if at least 1 selected sector */ + if (OB_WRP != 0x00000000U) { - if (NewState != OB_WRPSTATE_DISABLE) + if ((OB_WRP & WRP_MASK_HIGH) != 0x00000000U) { - WRP_Data = (uint16_t)((((OB_WRP & WRP_MASK_HIGH) >> 16U | OB->WRP23))); - OB->WRP23 = (uint32_t)(~(WRP_Data) << 16U) | (WRP_Data); - } - else - { - WRP_Data = (uint16_t)((((~OB_WRP & WRP_MASK_HIGH) >> 16U & OB->WRP23))); - OB->WRP23 = (uint32_t)((~WRP_Data) << 16U) | (WRP_Data); - } + if (NewState != OB_WRPSTATE_DISABLE) + { + WRP_Data = (uint16_t)((((OB_WRP & WRP_MASK_HIGH) >> 16U | OB->WRP23))); + OB->WRP23 = (uint32_t)(~(WRP_Data) << 16U) | (WRP_Data); + } + else + { + WRP_Data = (uint16_t)((((~OB_WRP & WRP_MASK_HIGH) >> 16U & OB->WRP23))); + OB->WRP23 = (uint32_t)((~WRP_Data) << 16U) | (WRP_Data); + } + } } OB_WRP = Sector2; - if (OB_WRP & 0x0000FFFFU) + /* Update WRP only if at least 1 selected sector */ + if (OB_WRP != 0x00000000U) { - if (NewState != OB_WRPSTATE_DISABLE) + if ((OB_WRP & WRP_MASK_LOW) != 0x00000000U) { - WRP_Data = (uint16_t)(((OB_WRP & WRP_MASK_LOW) | OB->WRP45)); - OB->WRP45 =(uint32_t)(~(WRP_Data) << 16U) | (WRP_Data); - } - else - { - WRP_Data = (uint16_t)(~OB_WRP & (WRP_MASK_LOW & OB->WRP45)); - OB->WRP45 = (uint32_t)((~WRP_Data) << 16U) | (WRP_Data); + if (NewState != OB_WRPSTATE_DISABLE) + { + WRP_Data = (uint16_t)(((OB_WRP & WRP_MASK_LOW) | OB->WRP45)); + OB->WRP45 =(uint32_t)(~(WRP_Data) << 16U) | (WRP_Data); + } + else + { + WRP_Data = (uint16_t)(~OB_WRP & (WRP_MASK_LOW & OB->WRP45)); + OB->WRP45 = (uint32_t)((~WRP_Data) << 16U) | (WRP_Data); + } } } #endif /* STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */ @@ -1078,6 +1117,143 @@ static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32 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 @ref OB_IWDG_SW Software WDG selected + * @arg @ref 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 @ref OB_STOP_NORST No reset generated when entering in STOP + * @arg @ref 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 @ref OB_STDBY_NORST No reset generated when entering in STANDBY + * @arg @ref OB_STDBY_RST Reset generated when entering in STANDBY + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) +{ + HAL_StatusTypeDef status = HAL_OK; + 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 = OB->USER & ((~FLASH_OPTR_USER) >> 16U); + + /* 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))) << 16U); + 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_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Write the User Option Byte */ + OB->USER = tmp; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + + /* Return the Option Byte program Status */ + return status; +} + +#if defined(FLASH_OPTR_BFB2) +/** + * @brief Configures to boot from Bank1 or Bank2. + * @param OB_BOOT select the FLASH Bank to boot from. + * This parameter can be one of the following values: + * This parameter can be one of the following values: + * @arg @ref OB_BOOT_BANK1 BFB2 option bit reset + * @arg @ref OB_BOOT_BANK2 BFB2 option bit set + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t OB_BOOT) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmp = 0U, tmp1 = 0U; + + /* Check the parameters */ + assert_param(IS_OB_BOOT_BANK(OB_BOOT)); + + /* Get the User Option byte register and BOR Level*/ + tmp1 = OB->USER & ((~FLASH_OPTR_BFB2) >> 16U); + + /* Calculate the option byte to write */ + tmp = (uint32_t)~(OB_BOOT | tmp1) << 16U; + tmp |= (OB_BOOT | tmp1); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Write the BOOT Option Byte */ + OB->USER = tmp; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + + /* Return the Option Byte program Status */ + return status; +} + +#endif /* FLASH_OPTR_BFB2 */ + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup FLASH + * @{ + */ + + +/** @addtogroup FLASH_Private_Functions + * @{ + */ + +/** + * @brief Erases a specified page in program memory. + * @param PageAddress 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 @ref FLASH_PAGE_SIZE bytes). + * @retval None + */ +void FLASH_PageErase(uint32_t PageAddress) +{ + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Set the ERASE bit */ + SET_BIT(FLASH->PECR, FLASH_PECR_ERASE); + + /* Set PROG bit */ + SET_BIT(FLASH->PECR, FLASH_PECR_PROG); + + /* Write 00000000h to the first word of the program page to erase */ + *(__IO uint32_t *)(uint32_t)(PageAddress & ~(FLASH_PAGE_SIZE - 1)) = 0x00000000; +} + /** * @} */ @@ -1090,4 +1266,5 @@ static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32 /** * @} */ + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ex.h index db945bb585..69008ee1c7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ex.h @@ -2,9 +2,7 @@ ****************************************************************************** * @file stm32l0xx_hal_flash_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief Header file of FLash HAL Extension module. + * @brief Header file of Flash HAL Extended module. ****************************************************************************** * @attention * @@ -50,113 +48,238 @@ * @{ */ -/** @defgroup FLASHEx FLASHEx +/** @addtogroup FLASHEx * @{ */ +/** @addtogroup FLASHEx_Private_Constants + * @{ + */ +#define FLASH_SIZE_DATA_REGISTER FLASHSIZE_BASE + +#define FLASH_NBPAGES_MAX (FLASH_SIZE / FLASH_PAGE_SIZE) + +#define WRP_MASK_LOW (0x0000FFFFU) +#define WRP_MASK_HIGH (0xFFFF0000U) + +/** + * @} + */ + +/** @addtogroup FLASHEx_Private_Macros + * @{ + */ + +#define IS_FLASH_TYPEERASE(__VALUE__) (((__VALUE__) == FLASH_TYPEERASE_PAGES)) + +#define IS_OPTIONBYTE(__VALUE__) (((__VALUE__) <= (OPTIONBYTE_WRP | OPTIONBYTE_RDP | \ + OPTIONBYTE_USER | OPTIONBYTE_BOR | OPTIONBYTE_BOOT_BIT1))) + +#define IS_WRPSTATE(__VALUE__) (((__VALUE__) == OB_WRPSTATE_DISABLE) || \ + ((__VALUE__) == OB_WRPSTATE_ENABLE)) + +#define IS_OB_WRP(__PAGE__) (((__PAGE__) != 0x0000000U)) + +#define IS_OB_RDP(__LEVEL__) (((__LEVEL__) == OB_RDP_LEVEL_0) ||\ + ((__LEVEL__) == OB_RDP_LEVEL_1) ||\ + ((__LEVEL__) == OB_RDP_LEVEL_2)) + +#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)) + +#define IS_OB_IWDG_SOURCE(__SOURCE__) (((__SOURCE__) == OB_IWDG_SW) || ((__SOURCE__) == OB_IWDG_HW)) + +#define IS_OB_STOP_SOURCE(__SOURCE__) (((__SOURCE__) == OB_STOP_NORST) || ((__SOURCE__) == OB_STOP_RST)) + +#define IS_OB_STDBY_SOURCE(__SOURCE__) (((__SOURCE__) == OB_STDBY_NORST) || ((__SOURCE__) == OB_STDBY_RST)) + +#if defined(FLASH_OPTR_WPRMOD) && defined(FLASH_OPTR_BFB2) + +#define IS_OBEX(__VALUE__) (((__VALUE__) == OPTIONBYTE_PCROP) || ((__VALUE__) == OPTIONBYTE_BOOTCONFIG)) + +#elif defined(FLASH_OPTR_WPRMOD) && !defined(FLASH_OPTR_BFB2) + +#define IS_OBEX(__VALUE__) ((__VALUE__) == OPTIONBYTE_PCROP) + +#elif !defined(FLASH_OPTR_WPRMOD) && defined(FLASH_OPTR_BFB2) + +#define IS_OBEX(__VALUE__) ((__VALUE__) == OPTIONBYTE_BOOTCONFIG) + +#endif /* FLASH_OPTR_WPRMOD && FLASH_OPTR_BFB2 */ + +#if defined(FLASH_OPTR_WPRMOD) + +#define IS_PCROPSTATE(__VALUE__) (((__VALUE__) == OB_PCROP_STATE_DISABLE) || \ + ((__VALUE__) == OB_PCROP_STATE_ENABLE)) + +#define IS_OB_PCROP(__PAGE__) (((__PAGE__) != 0x0000000U)) +#endif /* FLASH_OPTR_WPRMOD */ + +#if defined(FLASH_OPTR_BFB2) + +#define IS_OB_BOOT_BANK(__BANK__) (((__BANK__) == OB_BOOT_BANK2) || ((__BANK__) == OB_BOOT_BANK1)) + +#endif /* FLASH_OPTR_BFB2 */ + +#define IS_OB_BOOT1(__BOOT_BIT1__) (((__BOOT_BIT1__) == OB_BOOT_BIT1_RESET) || ((__BOOT_BIT1__) == OB_BOOT_BIT1_SET)) +#define IS_TYPEPROGRAMDATA(__VALUE__) (((__VALUE__) == FLASH_TYPEPROGRAMDATA_BYTE) || \ + ((__VALUE__) == FLASH_TYPEPROGRAMDATA_HALFWORD) || \ + ((__VALUE__) == FLASH_TYPEPROGRAMDATA_WORD)) + + +/** @defgroup FLASHEx_Address FLASHEx Address + * @{ + */ + +#if defined (STM32L071xx) || defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L081xx) || defined (STM32L082xx) || defined (STM32L083xx) + +#define IS_FLASH_DATA_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= DATA_EEPROM_BASE) && ((__ADDRESS__) <= DATA_EEPROM_BANK2_END)) +#define IS_FLASH_DATA_BANK1_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= DATA_EEPROM_BASE) && ((__ADDRESS__) <= DATA_EEPROM_BANK1_END)) +#define IS_FLASH_DATA_BANK2_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= DATA_EEPROM_BANK2_BASE) && ((__ADDRESS__) <= DATA_EEPROM_BANK2_END)) +#define IS_FLASH_PROGRAM_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= FLASH_BASE) && ((__ADDRESS__) < (FLASH_BASE + FLASH_SIZE))) +#define IS_FLASH_PROGRAM_BANK1_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= FLASH_BASE) && ((__ADDRESS__) < (FLASH_BASE + (FLASH_SIZE >> 1)))) +#define IS_FLASH_PROGRAM_BANK2_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= FLASH_BANK2_BASE) && ((__ADDRESS__) < (FLASH_BASE + FLASH_SIZE))) +#else +#define IS_FLASH_DATA_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= DATA_EEPROM_BASE) && ((__ADDRESS__) <= DATA_EEPROM_END)) +#define IS_FLASH_PROGRAM_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= FLASH_BASE) && ((__ADDRESS__) < (FLASH_BASE + FLASH_SIZE))) +#endif + +#define IS_NBPAGES(__PAGES__) (((__PAGES__) >= 1) && ((__PAGES__) <= FLASH_NBPAGES_MAX)) + +/** + * @} + */ + +/** + * @} + */ +/* Exported types ------------------------------------------------------------*/ + /** @defgroup FLASHEx_Exported_Types FLASHEx Exported Types * @{ */ +/** + * @brief FLASH Erase structure definition + */ +typedef struct +{ + uint32_t TypeErase; /*!< TypeErase: Page Erase only. + This parameter can be a value of @ref FLASHEx_Type_Erase */ + + uint32_t PageAddress; /*!< PageAddress: Initial FLASH address to be erased + This parameter must be a value belonging to FLASH Programm address (depending on the devices) */ + + uint32_t NbPages; /*!< NbPages: Number of pages to be erased. + This parameter must be a value between 1 and (max number of pages - value of Initial page)*/ + +} FLASH_EraseInitTypeDef; + /** * @brief FLASH Option Bytes PROGRAM structure definition */ typedef struct { - uint32_t OptionType; /*!< OptionType: Option byte to be configured. - This parameter can be a value of @ref FLASHEx_Option_Type */ + uint32_t OptionType; /*!< OptionType: Option byte to be configured. + This parameter can be a value of @ref FLASHEx_Option_Type */ - uint32_t WRPState; /*!< WRPState: Write protection activation or deactivation. - This parameter can be a value of @ref FLASHEx_WRP_State */ + uint32_t WRPState; /*!< WRPState: Write protection activation or deactivation. + This parameter can be a value of @ref FLASHEx_WRP_State */ - uint32_t WRPSector; /*!< WRPSector: This bitfield specifies the sector (s) which are write protected. - This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection */ + uint32_t WRPSector; /*!< WRPSector: This bitfield specifies the sector (s) which are write protected. + This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection */ #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) - uint32_t WRPSector2; /*!< WRPSector2 : This bitfield specifies the sector(s) upper Sector31 which are write protected. - This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection2 */ + uint32_t WRPSector2; /*!< WRPSector2 : This bitfield specifies the sector(s) upper Sector31 which are write protected. + This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection2 */ #endif - uint8_t RDPLevel; /*!< RDPLevel: Set the read protection level. - This parameter can be a value of @ref FLASHEx_Option_Bytes_Read_Protection */ + uint8_t RDPLevel; /*!< RDPLevel: Set the read protection level. + This parameter can be a value of @ref FLASHEx_Option_Bytes_Read_Protection */ - uint8_t BORLevel; /*!< BORLevel: Set the BOR Level. - This parameter can be a value of @ref FLASHEx_Option_Bytes_BOR_Level */ + uint8_t BORLevel; /*!< BORLevel: Set the BOR Level. + This parameter can be a value of @ref FLASHEx_Option_Bytes_BOR_Level */ + + uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. + This parameter can be a combination of @ref FLASHEx_Option_Bytes_IWatchdog, + @ref FLASHEx_Option_Bytes_nRST_STOP and @ref FLASHEx_Option_Bytes_nRST_STDBY*/ - uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. - This parameter can be a combination of @ref FLASHEx_Option_Bytes_IWatchdog, - @ref FLASHEx_Option_Bytes_nRST_STOP and @ref FLASHEx_Option_Bytes_nRST_STDBY */ - - uint8_t BOOTBit1Config; /*!< BOOT1Config: Together with input pad Boot0, this bit selects the boot source, flash, ram or system memory - This parameter can be a value of @ref FLASHEx_Option_Bytes_BOOTBit1 */ - + uint8_t BOOTBit1Config; /*!< BOOT1Config: Together with input pad Boot0, this bit selects the boot source, flash, ram or system memory + This parameter can be a value of @ref FLASHEx_Option_Bytes_BOOTBit1 */ } FLASH_OBProgramInitTypeDef; +#if defined(FLASH_OPTR_WPRMOD) || defined(FLASH_OPTR_BFB2) /** * @brief FLASH Advanced Option Bytes Program structure definition */ typedef struct { - uint32_t OptionType; /*!< OptionType: Option byte to be configured for extension . - This parameter can be a value of @ref FLASHEx_OptionAdv_Type */ - - uint8_t PCROPState; /*!< PCROPState: PCROP activation or deactivation. - This parameter can be a value of @ref FLASHEx_PCROP_State */ - + uint32_t OptionType; /*!< OptionType: Option byte to be configured for extension . + This parameter can be a value of @ref FLASHEx_OptionAdv_Type */ + +#if defined(FLASH_OPTR_WPRMOD) + uint32_t PCROPState; /*!< PCROPState: PCROP activation or deactivation. + This parameter can be a value of @ref FLASHEx_PCROP_State */ + uint32_t PCROPSector; /*!< PCROPSector : This bitfield specifies the sector(s) which are read/write protected. This parameter can be a combination of @ref FLASHEx_Option_Bytes_PC_ReadWrite_Protection */ #if defined (STM32L071xx) || defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L081xx) || defined (STM32L082xx) || defined (STM32L083xx) uint32_t PCROPSector2; /*!< PCROPSector : This bitfield specifies the sector(s) upper Sector31 which are read/write protected. This parameter can be a combination of @ref FLASHEx_Option_Bytes_PC_ReadWrite_Protection2 */ - - uint8_t BootConfig; /*!< BootConfig: specifies Option bytes for boot config. - This parameter can be a value of @ref FLASHEx_Option_Bytes_BOOT_BANK */ -#endif /* if STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */ +#endif /* STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */ +#endif /* FLASH_OPTR_WPRMOD */ + +#if defined(FLASH_OPTR_BFB2) + uint16_t BootConfig; /*!< BootConfig: specifies Option bytes for boot config + This parameter can be a value of @ref FLASHEx_Option_Bytes_BOOT */ +#endif /* FLASH_OPTR_BFB2*/ } FLASH_AdvOBProgramInitTypeDef; /** * @} - */ + */ +#endif /* FLASH_OPTR_WPRMOD || FLASH_OPTR_BFB2 */ + +/* Exported constants --------------------------------------------------------*/ + /** @defgroup FLASHEx_Exported_Constants FLASHEx Exported Constants * @{ */ -/** @defgroup FLASHEx_Type_Erase FLASH Type Erase +/** @defgroup FLASHEx_Type_Erase FLASHEx_Type_Erase * @{ - */ -#define FLASH_TYPEERASE_PAGES ((uint32_t)0x00U) /*!< Page erase only */ + */ +#define FLASH_TYPEERASE_PAGES ((uint32_t)0x00U) /*!> 16)) /*!< At startup, if boot pin 0 and BOOT1 bit are set in boot from user Flash position and this parameter is selected the device will boot from Bank 2 */ + /** * @} */ -#endif /* if STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */ +#endif /* FLASH_OPTR_BFB2 */ -/** @defgroup FLASHEx_Type_Program_Data FLASH Type Program Data - * @{ - */ -#define FLASH_TYPEPROGRAMDATA_BYTE ((uint32_t)0x00U) /*!< Program byte (8-bit) at a specified address.*/ -#define FLASH_TYPEPROGRAMDATA_HALFWORD ((uint32_t)0x01U) /*!< Program a half-word (16-bit) at a specified address.*/ -#define FLASH_TYPEPROGRAMDATA_WORD ((uint32_t)0x02U) /*!< Program a word (32-bit) at a specified address.*/ - -/* Aliases for compatibility with the V1.0.0 package */ -#define FLASH_TYPEPROGRAM_BYTE FLASH_TYPEPROGRAMDATA_BYTE -#define FLASH_TYPEPROGRAM_HALFWORD FLASH_TYPEPROGRAMDATA_HALFWORD /** * @} */ -/** @defgroup FLASHEx_Address FLASHEx Address - * @{ - */ -#define FLASH_NBPAGES_MAX (FLASH_SIZE / FLASH_PAGE_SIZE) -/** - * @} - */ - -/** - * @} - */ +/* Exported macro ------------------------------------------------------------*/ -/** @defgroup FLASHEx_Exported_Macros FLASHEx Exported Macros - * @brief +/** @defgroup FLASHEx_Exported_Macros FLASHEx Exported Macros * @{ */ /** * @brief Set the FLASH Latency. - * @param __LATENCY__: FLASH Latency - * 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 + * @param __LATENCY__ FLASH Latency + * This parameter can be one of the following values: + * @arg @ref FLASH_LATENCY_0 FLASH Zero Latency cycle + * @arg @ref FLASH_LATENCY_1 FLASH One Latency cycle * @retval none */ #define __HAL_FLASH_SET_LATENCY(__LATENCY__) \ MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(__LATENCY__)) /** - * @brief Get the FLASH Latency. - * @retval FLASH Latency - * 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 -*/ -#define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)) + * @brief Get the FLASH Latency. + * @retval FLASH Latency + * This parameter can be one of the following values: + * @arg @ref FLASH_LATENCY_0 FLASH Zero Latency cycle + * @arg @ref FLASH_LATENCY_1 FLASH One Latency cycle + */ +#define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)) /** - * @brief Enable/Disable the FLASH prefetch buffer. + * @brief Enable the FLASH prefetch buffer. * @retval none */ -#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() SET_BIT((FLASH->ACR), FLASH_ACR_PRFTEN) -#define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() CLEAR_BIT((FLASH->ACR), FLASH_ACR_PRFTEN) +#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() SET_BIT((FLASH->ACR), FLASH_ACR_PRFTEN) /** - * @brief Enable/Disable the FLASH Buffer cache. + * @brief Disable the FLASH prefetch buffer. * @retval none */ -#define __HAL_FLASH_BUFFER_CACHE_ENABLE() SET_BIT((FLASH->ACR), FLASH_ACR_DISAB_BUF) -#define __HAL_FLASH_BUFFER_CACHE_DISABLE() CLEAR_BIT((FLASH->ACR), FLASH_ACR_DISAB_BUF) +#define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() CLEAR_BIT((FLASH->ACR), FLASH_ACR_PRFTEN) /** - * @brief Enable/Disable the FLASH preread buffer. + * @brief Enable the FLASH Buffer cache. * @retval none */ -#define __HAL_FLASH_PREREAD_BUFFER_ENABLE() SET_BIT((FLASH->ACR), FLASH_ACR_PRE_READ) -#define __HAL_FLASH_PREREAD_BUFFER_DISABLE() CLEAR_BIT((FLASH->ACR), FLASH_ACR_PRE_READ) +#define __HAL_FLASH_BUFFER_CACHE_ENABLE() SET_BIT((FLASH->ACR), FLASH_ACR_DISAB_BUF) /** - * @brief Enable/Disable the FLASH power down during Sleep mode. + * @brief Disable the FLASH Buffer cache. * @retval none */ -#define __HAL_FLASH_SLEEP_POWERDOWN_ENABLE() SET_BIT(FLASH->ACR, FLASH_ACR_SLEEP_PD) -#define __HAL_FLASH_SLEEP_POWERDOWN_DISABLE() CLEAR_BIT(FLASH->ACR, FLASH_ACR_SLEEP_PD) +#define __HAL_FLASH_BUFFER_CACHE_DISABLE() CLEAR_BIT((FLASH->ACR), FLASH_ACR_DISAB_BUF) + +/** + * @brief Enable the FLASH preread buffer. + * @retval none + */ +#define __HAL_FLASH_PREREAD_BUFFER_ENABLE() SET_BIT((FLASH->ACR), FLASH_ACR_PRE_READ) + +/** + * @brief Disable the FLASH preread buffer. + * @retval none + */ +#define __HAL_FLASH_PREREAD_BUFFER_DISABLE() CLEAR_BIT((FLASH->ACR), FLASH_ACR_PRE_READ) + +/** + * @brief Enable the FLASH power down during Sleep mode + * @retval none + */ +#define __HAL_FLASH_SLEEP_POWERDOWN_ENABLE() SET_BIT(FLASH->ACR, FLASH_ACR_SLEEP_PD) + +/** + * @brief Disable the FLASH power down during Sleep mode + * @retval none + */ +#define __HAL_FLASH_SLEEP_POWERDOWN_DISABLE() CLEAR_BIT(FLASH->ACR, FLASH_ACR_SLEEP_PD) /** * @brief Enable the Flash Run power down mode. @@ -565,49 +736,67 @@ typedef struct /** * @brief Disable the Flash Run power down mode. - * @note Writing this bit to 0 this bit, automatically the keys are + * @note Writing this bit to 0 this bit, automatically the keys are * loss and a new unlock sequence is necessary to re-write it to 1. */ #define __HAL_FLASH_POWER_DOWN_DISABLE() do { FLASH->PDKEYR = FLASH_PDKEY1; \ FLASH->PDKEYR = FLASH_PDKEY2; \ - CLEAR_BIT((FLASH->ACR), FLASH_ACR_RUN_PD); \ + CLEAR_BIT((FLASH->ACR), FLASH_ACR_RUN_PD); \ } while (0) /** * @} */ -/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup FLASHEx_Exported_Functions * @{ */ -/** @defgroup FLASHEx_Exported_Functions_Group1 FLASH Memory Erasing functions +/** @addtogroup FLASHEx_Exported_Functions_Group1 * @{ */ + HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError); HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit); + /** * @} */ -/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions +/** @addtogroup FLASHEx_Exported_Functions_Group2 * @{ */ + HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit); void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit); + +#if defined(FLASH_OPTR_WPRMOD) || defined(FLASH_OPTR_BFB2) + HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram (FLASH_AdvOBProgramInitTypeDef *pAdvOBInit); void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit); + +#endif /* FLASH_OPTR_WPRMOD || FLASH_OPTR_BFB2 */ + +#if defined(FLASH_OPTR_WPRMOD) + HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void); HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void); + +#endif /* FLASH_OPTR_WPRMOD */ + /** * @} */ -/** @defgroup FLASHEx_Exported_Functions_Group3 DATA EEPROM Programming functions +/** @addtogroup FLASHEx_Exported_Functions_Group3 * @{ */ + HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Unlock(void); HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Lock(void); + HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address); HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data); void HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram(void); @@ -620,77 +809,6 @@ void HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void); /** * @} */ - -/** @addtogroup FLASHEx_Private - * @{ - */ -#define IS_FLASH_TYPEERASE(__VALUE__) (((__VALUE__) == FLASH_TYPEERASE_PAGES)) - -#define IS_OPTIONBYTE(__VALUE__) (((__VALUE__) <= (OPTIONBYTE_WRP | OPTIONBYTE_RDP | \ - OPTIONBYTE_USER | OPTIONBYTE_BOR | OPTIONBYTE_BOOT_BIT1))) - -#define IS_WRPSTATE(__VALUE__) (((__VALUE__) == OB_WRPSTATE_DISABLE) || \ - ((__VALUE__) == OB_WRPSTATE_ENABLE)) - -#define IS_OB_WRP(PAGE) (((PAGE) != 0x0000000U)) - -#define IS_OB_RDP(__LEVEL__) (((__LEVEL__) == OB_RDP_LEVEL_0)||\ - ((__LEVEL__) == OB_RDP_LEVEL_1)||\ - ((__LEVEL__) == OB_RDP_LEVEL_2)) - -#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)) - -#define IS_OB_IWDG_SOURCE(__SOURCE__) (((__SOURCE__) == OB_IWDG_SW) || ((__SOURCE__) == OB_IWDG_HW)) - -#define IS_OB_STOP_SOURCE(__SOURCE__) (((__SOURCE__) == OB_STOP_NORST) || ((__SOURCE__) == OB_STOP_RST)) - -#define IS_OB_STDBY_SOURCE(__SOURCE__) (((__SOURCE__) == OB_STDBY_NORST) || ((__SOURCE__) == OB_STDBY_RST)) - -#define IS_PCROPSTATE(VALUE)(((VALUE) == OB_PCROP_STATE_DISABLE) || \ - ((VALUE) == OB_PCROP_STATE_ENABLE)) - -#define IS_OB_PCROP(__PAGE__) (((__PAGE__) != 0x0000000U)) - -#define IS_OB_BOOT1(__BOOT_BIT1__) (((__BOOT_BIT1__) == OB_BOOT_BIT1_RESET) || ((__BOOT_BIT1__) == OB_BOOT_BIT1_SET)) - -#define IS_TYPEPROGRAMDATA(__VALUE__) (((__VALUE__) == FLASH_TYPEPROGRAMDATA_BYTE) || \ - ((__VALUE__) == FLASH_TYPEPROGRAMDATA_HALFWORD) || \ - ((__VALUE__) == FLASH_TYPEPROGRAMDATA_WORD)) - -#define IS_NBPAGES(__PAGES__) (((__PAGES__) >= 1) && ((__PAGES__) <= FLASH_NBPAGES_MAX)) - -#if defined (STM32L071xx) || defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L081xx) || defined (STM32L082xx) || defined (STM32L083xx) -#define IS_OBEX(__VALUE__)(((__VALUE__) <= (OPTIONBYTE_PCROP | OPTIONBYTE_BOOTCONFIG))) -#define IS_OB_BOOT_BANK(__BANK__) (((__BANK__) == OB_BOOT_BANK2) || ((__BANK__) == OB_BOOT_BANK1)) -#define IS_FLASH_DATA_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= DATA_EEPROM_BASE) && ((__ADDRESS__) <= DATA_EEPROM_BANK2_END)) -#define IS_FLASH_DATA_BANK1_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= DATA_EEPROM_BASE) && ((__ADDRESS__) <= DATA_EEPROM_BANK1_END)) -#define IS_FLASH_DATA_BANK2_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= DATA_EEPROM_BANK2_BASE) && ((__ADDRESS__) <= DATA_EEPROM_BANK2_END)) -#define IS_FLASH_PROGRAM_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= FLASH_BASE) && ((__ADDRESS__) < (FLASH_BASE + FLASH_SIZE))) -#define IS_FLASH_PROGRAM_BANK1_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= FLASH_BASE) && ((__ADDRESS__) < (FLASH_BASE + (FLASH_SIZE >> 1)))) -#define IS_FLASH_PROGRAM_BANK2_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= FLASH_BANK2_BASE) && ((__ADDRESS__) < (FLASH_BASE + FLASH_SIZE))) -#else -#define IS_OBEX(VALUE)((VALUE) == OPTIONBYTE_PCROP) -#define IS_FLASH_DATA_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= DATA_EEPROM_BASE) && ((__ADDRESS__) <= DATA_EEPROM_END)) -#define IS_FLASH_PROGRAM_ADDRESS(__ADDRESS__) (((__ADDRESS__) >= FLASH_BASE) && ((__ADDRESS__) < (FLASH_BASE + FLASH_SIZE))) -#endif -/** - * @} - */ - -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup FLASHEx_Private FLASHEx Private - * @{ - */ -/** - * @} - */ -/**************************************************************/ /** * @} @@ -707,4 +825,3 @@ void HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void); #endif /* __STM32L0xx_HAL_FLASH_EX_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ramfunc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ramfunc.c index 137fb2c37c..1c0be0deb7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ramfunc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ramfunc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_flash_ramfunc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief FLASH RAMFUNC driver. * This file provides a Flash firmware functions which should be * executed from internal SRAM @@ -57,7 +55,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal.h" @@ -68,30 +66,48 @@ #ifdef HAL_FLASH_MODULE_ENABLED +/** @addtogroup FLASH + * @{ + */ +/** @addtogroup FLASH_Private_Variables + * @{ + */ +extern FLASH_ProcessTypeDef pFlash; +/** + * @} + */ -/** @addtogroup FLASH_RAMFUNC +/** + * @} + */ + +/** @defgroup FLASH_RAMFUNC FLASH_RAMFUNC * @brief FLASH functions executed from RAM * @{ - */ -/** @addtogroup FLASH_RAMFUNC_Private - * @{ - */ + */ + /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASH_RAMFUNC_Private_Functions FLASH RAM Private Functions + * @{ + */ + static __RAM_FUNC FLASHRAM_WaitForLastOperation(uint32_t Timeout); static __RAM_FUNC FLASHRAM_SetErrorCode(void); + /** * @} */ - -/** @addtogroup FLASH_RAMFUNC_Exported_Functions +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup FLASH_RAMFUNC_Exported_Functions FLASH RAM Exported Functions * -@verbatim +@verbatim =============================================================================== ##### ramfunc functions ##### =============================================================================== @@ -101,33 +117,35 @@ static __RAM_FUNC FLASHRAM_SetErrorCode(void); @endverbatim * @{ - */ + */ -/** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group1 +/** @defgroup FLASH_RAMFUNC_Exported_Functions_Group1 Peripheral features functions * @{ */ /** * @brief Enable the power down mode during RUN mode. - * @note This function can be used only when the user code is running from Internal SRAM. - * @retval HAL Status + * @note This function can be used only when the user code is running from Internal SRAM. + * @retval HAL status */ __RAM_FUNC HAL_FLASHEx_EnableRunPowerDown(void) { /* Enable the Power Down in Run mode*/ __HAL_FLASH_POWER_DOWN_ENABLE(); + return HAL_OK; } /** * @brief Disable the power down mode during RUN mode. - * @note This function can be used only when the user code is running from Internal SRAM. - * @retval HAL Status + * @note This function can be used only when the user code is running from Internal SRAM. + * @retval HAL status */ __RAM_FUNC HAL_FLASHEx_DisableRunPowerDown(void) { /* Disable the Power Down in Run mode*/ __HAL_FLASH_POWER_DOWN_DISABLE(); + return HAL_OK; } @@ -135,22 +153,21 @@ __RAM_FUNC HAL_FLASHEx_DisableRunPowerDown(void) * @} */ -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) - -/** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group2 +/** @defgroup FLASH_RAMFUNC_Exported_Functions_Group2 Programming and erasing operation functions * @verbatim @endverbatim * @{ */ +#if defined(FLASH_PECR_PARALLBANK) /** * @brief Erases a specified 2 pages in program memory in parallel. * @note This function can be used only for STM32L07xxx/STM32L08xxx devices. - * To correctly run this function, the HAL_FLASH_Unlock() function + * To correctly run this function, the @ref HAL_FLASH_Unlock() function * must be called before. - * Call the HAL_FLASH_Lock() to disable the flash memory access - * (recommended to protect the FLASH memory against possible unwanted operation). + * Call the @ref HAL_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 FLASH_BASE * and FLASH_BANK1_END. @@ -158,9 +175,8 @@ __RAM_FUNC HAL_FLASHEx_DisableRunPowerDown(void) * the second Bank (BANK2). This parameter should be between FLASH_BANK2_BASE * and FLASH_BANK2_END. * @note A Page is erased in the Program memory only if the address to load - * is the start address of a page (multiple of 128 bytes). - * @retval HAL Status: The returned value can be: - * HAL_ERROR, HAL_OK or HAL_TIMEOUT. + * is the start address of a page (multiple of @ref FLASH_PAGE_SIZE bytes). + * @retval HAL status */ __RAM_FUNC HAL_FLASHEx_EraseParallelPage(uint32_t Page_Address1, uint32_t Page_Address2) { @@ -179,7 +195,7 @@ __RAM_FUNC HAL_FLASHEx_EraseParallelPage(uint32_t Page_Address1, uint32_t Page_A /* Write 00000000h to the first word of the first program page to erase */ *(__IO uint32_t *)Page_Address1 = 0x00000000U; /* Write 00000000h to the first word of the second program page to erase */ - *(__IO uint32_t *)Page_Address2 = 0x00000000U; + *(__IO uint32_t *)Page_Address2 = 0x00000000U; /* Wait for last operation to be completed */ status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE); @@ -189,24 +205,24 @@ __RAM_FUNC HAL_FLASHEx_EraseParallelPage(uint32_t Page_Address1, uint32_t Page_A CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE); CLEAR_BIT(FLASH->PECR, FLASH_PECR_PARALLBANK); } - /* Return the erasesStatus */ + /* Return the Erase Status */ return status; } /** - * @brief Programs 2 half pages in program memory in parallel. The half page size is 16 Words. - * @note This function can be used only for STM32L07xxx/STM32L08xxx devices. + * @brief Program 2 half pages in program memory in parallel (half page size is 16 Words). + * @note This function can be used only for STM32L07xxx/STM32L08xxx devices. * @param Address1: specifies the first address to be written in the first bank - * (BANK1). This parameter should be between FLASH_BASE and (FLASH_BANK1_END - FLASH_PAGE_SIZE). + * (BANK1). This parameter should be between FLASH_BASE and (FLASH_BANK1_END - FLASH_PAGE_SIZE). * @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 FLASH_BANK2_BASE and (FLASH_BANK2_END - FLASH_PAGE_SIZE). + * (BANK2). This parameter should be between FLASH_BANK2_BASE and (FLASH_BANK2_END - FLASH_PAGE_SIZE). * @param pBuffer2: pointer to the buffer containing the data to be written * to the second half page in the second bank. - * @note To correctly run this function, the HAL_FLASH_Unlock() function + * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function * must be called before. - * Call the HAL_FLASH_Lock() to disable the flash memory access + * Call the @ref HAL_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 A half page is written to the program memory only if the first @@ -219,13 +235,12 @@ __RAM_FUNC HAL_FLASHEx_EraseParallelPage(uint32_t Page_Address1, uint32_t Page_A * complete write operation is aborted. Software should then reset the * FPRG and PROG/DATA bits and restart the write operation from the * beginning. - * @retval HAL Status: The returned value can be: - * HAL_ERROR, HAL_OK or HAL_TIMEOUT. + * @retval HAL status */ __RAM_FUNC HAL_FLASHEx_ProgramParallelHalfPage(uint32_t Address1, uint32_t* pBuffer1, uint32_t Address2, uint32_t* pBuffer2) { - uint32_t count; - HAL_StatusTypeDef status; + uint32_t count = 0U; + HAL_StatusTypeDef status = HAL_OK; /* Wait for last operation to be completed */ status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE); @@ -237,67 +252,58 @@ __RAM_FUNC HAL_FLASHEx_ProgramParallelHalfPage(uint32_t Address1, uint32_t* pBuf SET_BIT(FLASH->PECR, FLASH_PECR_FPRG); SET_BIT(FLASH->PECR, FLASH_PECR_PROG); - /* Wait for last operation to be completed */ status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - if(status == HAL_OK) { - /* Write one half page, - Address1 doesn't need to be increased */ - count = 0U; - /* Disable all IRQs */ __disable_irq(); + /* Write the first half page directly with 16 different words */ while(count < 16U) { + /* Address1 doesn't need to be increased */ *(__IO uint32_t*) Address1 = *pBuffer1; pBuffer1++; - count++; + count ++; } - - /* Write the second half page, - Address2 doesn't need to be increased */ + + /* Write the second half page directly with 16 different words */ count = 0U; while(count < 16U) { + /* Address2 doesn't need to be increased */ *(__IO uint32_t*) Address2 = *pBuffer2; pBuffer2++; - count++; + count ++; } /* Enable IRQs */ __enable_irq(); - + /* Wait for last operation to be completed */ status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - } + } + /* if the write operation is completed, disable the PROG, FPRG and PARALLBANK bits */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG); CLEAR_BIT(FLASH->PECR, FLASH_PECR_FPRG); CLEAR_BIT(FLASH->PECR, FLASH_PECR_PARALLBANK); } + /* Return the Write Status */ return status; } -/** - * @} - */ -#endif /* STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */ +#endif /* FLASH_PECR_PARALLBANK */ -/** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group1 - * - * @{ - */ /** - * @brief Program a half page in program memory. + * @brief Program 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 HAL_FLASH_Unlock() function + * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function * must be called before. - * Call the HAL_FLASH_Lock() to disable the flash memory access + * Call the @ref HAL_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 A half page is written to the program memory only if the first @@ -310,67 +316,82 @@ __RAM_FUNC HAL_FLASHEx_ProgramParallelHalfPage(uint32_t Address1, uint32_t* pBuf * complete write operation is aborted. Software should then reset the * FPRG and PROG/DATA bits and restart the write operation from the * beginning. - * @retval HAL Status: The returned value can be: - * HAL_ERROR, HAL_OK or HAL_TIMEOUT. + * @retval HAL status */ -__RAM_FUNC HAL_FLASHEx_HalfPageProgram(uint32_t Address, uint32_t *pBuffer) +__RAM_FUNC HAL_FLASHEx_HalfPageProgram(uint32_t Address, uint32_t* pBuffer) { - uint32_t count; - HAL_StatusTypeDef status; + uint32_t count = 0U; + HAL_StatusTypeDef status = HAL_OK; /* Wait for last operation to be completed */ status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - + if(status == HAL_OK) { /* Proceed to program the new half page */ SET_BIT(FLASH->PECR, FLASH_PECR_FPRG); SET_BIT(FLASH->PECR, FLASH_PECR_PROG); - - - count = 0U; - /* Write one half page, - Address doesn't need to be increased */ - + /* Disable all IRQs */ __disable_irq(); + /* Write one half page directly with 16 different words */ while(count < 16U) { + /* Address doesn't need to be increased */ *(__IO uint32_t*) Address = *pBuffer; pBuffer++; - count++; + count ++; } /* Enable IRQs */ __enable_irq(); - + /* Wait for last operation to be completed */ status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE); - + /* If the write operation is completed, disable the PROG and FPRG bits */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG); CLEAR_BIT(FLASH->PECR, FLASH_PECR_FPRG); } - /* Return the write status */ + + /* Return the Write Status */ return status; } +/** + * @} + */ + +/** @defgroup FLASH_RAMFUNC_Exported_Functions_Group3 Peripheral errors functions + * @brief Peripheral errors functions + * +@verbatim + =============================================================================== + ##### Peripheral errors functions ##### + =============================================================================== + [..] + This subsection permit to get in run-time errors of the FLASH peripheral. + +@endverbatim + * @{ + */ + /** * @brief Get the specific FLASH errors flag. - * @param error pointer is the error value. It can be a mixed of : - * @arg HAL_FLASH_ERROR_RD: FLASH Read Protection error flag (PCROP) - * @arg HAL_FLASH_ERROR_SIZE: FLASH Programming Parallelism error flag - * @arg HAL_FLASH_ERROR_PGA: FLASH Programming Alignment error flag - * @arg HAL_FLASH_ERROR_WRP: FLASH Write protected error flag - * @arg HAL_FLASH_ERROR_OPTV: FLASH Option valid error flag - * @arg HAL_FLASH_ERROR_FWWERR: FLASH Write or Errase operation aborted - * @arg HAL_FLASH_ERROR_NOTZERO: FLASH Write operation is done in a not-erased region + * @param Error pointer is the error value. It can be a mixed of: + * @arg @ref HAL_FLASH_ERROR_RD FLASH Read Protection error flag (PCROP) + * @arg @ref HAL_FLASH_ERROR_SIZE FLASH Programming Parallelism error flag + * @arg @ref HAL_FLASH_ERROR_PGA FLASH Programming Alignment error flag + * @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protected error flag + * @arg @ref HAL_FLASH_ERROR_OPTV FLASH Option valid error flag + * @arg @ref HAL_FLASH_ERROR_FWWERR FLASH Write or Erase operation aborted + * @arg @ref HAL_FLASH_ERROR_NOTZERO FLASH Write operation is done in a not-erased region * @retval HAL Status */ -__RAM_FUNC HAL_FLASHRAM_GetError(uint32_t * error) +__RAM_FUNC HAL_FLASHEx_GetError(uint32_t * Error) { - *error = ProcFlash.ErrorCode; + *Error = pFlash.ErrorCode; return HAL_OK; } @@ -382,7 +403,7 @@ __RAM_FUNC HAL_FLASHRAM_GetError(uint32_t * error) * @} */ -/** @addtogroup FLASH_RAMFUNC_Private +/** @addtogroup FLASH_RAMFUNC_Private_Functions * @{ */ @@ -391,21 +412,26 @@ __RAM_FUNC HAL_FLASHRAM_GetError(uint32_t * error) * @retval HAL Status */ static __RAM_FUNC FLASHRAM_SetErrorCode(void) -{ +{ + uint32_t flags = 0; + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) - { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; + flags |= FLASH_FLAG_WRPERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) - { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_PGA; + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA; + flags |= FLASH_FLAG_PGAERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE; + pFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE; + flags |= FLASH_FLAG_SIZERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)) - { + { /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices, * (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving * as expected. If the user run an application using the first @@ -414,36 +440,38 @@ static __RAM_FUNC FLASHRAM_SetErrorCode(void) * can be retrieved via the HAL_GetREVID() function. * */ - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV; + pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV; + flags |= FLASH_FLAG_OPTVERR; } + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)) - { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_RD; + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_RD; + flags |= FLASH_FLAG_RDERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR)) { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_FWWERR; + pFlash.ErrorCode |= HAL_FLASH_ERROR_FWWERR; + flags |= HAL_FLASH_ERROR_FWWERR; } if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR)) { - ProcFlash.ErrorCode |= HAL_FLASH_ERROR_NOTZERO; + pFlash.ErrorCode |= HAL_FLASH_ERROR_NOTZERO; + flags |= FLASH_FLAG_NOTZEROERR; } - - /* Errors are now stored, clear errors flags */ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | - FLASH_FLAG_OPTVERR | FLASH_FLAG_RDERR | FLASH_FLAG_FWWERR | - FLASH_FLAG_NOTZEROERR); + /* Clear FLASH error pending bits */ + __HAL_FLASH_CLEAR_FLAG(flags); + return HAL_OK; -} - +} /** * @brief Wait for a FLASH operation to complete. * @param Timeout: maximum flash operationtimeout * @retval HAL status */ -static __RAM_FUNC FLASHRAM_WaitForLastOperation(uint32_t Timeout) +static __RAM_FUNC FLASHRAM_WaitForLastOperation(uint32_t Timeout) { /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. Even if the FLASH operation fails, the BUSY flag will be reset and an error @@ -454,36 +482,42 @@ static __RAM_FUNC FLASHRAM_WaitForLastOperation(uint32_t Timeout) Timeout--; } - if(Timeout == 0x00U ) + if(Timeout == 0x00U) { return HAL_TIMEOUT; } - if( (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET) || - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET) || - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET) || - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) != RESET) || - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) != RESET) || - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR) != RESET) || - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) != RESET) ) - { - /*Save the error code*/ - - /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices, - * (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving - * as expected. If the user run an application using the first - * cut of the STM32L031xx device or the first cut of the STM32L041xx - * device, this error should be ignored. The revId of the device - * can be retrieved via the HAL_GetREVID() function. - * - */ - - FLASHRAM_SetErrorCode(); - return HAL_ERROR; - } + /* Check FLASH End of Operation flag */ + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) + { + /* Clear FLASH End of Operation pending bit */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + } - /* If there is an error flag set */ - return HAL_OK; + if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) ) + { + /*Save the error code*/ + + /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices, + * (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving + * as expected. If the user run an application using the first + * cut of the STM32L031xx device or the first cut of the STM32L041xx + * device, this error should be ignored. The revId of the device + * can be retrieved via the HAL_GetREVID() function. + * + */ + FLASHRAM_SetErrorCode(); + return HAL_ERROR; + } + + /* There is no error flag set */ + return HAL_OK; } /** @@ -495,11 +529,9 @@ static __RAM_FUNC FLASHRAM_WaitForLastOperation(uint32_t Timeout) */ #endif /* HAL_FLASH_MODULE_ENABLED */ - /** * @} */ - + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ramfunc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ramfunc.h index 70f62a756f..bc5668f978 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ramfunc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_flash_ramfunc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_flash_ramfunc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of FLASH RAMFUNC driver. ****************************************************************************** * @attention @@ -50,13 +48,16 @@ * @{ */ -/** @defgroup FLASH_RAMFUNC FLASH Ram Function +/** @addtogroup FLASH_RAMFUNC * @{ */ +/* Exported types ------------------------------------------------------------*/ + + /* Exported functions --------------------------------------------------------*/ -/** @defgroup FLASH_RAMFUNC_Exported_Functions FLASH Ram Exported Functions +/** @addtogroup FLASH_RAMFUNC_Exported_Functions * @{ */ @@ -66,41 +67,45 @@ * file. */ -/** @defgroup FLASH_RAMFUNC_Exported_Functions_Group1 FLASH RAM peripheral features functions +/** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group1 * @{ */ -__RAM_FUNC HAL_FLASHEx_HalfPageProgram(uint32_t Address, uint32_t* pBuffer); -__RAM_FUNC HAL_FLASHEx_EnableRunPowerDown(void); -__RAM_FUNC HAL_FLASHEx_DisableRunPowerDown(void); -__RAM_FUNC HAL_FLASHRAM_GetError(uint32_t * error); + +__RAM_FUNC HAL_FLASHEx_EnableRunPowerDown(void); +__RAM_FUNC HAL_FLASHEx_DisableRunPowerDown(void); + /** * @} */ -#if defined (STM32L071xx) || defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L081xx) || defined (STM32L082xx) || defined (STM32L083xx) -/** @defgroup FLASH_RAMFUNC_Exported_Functions_Group2 FLASH RAM programming and erasing operation functions +/** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group2 * @{ */ + +#if defined(FLASH_PECR_PARALLBANK) + __RAM_FUNC HAL_FLASHEx_EraseParallelPage(uint32_t Page_Address1, uint32_t Page_Address2); __RAM_FUNC HAL_FLASHEx_ProgramParallelHalfPage(uint32_t Address1, uint32_t* pBuffer1, uint32_t Address2, uint32_t* pBuffer2); + +#endif /* FLASH_PECR_PARALLBANK */ + +__RAM_FUNC HAL_FLASHEx_HalfPageProgram(uint32_t Address, uint32_t* pBuffer); + /** * @} */ -#endif /* STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */ -/** - * @} - */ - -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup FLASH_RAMFUNC_Private FLASH Ram Private +/** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group3 * @{ */ +__RAM_FUNC HAL_FLASHEx_GetError(uint32_t *Error); /** * @} - */ -/**************************************************************/ + */ + +/** + * @} + */ /** * @} @@ -117,4 +122,3 @@ __RAM_FUNC HAL_FLASHEx_ProgramParallelHalfPage(uint32_t Address1, uint32_t* pBuf #endif /* __STM32L0xx_FLASH_RAMFUNC_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio.c index c929efea34..563e0866e6 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_gpio.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief GPIO HAL module driver. * This file provides firmware functions to manage the following * functionalities of the General Purpose Input/Output (GPIO) peripheral: @@ -194,7 +192,7 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) assert_param(IS_GPIO_PIN_AVAILABLE(GPIOx,(GPIO_Init->Pin))); /* Configure the port pins */ - while ((GPIO_Init->Pin) >> position) + while (((GPIO_Init->Pin) >> position) != 0) { /* Get the IO position */ iocurrent = (GPIO_Init->Pin) & (1U << position); @@ -251,12 +249,12 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) { /* Enable SYSCFG Clock */ __HAL_RCC_SYSCFG_CLK_ENABLE(); - + temp = SYSCFG->EXTICR[position >> 2U]; - temp &= ~(((uint32_t)0x0FU) << (4U * (position & 0x03U))); - temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U))); + CLEAR_BIT(temp, ((uint32_t)0x0FU) << (4U * (position & 0x03U))); + SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03U))); SYSCFG->EXTICR[position >> 2U] = temp; - + /* Clear EXTI line configuration */ temp = EXTI->IMR; temp &= ~((uint32_t)iocurrent); @@ -315,7 +313,7 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) assert_param(IS_GPIO_PIN_AVAILABLE(GPIOx,GPIO_Pin)); /* Configure the port pins */ - while (GPIO_Pin >> position) + while ((GPIO_Pin >> position) != 0) { /* Get the IO position */ iocurrent = (GPIO_Pin) & (1U << position); @@ -324,8 +322,8 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) { /*------------------------- GPIO Mode Configuration --------------------*/ /* Configure IO Direction in Input Floting Mode */ - GPIOx->MODER &= ~(GPIO_MODER_MODE0 << (position * 2U)); - + GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2U)); + /* Configure the default Alternate Function in current IO */ GPIOx->AFR[position >> 3U] &= ~((uint32_t)0xFU << ((uint32_t)(position & (uint32_t)0x07U) * 4U)) ; diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio.h index c8e6e8ba8b..aac51fea9a 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_gpio.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of GPIO HAL module. ****************************************************************************** * @attention @@ -142,7 +140,8 @@ typedef enum */ #define GPIO_PIN_MASK ((uint32_t)0x0000FFFFU) /* PIN mask for assert test */ -#define IS_GPIO_PIN(__PIN__) (((__PIN__) & GPIO_PIN_MASK ) != (uint32_t)0x00U) +#define IS_GPIO_PIN(__PIN__) ((((__PIN__) & GPIO_PIN_MASK) != (uint32_t)0x00) &&\ + (((__PIN__) & ~GPIO_PIN_MASK) == (uint32_t)0x00)) /** @defgroup GPIO_mode_define Mode definition * @brief GPIO Configuration Mode diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio_ex.h index 82347ccdee..e727fa6109 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_gpio_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_gpio_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of GPIO HAL Extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c index 8b13d80d78..91fde8d78d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_i2c.c * @author MCD Application Team - * @version $VERSION$ - * @date $DATE$ * @brief I2C HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Inter Integrated Circuit (I2C) peripheral: @@ -238,7 +236,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal.h" @@ -350,6 +348,10 @@ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32 static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); static HAL_StatusTypeDef I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); +/* Private functions to centralize the enable/disable of Interrupts */ +static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); +static HAL_StatusTypeDef I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); + /* Private functions to flush TXDR register */ static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c); @@ -366,7 +368,7 @@ static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, ui */ /** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions + * @brief Initialization and Configuration functions * @verbatim =============================================================================== @@ -406,7 +408,7 @@ static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, ui HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) { /* Check the I2C handle allocation */ - if(hi2c == NULL) + if (hi2c == NULL) { return HAL_ERROR; } @@ -421,7 +423,7 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); - if(hi2c->State == HAL_I2C_STATE_RESET) + if (hi2c->State == HAL_I2C_STATE_RESET) { /* Allocate lock resource and initialize it */ hi2c->Lock = HAL_UNLOCKED; @@ -444,7 +446,7 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN; /* Configure I2Cx: Own Address1 and ack own address1 mode */ - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) { hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1); } @@ -455,7 +457,7 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) /*---------------------------- I2Cx CR2 Configuration ----------------------*/ /* Configure I2Cx: Addressing Master mode */ - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) { hi2c->Instance->CR2 = (I2C_CR2_ADD10); } @@ -493,7 +495,7 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) { /* Check the I2C handle allocation */ - if(hi2c == NULL) + if (hi2c == NULL) { return HAL_ERROR; } @@ -557,7 +559,7 @@ __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) */ /** @defgroup I2C_Exported_Functions_Group2 Input and Output operation functions - * @brief Data transfers functions + * @brief Data transfers functions * @verbatim =============================================================================== @@ -569,7 +571,7 @@ __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) (#) There are two modes of transfer: (++) Blocking mode : The communication is performed in the polling mode. - The status of all data processing is returned by the same function + The status of all data processing is returned by the same function after finishing transfer. (++) No-Blocking mode : The communication is performed using Interrupts or DMA. These functions return the status of the transfer startup. @@ -630,7 +632,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA { uint32_t tickstart = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -638,7 +640,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA /* Init tickstart for timeout management*/ tickstart = HAL_GetTick(); - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) { return HAL_TIMEOUT; } @@ -646,7 +648,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA hi2c->State = HAL_I2C_STATE_BUSY_TX; hi2c->Mode = HAL_I2C_MODE_MASTER; hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - + /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; @@ -654,7 +656,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA /* Send Slave Address */ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); @@ -665,12 +667,12 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE); } - while(hi2c->XferCount > 0U) + while (hi2c->XferCount > 0U) { /* Wait until TXIS flag is set */ - if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -684,15 +686,15 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA hi2c->XferCount--; hi2c->XferSize--; - if((hi2c->XferSize == 0U) && (hi2c->XferCount!=0U)) + if ((hi2c->XferSize == 0U) && (hi2c->XferCount != 0U)) { /* Wait until TCR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); @@ -707,9 +709,9 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ /* Wait until STOPF flag is set */ - if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -754,15 +756,15 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd { uint32_t tickstart = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) - { + if (hi2c->State == HAL_I2C_STATE_READY) + { /* Process Locked */ __HAL_LOCK(hi2c); /* Init tickstart for timeout management*/ tickstart = HAL_GetTick(); - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) { return HAL_TIMEOUT; } @@ -778,7 +780,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd /* Send Slave Address */ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ); @@ -789,12 +791,12 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); } - while(hi2c->XferCount > 0U) + while (hi2c->XferCount > 0U) { /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -809,15 +811,15 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd hi2c->XferSize--; hi2c->XferCount--; - if((hi2c->XferSize == 0U) && (hi2c->XferCount != 0U)) + if ((hi2c->XferSize == 0U) && (hi2c->XferCount != 0U)) { /* Wait until TCR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); @@ -832,9 +834,9 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ /* Wait until STOPF flag is set */ - if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -843,7 +845,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd return HAL_TIMEOUT; } } - + /* Clear STOP Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); @@ -865,7 +867,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd } /** - * @brief Transmits in slave mode an amount of data in blocking mode. + * @brief Transmits in slave mode an amount of data in blocking mode. * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param pData Pointer to data buffer @@ -877,15 +879,15 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData { uint32_t tickstart = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hi2c); - + /* Init tickstart for timeout management*/ tickstart = HAL_GetTick(); @@ -902,7 +904,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData hi2c->Instance->CR2 &= ~I2C_CR2_NACK; /* Wait until ADDR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; @@ -910,13 +912,13 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData } /* Clear ADDR flag */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); /* If 10bit addressing mode is selected */ - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) { /* Wait until ADDR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; @@ -924,26 +926,26 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData } /* Clear ADDR flag */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); } /* Wait until DIR flag is set Transmitter mode */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; return HAL_TIMEOUT; } - while(hi2c->XferCount > 0U) + while (hi2c->XferCount > 0U) { /* Wait until TXIS flag is set */ - if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -959,16 +961,16 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData } /* Wait until STOP flag is set */ - if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { - /* Normal use case for Transmitter mode */ - /* A NACK is generated to confirm the end of transfer */ - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + /* Normal use case for Transmitter mode */ + /* A NACK is generated to confirm the end of transfer */ + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; } else { @@ -977,10 +979,10 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData } /* Clear STOP flag */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_STOPF); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) + /* Wait until BUSY flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; @@ -1017,9 +1019,9 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, { uint32_t tickstart = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) - { - if((pData == NULL) || (Size == 0U)) + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -1042,7 +1044,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, hi2c->Instance->CR2 &= ~I2C_CR2_NACK; /* Wait until ADDR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; @@ -1050,33 +1052,33 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, } /* Clear ADDR flag */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); /* Wait until DIR flag is reset Receiver mode */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; return HAL_TIMEOUT; } - while(hi2c->XferCount > 0U) + while (hi2c->XferCount > 0U) { /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; /* Store Last receive data if any */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) { /* Read data from RXDR */ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR; hi2c->XferCount--; } - if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + if (hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) { return HAL_TIMEOUT; } @@ -1092,12 +1094,12 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, } /* Wait until STOP flag is set */ - if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -1108,10 +1110,10 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, } /* Clear STOP flag */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_STOPF); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) { /* Disable Address Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; @@ -1149,9 +1151,9 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t D { uint32_t xfermode = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -1168,8 +1170,8 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t D hi2c->XferCount = Size; hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->XferISR = I2C_Master_ISR_IT; - - if(hi2c->XferCount > MAX_NBYTE_SIZE) + + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -1185,7 +1187,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t D I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE); /* Process Unlocked */ - __HAL_UNLOCK(hi2c); + __HAL_UNLOCK(hi2c); /* Note : The I2C interrupts must be enabled after unlocking current process to avoid the risk of I2C interrupt handle execution before current @@ -1218,9 +1220,9 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t De { uint32_t xfermode = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -1237,8 +1239,8 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t De hi2c->XferCount = Size; hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->XferISR = I2C_Master_ISR_IT; - - if(hi2c->XferCount > MAX_NBYTE_SIZE) + + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -1252,7 +1254,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t De /* Send Slave Address */ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); - + /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -1283,7 +1285,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t De */ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) { - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -1323,7 +1325,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pD } /** - * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt + * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param pData Pointer to data buffer @@ -1332,7 +1334,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pD */ HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) { - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -1385,9 +1387,9 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t { uint32_t xfermode = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -1404,8 +1406,8 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t hi2c->XferCount = Size; hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->XferISR = I2C_Master_ISR_DMA; - - if(hi2c->XferCount > MAX_NBYTE_SIZE) + + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -1416,7 +1418,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t xfermode = I2C_AUTOEND_MODE; } - if(hi2c->XferSize > 0U) + if (hi2c->XferSize > 0U) { /* Set the I2C DMA transfer complete callback */ hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt; @@ -1454,7 +1456,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t { /* Update Transfer ISR function pointer */ hi2c->XferISR = I2C_Master_ISR_IT; - + /* Send Slave Address */ /* Set NBYTES to write and generate START condition */ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE); @@ -1493,9 +1495,9 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D { uint32_t xfermode = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -1512,8 +1514,8 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D hi2c->XferCount = Size; hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->XferISR = I2C_Master_ISR_DMA; - - if(hi2c->XferCount > MAX_NBYTE_SIZE) + + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -1524,7 +1526,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D xfermode = I2C_AUTOEND_MODE; } - if(hi2c->XferSize > 0U) + if (hi2c->XferSize > 0U) { /* Set the I2C DMA transfer complete callback */ hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt; @@ -1541,7 +1543,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D /* Send Slave Address */ /* Set NBYTES to read and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ - I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); /* Update XferCount value */ hi2c->XferCount -= hi2c->XferSize; @@ -1562,7 +1564,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D { /* Update Transfer ISR function pointer */ hi2c->XferISR = I2C_Master_ISR_IT; - + /* Send Slave Address */ /* Set NBYTES to read and generate START condition */ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); @@ -1596,12 +1598,12 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D */ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) { - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; - } + } /* Process Locked */ __HAL_LOCK(hi2c); @@ -1642,7 +1644,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *p I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); /* Enable DMA Request */ - hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; return HAL_OK; } @@ -1662,12 +1664,12 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *p */ HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) { - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; - } + } /* Process Locked */ __HAL_LOCK(hi2c); @@ -1737,9 +1739,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress /* Check the parameters */ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -1750,7 +1752,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress /* Init tickstart for timeout management*/ tickstart = HAL_GetTick(); - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) { return HAL_TIMEOUT; } @@ -1765,9 +1767,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress hi2c->XferISR = NULL; /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -1782,7 +1784,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress } /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); @@ -1796,9 +1798,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress do { /* Wait until TXIS flag is set */ - if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -1813,15 +1815,15 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress hi2c->XferCount--; hi2c->XferSize--; - if((hi2c->XferSize == 0U) && (hi2c->XferCount!=0U)) + if ((hi2c->XferSize == 0U) && (hi2c->XferCount != 0U)) { /* Wait until TCR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); @@ -1833,13 +1835,14 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress } } - }while(hi2c->XferCount > 0U); + } + while (hi2c->XferCount > 0U); /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ - /* Wait until STOPF flag is reset */ - if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -1889,9 +1892,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, /* Check the parameters */ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -1902,7 +1905,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, /* Init tickstart for timeout management*/ tickstart = HAL_GetTick(); - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) { return HAL_TIMEOUT; } @@ -1917,9 +1920,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, hi2c->XferISR = NULL; /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -1935,7 +1938,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, /* Send Slave Address */ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ); @@ -1949,7 +1952,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, do { /* Wait until RXNE flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } @@ -1959,15 +1962,15 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, hi2c->XferSize--; hi2c->XferCount--; - if((hi2c->XferSize == 0U) && (hi2c->XferCount != 0U)) + if ((hi2c->XferSize == 0U) && (hi2c->XferCount != 0U)) { /* Wait until TCR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); @@ -1978,13 +1981,14 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); } } - }while(hi2c->XferCount > 0U); + } + while (hi2c->XferCount > 0U); /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ - /* Wait until STOPF flag is reset */ - if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -2033,14 +2037,14 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr /* Check the parameters */ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -2060,8 +2064,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr hi2c->XferCount = Size; hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->XferISR = I2C_Master_ISR_IT; - - if(hi2c->XferCount > MAX_NBYTE_SIZE) + + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -2073,9 +2077,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr } /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -2090,12 +2094,12 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr } /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ - I2C_TransferConfig(hi2c,DevAddress, hi2c->XferSize, xfermode, I2C_NO_STARTSTOP); + I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_NO_STARTSTOP); /* Process Unlocked */ - __HAL_UNLOCK(hi2c); + __HAL_UNLOCK(hi2c); - /* Note : The I2C interrupts must be enabled after unlocking current process + /* Note : The I2C interrupts must be enabled after unlocking current process to avoid the risk of I2C interrupt handle execution before current process unlock */ @@ -2132,14 +2136,14 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre /* Check the parameters */ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -2154,13 +2158,17 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre hi2c->Mode = HAL_I2C_MODE_MEM; hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + /* Prepare transfer parameters */ + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->XferISR = I2C_Master_ISR_IT; - - if(hi2c->XferCount > MAX_NBYTE_SIZE) + + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -2172,9 +2180,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre } /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -2189,7 +2197,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre } /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ - I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -2230,14 +2238,14 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd /* Check the parameters */ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -2257,8 +2265,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd hi2c->XferCount = Size; hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->XferISR = I2C_Master_ISR_DMA; - - if(hi2c->XferCount > MAX_NBYTE_SIZE) + + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -2270,9 +2278,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd } /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -2346,14 +2354,14 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr /* Check the parameters */ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -2374,7 +2382,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->XferISR = I2C_Master_ISR_DMA; - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -2386,9 +2394,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr } /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -2416,7 +2424,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize); /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ - I2C_TransferConfig(hi2c,DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); /* Update XferCount value */ hi2c->XferCount -= hi2c->XferSize; @@ -2458,9 +2466,9 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd __IO uint32_t I2C_Trials = 0U; - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } @@ -2474,16 +2482,16 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd do { /* Generate Start */ - hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode,DevAddress); + hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress); /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ /* Wait until STOPF flag is set or a NACK flag is set*/ tickstart = HAL_GetTick(); - while((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) && (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET) && (hi2c->State != HAL_I2C_STATE_TIMEOUT)) + while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) && (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET) && (hi2c->State != HAL_I2C_STATE_TIMEOUT)) { - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + if (Timeout != HAL_MAX_DELAY) + { + if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) { /* Device is ready */ hi2c->State = HAL_I2C_STATE_READY; @@ -2491,14 +2499,14 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd __HAL_UNLOCK(hi2c); return HAL_TIMEOUT; } - } + } } /* Check if the NACKF flag has not been set */ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET) { - /* Wait until STOPF flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } @@ -2517,7 +2525,7 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd else { /* Wait until STOPF flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } @@ -2535,8 +2543,8 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd /* Generate Stop */ hi2c->Instance->CR2 |= I2C_CR2_STOP; - /* Wait until STOPF flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) { return HAL_TIMEOUT; } @@ -2544,7 +2552,8 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd /* Clear STOP Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); } - }while(I2C_Trials < Trials); + } + while (I2C_Trials < Trials); hi2c->State = HAL_I2C_STATE_READY; @@ -2579,7 +2588,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Check the parameters */ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -2595,7 +2604,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, hi2c->XferISR = I2C_Master_ISR_IT; /* If size > MAX_NBYTE_SIZE, use reload mode */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -2606,6 +2615,13 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, xfermode = hi2c->XferOptions; } + /* If transfer direction not change, do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) + { + xferrequest = I2C_NO_STARTSTOP; + } + /* Send Slave Address and set NBYTES to write */ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, xferrequest); @@ -2645,7 +2661,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, /* Check the parameters */ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -2661,7 +2677,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, hi2c->XferISR = I2C_Master_ISR_IT; /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -2672,8 +2688,15 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, xfermode = hi2c->XferOptions; } + /* If transfer direction not change, do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) + { + xferrequest = I2C_NO_STARTSTOP; + } + /* Send Slave Address and set NBYTES to read */ - I2C_TransferConfig(hi2c,DevAddress, hi2c->XferSize, xfermode, xferrequest); + I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, xferrequest); /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -2706,9 +2729,9 @@ HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Check the parameters */ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); - if((hi2c->State & HAL_I2C_STATE_LISTEN) == HAL_I2C_STATE_LISTEN) + if ((hi2c->State & HAL_I2C_STATE_LISTEN) == HAL_I2C_STATE_LISTEN) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -2718,10 +2741,10 @@ HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Process Locked */ __HAL_LOCK(hi2c); - + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ /* and then toggle the HAL slave RX state to TX state */ - if(hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) { /* Disable associated Interrupts */ I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); @@ -2741,11 +2764,11 @@ HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Slave_ISR_IT; - if(I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) + if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) { /* Clear ADDR flag after prepare the transfer parameters */ /* This action will generate an acknowledge to the Master */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); } /* Process Unlocked */ @@ -2780,9 +2803,9 @@ HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, u /* Check the parameters */ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); - if((hi2c->State & HAL_I2C_STATE_LISTEN) == HAL_I2C_STATE_LISTEN) + if ((hi2c->State & HAL_I2C_STATE_LISTEN) == HAL_I2C_STATE_LISTEN) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -2792,15 +2815,15 @@ HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, u /* Process Locked */ __HAL_LOCK(hi2c); - + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ /* and then toggle the HAL slave TX state to RX state */ - if(hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) { /* Disable associated Interrupts */ I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); } - + hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; hi2c->Mode = HAL_I2C_MODE_SLAVE; hi2c->ErrorCode = HAL_I2C_ERROR_NONE; @@ -2815,11 +2838,11 @@ HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, u hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Slave_ISR_IT; - if(I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) + if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) { /* Clear ADDR flag after prepare the transfer parameters */ /* This action will generate an acknowledge to the Master */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); } /* Process Unlocked */ @@ -2847,7 +2870,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, u */ HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) { - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { hi2c->State = HAL_I2C_STATE_LISTEN; hi2c->XferISR = I2C_Slave_ISR_IT; @@ -2875,7 +2898,7 @@ HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) uint32_t tmp; /* Disable Address listen mode only if a transfer is not ongoing */ - if(hi2c->State == HAL_I2C_STATE_LISTEN) + if (hi2c->State == HAL_I2C_STATE_LISTEN) { tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK; hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode); @@ -2904,7 +2927,7 @@ HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) */ HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) { - if(hi2c->Mode == HAL_I2C_MODE_MASTER) + if (hi2c->Mode == HAL_I2C_MODE_MASTER) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -2923,7 +2946,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevA /* Process Unlocked */ __HAL_UNLOCK(hi2c); - /* Note : The I2C interrupts must be enabled after unlocking current process + /* Note : The I2C interrupts must be enabled after unlocking current process to avoid the risk of I2C interrupt handle execution before current process unlock */ I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); @@ -2944,7 +2967,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevA /** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks * @{ - */ + */ /** * @brief This function handles I2C event interrupt request. @@ -2958,6 +2981,13 @@ void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) uint32_t itflags = READ_REG(hi2c->Instance->ISR); uint32_t itsources = READ_REG(hi2c->Instance->CR1); + /* I2C events treatment -------------------------------------*/ + if (hi2c->XferISR != NULL) + { + hi2c->XferISR(hi2c, itflags, itsources); + uint32_t itflags = READ_REG(hi2c->Instance->ISR); + uint32_t itsources = READ_REG(hi2c->Instance->CR1); + /* I2C events treatment -------------------------------------*/ if(hi2c->XferISR != NULL) { @@ -2977,7 +3007,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) uint32_t itsources = READ_REG(hi2c->Instance->CR1); /* I2C Bus error interrupt occurred ------------------------------------*/ - if(((itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERRI) != RESET)) + if (((itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERRI) != RESET)) { hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; @@ -2986,7 +3016,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) } /* I2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/ - if(((itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERRI) != RESET)) + if (((itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERRI) != RESET)) { hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; @@ -2995,7 +3025,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) } /* I2C Arbitration Loss error interrupt occurred -------------------------------------*/ - if(((itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERRI) != RESET)) + if (((itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERRI) != RESET)) { hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; @@ -3004,7 +3034,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) } /* Call the Error Callback in case of Error detected */ - if((hi2c->ErrorCode & (HAL_I2C_ERROR_BERR | HAL_I2C_ERROR_OVR | HAL_I2C_ERROR_ARLO)) != HAL_I2C_ERROR_NONE) + if ((hi2c->ErrorCode & (HAL_I2C_ERROR_BERR | HAL_I2C_ERROR_OVR | HAL_I2C_ERROR_ARLO)) != HAL_I2C_ERROR_NONE) { I2C_ITError(hi2c, hi2c->ErrorCode); } @@ -3077,8 +3107,8 @@ __weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) * @brief Slave Address Match callback. * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. - * @param TransferDirection: Master request Transfer Direction (Write/Read), value of @ref I2C_XFERDIRECTION - * @param AddrMatchCode: Address Match Code + * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XFERDIRECTION + * @param AddrMatchCode Address Match Code * @retval None */ __weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) @@ -3228,7 +3258,7 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) /** * @} - */ + */ /** * @} @@ -3246,14 +3276,14 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) * @param ITSources Interrupt sources enabled. * @retval HAL status */ -static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) +static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) { uint16_t devaddress = 0U; /* Process Locked */ __HAL_LOCK(hi2c); - if(((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET)) + if (((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET)) { /* Clear NACK Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); @@ -3266,27 +3296,27 @@ static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uin /* Flush TX register */ I2C_Flush_TXDR(hi2c); } - else if(((ITFlags & I2C_FLAG_RXNE) != RESET) && ((ITSources & I2C_IT_RXI) != RESET)) + else if (((ITFlags & I2C_FLAG_RXNE) != RESET) && ((ITSources & I2C_IT_RXI) != RESET)) { /* Read data from RXDR */ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR; hi2c->XferSize--; hi2c->XferCount--; } - else if(((ITFlags & I2C_FLAG_TXIS) != RESET) && ((ITSources & I2C_IT_TXI) != RESET)) + else if (((ITFlags & I2C_FLAG_TXIS) != RESET) && ((ITSources & I2C_IT_TXI) != RESET)) { /* Write data to TXDR */ hi2c->Instance->TXDR = (*hi2c->pBuffPtr++); hi2c->XferSize--; - hi2c->XferCount--; + hi2c->XferCount--; } - else if(((ITFlags & I2C_FLAG_TCR) != RESET) && ((ITSources & I2C_IT_TCI) != RESET)) + else if (((ITFlags & I2C_FLAG_TCR) != RESET) && ((ITSources & I2C_IT_TCI) != RESET)) { - if((hi2c->XferSize == 0U) && (hi2c->XferCount != 0U)) + if ((hi2c->XferSize == 0U) && (hi2c->XferCount != 0U)) { devaddress = (hi2c->Instance->CR2 & I2C_CR2_SADD); - - if(hi2c->XferCount > MAX_NBYTE_SIZE) + + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; I2C_TransferConfig(hi2c, devaddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); @@ -3294,7 +3324,7 @@ static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uin else { hi2c->XferSize = hi2c->XferCount; - if(hi2c->XferOptions != I2C_NO_OPTION_FRAME) + if (hi2c->XferOptions != I2C_NO_OPTION_FRAME) { I2C_TransferConfig(hi2c, devaddress, hi2c->XferSize, hi2c->XferOptions, I2C_NO_STARTSTOP); } @@ -3307,7 +3337,7 @@ static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uin else { /* Call TxCpltCallback() if no stop mode is set */ - if(I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) { /* Call I2C Master Sequential complete process */ I2C_ITMasterSequentialCplt(hi2c); @@ -3320,14 +3350,14 @@ static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uin } } } - else if(((ITFlags & I2C_FLAG_TC) != RESET) && ((ITSources & I2C_IT_TCI) != RESET)) + else if (((ITFlags & I2C_FLAG_TC) != RESET) && ((ITSources & I2C_IT_TCI) != RESET)) { - if(hi2c->XferCount == 0U) + if (hi2c->XferCount == 0U) { - if(I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) { /* Generate a stop condition in case of no transfer option */ - if(hi2c->XferOptions == I2C_NO_OPTION_FRAME) + if (hi2c->XferOptions == I2C_NO_OPTION_FRAME) { /* Generate Stop */ hi2c->Instance->CR2 |= I2C_CR2_STOP; @@ -3347,7 +3377,7 @@ static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uin } } - if(((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET)) + if (((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET)) { /* Call I2C Master complete process */ I2C_ITMasterCplt(hi2c, ITFlags); @@ -3367,26 +3397,26 @@ static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uin * @param ITSources Interrupt sources enabled. * @retval HAL status */ -static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) +static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) { /* Process locked */ __HAL_LOCK(hi2c); - - if(((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET)) + + if (((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET)) { /* Check that I2C transfer finished */ /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ /* Mean XferCount == 0*/ /* So clear Flag NACKF only */ - if(hi2c->XferCount == 0U) + if (hi2c->XferCount == 0U) { - if(((hi2c->XferOptions == I2C_FIRST_AND_LAST_FRAME) || (hi2c->XferOptions == I2C_LAST_FRAME)) && \ - (hi2c->State == HAL_I2C_STATE_LISTEN)) + if (((hi2c->XferOptions == I2C_FIRST_AND_LAST_FRAME) || (hi2c->XferOptions == I2C_LAST_FRAME)) && \ + (hi2c->State == HAL_I2C_STATE_LISTEN)) { /* Call I2C Listen complete process */ I2C_ITListenCplt(hi2c, ITFlags); } - else if((hi2c->XferOptions != I2C_NO_OPTION_FRAME) && (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)) + else if ((hi2c->XferOptions != I2C_NO_OPTION_FRAME) && (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)) { /* Clear NACK Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); @@ -3414,9 +3444,9 @@ static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint hi2c->ErrorCode |= HAL_I2C_ERROR_AF; } } - else if(((ITFlags & I2C_FLAG_RXNE) != RESET) && ((ITSources & I2C_IT_RXI) != RESET)) + else if (((ITFlags & I2C_FLAG_RXNE) != RESET) && ((ITSources & I2C_IT_RXI) != RESET)) { - if(hi2c->XferCount > 0U) + if (hi2c->XferCount > 0U) { /* Read data from RXDR */ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR; @@ -3424,24 +3454,24 @@ static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint hi2c->XferCount--; } - if((hi2c->XferCount == 0U) && \ - (hi2c->XferOptions != I2C_NO_OPTION_FRAME)) + if ((hi2c->XferCount == 0U) && \ + (hi2c->XferOptions != I2C_NO_OPTION_FRAME)) { /* Call I2C Slave Sequential complete process */ I2C_ITSlaveSequentialCplt(hi2c); } } - else if(((ITFlags & I2C_FLAG_ADDR) != RESET) && ((ITSources & I2C_IT_ADDRI) != RESET)) + else if (((ITFlags & I2C_FLAG_ADDR) != RESET) && ((ITSources & I2C_IT_ADDRI) != RESET)) { I2C_ITAddrCplt(hi2c, ITFlags); } - else if(((ITFlags & I2C_FLAG_TXIS) != RESET) && ((ITSources & I2C_IT_TXI) != RESET)) + else if (((ITFlags & I2C_FLAG_TXIS) != RESET) && ((ITSources & I2C_IT_TXI) != RESET)) { /* Write data to TXDR only if XferCount not reach "0" */ /* A TXIS flag can be set, during STOP treatment */ /* Check if all Datas have already been sent */ /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ - if(hi2c->XferCount > 0U) + if (hi2c->XferCount > 0U) { /* Write data to TXDR */ hi2c->Instance->TXDR = (*hi2c->pBuffPtr++); @@ -3450,7 +3480,7 @@ static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint } else { - if((hi2c->XferOptions == I2C_NEXT_FRAME) || (hi2c->XferOptions == I2C_FIRST_FRAME)) + if ((hi2c->XferOptions == I2C_NEXT_FRAME) || (hi2c->XferOptions == I2C_FIRST_FRAME)) { /* Last Byte is Transmitted */ /* Call I2C Slave Sequential complete process */ @@ -3460,7 +3490,7 @@ static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint } /* Check if STOPF is set */ - if(((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET)) + if (((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET)) { /* Call I2C Slave complete process */ I2C_ITSlaveCplt(hi2c, ITFlags); @@ -3480,7 +3510,7 @@ static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint * @param ITSources Interrupt sources enabled. * @retval HAL status */ -static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) +static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) { uint16_t devaddress = 0U; uint32_t xfermode = 0U; @@ -3488,7 +3518,7 @@ static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, ui /* Process Locked */ __HAL_LOCK(hi2c); - if(((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET)) + if (((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET)) { /* Clear NACK Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); @@ -3504,18 +3534,18 @@ static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, ui /* Flush TX register */ I2C_Flush_TXDR(hi2c); } - else if(((ITFlags & I2C_FLAG_TCR) != RESET) && ((ITSources & I2C_IT_TCI) != RESET)) + else if (((ITFlags & I2C_FLAG_TCR) != RESET) && ((ITSources & I2C_IT_TCI) != RESET)) { /* Disable TC interrupt */ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_TCI); - - if(hi2c->XferCount != 0U) + + if (hi2c->XferCount != 0U) { /* Recover Slave address */ devaddress = (hi2c->Instance->CR2 & I2C_CR2_SADD); /* Prepare the new XferSize to transfer */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; xfermode = I2C_RELOAD_MODE; @@ -3533,7 +3563,7 @@ static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, ui hi2c->XferCount -= hi2c->XferSize; /* Enable DMA Request */ - if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + if (hi2c->State == HAL_I2C_STATE_BUSY_RX) { hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; } @@ -3554,6 +3584,11 @@ static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, ui /* Call I2C Master complete process */ I2C_ITMasterCplt(hi2c, ITFlags); } + else if (((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET)) + { + /* Call I2C Master complete process */ + I2C_ITMasterCplt(hi2c, ITFlags); + } /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -3569,18 +3604,18 @@ static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, ui * @param ITSources Interrupt sources enabled. * @retval HAL status */ -static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) +static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) { /* Process locked */ __HAL_LOCK(hi2c); - - if(((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET)) + + if (((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET)) { /* Check that I2C transfer finished */ /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ /* Mean XferCount == 0 */ /* So clear Flag NACKF only */ - if(I2C_GET_DMA_REMAIN_DATA(hi2c) == 0U) + if (I2C_GET_DMA_REMAIN_DATA(hi2c) == 0U) { /* Clear NACK Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); @@ -3595,12 +3630,12 @@ static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uin hi2c->ErrorCode |= HAL_I2C_ERROR_AF; } } - else if(((ITFlags & I2C_FLAG_ADDR) != RESET) && ((ITSources & I2C_IT_ADDRI) != RESET)) + else if (((ITFlags & I2C_FLAG_ADDR) != RESET) && ((ITSources & I2C_IT_ADDRI) != RESET)) { /* Clear ADDR flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); } - else if(((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET)) + else if (((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET)) { /* Call I2C Slave complete process */ I2C_ITSlaveCplt(hi2c, ITFlags); @@ -3626,12 +3661,12 @@ static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uin */ static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) { - I2C_TransferConfig(hi2c,DevAddress,MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); + I2C_TransferConfig(hi2c, DevAddress, MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); /* Wait until TXIS flag is set */ - if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -3642,7 +3677,7 @@ static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_ } /* If Memory address size is 8Bit */ - if(MemAddSize == I2C_MEMADD_SIZE_8BIT) + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) { /* Send Memory Address */ hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); @@ -3654,9 +3689,9 @@ static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_ hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); /* Wait until TXIS flag is set */ - if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -3665,18 +3700,18 @@ static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_ return HAL_TIMEOUT; } } - + /* Send LSB of Memory Address */ hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); } /* Wait until TCR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK) { return HAL_TIMEOUT; } -return HAL_OK; + return HAL_OK; } /** @@ -3693,12 +3728,12 @@ return HAL_OK; */ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) { - I2C_TransferConfig(hi2c,DevAddress,MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE); + I2C_TransferConfig(hi2c, DevAddress, MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE); /* Wait until TXIS flag is set */ - if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -3709,7 +3744,7 @@ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t } /* If Memory address size is 8Bit */ - if(MemAddSize == I2C_MEMADD_SIZE_8BIT) + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) { /* Send Memory Address */ hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); @@ -3721,9 +3756,9 @@ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); /* Wait until TXIS flag is set */ - if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { return HAL_ERROR; } @@ -3732,17 +3767,17 @@ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t return HAL_TIMEOUT; } } - + /* Send LSB of Memory Address */ hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); } /* Wait until TC flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK) + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK) { return HAL_TIMEOUT; } - + return HAL_OK; } @@ -3763,7 +3798,7 @@ static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) UNUSED(ITFlags); /* In case of Listen state, need to inform upper layer of address match code event */ - if((hi2c->State & HAL_I2C_STATE_LISTEN) == HAL_I2C_STATE_LISTEN) + if ((hi2c->State & HAL_I2C_STATE_LISTEN) == HAL_I2C_STATE_LISTEN) { transferdirection = I2C_GET_DIR(hi2c); slaveaddrcode = I2C_GET_ADDR_MATCH(hi2c); @@ -3771,19 +3806,19 @@ static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) ownadd2code = I2C_GET_OWN_ADDRESS2(hi2c); /* If 10bits addressing mode is selected */ - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) { - if((slaveaddrcode & SlaveAddr_MSK) == ((ownadd1code >> SlaveAddr_SHIFT) & SlaveAddr_MSK)) + if ((slaveaddrcode & SlaveAddr_MSK) == ((ownadd1code >> SlaveAddr_SHIFT) & SlaveAddr_MSK)) { slaveaddrcode = ownadd1code; hi2c->AddrEventCount++; - if(hi2c->AddrEventCount == 2U) + if (hi2c->AddrEventCount == 2U) { /* Reset Address Event counter */ hi2c->AddrEventCount = 0U; /* Clear ADDR flag */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -3885,7 +3920,7 @@ static void I2C_ITSlaveSequentialCplt(I2C_HandleTypeDef *hi2c) /* Reset I2C handle mode */ hi2c->Mode = HAL_I2C_MODE_NONE; - if(hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) { /* Remove HAL_I2C_STATE_SLAVE_BUSY_TX, keep only HAL_I2C_STATE_LISTEN */ hi2c->State = HAL_I2C_STATE_LISTEN; @@ -3901,7 +3936,7 @@ static void I2C_ITSlaveSequentialCplt(I2C_HandleTypeDef *hi2c) HAL_I2C_SlaveTxCpltCallback(hi2c); } - else if(hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) { /* Remove HAL_I2C_STATE_SLAVE_BUSY_RX, keep only HAL_I2C_STATE_LISTEN */ hi2c->State = HAL_I2C_STATE_LISTEN; @@ -3937,7 +3972,7 @@ static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) hi2c->XferISR = NULL; hi2c->XferOptions = I2C_NO_OPTION_FRAME; - if((ITFlags & I2C_FLAG_AF) != RESET) + if ((ITFlags & I2C_FLAG_AF) != RESET) { /* Clear NACK Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); @@ -3950,16 +3985,16 @@ static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) I2C_Flush_TXDR(hi2c); /* Disable Interrupts */ - I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT| I2C_XFER_RX_IT); + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_RX_IT); /* Call the corresponding callback to inform upper layer of End of Transfer */ - if((hi2c->ErrorCode != HAL_I2C_ERROR_NONE) || (hi2c->State == HAL_I2C_STATE_ABORT)) + if ((hi2c->ErrorCode != HAL_I2C_ERROR_NONE) || (hi2c->State == HAL_I2C_STATE_ABORT)) { /* Call the corresponding callback to inform upper layer of End of Transfer */ I2C_ITError(hi2c, hi2c->ErrorCode); } /* hi2c->State == HAL_I2C_STATE_BUSY_TX */ - else if(hi2c->State == HAL_I2C_STATE_BUSY_TX) + else if (hi2c->State == HAL_I2C_STATE_BUSY_TX) { hi2c->State = HAL_I2C_STATE_READY; @@ -3985,7 +4020,7 @@ static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) } } /* hi2c->State == HAL_I2C_STATE_BUSY_RX */ - else if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX) { hi2c->State = HAL_I2C_STATE_READY; @@ -4022,7 +4057,7 @@ static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); /* Clear ADDR flag */ - __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR); + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); /* Disable all interrupts */ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT | I2C_XFER_RX_IT); @@ -4037,26 +4072,26 @@ static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) I2C_Flush_TXDR(hi2c); /* If a DMA is ongoing, Update handle size context */ - if(((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) || - ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)) + if (((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) || + ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)) { hi2c->XferCount = I2C_GET_DMA_REMAIN_DATA(hi2c); } /* All data are not transferred, so set error code accordingly */ - if(hi2c->XferCount != 0U) + if (hi2c->XferCount != 0U) { /* Set ErrorCode corresponding to a Non-Acknowledge */ hi2c->ErrorCode |= HAL_I2C_ERROR_AF; } /* Store Last receive data if any */ - if(((ITFlags & I2C_FLAG_RXNE) != RESET)) + if (((ITFlags & I2C_FLAG_RXNE) != RESET)) { /* Read data from RXDR */ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR; - if((hi2c->XferSize > 0U)) + if ((hi2c->XferSize > 0U)) { hi2c->XferSize--; hi2c->XferCount--; @@ -4070,19 +4105,19 @@ static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) hi2c->Mode = HAL_I2C_MODE_NONE; hi2c->XferISR = NULL; - if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE) { /* Call the corresponding callback to inform upper layer of End of Transfer */ I2C_ITError(hi2c, hi2c->ErrorCode); /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ - if(hi2c->State == HAL_I2C_STATE_LISTEN) + if (hi2c->State == HAL_I2C_STATE_LISTEN) { /* Call I2C Listen complete process */ I2C_ITListenCplt(hi2c, ITFlags); } } - else if(hi2c->XferOptions != I2C_NO_OPTION_FRAME) + else if (hi2c->XferOptions != I2C_NO_OPTION_FRAME) { hi2c->XferOptions = I2C_NO_OPTION_FRAME; hi2c->State = HAL_I2C_STATE_READY; @@ -4094,7 +4129,7 @@ static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) HAL_I2C_ListenCpltCallback(hi2c); } /* Call the corresponding callback to inform upper layer of End of Transfer */ - else if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX) { hi2c->State = HAL_I2C_STATE_READY; @@ -4132,12 +4167,12 @@ static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) hi2c->XferISR = NULL; /* Store Last receive data if any */ - if(((ITFlags & I2C_FLAG_RXNE) != RESET)) + if (((ITFlags & I2C_FLAG_RXNE) != RESET)) { /* Read data from RXDR */ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR; - if((hi2c->XferSize > 0U)) + if ((hi2c->XferSize > 0U)) { hi2c->XferSize--; hi2c->XferCount--; @@ -4177,9 +4212,9 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode) hi2c->ErrorCode |= ErrorCode; /* Disable Interrupts */ - if((hi2c->State == HAL_I2C_STATE_LISTEN) || - (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) || - (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) + if ((hi2c->State == HAL_I2C_STATE_LISTEN) || + (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) || + (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) { /* Disable all interrupts, except interrupts related to LISTEN state */ I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_TX_IT); @@ -4196,7 +4231,7 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode) /* If state is an abort treatment on goind, don't change state */ /* This change will be do later */ - if(hi2c->State != HAL_I2C_STATE_ABORT) + if (hi2c->State != HAL_I2C_STATE_ABORT) { /* Set HAL_I2C_STATE_READY */ hi2c->State = HAL_I2C_STATE_READY; @@ -4206,7 +4241,7 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode) } /* Abort DMA TX transfer if any */ - if((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) { hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; @@ -4218,14 +4253,14 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode) __HAL_UNLOCK(hi2c); /* Abort DMA TX */ - if(HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) { /* Call Directly XferAbortCallback function in case of error */ hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); } } /* Abort DMA RX transfer if any */ - else if((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + else if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) { hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; @@ -4237,13 +4272,13 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode) __HAL_UNLOCK(hi2c); /* Abort DMA RX */ - if(HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) { /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */ hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); } } - else if(hi2c->State == HAL_I2C_STATE_ABORT) + else if (hi2c->State == HAL_I2C_STATE_ABORT) { hi2c->State = HAL_I2C_STATE_READY; @@ -4272,13 +4307,13 @@ static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c) { /* If a pending TXIS flag is set */ /* Write a dummy data in TXDR to clear it */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET) { - hi2c->Instance->TXDR = 0x00U; + hi2c->Instance->TXDR = 0x00U; } /* Flush TX register if not empty */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) { __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE); } @@ -4291,13 +4326,13 @@ static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c) */ static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) { - I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Disable DMA Request */ hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; /* If last transfer, enable STOP interrupt */ - if(hi2c->XferCount == 0U) + if (hi2c->XferCount == 0U) { /* Enable STOP interrupt */ I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); @@ -4309,7 +4344,7 @@ static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) hi2c->pBuffPtr += hi2c->XferSize; /* Set the XferSize to transfer */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; } @@ -4348,13 +4383,13 @@ static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma) */ static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) { - I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Disable DMA Request */ hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; /* If last transfer, enable STOP interrupt */ - if(hi2c->XferCount == 0U) + if (hi2c->XferCount == 0U) { /* Enable STOP interrupt */ I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); @@ -4366,7 +4401,7 @@ static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) hi2c->pBuffPtr += hi2c->XferSize; /* Set the XferSize to transfer */ - if(hi2c->XferCount > MAX_NBYTE_SIZE) + if (hi2c->XferCount > MAX_NBYTE_SIZE) { hi2c->XferSize = MAX_NBYTE_SIZE; } @@ -4405,7 +4440,7 @@ static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma) */ static void I2C_DMAError(DMA_HandleTypeDef *hdma) { - I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Disable Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; @@ -4417,12 +4452,12 @@ static void I2C_DMAError(DMA_HandleTypeDef *hdma) /** * @brief DMA I2C communication abort callback * (To be called at end of DMA Abort procedure). - * @param hdma: DMA handle. + * @param hdma DMA handle. * @retval None */ static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) { - I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Disable Acknowledge */ hi2c->Instance->CR2 |= I2C_CR2_NACK; @@ -4432,10 +4467,10 @@ static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) hi2c->hdmarx->XferAbortCallback = NULL; /* Check if come from abort from user */ - if(hi2c->State == HAL_I2C_STATE_ABORT) + if (hi2c->State == HAL_I2C_STATE_ABORT) { hi2c->State = HAL_I2C_STATE_READY; - + /* Call the corresponding callback to inform upper layer of End of Transfer */ HAL_I2C_AbortCpltCallback(hi2c); } @@ -4458,14 +4493,14 @@ static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) */ static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) { - while(__HAL_I2C_GET_FLAG(hi2c, Flag) == Status) + while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status) { /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + if (Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) + if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) { - hi2c->State= HAL_I2C_STATE_READY; + hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; /* Process Unlocked */ @@ -4487,21 +4522,21 @@ static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uin */ static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) { - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET) + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET) { /* Check if a NACK is detected */ - if(I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) { return HAL_ERROR; } /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + if (Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - Tickstart) > Timeout)) + if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) { hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->State= HAL_I2C_STATE_READY; + hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; /* Process Unlocked */ @@ -4524,19 +4559,19 @@ static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, */ static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) { - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) { /* Check if a NACK is detected */ - if(I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) { return HAL_ERROR; } /* Check for the Timeout */ - if((Timeout == 0U)||((HAL_GetTick() - Tickstart) > Timeout)) + if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) { hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->State= HAL_I2C_STATE_READY; + hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; /* Process Unlocked */ @@ -4558,16 +4593,16 @@ static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, */ static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) { - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) { /* Check if a NACK is detected */ - if(I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) { return HAL_ERROR; } /* Check if a STOPF is detected */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) { /* Clear STOP Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); @@ -4576,7 +4611,7 @@ static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, I2C_RESET_CR2(hi2c); hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - hi2c->State= HAL_I2C_STATE_READY; + hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; /* Process Unlocked */ @@ -4586,10 +4621,10 @@ static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, } /* Check for the Timeout */ - if((Timeout == 0U)||((HAL_GetTick() - Tickstart) > Timeout)) + if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) { hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->State= HAL_I2C_STATE_READY; + hi2c->State = HAL_I2C_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -4610,18 +4645,18 @@ static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, */ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) { - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) { /* Wait until STOP Flag is reset */ /* AutoEnd should be initiate after AF */ - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) { /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + if (Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - Tickstart) > Timeout)) + if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) { - hi2c->State= HAL_I2C_STATE_READY; + hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; /* Process Unlocked */ @@ -4644,7 +4679,7 @@ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32 I2C_RESET_CR2(hi2c); hi2c->ErrorCode = HAL_I2C_ERROR_AF; - hi2c->State= HAL_I2C_STATE_READY; + hi2c->State = HAL_I2C_STATE_READY; hi2c->Mode = HAL_I2C_MODE_NONE; /* Process Unlocked */ @@ -4676,25 +4711,14 @@ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32 */ static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request) { - uint32_t tmpreg = 0U; - /* Check the parameters */ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); assert_param(IS_TRANSFER_MODE(Mode)); assert_param(IS_TRANSFER_REQUEST(Request)); - /* Get the CR2 register value */ - tmpreg = hi2c->Instance->CR2; - - /* clear tmpreg specific bits */ - tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)); - - /* update tmpreg */ - tmpreg |= (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << 16 ) & I2C_CR2_NBYTES) | \ - (uint32_t)Mode | (uint32_t)Request); - /* update CR2 register */ - hi2c->Instance->CR2 = tmpreg; + MODIFY_REG(hi2c->Instance->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP)), \ + (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request)); } /** @@ -4708,6 +4732,79 @@ static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t Interr { uint32_t tmpisr = 0U; + if ((hi2c->XferISR == I2C_Master_ISR_DMA) || \ + (hi2c->XferISR == I2C_Slave_ISR_DMA)) + { + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + { + /* Enable ERR, STOP, NACK and ADDR interrupts */ + tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + + if ((InterruptRequest & I2C_XFER_ERROR_IT) == I2C_XFER_ERROR_IT) + { + /* Enable ERR and NACK interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI; + } + + if ((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) + { + /* Enable STOP interrupts */ + tmpisr |= I2C_IT_STOPI; + } + + if ((InterruptRequest & I2C_XFER_RELOAD_IT) == I2C_XFER_RELOAD_IT) + { + /* Enable TC interrupts */ + tmpisr |= I2C_IT_TCI; + } + } + else + { + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + { + /* Enable ERR, STOP, NACK, and ADDR interrupts */ + tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + + if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) + { + /* Enable ERR, TC, STOP, NACK and RXI interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI; + } + + if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) + { + /* Enable ERR, TC, STOP, NACK and TXI interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI; + } + + if ((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) + { + /* Enable STOP interrupts */ + tmpisr |= I2C_IT_STOPI; + } + } + + /* Enable interrupts only at the end */ + /* to avoid the risk of I2C interrupt handle execution before */ + /* all interrupts requested done */ + __HAL_I2C_ENABLE_IT(hi2c, tmpisr); + + return HAL_OK; +} + +/** + * @brief Manage the disabling of Interrupts. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param InterruptRequest Value of @ref I2C_Interrupt_configuration_definition. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest) +{ + uint32_t tmpisr = 0U; + if((hi2c->XferISR == I2C_Master_ISR_DMA) || \ (hi2c->XferISR == I2C_Slave_ISR_DMA)) { @@ -4781,49 +4878,49 @@ static HAL_StatusTypeDef I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t Inter { uint32_t tmpisr = 0U; - if((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) + if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) { /* Disable TC and TXI interrupts */ tmpisr |= I2C_IT_TCI | I2C_IT_TXI; - if((hi2c->State & HAL_I2C_STATE_LISTEN) != HAL_I2C_STATE_LISTEN) + if ((hi2c->State & HAL_I2C_STATE_LISTEN) != HAL_I2C_STATE_LISTEN) { /* Disable NACK and STOP interrupts */ tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; } } - if((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) + if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) { /* Disable TC and RXI interrupts */ tmpisr |= I2C_IT_TCI | I2C_IT_RXI; - if((hi2c->State & HAL_I2C_STATE_LISTEN) != HAL_I2C_STATE_LISTEN) + if ((hi2c->State & HAL_I2C_STATE_LISTEN) != HAL_I2C_STATE_LISTEN) { /* Disable NACK and STOP interrupts */ tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; } } - if((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) { /* Disable ADDR, NACK and STOP interrupts */ tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; } - if((InterruptRequest & I2C_XFER_ERROR_IT) == I2C_XFER_ERROR_IT) + if ((InterruptRequest & I2C_XFER_ERROR_IT) == I2C_XFER_ERROR_IT) { /* Enable ERR and NACK interrupts */ tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI; } - if((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) + if ((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) { /* Enable STOP interrupts */ tmpisr |= I2C_IT_STOPI; } - - if((InterruptRequest & I2C_XFER_RELOAD_IT) == I2C_XFER_RELOAD_IT) + + if ((InterruptRequest & I2C_XFER_RELOAD_IT) == I2C_XFER_RELOAD_IT) { /* Enable TC interrupts */ tmpisr |= I2C_IT_TCI; diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.h index f59537c028..66f5ded5fb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_i2c.h * @author MCD Application Team - * @version $VERSION$ - * @date $DATE$ * @brief Header file of I2C HAL module. ****************************************************************************** * @attention @@ -40,11 +38,11 @@ #define __STM32L0xx_HAL_I2C_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ -#include "stm32l0xx_hal_def.h" +#include "stm32l0xx_hal_def.h" /** @addtogroup STM32L0xx_HAL_Driver * @{ @@ -52,7 +50,7 @@ /** @addtogroup I2C * @{ - */ + */ /* Exported types ------------------------------------------------------------*/ /** @defgroup I2C_Exported_Types I2C Exported Types @@ -60,13 +58,13 @@ */ /** @defgroup I2C_Configuration_Structure_definition I2C Configuration Structure definition - * @brief I2C Configuration Structure definition + * @brief I2C Configuration Structure definition * @{ */ typedef struct { uint32_t Timing; /*!< Specifies the I2C_TIMINGR_register value. - This parameter calculated by referring to I2C initialization + This parameter calculated by referring to I2C initialization section in Reference manual */ uint32_t OwnAddress1; /*!< Specifies the first device own address. @@ -90,9 +88,9 @@ typedef struct uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. This parameter can be a value of @ref I2C_NOSTRETCH_MODE */ -}I2C_InitTypeDef; +} I2C_InitTypeDef; -/** +/** * @} */ @@ -122,7 +120,7 @@ typedef struct * 0 : Ready (no Tx operation ongoing)\n * 1 : Busy (Tx operation ongoing) * @{ - */ + */ typedef enum { HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ @@ -139,7 +137,7 @@ typedef enum HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ -}HAL_I2C_StateTypeDef; +} HAL_I2C_StateTypeDef; /** * @} @@ -170,9 +168,9 @@ typedef enum HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ -}HAL_I2C_ModeTypeDef; +} HAL_I2C_ModeTypeDef; -/** +/** * @} */ @@ -213,7 +211,7 @@ typedef struct __I2C_HandleTypeDef __IO uint32_t PreviousState; /*!< I2C communication Previous state */ - HAL_StatusTypeDef (*XferISR)(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); /*!< I2C transfer IRQ handler function pointer */ + HAL_StatusTypeDef(*XferISR)(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); /*!< I2C transfer IRQ handler function pointer */ DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ @@ -227,8 +225,10 @@ typedef struct __I2C_HandleTypeDef __IO uint32_t ErrorCode; /*!< I2C Error code */ + __IO uint32_t ErrorCode; /*!< I2C Error code */ + __IO uint32_t AddrEventCount; /*!< I2C Address Event counter */ -}I2C_HandleTypeDef; +} I2C_HandleTypeDef; /** * @} */ @@ -313,7 +313,7 @@ typedef struct __I2C_HandleTypeDef /** * @} */ - + /** @defgroup I2C_XFERDIRECTION I2C Transfer Direction Master Point of View * @{ */ @@ -337,9 +337,9 @@ typedef struct __I2C_HandleTypeDef * @{ */ #define I2C_NO_STARTSTOP (0x00000000U) -#define I2C_GENERATE_STOP I2C_CR2_STOP -#define I2C_GENERATE_START_READ (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN) -#define I2C_GENERATE_START_WRITE I2C_CR2_START +#define I2C_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP) +#define I2C_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) +#define I2C_GENERATE_START_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) /** * @} */ @@ -431,7 +431,7 @@ typedef struct __I2C_HandleTypeDef * @retval None */ #define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__))) - + /** @brief Check whether the specified I2C interrupt source is enabled or not. * @param __HANDLE__ specifies the I2C Handle. * @param __INTERRUPT__ specifies the I2C interrupt source to check. @@ -506,7 +506,7 @@ typedef struct __I2C_HandleTypeDef #define __HAL_I2C_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) /** @brief Generate a Non-Acknowledge I2C peripheral in Slave mode. - * @param __HANDLE__: specifies the I2C Handle. + * @param __HANDLE__ specifies the I2C Handle. * @retval None */ #define __HAL_I2C_GENERATE_NACK(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR2, I2C_CR2_NACK)) @@ -527,7 +527,7 @@ typedef struct __I2C_HandleTypeDef */ /* Initialization and de-initialization functions******************************/ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); -HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c); void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); /** @@ -538,7 +538,7 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); * @{ */ /* IO operation functions ****************************************************/ - /******* Blocking mode: Polling */ +/******* Blocking mode: Polling */ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); @@ -547,7 +547,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); - /******* Non-Blocking mode: Interrupt */ +/******* Non-Blocking mode: Interrupt */ HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); @@ -563,7 +563,7 @@ HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); - /******* Non-Blocking mode: DMA */ +/******* Non-Blocking mode: DMA */ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); @@ -604,11 +604,11 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); /** * @} - */ + */ /** * @} - */ + */ /* Private constants ---------------------------------------------------------*/ /** @defgroup I2C_Private_Constants I2C Private Constants @@ -617,7 +617,10 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); /** * @} - */ + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2C_Private_Macro I2C Private Macros /* Private macros ------------------------------------------------------------*/ /** @defgroup I2C_Private_Macro I2C Private Macros @@ -683,6 +686,70 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); * @} */ +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ + +#define IS_I2C_ADDRESSING_MODE(MODE) (((MODE) == I2C_ADDRESSINGMODE_7BIT) || \ + ((MODE) == I2C_ADDRESSINGMODE_10BIT)) + +#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) + +#define IS_I2C_OWN_ADDRESS2_MASK(MASK) (((MASK) == I2C_OA2_NOMASK) || \ + ((MASK) == I2C_OA2_MASK01) || \ + ((MASK) == I2C_OA2_MASK02) || \ + ((MASK) == I2C_OA2_MASK03) || \ + ((MASK) == I2C_OA2_MASK04) || \ + ((MASK) == I2C_OA2_MASK05) || \ + ((MASK) == I2C_OA2_MASK06) || \ + ((MASK) == I2C_OA2_MASK07)) + +#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ + ((CALL) == I2C_GENERALCALL_ENABLE)) + +#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ + ((STRETCH) == I2C_NOSTRETCH_ENABLE)) + +#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ + ((SIZE) == I2C_MEMADD_SIZE_16BIT)) + +#define IS_TRANSFER_MODE(MODE) (((MODE) == I2C_RELOAD_MODE) || \ + ((MODE) == I2C_AUTOEND_MODE) || \ + ((MODE) == I2C_SOFTEND_MODE)) + +#define IS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == I2C_GENERATE_STOP) || \ + ((REQUEST) == I2C_GENERATE_START_READ) || \ + ((REQUEST) == I2C_GENERATE_START_WRITE) || \ + ((REQUEST) == I2C_NO_STARTSTOP)) + +#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_NEXT_FRAME) || \ + ((REQUEST) == I2C_NEXT_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME)) + +#define I2C_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN))) + +#define I2C_GET_ADDR_MATCH(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) >> 16U) +#define I2C_GET_DIR(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) >> 16U) +#define I2C_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND) +#define I2C_GET_OWN_ADDRESS1(__HANDLE__) ((__HANDLE__)->Instance->OAR1 & I2C_OAR1_OA1) +#define I2C_GET_OWN_ADDRESS2(__HANDLE__) ((__HANDLE__)->Instance->OAR2 & I2C_OAR2_OA2) + +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x000003FFU) +#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU) + +#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U))) +#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU)))) + +#define I2C_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == I2C_ADDRESSINGMODE_7BIT) ? (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & (~I2C_CR2_RD_WRN)) : \ + (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_ADD10) | (I2C_CR2_START)) & (~I2C_CR2_RD_WRN))) +/** + * @} + */ + /* Private Functions ---------------------------------------------------------*/ /** @defgroup I2C_Private_Functions I2C Private Functions * @{ @@ -694,11 +761,11 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); /** * @} - */ + */ /** * @} - */ + */ #ifdef __cplusplus } diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c_ex.c index b76e9cb8b0..ae9c569fea 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c_ex.c @@ -2,10 +2,8 @@ ****************************************************************************** * @file stm32l0xx_hal_i2c_ex.c * @author MCD Application Team - * @version $VERSION$ - * @date $DATE$ * @brief I2C Extended HAL module driver. - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of I2C Extended peripheral: * + Extended features functions * @@ -19,7 +17,8 @@ (+) Possibility to disable or enable Analog Noise Filter (+) Use of a configured Digital Noise Filter - (+) Disable or enable wakeup from Stop mode + (+) Disable or enable wakeup from Stop mode(s) + (+) Disable or enable Fast Mode Plus ##### How to use this driver ##### ============================================================================== @@ -96,8 +95,9 @@ ##### Extended features functions ##### =============================================================================== [..] This section provides functions allowing to: - (+) Configure Noise Filters + (+) Configure Noise Filters (+) Configure Wake Up Feature + (+) Configure Fast Mode Plus @endverbatim * @{ @@ -116,7 +116,7 @@ HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -162,7 +162,7 @@ HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -200,17 +200,17 @@ HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_ } /** - * @brief Enable I2C wakeup from stop mode. + * @brief Enable I2C wakeup from Stop mode(s). * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2Cx peripheral. * @retval HAL status */ -HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp (I2C_HandleTypeDef *hi2c) +HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c) { /* Check the parameters */ assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -239,17 +239,17 @@ HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp (I2C_HandleTypeDef *hi2c) } /** - * @brief Disable I2C wakeup from stop mode. + * @brief Disable I2C wakeup from Stop mode(s). * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2Cx peripheral. * @retval HAL status */ -HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp (I2C_HandleTypeDef *hi2c) +HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c) { /* Check the parameters */ assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance)); - if(hi2c->State == HAL_I2C_STATE_READY) + if (hi2c->State == HAL_I2C_STATE_READY) { /* Process Locked */ __HAL_LOCK(hi2c); @@ -262,7 +262,7 @@ HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp (I2C_HandleTypeDef *hi2c) /* Enable wakeup from stop mode */ hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN); - __HAL_I2C_ENABLE(hi2c); + __HAL_I2C_ENABLE(hi2c); hi2c->State = HAL_I2C_STATE_READY; diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c_ex.h index e1a6983142..4d1b4b3f4f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_i2c_ex.h * @author MCD Application Team - * @version $VERSION$ - * @date $DATE$ * @brief Header file of I2C HAL Extended module. ****************************************************************************** * @attention @@ -40,7 +38,7 @@ #define __STM32L0xx_HAL_I2C_EX_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ @@ -52,7 +50,7 @@ /** @addtogroup I2CEx * @{ - */ + */ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ @@ -95,7 +93,7 @@ /** * @} - */ + */ /* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ @@ -145,7 +143,7 @@ void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus); (((__CONFIG__) & (I2C_FASTMODEPLUS_I2C3)) == I2C_FASTMODEPLUS_I2C3))) /** * @} - */ + */ /* Private Functions ---------------------------------------------------------*/ /** @defgroup I2CEx_Private_Functions I2C Extended Private Functions diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2s.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2s.c index c1c3fad6fc..57a11c94e9 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2s.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2s.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_i2s.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief I2S HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Integrated Interchip Sound (I2S) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2s.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2s.h index e8a0004e1c..1f50039fa0 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2s.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2s.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_i2s.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of I2S HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda.c index 06bd6981c2..ecf973c8b1 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda.c @@ -2,100 +2,108 @@ ****************************************************************************** * @file stm32l0xx_hal_irda.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief IRDA HAL module driver. - * - * This file provides firmware functions to manage the following - * functionalities of the IrDA (Infrared Data Association) Peripheral + * This file provides firmware functions to manage the following + * functionalities of the IrDA (Infrared Data Association) Peripheral * (IRDA) * + Initialization and de-initialization functions * + IO operation functions + * + Peripheral State and Errors functions * + Peripheral Control functions * - * - @verbatim - =============================================================================== + @verbatim + ============================================================================== ##### How to use this driver ##### - =============================================================================== - [..] + ============================================================================== + [..] The IRDA HAL driver can be used as follows: - - (#) Declare a IRDA_HandleTypeDef handle structure. - (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API: - (##) Enable the USARTx interface clock. - (##) IRDA pins configuration: - (+) Enable the clock for the IRDA GPIOs. - (+) Configure these IRDA pins as alternate function pull-up. - (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT() - and HAL_IRDA_Receive_IT() APIs): - (+) Configure the USARTx interrupt priority. - (+) Enable the NVIC USART IRQ handle. - (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA() + (#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda). + (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API + in setting the associated USART or UART in IRDA mode: + (++) Enable the USARTx/UARTx interface clock. + (++) USARTx/UARTx pins configuration: + (+++) Enable the clock for the USARTx/UARTx GPIOs. + (+++) Configure these USARTx/UARTx pins (TX as alternate function pull-up, RX as alternate function Input). + (++) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT() + and HAL_IRDA_Receive_IT() APIs): + (+++) Configure the USARTx/UARTx interrupt priority. + (+++) Enable the NVIC USARTx/UARTx IRQ handle. + (+++) The specific IRDA interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. + + (++) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA() and HAL_IRDA_Receive_DMA() APIs): - (+) Declare a DMA handle structure for the Tx/Rx channel. - (+) Enable the DMAx interface clock. - (+) Configure the declared DMA handle structure with the required Tx/Rx parameters. - (+) Configure the DMA Tx/Rx channel. - (+) Associate the initilalized DMA handle to the IRDA DMA Tx/Rx handle. - (+) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. + (+++) Declare a DMA handle structure for the Tx/Rx channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx channel. + (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. - (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler - and Mode(Receiver/Transmitter) in the hirda Init structure. + (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter), + the normal or low power mode and the clock prescaler in the hirda handle Init structure. (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API: (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) - by calling the customed HAL_IRDA_MspInit() API. - -@@- The specific IRDA interrupts (Transmission complete interrupt, - RXNE interrupt and Error Interrupts) will be managed using the macros - __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. + by calling the customized HAL_IRDA_MspInit() API. + -@@- The specific IRDA interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. + (#) Three operation modes are available within this driver : - - *** Polling mode IO operation *** - ================================= - [..] - (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit() - (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive() - - *** Interrupt mode IO operation *** - =================================== - [..] - (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT() - (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_IRDA_TxCpltCallback - (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT() - (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_IRDA_RxCpltCallback - (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_IRDA_ErrorCallback - *** DMA mode IO operation *** - ============================= - [..] - (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA() - (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_IRDA_TxCpltCallback - (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA() - (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_IRDA_RxCpltCallback - (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_IRDA_ErrorCallback + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit() + (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive() - *** IRDA HAL driver macros list *** - =================================== - [..] - Below the list of most used macros in IRDA HAL driver. - - (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral - (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral - (+) __HAL_IRDA_GET_FLAG : Checks whether the specified IRDA flag is set or not - (+) __HAL_IRDA_CLEAR_FLAG : Clears the specified IRDA pending flag - (+) __HAL_IRDA_ENABLE_IT: Enables the specified IRDA interrupt - (+) __HAL_IRDA_DISABLE_IT: Disables the specified IRDA interrupt - - (@) You can refer to the IRDA HAL driver header file for more useful macros + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non-blocking mode using HAL_IRDA_Transmit_IT() + (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode using HAL_IRDA_Receive_IT() + (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_RxCpltCallback() + (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_IRDA_ErrorCallback() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non-blocking mode (DMA) using HAL_IRDA_Transmit_DMA() + (+) At transmission half of transfer HAL_IRDA_TxHalfCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback() + (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode (DMA) using HAL_IRDA_Receive_DMA() + (+) At reception half of transfer HAL_IRDA_RxHalfCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback() + (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_RxCpltCallback() + (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_IRDA_ErrorCallback() + + *** IRDA HAL driver macros list *** + ==================================== + [..] + Below the list of most used macros in IRDA HAL driver. + + (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral + (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral + (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not + (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag + (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt + (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt + (+) __HAL_IRDA_GET_IT_SOURCE: Check whether or not the specified IRDA interrupt is enabled + + [..] + (@) You can refer to the IRDA HAL driver header file for more useful macros @endverbatim ****************************************************************************** @@ -125,8 +133,8 @@ * 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. * - ****************************************************************************** - */ + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal.h" @@ -135,96 +143,113 @@ * @{ */ +/** @defgroup IRDA IRDA + * @brief HAL IRDA module driver + * @{ + */ + #ifdef HAL_IRDA_MODULE_ENABLED -/** @addtogroup IRDA - * @brief IRDA HAL module driver - * @{ - */ - -/** @addtogroup IRDA_Private - * @{ - */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -#define TEACK_REACK_TIMEOUT 1000U -#define HAL_IRDA_TXDMA_TIMEOUTVALUE 22000U +/** @defgroup IRDA_Private_Constants IRDA Private Constants + * @{ + */ +#define IRDA_TEACK_REACK_TIMEOUT 1000U /*!< IRDA TX or RX enable acknowledge time-out value */ #define IRDA_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE \ - | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE)) -/* Private macro -------------------------------------------------------------*/ + | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE)) /*!< UART or USART CR1 fields of parameters set by IRDA_SetConfig API */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ +/** @addtogroup IRDA_Private_Functions + * @{ + */ +static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda); +static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda); +static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout); +static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda); +static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda); static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma); static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma); static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma); static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma); -static void IRDA_DMAError(DMA_HandleTypeDef *hdma); -static void IRDA_SetConfig (IRDA_HandleTypeDef *hirda); -static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda); -static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +static void IRDA_DMAError(DMA_HandleTypeDef *hdma); +static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda); static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda); static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda); /** * @} */ -/** @addtogroup IRDA_Exported_Functions + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup IRDA_Exported_Functions IRDA Exported Functions * @{ */ -/** @addtogroup IRDA_Exported_Functions_Group1 - * @brief Initialization and Configuration functions +/** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions * -@verbatim -=============================================================================== - ##### Initialization and Configuration functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to initialize the USARTx - in asynchronous IRDA mode. - (+) For the asynchronous mode only these parameters can be configured: - (++) Baud Rate - (++) Word Length - (++) 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. - (++) Power mode - (++) Prescaler setting - (++) Receiver/transmitter modes +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USARTx + in asynchronous IRDA mode. + (+) For the asynchronous mode only these parameters can be configured: + (++) Baud Rate + (++) Word Length + (++) 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. + (++) Power mode + (++) Prescaler setting + (++) Receiver/transmitter modes - [..] - The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures - (details for the procedures are available in reference manual). + [..] + The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures + (details for the procedures are available in reference manual). @endverbatim - Depending on the frame length defined by the M bit (8-bits or 9-bits) - or by the M1 and M0 bits (7-bit, 8-bit or 9-bit), - the possible IRDA frame formats are as listed in the following table: - - Table 1. IRDA frame format. - +---------------------------------------------------------------+ - | M1M0 bits | PCE bit | IRDA frame | - |-----------|-----------|---------------------------------------| - | 00 | 0 | | SB | 8-bit data | STB | | - |-----------|-----------|---------------------------------------| - | 00 | 1 | | SB | 7-bit data | PB | STB | | - |-----------|-----------|---------------------------------------| - | 01 | 0 | | SB | 9-bit data | STB | | - |-----------|-----------|---------------------------------------| - | 01 | 1 | | SB | 8-bit data | PB | STB | | - |-----------------------|---------------------------------------| - | 10 | 0 | | SB | 7-bit data | STB | | - |-----------|-----------|---------------------------------------| - | 10 | 1 | | SB | 6-bit data | PB | STB | | - +---------------------------------------------------------------+ + Depending on the frame length defined by the M1 and M0 bits (7-bit, + 8-bit or 9-bit), the possible IRDA frame formats are listed in the + following table. + + Table 1. IRDA frame format. + +-----------------------------------------------------------------------+ + | M1 bit | M0 bit | PCE bit | IRDA frame | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 0 | | SB | 8 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 0 | | SB | 9 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 0 | | SB | 7 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + +-----------------------------------------------------------------------+ * @{ */ /** - * @brief Initializes the IRDA mode according to the specified - * parameters in the IRDA_InitTypeDef and creates the associated handle . - * @param hirda: IRDA handle + * @brief Initialize the IRDA mode according to the specified + * parameters in the IRDA_InitTypeDef and initialize the associated handle. + * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda) @@ -238,42 +263,46 @@ HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda) /* Check the USART/UART associated to the IRDA handle */ assert_param(IS_IRDA_INSTANCE(hirda->Instance)); - if(hirda->State == HAL_IRDA_STATE_RESET) + if(hirda->gState == HAL_IRDA_STATE_RESET) { /* Allocate lock resource and initialize it */ hirda->Lock = HAL_UNLOCKED; - /* Init the low level hardware : GPIO, CLOCK, CORTEX */ + /* Init the low level hardware : GPIO, CLOCK */ HAL_IRDA_MspInit(hirda); } - hirda->State = HAL_IRDA_STATE_BUSY; + hirda->gState = HAL_IRDA_STATE_BUSY; /* Disable the Peripheral to update the configuration registers */ __HAL_IRDA_DISABLE(hirda); /* Set the IRDA Communication parameters */ - IRDA_SetConfig(hirda); + if (IRDA_SetConfig(hirda) == HAL_ERROR) + { + return HAL_ERROR; + } - /* In IRDA mode, the following bits must be kept cleared: + /* 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.*/ - hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP); - hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL); + CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP)); + CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); /* set the UART/USART in IRDA mode */ - hirda->Instance->CR3 |= USART_CR3_IREN; + hirda->Instance->CR3 |= USART_CR3_IREN; /* Enable the Peripheral */ __HAL_IRDA_ENABLE(hirda); - /* TEACK and/or REACK to check before moving hirda->State to Ready */ + /* TEACK and/or REACK to check before moving hirda->gState and hirda->RxState to Ready */ return (IRDA_CheckIdleState(hirda)); } /** - * @brief DeInitializes the IRDA peripheral - * @param hirda: IRDA handle + * @brief DeInitialize the IRDA peripheral. + * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda) @@ -287,7 +316,7 @@ HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda) /* Check the USART/UART associated to the IRDA handle */ assert_param(IS_IRDA_INSTANCE(hirda->Instance)); - hirda->State = HAL_IRDA_STATE_BUSY; + hirda->gState = HAL_IRDA_STATE_BUSY; /* DeInit the low level hardware */ HAL_IRDA_MspDeInit(hirda); @@ -295,212 +324,270 @@ HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda) __HAL_IRDA_DISABLE(hirda); hirda->ErrorCode = HAL_IRDA_ERROR_NONE; - hirda->State = HAL_IRDA_STATE_RESET; + hirda->gState = HAL_IRDA_STATE_RESET; + hirda->RxState = HAL_IRDA_STATE_RESET; - /* Release Lock */ + /* Process Unlock */ __HAL_UNLOCK(hirda); return HAL_OK; } /** - * @brief IRDA MSP Init - * @param hirda: IRDA handle + * @brief Initialize the IRDA MSP. + * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval None */ - __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda) +__weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda) { /* Prevent unused argument(s) compilation warning */ UNUSED(hirda); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_IRDA_MspInit could be implented in the user file - */ + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_IRDA_MspInit can be implemented in the user file + */ } /** - * @brief IRDA MSP DeInit - * @param hirda: IRDA handle + * @brief DeInitialize the IRDA MSP. + * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval None */ - __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda) +__weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda) { /* Prevent unused argument(s) compilation warning */ UNUSED(hirda); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_IRDA_MspDeInit could be implented in the user file - */ + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_IRDA_MspDeInit can be implemented in the user file + */ } /** * @} */ -/** @addtogroup IRDA_Exported_Functions_Group2 - * @brief IRDA Transmit-Receive functions +/** @defgroup IRDA_Exported_Functions_Group2 IO operation functions + * @brief IRDA Transmit and Receive functions * -@verbatim -=============================================================================== +@verbatim + =============================================================================== ##### IO operation functions ##### -=============================================================================== - [..] - This subsection provides a set of functions allowing to manage the IRDA asynchronous - data transfers. + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the IRDA data transfers. - (#) There are two modes of transfer: - (++) Blocking mode: the communication is performed in polling mode. - The HAL status of all data processing is returned by the same function - after finishing transfer. - (++) No-Blocking mode: the communication is performed using Interrupts - or DMA, these API's return the HAL status. - The end of the data processing will be indicated through the - dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when - using DMA mode. - The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks - will be executed respectivelly at the end of the Transmit or Receive process - The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected + [..] + 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. - (#) Blocking mode API's are : + (#) There are two mode of transfer: + (++) Blocking mode: the communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) Non-Blocking mode: the communication is performed using Interrupts + or DMA, these API's return the HAL status. + The end of the data processing will be indicated through the + dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks + will be executed respectively at the end of the Transmit or Receive process + The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected + + (#) Blocking mode APIs are : (++) HAL_IRDA_Transmit() - (++) HAL_IRDA_Receive() - - (#) Non-Blocking mode API's with Interrupt are : + (++) HAL_IRDA_Receive() + + (#) Non Blocking mode APIs with Interrupt are : (++) HAL_IRDA_Transmit_IT() (++) HAL_IRDA_Receive_IT() (++) HAL_IRDA_IRQHandler() - (++) IRDA_Transmit_IT() - (++) IRDA_Receive_IT() - (#) Non-Blocking mode functions with DMA are : + (#) Non Blocking mode functions with DMA are : (++) HAL_IRDA_Transmit_DMA() (++) HAL_IRDA_Receive_DMA() + (++) HAL_IRDA_DMAPause() + (++) HAL_IRDA_DMAResume() + (++) HAL_IRDA_DMAStop() - (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: + (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode: + (++) HAL_IRDA_TxHalfCpltCallback() (++) HAL_IRDA_TxCpltCallback() + (++) HAL_IRDA_RxHalfCpltCallback() (++) HAL_IRDA_RxCpltCallback() (++) HAL_IRDA_ErrorCallback() - + + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (+) HAL_IRDA_Abort() + (+) HAL_IRDA_AbortTransmit() + (+) HAL_IRDA_AbortReceive() + (+) HAL_IRDA_Abort_IT() + (+) HAL_IRDA_AbortTransmit_IT() + (+) HAL_IRDA_AbortReceive_IT() + + (#) For Abort services based on interrupts (HAL_IRDA_Abortxxx_IT), a set of Abort Complete Callbacks are provided: + (+) HAL_IRDA_AbortCpltCallback() + (+) HAL_IRDA_AbortTransmitCpltCallback() + (+) HAL_IRDA_AbortReceiveCpltCallback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, + and HAL_IRDA_ErrorCallback() user callback is executed. Transfer is kept ongoing on IRDA side. + If user wants to abort it, Abort services should be called by user. + (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, and HAL_IRDA_ErrorCallback() user callback is executed. + @endverbatim * @{ */ /** - * @brief Send an amount of data in blocking mode - * @param hirda: IRDA handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent - * @param Timeout: Duration of the timeout + * @brief Send an amount of data in blocking mode. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer. + * @param Size Amount of data to be sent. + * @param Timeout Specify timeout value. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) { - uint16_t* tmp; - - if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX)) + uint16_t* tmp; + uint32_t tickstart = 0; + + /* Check that a Tx process is not already ongoing */ + if(hirda->gState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { - return HAL_ERROR; + return HAL_ERROR; } - + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((hirda->Init.WordLength == UART_WORDLENGTH_9B) && (hirda->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(hirda); - hirda->ErrorCode = HAL_IRDA_ERROR_NONE; - if(hirda->State == HAL_IRDA_STATE_BUSY_RX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; - } - else - { - hirda->State = HAL_IRDA_STATE_BUSY_TX; - } - + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->gState = HAL_IRDA_STATE_BUSY_TX; + + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + hirda->TxXferSize = Size; hirda->TxXferCount = Size; while(hirda->TxXferCount > 0U) { hirda->TxXferCount--; - if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } + if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) - { - tmp = (uint16_t*) pData; - hirda->Instance->TDR = (*tmp & (uint16_t)0x01FFU); - pData +=2; - } - else - { - hirda->Instance->TDR = (*pData++ & (uint8_t)0xFFU); - } - } - - if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } - - if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) - { - hirda->State = HAL_IRDA_STATE_BUSY_RX; + { + tmp = (uint16_t*) pData; + hirda->Instance->TDR = (*tmp & (uint16_t)0x01FFU); + pData += 2; + } + else + { + hirda->Instance->TDR = (*pData++ & (uint8_t)0xFFU); + } } - else + + if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) { - hirda->State = HAL_IRDA_STATE_READY; - } - + return HAL_TIMEOUT; + } + + /* At end of Tx process, restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(hirda); - + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Receive an amount of data in blocking mode - * @param hirda: IRDA handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received - * @param Timeout: Duration of the timeout + * @brief Receive an amount of data in blocking mode. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer. + * @param Size Amount of data to be received. + * @param Timeout Specify timeout value. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ +{ uint16_t* tmp; uint16_t uhMask; - - if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX)) - { - if((pData == NULL) || (Size == 0U)) + uint32_t tickstart = 0; + + /* Check that a Rx process is not already ongoing */ + if(hirda->RxState == HAL_IRDA_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) { - return HAL_ERROR; + return HAL_ERROR; } - + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be received from RDR will be + handled through a u16 cast. */ + if ((hirda->Init.WordLength == UART_WORDLENGTH_9B) && (hirda->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(hirda); - hirda->ErrorCode = HAL_IRDA_ERROR_NONE; - if(hirda->State == HAL_IRDA_STATE_BUSY_TX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; - } - else - { - hirda->State = HAL_IRDA_STATE_BUSY_RX; - } - - hirda->RxXferSize = Size; + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->RxState = HAL_IRDA_STATE_BUSY_RX; + + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + + hirda->RxXferSize = Size; hirda->RxXferCount = Size; - /* Computation of the mask to apply to the RDR register + /* Computation of the mask to apply to RDR register of the UART associated to the IRDA */ IRDA_MASK_COMPUTATION(hirda); uhMask = hirda->Mask; @@ -510,10 +597,10 @@ HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, ui { hirda->RxXferCount--; - if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) - { + if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { return HAL_TIMEOUT; - } + } if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) { tmp = (uint16_t*) pData ; @@ -522,496 +609,1020 @@ HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, ui } else { - *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); - } - } + *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); + } + } + + /* At end of Rx process, restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; - if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX; - } - else - { - hirda->State = HAL_IRDA_STATE_READY; - } - /* Process Unlocked */ __HAL_UNLOCK(hirda); - + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Send an amount of data in interrupt mode - * @param hirda: IRDA handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @brief Send an amount of data in interrupt mode. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer. + * @param Size Amount of data to be sent. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) { - if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX)) + /* Check that a Tx process is not already ongoing */ + if(hirda->gState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((hirda->Init.WordLength == UART_WORDLENGTH_9B) && (hirda->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(hirda); - + hirda->pTxBuffPtr = pData; hirda->TxXferSize = Size; hirda->TxXferCount = Size; hirda->ErrorCode = HAL_IRDA_ERROR_NONE; - if(hirda->State == HAL_IRDA_STATE_BUSY_RX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; - } - else - { - hirda->State = HAL_IRDA_STATE_BUSY_TX; - } - + hirda->gState = HAL_IRDA_STATE_BUSY_TX; + /* Process Unlocked */ - __HAL_UNLOCK(hirda); - + __HAL_UNLOCK(hirda); + /* Enable the IRDA Transmit Data Register Empty Interrupt */ - __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE); - + SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Receive an amount of data in interrupt mode - * @param hirda: IRDA handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received + * @brief Receive an amount of data in interrupt mode. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer. + * @param Size Amount of data to be received. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) -{ - if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX)) +{ + /* Check that a Rx process is not already ongoing */ + if(hirda->RxState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - + /* Process Locked */ - __HAL_LOCK(hirda); - + __HAL_LOCK(hirda); + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((hirda->Init.WordLength == UART_WORDLENGTH_9B) && (hirda->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + hirda->pRxBuffPtr = pData; hirda->RxXferSize = Size; hirda->RxXferCount = Size; - - /* Computation of the mask to apply to the RDR register + + /* Computation of the mask to apply to the RDR register of the UART associated to the IRDA */ IRDA_MASK_COMPUTATION(hirda); - - hirda->ErrorCode = HAL_IRDA_ERROR_NONE; - if(hirda->State == HAL_IRDA_STATE_BUSY_TX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; - } - else - { - hirda->State = HAL_IRDA_STATE_BUSY_RX; - } - - /* Enable the IRDA Parity Error Interrupt */ - __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE); - - /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR); - + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->RxState = HAL_IRDA_STATE_BUSY_RX; + /* Process Unlocked */ __HAL_UNLOCK(hirda); - - /* Enable the IRDA Data Register not empty Interrupt */ - __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE); - + + /* Enable the IRDA Parity Error and Data Register not empty Interrupts */ + SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE| USART_CR1_RXNEIE); + + /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Send an amount of data in DMA mode - * @param hirda: IRDA handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @brief Send an amount of data in DMA mode. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData pointer to data buffer. + * @param Size amount of data to be sent. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) { - uint32_t *tmp; - - if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX)) + /* Check that a Tx process is not already ongoing */ + if(hirda->gState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((hirda->Init.WordLength == UART_WORDLENGTH_9B) && (hirda->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(hirda); - + hirda->pTxBuffPtr = pData; hirda->TxXferSize = Size; - hirda->TxXferCount = Size; - + hirda->TxXferCount = Size; + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; - - if(hirda->State == HAL_IRDA_STATE_BUSY_RX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; - } - else - { - hirda->State = HAL_IRDA_STATE_BUSY_TX; - } - + hirda->gState = HAL_IRDA_STATE_BUSY_TX; + /* Set the IRDA DMA transfer complete callback */ hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt; - + /* Set the IRDA DMA half transfer complete callback */ hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt; /* Set the DMA error callback */ hirda->hdmatx->XferErrorCallback = IRDA_DMAError; - /* Enable the IRDA transmit DMA channel */ - tmp = (uint32_t*)&pData; - HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size); - - /* Clear the TC flag in the SR register by writing 0 to it */ - __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC); + /* Set the DMA abort callback */ + hirda->hdmatx->XferAbortCallback = NULL; + + /* Enable the IRDA transmit DMA channel */ + HAL_DMA_Start_IT(hirda->hdmatx, (uint32_t)hirda->pTxBuffPtr, (uint32_t)&hirda->Instance->TDR, Size); + + /* Clear the TC flag in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF); - /* Enable the DMA transfer for transmit request by setting the DMAT bit - in the IRDA CR3 register */ - hirda->Instance->CR3 |= USART_CR3_DMAT; - /* Process Unlocked */ __HAL_UNLOCK(hirda); - + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Receive an amount of data in DMA mode - * @param hirda: IRDA handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received - * @note When the IRDA parity is enabled (PCE = 1), the received data contain - * the parity bit (MSB position) + * @brief Receive an amount of data in DMA mode. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer. + * @param Size Amount of data to be received. + * @note When the IRDA parity is enabled (PCE = 1), the received data contains + * the parity bit (MSB position). + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) { - uint32_t *tmp; - - if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX)) + /* Check that a Rx process is not already ongoing */ + if(hirda->RxState == HAL_IRDA_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((hirda->Init.WordLength == UART_WORDLENGTH_9B) && (hirda->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(hirda); - + hirda->pRxBuffPtr = pData; hirda->RxXferSize = Size; hirda->ErrorCode = HAL_IRDA_ERROR_NONE; - if(hirda->State == HAL_IRDA_STATE_BUSY_TX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; - } - else - { - hirda->State = HAL_IRDA_STATE_BUSY_RX; - } - + hirda->RxState = HAL_IRDA_STATE_BUSY_RX; + /* Set the IRDA DMA transfer complete callback */ hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt; - + /* Set the IRDA DMA half transfer complete callback */ hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt; - + /* Set the DMA error callback */ hirda->hdmarx->XferErrorCallback = IRDA_DMAError; - /* Enable the DMA channel */ - tmp = (uint32_t*)&pData; - HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size); + /* Set the DMA abort callback */ + hirda->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, (uint32_t)hirda->pRxBuffPtr, Size); + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + /* Enable the UART Parity Error Interrupt */ + SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE); + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR); - /* Enable the DMA transfer for the receiver request by setting the DMAR bit - in the IRDA CR3 register */ - hirda->Instance->CR3 |= USART_CR3_DMAR; - - /* Process Unlocked */ - __HAL_UNLOCK(hirda); - return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } + /** - * @brief Pauses the DMA Transfer. - * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains - * the configuration information for the specified IRDA module. + * @brief Pause the DMA Transfer. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda) { /* Process Locked */ __HAL_LOCK(hirda); - - if(hirda->State == HAL_IRDA_STATE_BUSY_TX) + + if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && + (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))) { - /* Disable the UART DMA Tx request */ - hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); + /* Disable the IRDA DMA Tx request */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); } - else if(hirda->State == HAL_IRDA_STATE_BUSY_RX) + if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && + (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))) { - /* Disable the UART DMA Rx request */ - hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the IRDA DMA Rx request */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); } - else if (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) - { - /* Disable the UART DMA Tx & Rx requests */ - hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); - hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); - } - + /* Process Unlocked */ __HAL_UNLOCK(hirda); - - return HAL_OK; + + return HAL_OK; } /** - * @brief Resumes the DMA Transfer. - * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains - * the configuration information for the specified UART module. + * @brief Resume the DMA Transfer. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda) { /* Process Locked */ __HAL_LOCK(hirda); - - if(hirda->State == HAL_IRDA_STATE_BUSY_TX) - { - /* Enable the UART DMA Tx request */ - hirda->Instance->CR3 |= USART_CR3_DMAT; - } - else if(hirda->State == HAL_IRDA_STATE_BUSY_RX) - { - /* Clear the Overrun flag before resumming the Rx transfer*/ - __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF); - /* Enable the UART DMA Rx request */ - hirda->Instance->CR3 |= USART_CR3_DMAR; - } - else if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) + if(hirda->gState == HAL_IRDA_STATE_BUSY_TX) { - /* Clear the Overrun flag before resumming the Rx transfer*/ - __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF); - - /* Enable the UART DMA Tx & Rx request */ - hirda->Instance->CR3 |= USART_CR3_DMAT; - hirda->Instance->CR3 |= USART_CR3_DMAR; + /* Enable the IRDA DMA Tx request */ + SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT); } - + if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX) + { + /* Clear the Overrun flag before resuming the Rx transfer*/ + __HAL_IRDA_CLEAR_OREFLAG(hirda); + + /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */ + SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE); + SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Enable the IRDA DMA Rx request */ + SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + } + /* Process Unlocked */ __HAL_UNLOCK(hirda); - + return HAL_OK; } /** - * @brief Stops the DMA Transfer. - * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains - * the configuration information for the specified UART module. + * @brief Stop the DMA Transfer. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda) { /* The Lock is not implemented on this API to allow the user application - to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback(): - when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated - and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() - */ + to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() / + HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback: + indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete + interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of + the stream and the corresponding call back is executed. */ - /* Disable the UART Tx/Rx DMA requests */ - hirda->Instance->CR3 &= ~USART_CR3_DMAT; - hirda->Instance->CR3 &= ~USART_CR3_DMAR; - - /* Abort the UART DMA tx channel */ - if(hirda->hdmatx != NULL) + /* Stop IRDA DMA Tx request if ongoing */ + if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && + (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))) { - HAL_DMA_Abort(hirda->hdmatx); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel */ + if(hirda->hdmatx != NULL) + { + HAL_DMA_Abort(hirda->hdmatx); + } + + IRDA_EndTxTransfer(hirda); } - /* Abort the UART DMA rx channel */ - if(hirda->hdmarx != NULL) + + /* Stop IRDA DMA Rx request if ongoing */ + if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && + (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))) { - HAL_DMA_Abort(hirda->hdmarx); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel */ + if(hirda->hdmarx != NULL) + { + HAL_DMA_Abort(hirda->hdmarx); + } + + IRDA_EndRxTransfer(hirda); } - - hirda->State = HAL_IRDA_STATE_READY; return HAL_OK; } /** - * @brief This function handles IRDA interrupt request. - * @param hirda: IRDA handle + * @brief Abort ongoing transfers (blocking mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the IRDA DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hirda->hdmatx); + } + } + + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hirda->hdmarx); + } + } + + /* Reset Tx and Rx transfer counters */ + hirda->TxXferCount = 0; + hirda->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Reset Handle ErrorCode to No Error */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (blocking mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* Disable the IRDA DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hirda->hdmatx); + } + } + + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (blocking mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hirda->hdmarx); + } + } + + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda) +{ + uint32_t abortcplt = 1; + + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised + before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if(hirda->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback; + } + else + { + hirda->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if(hirda->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback; + } + else + { + hirda->hdmarx->XferAbortCallback = NULL; + } + } + + /* Disable the IRDA DMA Tx request if enabled */ + if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable DMA Tx at UART level */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */ + if(hirda->hdmatx != NULL) + { + /* IRDA Tx DMA Abort callback has already been initialised : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK) + { + hirda->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0; + } + } + } + + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */ + if(hirda->hdmarx != NULL) + { + /* IRDA Rx DMA Abort callback has already been initialised : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) + { + hirda->hdmarx->XferAbortCallback = NULL; + abortcplt = 1; + } + else + { + abortcplt = 0; + } + } + } + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1) + { + /* Reset Tx and Rx transfer counters */ + hirda->TxXferCount = 0; + hirda->RxXferCount = 0; + + /* Reset errorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (Interrupt mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* Disable the IRDA DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */ + if(hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback; + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK) + { + /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */ + hirda->hdmatx->XferAbortCallback(hirda->hdmatx); + } + } + else + { + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); + } + } + else + { + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (Interrupt mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */ + if(hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) + { + /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */ + hirda->hdmarx->XferAbortCallback(hirda->hdmarx); + } + } + else + { + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); + } + } + else + { + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); + } + + return HAL_OK; +} + +/** + * @brief Handle IRDA interrupt request. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval None */ void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda) { - /* IRDA parity error interrupt occurred -------------------------------------*/ - if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_PE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE) != RESET)) - { - __HAL_IRDA_CLEAR_PEFLAG(hirda); + uint32_t isrflags = READ_REG(hirda->Instance->ISR); + uint32_t cr1its = READ_REG(hirda->Instance->CR1); + uint32_t cr3its; + uint32_t errorflags; - hirda->ErrorCode |= HAL_IRDA_ERROR_PE; - /* Set the IRDA state ready to be able to start again the process */ - hirda->State = HAL_IRDA_STATE_READY; - } - - /* IRDA frame error interrupt occured --------------------------------------*/ - if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_FE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) - { - __HAL_IRDA_CLEAR_FEFLAG(hirda); - - hirda->ErrorCode |= HAL_IRDA_ERROR_FE; - /* Set the IRDA state ready to be able to start again the process */ - hirda->State = HAL_IRDA_STATE_READY; - } - - /* IRDA noise error interrupt occured --------------------------------------*/ - if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_NE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) - { - __HAL_IRDA_CLEAR_NEFLAG(hirda); - - hirda->ErrorCode |= HAL_IRDA_ERROR_NE; - /* Set the IRDA state ready to be able to start again the process */ - hirda->State = HAL_IRDA_STATE_READY; - } - - /* IRDA Over-Run interrupt occured -----------------------------------------*/ - if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_ORE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) - { - __HAL_IRDA_CLEAR_OREFLAG(hirda); - - hirda->ErrorCode |= HAL_IRDA_ERROR_ORE; - /* Set the IRDA state ready to be able to start again the process */ - hirda->State = HAL_IRDA_STATE_READY; - } - - /* Call IRDA Error Call back function if need be --------------------------*/ - if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE) + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); + if (errorflags == RESET) { - HAL_IRDA_ErrorCallback(hirda); - } + /* IRDA in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + IRDA_Receive_IT(hirda); + return; + } + } + + /* If some errors occur */ + cr3its = READ_REG(hirda->Instance->CR3); + if( (errorflags != RESET) + && ( ((cr3its & USART_CR3_EIE) != RESET) + || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)) ) + { + /* IRDA parity error interrupt occurred -------------------------------------*/ + if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) + { + __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF); + + hirda->ErrorCode |= HAL_IRDA_ERROR_PE; + } + + /* IRDA frame error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF); + + hirda->ErrorCode |= HAL_IRDA_ERROR_FE; + } + + /* IRDA noise error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF); + + hirda->ErrorCode |= HAL_IRDA_ERROR_NE; + } + + /* IRDA Over-Run interrupt occurred -----------------------------------------*/ + if(((isrflags & USART_ISR_ORE) != RESET) && + (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) + { + __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF); + + hirda->ErrorCode |= HAL_IRDA_ERROR_ORE; + } + + /* Call IRDA Error Call back function if need be --------------------------*/ + if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE) + { + /* IRDA in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + IRDA_Receive_IT(hirda); + } + + /* If Overrun error occurs, or if any error occurs in DMA mode reception, + consider error as blocking */ + if (((hirda->ErrorCode & HAL_IRDA_ERROR_ORE) != RESET) || + (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))) + { + /* Blocking error : transfer is aborted + Set the IRDA state ready to be able to start again the process, + Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ + IRDA_EndRxTransfer(hirda); + + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel */ + if(hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback : + will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) + { + /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */ + hirda->hdmarx->XferAbortCallback(hirda->hdmarx); + } + } + else + { + /* Call user error callback */ + HAL_IRDA_ErrorCallback(hirda); + } + } + else + { + /* Call user error callback */ + HAL_IRDA_ErrorCallback(hirda); + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ + HAL_IRDA_ErrorCallback(hirda); + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ - /* IRDA in mode Receiver ---------------------------------------------------*/ - if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_RXNE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE) != RESET)) - { - IRDA_Receive_IT(hirda); - /* Clear RXNE interrupt flag */ - __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST); - } - /* IRDA in mode Transmitter ------------------------------------------------*/ - if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TXE) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE) != RESET)) + if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) { IRDA_Transmit_IT(hirda); - } + return; + } - /* IRDA in mode Transmitter (transmission end) -----------------------------*/ - if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TC) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC) != RESET)) + /* IRDA in mode Transmitter (transmission end) -----------------------------*/ + if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { IRDA_EndTransmit_IT(hirda); - } + return; + } } /** - * @brief Tx Half Transfer completed callback - * @param hirda: irda handle + * @brief Tx Transfer completed callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval None */ - __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda) +__weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda) { /* Prevent unused argument(s) compilation warning */ UNUSED(hirda); /* NOTE : This function should not be modified, when the callback is needed, - the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file - */ -} - -/** - * @brief Tx Transfer completed callback - * @param hirda: irda handle - * @retval None - */ - __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hirda); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_IRDA_TxCpltCallback can be implemented in the user file - */ -} - -/** - * @brief Rx Half Transfer completed callback - * @param hirda: irda handle - * @retval None - */ -__weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hirda); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file + the HAL_IRDA_TxCpltCallback can be implemented in the user file. */ } /** - * @brief Rx Transfer completed callback - * @param hirda: irda handle + * @brief Tx Half Transfer completed callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ +__weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval None */ __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda) @@ -1020,60 +1631,135 @@ __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda) UNUSED(hirda); /* NOTE : This function should not be modified, when the callback is needed, - the HAL_IRDA_RxCpltCallback can be implemented in the user file + the HAL_IRDA_RxCpltCallback can be implemented in the user file. */ } /** - * @brief IRDA error callback - * @param hirda: IRDA handle + * @brief Rx Half Transfer complete callback. + * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval None */ - __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda) +__weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda) { /* Prevent unused argument(s) compilation warning */ UNUSED(hirda); /* NOTE : This function should not be modified, when the callback is needed, - the HAL_IRDA_ErrorCallback can be implemented in the user file - */ + the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA error callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_ErrorCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA Abort Complete callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_AbortCpltCallback (IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA Abort Complete callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_AbortTransmitCpltCallback (IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA Abort Receive Complete callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_AbortReceiveCpltCallback (IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file. + */ } /** * @} */ -/** @addtogroup IRDA_Exported_Functions_Group3 - * @brief IRDA control functions +/** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions + * @brief IRDA State and Errors functions * -@verbatim - =============================================================================== - ##### Peripheral Control functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to control the IRDA. - (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IRDA peripheral. - (+) IRDA_SetConfig() API is used to configure the IRDA communications parameters. +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of IrDA + communication process and also return Peripheral Errors occurred during communication process + (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state + of the IRDA peripheral handle. + (+) HAL_IRDA_GetError() checks in run-time errors that could occur during + communication. + @endverbatim * @{ */ /** - * @brief return the IRDA state - * @param hirda: irda handle + * @brief Return the IRDA handle state. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval HAL state */ HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda) { - return hirda->State; + /* Return IRDA handle state */ + uint32_t temp1= 0x00, temp2 = 0x00; + temp1 = hirda->gState; + temp2 = hirda->RxState; + + return (HAL_IRDA_StateTypeDef)(temp1 | temp2); } /** -* @brief Return the IRDA error code -* @param hirda : pointer to a IRDA_HandleTypeDef structure that contains - * the configuration information for the specified IRDA. -* @retval IRDA Error Code -*/ + * @brief Return the IRDA handle error code. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval IRDA Error Code + */ uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda) { return hirda->ErrorCode; @@ -1087,192 +1773,473 @@ uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda) * @} */ -/** @addtogroup IRDA_Private +/** @defgroup IRDA_Private_Functions IRDA Private Functions * @{ */ + /** - * @brief Configure the IRDA peripheral - * @param hirda: irda handle - * @retval None + * @brief Configure the IRDA peripheral. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status */ -static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda) +static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda) { - uint32_t tmpreg = 0x00000000U; - uint32_t clocksource = 0x00000000U; - - /* Check the communication parameters */ - assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate)); + uint32_t tmpreg = 0x00000000U; + IRDA_ClockSourceTypeDef clocksource = IRDA_CLOCKSOURCE_UNDEFINED; + HAL_StatusTypeDef ret = HAL_OK; + + /* Check the communication parameters */ + assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate)); assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength)); assert_param(IS_IRDA_PARITY(hirda->Init.Parity)); assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode)); - assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler)); - assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode)); - /*-------------------------- USART CR1 Configuration -----------------------*/ - /* Configure the IRDA Word Length, Parity and transfer Mode: - Set the M bits according to hirda->Init.WordLength value - Set PCE and PS bits according to hirda->Init.Parity value - Set TE and RE bits according to hirda->Init.Mode value */ + assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler)); + assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode)); + + /*-------------------------- USART CR1 Configuration -----------------------*/ + /* Configure the IRDA Word Length, Parity and transfer Mode: + Set the M bits according to hirda->Init.WordLength value + Set PCE and PS bits according to hirda->Init.Parity value + Set TE and RE bits according to hirda->Init.Mode value */ tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ; - + MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg); - + /*-------------------------- USART CR3 Configuration -----------------------*/ MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode); - - /*-------------------------- USART GTPR Configuration ----------------------*/ - MODIFY_REG(hirda->Instance->GTPR, (uint32_t)USART_GTPR_PSC, hirda->Init.Prescaler); - - /*-------------------------- USART BRR Configuration -----------------------*/ + + /*-------------------------- USART GTPR Configuration ----------------------*/ + MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler); + + /*-------------------------- USART BRR Configuration -----------------------*/ IRDA_GETCLOCKSOURCE(hirda, clocksource); switch (clocksource) { - case IRDA_CLOCKSOURCE_PCLK1: - hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); - break; - case IRDA_CLOCKSOURCE_PCLK2: - hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); - break; - case IRDA_CLOCKSOURCE_HSI: - hirda->Instance->BRR = (uint16_t)((HSI_VALUE + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); - break; - case IRDA_CLOCKSOURCE_SYSCLK: - hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); - break; - case IRDA_CLOCKSOURCE_LSE: - hirda->Instance->BRR = (uint16_t)((LSE_VALUE + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); - break; - default: - break; - } + case IRDA_CLOCKSOURCE_PCLK1: + hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); + break; + case IRDA_CLOCKSOURCE_PCLK2: + hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); + break; + case IRDA_CLOCKSOURCE_HSI: + hirda->Instance->BRR = (uint16_t)((HSI_VALUE + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); + break; + case IRDA_CLOCKSOURCE_SYSCLK: + hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); + break; + case IRDA_CLOCKSOURCE_LSE: + hirda->Instance->BRR = (uint16_t)((LSE_VALUE + (hirda->Init.BaudRate/2U)) / hirda->Init.BaudRate); + break; + case IRDA_CLOCKSOURCE_UNDEFINED: + default: + ret = HAL_ERROR; + break; + } + + return ret; } /** - * @brief Check the IRDA Idle State - * @param hirda: IRDA handle + * @brief Check the IRDA Idle State. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval HAL status */ static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda) { + uint32_t tickstart = 0; + /* Initialize the IRDA ErrorCode */ hirda->ErrorCode = HAL_IRDA_ERROR_NONE; - + + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + /* Check if the Transmitter is enabled */ if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) { /* Wait until TEACK flag is set */ - if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) - { - hirda->State= HAL_IRDA_STATE_TIMEOUT; + if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ return HAL_TIMEOUT; - } + } } /* Check if the Receiver is enabled */ if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) { - if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) - { - hirda->State= HAL_IRDA_STATE_TIMEOUT; + /* Wait until REACK flag is set */ + if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ return HAL_TIMEOUT; - } + } } + + /* Initialize the IRDA state*/ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(hirda); - - /* Initialize the IRDA state*/ - hirda->State= HAL_IRDA_STATE_READY; - + return HAL_OK; } /** * @brief Handle IRDA Communication Timeout. - * @param hirda: IRDA handle - * @param Flag: specifies the IRDA flag to check. - * @param Status: the flag status (SET or RESET). The function is locked in a while loop as long as the flag remains set to Status. - * @param Timeout: Timeout duration + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param Flag Specifies the IRDA flag to check. + * @param Status Flag status (SET or RESET) + * @param Tickstart Tick start value + * @param Timeout Timeout duration * @retval HAL status */ -static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) { - uint32_t tickstart = 0x00U; - tickstart = HAL_GetTick(); - /* Wait until flag is set */ - if(Status == RESET) + while((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status) { - while(__HAL_IRDA_GET_FLAG(hirda, Flag) == RESET) + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout)) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); - hirda->State= HAL_IRDA_STATE_READY; + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; - /* Process Unlocked */ - __HAL_UNLOCK(hirda); - - return HAL_TIMEOUT; - } + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + return HAL_TIMEOUT; } } } + return HAL_OK; +} + + +/** + * @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* At end of Tx process, restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; +} + + +/** + * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* At end of Rx process, restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; +} + + +/** + * @brief DMA IRDA transmit process complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef*)(hdma->Parent); + + /* DMA Normal mode */ + if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) + { + hirda->TxXferCount = 0U; + + /* Disable the DMA transfer for transmit request by resetting the DMAT bit + in the IRDA CR3 register */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Enable the IRDA Transmit Complete Interrupt */ + SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE); + } + /* DMA Circular mode */ else { - while(__HAL_IRDA_GET_FLAG(hirda, Flag) != RESET) - { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); - - hirda->State= HAL_IRDA_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hirda); - - return HAL_TIMEOUT; - } - } - } + HAL_IRDA_TxCpltCallback(hirda); } - return HAL_OK; + } /** - * @brief Receive an amount of data in non blocking mode. - * Function called under interruption only, once - * interruptions have been enabled by HAL_IRDA_Transmit_IT() - * @param hirda: IRDA handle + * @brief DMA IRDA transmit process half complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef*)(hdma->Parent); + + HAL_IRDA_TxHalfCpltCallback(hirda); +} + +/** + * @brief DMA IRDA receive process complete callback. + * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef*)(hdma->Parent); + + /* DMA Normal mode */ + if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) + { + hirda->RxXferCount = 0; + + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit + in the IRDA CR3 register */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* At end of Rx process, restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + } + + HAL_IRDA_RxCpltCallback(hirda); +} + +/** + * @brief DMA IRDA receive process half complete callback. + * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef*)(hdma->Parent); + + HAL_IRDA_RxHalfCpltCallback(hirda); +} + +/** + * @brief DMA IRDA communication error callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMAError(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef*)(hdma->Parent); + + /* Stop IRDA DMA Tx request if ongoing */ + if ( (hirda->gState == HAL_IRDA_STATE_BUSY_TX) + &&(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) ) + { + hirda->TxXferCount = 0; + IRDA_EndTxTransfer(hirda); + } + + /* Stop IRDA DMA Rx request if ongoing */ + if ( (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) + &&(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) ) + { + hirda->RxXferCount = 0; + IRDA_EndRxTransfer(hirda); + } + + hirda->ErrorCode |= HAL_IRDA_ERROR_DMA; + HAL_IRDA_ErrorCallback(hirda); +} + +/** + * @brief DMA IRDA communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef*)(hdma->Parent); + hirda->RxXferCount = 0; + hirda->TxXferCount = 0; + + HAL_IRDA_ErrorCallback(hirda); +} + +/** + * @brief DMA IRDA Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef* )(hdma->Parent); + + hirda->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(hirda->hdmarx != NULL) + { + if(hirda->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hirda->TxXferCount = 0; + hirda->RxXferCount = 0; + + /* Reset errorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); +} + + +/** + * @brief DMA IRDA Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef* )(hdma->Parent); + + hirda->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(hirda->hdmatx != NULL) + { + if(hirda->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hirda->TxXferCount = 0; + hirda->RxXferCount = 0; + + /* Reset errorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); +} + + +/** + * @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to + * HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer) + * (This callback is executed at end of DMA Tx Abort procedure following user abort request, + * and leads to user Tx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = (IRDA_HandleTypeDef*)(hdma->Parent); + + hirda->TxXferCount = 0; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); +} + +/** + * @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to + * HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer) + * (This callback is executed at end of DMA Rx Abort procedure following user abort request, + * and leads to user Rx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hirda->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); +} + +/** + * @brief Send an amount of data in interrupt mode. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_IRDA_Transmit_IT(). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval HAL status */ static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) { uint16_t* tmp; - - if((hirda->State == HAL_IRDA_STATE_BUSY_TX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)) - { + /* Check that a Tx process is ongoing */ + if(hirda->gState == HAL_IRDA_STATE_BUSY_TX) + { if(hirda->TxXferCount == 0U) { /* Disable the IRDA Transmit Data Register Empty Interrupt */ - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); - - /* Enable the IRDA Transmit Complete Interrupt */ - __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); - + CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE); + + /* Enable the IRDA Transmit Complete Interrupt */ + SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE); + return HAL_OK; } else @@ -1285,9 +2252,10 @@ static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) } else { - hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFFU); + hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFFU); } hirda->TxXferCount--; + return HAL_OK; } } @@ -1296,197 +2264,81 @@ static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) return HAL_BUSY; } } + /** - * @brief Wraps up transmission in non blocking mode. - * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains - * the configuration information for the specified IRDA module. + * @brief Wrap up transmission in non-blocking mode. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval HAL status */ static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda) { - /* Disable the IRDA Transmit Complete Interrupt */ - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC); - - /* Check if a receive process is ongoing or not */ - if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) - { - hirda->State = HAL_IRDA_STATE_BUSY_RX; - } - else - { - /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); - - hirda->State = HAL_IRDA_STATE_READY; - } - + /* Disable the IRDA Transmit Complete Interrupt */ + CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE); + + /* Tx process is ended, restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + HAL_IRDA_TxCpltCallback(hirda); - + return HAL_OK; } /** - * @brief Receive an amount of data in non blocking mode. - * Function called under interruption only, once + * @brief Receive an amount of data in interrupt mode. + * @note Function is called under interruption only, once * interruptions have been enabled by HAL_IRDA_Receive_IT() - * @param hirda: IRDA handle + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. * @retval HAL status */ static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda) { uint16_t* tmp; - uint16_t uhMask = hirda->Mask; - - if ((hirda->State == HAL_IRDA_STATE_BUSY_RX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)) + uint16_t uhMask = hirda->Mask; + uint16_t uhdata; + + /* Check that a Rx process is ongoing */ + if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) { + uhdata = (uint16_t) READ_REG(hirda->Instance->RDR); if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) { tmp = (uint16_t*) hirda->pRxBuffPtr ; - *tmp = (uint16_t)(hirda->Instance->RDR & uhMask); - hirda->pRxBuffPtr +=2U; + *tmp = (uint16_t)(uhdata & uhMask); + hirda->pRxBuffPtr +=2U; } else { - *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); + *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)uhMask); } - + if(--hirda->RxXferCount == 0U) { - while(HAL_IS_BIT_SET(hirda->Instance->ISR, IRDA_FLAG_RXNE)) - { - } - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); + /* Disable the IRDA Parity Error Interrupt and RXNE interrupt */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); - /* Disable the IRDA Parity Error Interrupt */ - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); - /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; - if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX; - } - else - { - hirda->State = HAL_IRDA_STATE_READY; - } - HAL_IRDA_RxCpltCallback(hirda); - + return HAL_OK; } - + return HAL_OK; } else { - return HAL_BUSY; + /* Clear RXNE interrupt flag */ + __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST); + + return HAL_BUSY; } } - -/** - * @brief DMA IRDA Tx transfer completed callback - * @param hdma: DMA handle - * @retval None - */ -static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) -{ - IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - /* DMA Normal mode */ - if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) - { - hirda->TxXferCount = 0U; - - /* Disable the DMA transfer for transmit request by resetting the DMAT bit - in the IRDA CR3 register */ - hirda->Instance->CR3 &= ~(USART_CR3_DMAT); - - /* Enable the IRDA Transmit Complete Interrupt */ - __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); - } - /* DMA Circular mode */ - else - { - HAL_IRDA_TxCpltCallback(hirda); - } -} - -/** - * @brief DMA IRDA receive process half complete callback - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma) -{ - IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - HAL_IRDA_TxHalfCpltCallback(hirda); -} - -/** - * @brief DMA IRDA Rx Transfer completed callback - * @param hdma: DMA handle - * @retval None - */ -static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) -{ - IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - /* DMA Normal mode */ - if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) - { - hirda->RxXferCount = 0U; - - /* Disable the DMA transfer for the receiver request by setting the DMAR bit - in the IRDA CR3 register */ - hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAR); - - if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) - { - hirda->State = HAL_IRDA_STATE_BUSY_TX; - } - else - { - hirda->State = HAL_IRDA_STATE_READY; - } - } - - HAL_IRDA_RxCpltCallback(hirda); -} - -/** - * @brief DMA IRDA receive process half complete callback - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma) -{ - IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - HAL_IRDA_RxHalfCpltCallback(hirda); -} - -/** - * @brief DMA IRDA communication error callback - * @param hdma: DMA handle - * @retval None - */ -static void IRDA_DMAError(DMA_HandleTypeDef *hdma) -{ - IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - hirda->RxXferCount = 0U; - hirda->TxXferCount = 0U; - hirda->State= HAL_IRDA_STATE_READY; - hirda->ErrorCode |= HAL_IRDA_ERROR_DMA; - HAL_IRDA_ErrorCallback(hirda); -} - -/** - * @} - */ /** * @} @@ -1497,5 +2349,9 @@ static void IRDA_DMAError(DMA_HandleTypeDef *hdma) * @} */ +/** + * @} + */ + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda.h index 91f2b35663..2887d93792 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_irda.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of IRDA HAL module. ****************************************************************************** * @attention @@ -33,7 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32L0xx_HAL_IRDA_H @@ -50,18 +48,18 @@ * @{ */ -/** @defgroup IRDA IRDA - * @{ - */ - - /** @defgroup IRDA_Exported_Types IRDA Exported Types +/** @addtogroup IRDA * @{ */ -/* Exported types ------------------------------------------------------------*/ -/** - * @brief IRDA Init Structure definition - */ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Types IRDA Exported Types + * @{ + */ + +/** + * @brief IRDA Init Structure definition + */ typedef struct { uint32_t BaudRate; /*!< This member configures the IRDA communication baud rate. @@ -69,7 +67,7 @@ typedef struct Baud Rate Register = ((PCLKx) / ((hirda->Init.BaudRate))) */ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref IRDAEx_Word_Length */ + This parameter can be a value of @ref IRDA_Word_Length */ uint32_t Parity; /*!< Specifies the parity mode. This parameter can be a value of @ref IRDA_Parity @@ -77,86 +75,80 @@ typedef struct 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 Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. + + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. This parameter can be a value of @ref IRDA_Transfer_Mode */ - + uint8_t Prescaler; /*!< Specifies the Prescaler value for dividing the UART/USART source clock to achieve low-power frequency. @note Prescaler value 0 is forbidden */ - + uint16_t PowerMode; /*!< Specifies the IRDA power mode. This parameter can be a value of @ref IRDA_Low_Power */ }IRDA_InitTypeDef; -/** - * @brief HAL IRDA State structures definition - */ +/** + * @brief HAL IRDA State structures definition + * @note HAL IRDA State value is a combination of 2 different substates: gState and RxState. + * - gState contains IRDA state information related to global Handle management + * and also information related to Tx operations. + * gState value coding follow below described bitmap : + * b7-b6 Error information + * 00 : No Error + * 01 : (Not Used) + * 10 : Timeout + * 11 : Error + * b5 IP initilisation status + * 0 : Reset (IP not initialized) + * 1 : Init done (IP not initialized. HAL IRDA Init function already called) + * b4-b3 (not used) + * xx : Should be set to 00 + * b2 Intrinsic process state + * 0 : Ready + * 1 : Busy (IP busy with some configuration or internal operations) + * b1 (not used) + * x : Should be set to 0 + * b0 Tx state + * 0 : Ready (no Tx operation ongoing) + * 1 : Busy (Tx operation ongoing) + * - RxState contains information related to Rx operations. + * RxState value coding follow below described bitmap : + * b7-b6 (not used) + * xx : Should be set to 00 + * b5 IP initilisation status + * 0 : Reset (IP not initialized) + * 1 : Init done (IP not initialized) + * b4-b2 (not used) + * xxx : Should be set to 000 + * b1 Rx state + * 0 : Ready (no Rx operation ongoing) + * 1 : Busy (Rx operation ongoing) + * b0 (not used) + * x : Should be set to 0. + */ typedef enum { - HAL_IRDA_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ - HAL_IRDA_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ - HAL_IRDA_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */ - HAL_IRDA_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */ - HAL_IRDA_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ - HAL_IRDA_STATE_BUSY_TX_RX = 0x32U, /*!< Data Transmission and Reception process is ongoing */ - HAL_IRDA_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ - HAL_IRDA_STATE_ERROR = 0x04U /*!< Error */ + HAL_IRDA_STATE_RESET = 0x00U, /*!< Peripheral is not initialized + Value is allowed for gState and RxState */ + HAL_IRDA_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use + Value is allowed for gState and RxState */ + HAL_IRDA_STATE_BUSY = 0x24U, /*!< an internal process is ongoing + Value is allowed for gState only */ + HAL_IRDA_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing + Value is allowed for gState only */ + HAL_IRDA_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing + Value is allowed for RxState only */ + HAL_IRDA_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing + Not to be used for neither gState nor RxState. + Value is result of combination (Or) between gState and RxState values */ + HAL_IRDA_STATE_TIMEOUT = 0xA0U, /*!< Timeout state + Value is allowed for gState only */ + HAL_IRDA_STATE_ERROR = 0xE0U /*!< Error + Value is allowed for gState only */ }HAL_IRDA_StateTypeDef; - - - -/** - * @brief IRDA handle Structure definition - */ -typedef struct -{ - USART_TypeDef *Instance; /* IRDA registers base address */ - - IRDA_InitTypeDef Init; /* IRDA communication parameters */ - - uint8_t *pTxBuffPtr; /* Pointer to IRDA Tx transfer Buffer */ - - uint16_t TxXferSize; /* IRDA Tx Transfer size */ - - uint16_t TxXferCount; /* IRDA Tx Transfer Counter */ - - uint8_t *pRxBuffPtr; /* Pointer to IRDA Rx transfer Buffer */ - - uint16_t RxXferSize; /* IRDA Rx Transfer size */ - - uint16_t RxXferCount; /* IRDA Rx Transfer Counter */ - - uint16_t Mask; /* IRDA RX RDR register mask */ - - DMA_HandleTypeDef *hdmatx; /* IRDA Tx DMA Handle parameters */ - - DMA_HandleTypeDef *hdmarx; /* IRDA Rx DMA Handle parameters */ - - HAL_LockTypeDef Lock; /* Locking object */ - - __IO HAL_IRDA_StateTypeDef State; /* IRDA communication state */ - - __IO uint32_t ErrorCode; /* IRDA Error code */ - -}IRDA_HandleTypeDef; - /** - * @} - */ - -/** - * @brief IRDA Configuration enumeration values definition - */ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup IRDA_Exported_Constants IRDA Exported Constants - * @{ - */ - -/** - * @brief HAL IRDA Error Code definition + * @brief HAL IRDA Error Code structure definition */ #define HAL_IRDA_ERROR_NONE ((uint32_t)0x00U) /*!< No error */ @@ -164,133 +156,186 @@ typedef struct #define HAL_IRDA_ERROR_NE ((uint32_t)0x02U) /*!< Noise error */ #define HAL_IRDA_ERROR_FE ((uint32_t)0x04U) /*!< frame error */ #define HAL_IRDA_ERROR_ORE ((uint32_t)0x08U) /*!< Overrun error */ -#define HAL_IRDA_ERROR_DMA ((uint32_t)0x10U) /*!< DMA transfer error */ +#define HAL_IRDA_ERROR_DMA ((uint32_t)0x10U) /*!< DMA transfer error */ /** * @brief IRDA clock sources definition */ typedef enum { - IRDA_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ - IRDA_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ - IRDA_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ - IRDA_CLOCKSOURCE_SYSCLK = 0x04U, /*!< SYSCLK clock source */ - IRDA_CLOCKSOURCE_LSE = 0x08U /*!< LSE clock source */ + IRDA_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ + IRDA_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ + IRDA_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ + IRDA_CLOCKSOURCE_SYSCLK = 0x04U, /*!< SYSCLK clock source */ + IRDA_CLOCKSOURCE_LSE = 0x08U, /*!< LSE clock source */ + IRDA_CLOCKSOURCE_UNDEFINED = 0x10U /*!< Undefined clock source */ }IRDA_ClockSourceTypeDef; +/** + * @brief IRDA handle Structure definition + */ +typedef struct +{ + USART_TypeDef *Instance; /*!< IRDA registers base address */ + + IRDA_InitTypeDef Init; /*!< IRDA communication parameters */ + + uint8_t *pTxBuffPtr; /*!< Pointer to IRDA Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< IRDA Tx Transfer size */ + + __IO uint16_t TxXferCount; /*!< IRDA Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to IRDA Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< IRDA Rx Transfer size */ + + __IO uint16_t RxXferCount; /*!< IRDA Rx Transfer Counter */ + + uint16_t Mask; /*!< IRDA RX RDR register mask */ + + DMA_HandleTypeDef *hdmatx; /*!< IRDA Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< IRDA Rx DMA Handle parameters */ + + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_IRDA_StateTypeDef gState; /*!< IRDA state information related to global Handle management + and also related to Tx operations. + This parameter can be a value of @ref HAL_IRDA_StateTypeDef */ + + __IO HAL_IRDA_StateTypeDef RxState; /*!< IRDA state information related to Rx operations. + This parameter can be a value of @ref HAL_IRDA_StateTypeDef */ + + __IO uint32_t ErrorCode; /*!< IRDA Error code */ + +}IRDA_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Constants IRDA Exported Constants + * @{ + */ + +/** @defgroup IRDA_Word_Length IRDA Word Length + * @{ + */ +#define IRDA_WORDLENGTH_7B ((uint32_t)USART_CR1_M1) /*!< 7-bit long frame */ +#define IRDA_WORDLENGTH_8B ((uint32_t)0x00000000) /*!< 8-bit long frame */ +#define IRDA_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) /*!< 9-bit long frame */ +/** + * @} + */ + /** @defgroup IRDA_Parity IRDA Parity * @{ - */ -#define IRDA_PARITY_NONE ((uint32_t)0x0000U) -#define IRDA_PARITY_EVEN ((uint32_t)USART_CR1_PCE) -#define IRDA_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) -#define IS_IRDA_PARITY(PARITY) (((PARITY) == IRDA_PARITY_NONE) || \ - ((PARITY) == IRDA_PARITY_EVEN) || \ - ((PARITY) == IRDA_PARITY_ODD)) -/** - * @} - */ - - -/** @defgroup IRDA_Transfer_Mode IRDA transfer mode - * @{ - */ -#define IRDA_MODE_RX ((uint32_t)USART_CR1_RE) -#define IRDA_MODE_TX ((uint32_t)USART_CR1_TE) -#define IRDA_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) -#define IS_IRDA_TX_RX_MODE(MODE) ((((MODE) & (~((uint32_t)(IRDA_MODE_TX_RX)))) == (uint32_t)0x00) && ((MODE) != (uint32_t)0x00)) + */ +#define IRDA_PARITY_NONE ((uint32_t)0x00000000U) /*!< No parity */ +#define IRDA_PARITY_EVEN ((uint32_t)USART_CR1_PCE) /*!< Even parity */ +#define IRDA_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) /*!< Odd parity */ /** * @} */ -/** @defgroup IRDA_Low_Power IRDA low power +/** @defgroup IRDA_Transfer_Mode IRDA Transfer Mode * @{ */ -#define IRDA_POWERMODE_NORMAL ((uint32_t)0x0000U) -#define IRDA_POWERMODE_LOWPOWER ((uint32_t)USART_CR3_IRLP) -#define IS_IRDA_POWERMODE(MODE) (((MODE) == IRDA_POWERMODE_LOWPOWER) || \ - ((MODE) == IRDA_POWERMODE_NORMAL)) -/** - * @} - */ - - /** @defgroup IRDA_State IRDA State - * @{ - */ -#define IRDA_STATE_DISABLE ((uint32_t)0x0000U) -#define IRDA_STATE_ENABLE ((uint32_t)USART_CR1_UE) -#define IS_IRDA_STATE(STATE) (((STATE) == IRDA_STATE_DISABLE) || \ - ((STATE) == IRDA_STATE_ENABLE)) +#define IRDA_MODE_RX ((uint32_t)USART_CR1_RE) /*!< RX mode */ +#define IRDA_MODE_TX ((uint32_t)USART_CR1_TE) /*!< TX mode */ +#define IRDA_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) /*!< RX and TX mode */ /** * @} */ - /** @defgroup IRDA_Mode IRDA Mode +/** @defgroup IRDA_Low_Power IRDA Low Power * @{ - */ -#define IRDA_MODE_DISABLE ((uint32_t)0x0000U) -#define IRDA_MODE_ENABLE ((uint32_t)USART_CR3_IREN) -#define IS_IRDA_MODE(STATE) (((STATE) == IRDA_MODE_DISABLE) || \ - ((STATE) == IRDA_MODE_ENABLE)) + */ +#define IRDA_POWERMODE_NORMAL ((uint32_t)0x00000000U) /*!< IRDA normal power mode */ +#define IRDA_POWERMODE_LOWPOWER ((uint32_t)USART_CR3_IRLP) /*!< IRDA low power mode */ /** * @} */ -/** @defgroup IRDA_One_Bit IRDA One bit +/** @defgroup IRDA_State IRDA State * @{ */ -#define IRDA_ONE_BIT_SAMPLE_DISABLE ((uint32_t)0x00000000U) -#define IRDA_ONE_BIT_SAMPLE_ENABLE ((uint32_t)USART_CR3_ONEBIT) -#define IS_IRDA_ONE_BIT_SAMPLE(ONEBIT) (((ONEBIT) == IRDA_ONE_BIT_SAMPLE_DISABLE) || \ - ((ONEBIT) == IRDA_ONE_BIT_SAMPLE_ENABLE)) -/** - * @} - */ - -/** @defgroup IRDA_DMA_Tx IRDA DMA TX - * @{ - */ -#define IRDA_DMA_TX_DISABLE ((uint32_t)0x00000000U) -#define IRDA_DMA_TX_ENABLE ((uint32_t)USART_CR3_DMAT) -#define IS_IRDA_DMA_TX(DMATX) (((DMATX) == IRDA_DMA_TX_DISABLE) || \ - ((DMATX) == IRDA_DMA_TX_ENABLE)) -/** - * @} - */ - -/** @defgroup IRDA_DMA_Rx IRDA DMA RX - * @{ - */ -#define IRDA_DMA_RX_DISABLE ((uint32_t)0x0000U) -#define IRDA_DMA_RX_ENABLE ((uint32_t)USART_CR3_DMAR) -#define IS_IRDA_DMA_RX(DMARX) (((DMARX) == IRDA_DMA_RX_DISABLE) || \ - ((DMARX) == IRDA_DMA_RX_ENABLE)) +#define IRDA_STATE_DISABLE ((uint32_t)0x00000000U) /*!< IRDA disabled */ +#define IRDA_STATE_ENABLE ((uint32_t)USART_CR1_UE) /*!< IRDA enabled */ /** * @} */ - + +/** @defgroup IRDA_Mode IRDA Mode + * @{ + */ +#define IRDA_MODE_DISABLE ((uint32_t)0x00000000U) /*!< Associated UART disabled in IRDA mode */ +#define IRDA_MODE_ENABLE ((uint32_t)USART_CR3_IREN) /*!< Associated UART enabled in IRDA mode */ +/** + * @} + */ + +/** @defgroup IRDA_One_Bit IRDA One Bit Sampling + * @{ + */ +#define IRDA_ONE_BIT_SAMPLE_DISABLE ((uint32_t)0x00000000U) /*!< One-bit sampling disabled */ +#define IRDA_ONE_BIT_SAMPLE_ENABLE ((uint32_t)USART_CR3_ONEBIT) /*!< One-bit sampling enabled */ +/** + * @} + */ + +/** @defgroup IRDA_DMA_Tx IRDA DMA Tx + * @{ + */ +#define IRDA_DMA_TX_DISABLE ((uint32_t)0x00000000U) /*!< IRDA DMA TX disabled */ +#define IRDA_DMA_TX_ENABLE ((uint32_t)USART_CR3_DMAT) /*!< IRDA DMA TX enabled */ +/** + * @} + */ + +/** @defgroup IRDA_DMA_Rx IRDA DMA Rx + * @{ + */ +#define IRDA_DMA_RX_DISABLE ((uint32_t)0x00000000) /*!< IRDA DMA RX disabled */ +#define IRDA_DMA_RX_ENABLE ((uint32_t)USART_CR3_DMAR) /*!< IRDA DMA RX enabled */ +/** + * @} + */ + +/** @defgroup IRDA_Request_Parameters IRDA Request Parameters + * @{ + */ +#define IRDA_AUTOBAUD_REQUEST ((uint16_t)USART_RQR_ABRRQ) /*!< Auto-Baud Rate Request */ +#define IRDA_RXDATA_FLUSH_REQUEST ((uint16_t)USART_RQR_RXFRQ) /*!< Receive Data flush Request */ +#define IRDA_TXDATA_FLUSH_REQUEST ((uint16_t)USART_RQR_TXFRQ) /*!< Transmit data flush Request */ +/** + * @} + */ + /** @defgroup IRDA_Flags IRDA Flags * Elements values convention: 0xXXXX * - 0xXXXX : Flag mask in the ISR register * @{ */ -#define IRDA_FLAG_REACK USART_ISR_REACK /*!< Receive Enable Acknowledge Flag */ -#define IRDA_FLAG_TEACK USART_ISR_TEACK /*!< Transmit Enable Acknowledge Flag */ -#define IRDA_FLAG_BUSY USART_ISR_BUSY /*!< Busy Flag */ -#define IRDA_FLAG_ABRF USART_ISR_ABRF /*!< Auto-Baud Rate Flag */ -#define IRDA_FLAG_ABRE USART_ISR_ABRE /*!< Auto-Baud Rate Error */ -#define IRDA_FLAG_TXE USART_ISR_TXE /*!< Transmit Data Register Empty */ -#define IRDA_FLAG_TC USART_ISR_TC /*!< Transmission Complete */ -#define IRDA_FLAG_RXNE USART_ISR_RXNE /*!< Read Data Register Not Empty */ -#define IRDA_FLAG_ORE USART_ISR_ORE /*!< OverRun Error */ -#define IRDA_FLAG_NE USART_ISR_NE /*!< Noise detected Flag */ -#define IRDA_FLAG_FE USART_ISR_FE /*!< Framing Error */ -#define IRDA_FLAG_PE USART_ISR_PE /*!< Parity Error */ +#define IRDA_FLAG_REACK USART_ISR_REACK /*!< IRDA Receive enable acknowledge flag */ +#define IRDA_FLAG_TEACK USART_ISR_TEACK /*!< IRDA Transmit enable acknowledge flag */ +#define IRDA_FLAG_BUSY USART_ISR_BUSY /*!< IRDA Busy flag */ +#define IRDA_FLAG_ABRF USART_ISR_ABRF /*!< IRDA Auto baud rate flag */ +#define IRDA_FLAG_ABRE USART_ISR_ABRE /*!< IRDA Auto baud rate error */ +#define IRDA_FLAG_TXE USART_ISR_TXE /*!< IRDA Transmit data register empty */ +#define IRDA_FLAG_TC USART_ISR_TC /*!< IRDA Transmission complete */ +#define IRDA_FLAG_RXNE USART_ISR_RXNE /*!< IRDA Read data register not empty */ +#define IRDA_FLAG_ORE USART_ISR_ORE /*!< IRDA Overrun error */ +#define IRDA_FLAG_NE USART_ISR_NE /*!< IRDA Noise error */ +#define IRDA_FLAG_FE USART_ISR_FE /*!< IRDA Framing error */ +#define IRDA_FLAG_PE USART_ISR_PE /*!< IRDA Parity error */ /** * @} - */ + */ -/** @defgroup IRDA_Interrupt_definition IRDA Interrupt definition +/** @defgroup IRDA_Interrupt_definition IRDA Interrupts Definition * Elements values convention: 0000ZZZZ0XXYYYYYb * - YYYYY : Interrupt source position in the XX register (5bits) * - XX : Interrupt source register (2bits) @@ -298,16 +343,14 @@ typedef enum * - 10: CR2 register * - 11: CR3 register * - ZZZZ : Flag position in the ISR register(4bits) - * @{ - */ -#define IRDA_IT_PE ((uint16_t)0x0028U) -#define IRDA_IT_TXE ((uint16_t)0x0727U) -#define IRDA_IT_TC ((uint16_t)0x0626U) -#define IRDA_IT_RXNE ((uint16_t)0x0525U) -#define IRDA_IT_IDLE ((uint16_t)0x0424U) + * @{ + */ +#define IRDA_IT_PE ((uint16_t)0x0028U) /*!< IRDA Parity error interruption */ +#define IRDA_IT_TXE ((uint16_t)0x0727U) /*!< IRDA Transmit data register empty interruption */ +#define IRDA_IT_TC ((uint16_t)0x0626U) /*!< IRDA Transmission complete interruption */ +#define IRDA_IT_RXNE ((uint16_t)0x0525U) /*!< IRDA Read data register not empty interruption */ +#define IRDA_IT_IDLE ((uint16_t)0x0424U) /*!< IRDA Idle interruption */ - - /** Elements values convention: 000000000XXYYYYYb * - YYYYY : Interrupt source position in the XX register (5bits) * - XX : Interrupt source register (2bits) @@ -315,76 +358,60 @@ typedef enum * - 10: CR2 register * - 11: CR3 register */ -#define IRDA_IT_ERR ((uint16_t)0x0060U) +#define IRDA_IT_ERR ((uint16_t)0x0060U) /*!< IRDA Error interruption */ /** Elements values convention: 0000ZZZZ00000000b * - ZZZZ : Flag position in the ISR register(4bits) */ -#define IRDA_IT_ORE ((uint16_t)0x0300U) -#define IRDA_IT_NE ((uint16_t)0x0200U) -#define IRDA_IT_FE ((uint16_t)0x0100U) +#define IRDA_IT_ORE ((uint16_t)0x0300U) /*!< IRDA Overrun error interruption */ +#define IRDA_IT_NE ((uint16_t)0x0200U) /*!< IRDA Noise error interruption */ +#define IRDA_IT_FE ((uint16_t)0x0100U) /*!< IRDA Frame error interruption */ /** * @} */ - -/** @defgroup IRDA_IT_CLEAR_Flags IRDA Interrupt clear flag + +/** @defgroup IRDA_IT_CLEAR_Flags IRDA Interruption Clear Flags * @{ */ -#define IRDA_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ -#define IRDA_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ -#define IRDA_CLEAR_NEF USART_ICR_NCF /*!< Noise detected Clear Flag */ -#define IRDA_CLEAR_OREF USART_ICR_ORECF /*!< OverRun Error Clear Flag */ +#define IRDA_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ +#define IRDA_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ +#define IRDA_CLEAR_NEF USART_ICR_NCF /*!< Noise detected Clear Flag */ +#define IRDA_CLEAR_OREF USART_ICR_ORECF /*!< OverRun Error Clear Flag */ +#define IRDA_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ #define IRDA_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ -#define IRDA_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ /** * @} - */ + */ - - -/** @defgroup IRDA_Request_Parameters IRDA Request parameters +/** @defgroup IRDA_Interruption_Mask IRDA interruptions flags mask * @{ */ -#define IRDA_AUTOBAUD_REQUEST ((uint32_t)USART_RQR_ABRRQ) /*!< Auto-Baud Rate Request */ -#define IRDA_RXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_RXFRQ) /*!< Receive Data flush Request */ -#define IRDA_TXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_TXFRQ) /*!< Transmit data flush Request */ -#define IS_IRDA_REQUEST_PARAMETER(PARAM) (((PARAM) == IRDA_AUTOBAUD_REQUEST) || \ - ((PARAM) == IRDA_SENDBREAK_REQUEST) || \ - ((PARAM) == IRDA_MUTE_MODE_REQUEST) || \ - ((PARAM) == IRDA_RXDATA_FLUSH_REQUEST) || \ - ((PARAM) == IRDA_TXDATA_FLUSH_REQUEST)) +#define IRDA_IT_MASK ((uint16_t)0x001FU) /*!< IRDA Interruptions flags mask */ /** * @} */ - -/** @defgroup IRDA_Interruption_Mask IRDA Interruption mask - * @{ - */ -#define IRDA_IT_MASK ((uint16_t)0x001FU) -/** - * @} - */ - + /** * @} */ - -/* Exported macro ------------------------------------------------------------*/ + +/* Exported macros -----------------------------------------------------------*/ /** @defgroup IRDA_Exported_Macros IRDA Exported Macros * @{ */ -/** @brief Reset IRDA handle state - * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. +/** @brief Reset IRDA handle state. + * @param __HANDLE__: IRDA handle. * @retval None */ -#define __HAL_IRDA_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_IRDA_STATE_RESET) +#define __HAL_IRDA_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_IRDA_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_IRDA_STATE_RESET; \ + } while(0) -/** @brief Flushs the IRDA DR register +/** @brief Flush the IRDA DR register. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. * @retval None */ #define __HAL_IRDA_FLUSH_DRREGISTER(__HANDLE__) \ @@ -393,242 +420,362 @@ typedef enum SET_BIT((__HANDLE__)->Instance->RQR, IRDA_TXDATA_FLUSH_REQUEST); \ } while(0) - -/** @brief Clears the specified IRDA pending flag. +/** @brief Clear the specified IRDA pending flag. * @param __HANDLE__: specifies the IRDA Handle. * @param __FLAG__: specifies the flag to check. * This parameter can be any combination of the following values: - * @arg IRDA_CLEAR_PEF - * @arg IRDA_CLEAR_FEF - * @arg IRDA_CLEAR_NEF - * @arg IRDA_CLEAR_OREF - * @arg IRDA_CLEAR_TCF - * @arg IRDA_CLEAR_IDLEF + * @arg @ref IRDA_CLEAR_PEF + * @arg @ref IRDA_CLEAR_FEF + * @arg @ref IRDA_CLEAR_NEF + * @arg @ref IRDA_CLEAR_OREF + * @arg @ref IRDA_CLEAR_TCF + * @arg @ref IRDA_CLEAR_IDLEF * @retval None */ #define __HAL_IRDA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) - /** @brief Clear the IRDA PE pending flag. * @param __HANDLE__: specifies the IRDA Handle. * @retval None */ -#define __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG(__HANDLE__, IRDA_CLEAR_PEF) +#define __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_PEF) /** @brief Clear the IRDA FE pending flag. * @param __HANDLE__: specifies the IRDA Handle. * @retval None */ -#define __HAL_IRDA_CLEAR_FEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG(__HANDLE__, IRDA_CLEAR_FEF) +#define __HAL_IRDA_CLEAR_FEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_FEF) /** @brief Clear the IRDA NE pending flag. * @param __HANDLE__: specifies the IRDA Handle. * @retval None */ -#define __HAL_IRDA_CLEAR_NEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG(__HANDLE__, IRDA_CLEAR_NEF) +#define __HAL_IRDA_CLEAR_NEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_NEF) /** @brief Clear the IRDA ORE pending flag. * @param __HANDLE__: specifies the IRDA Handle. * @retval None */ -#define __HAL_IRDA_CLEAR_OREFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG(__HANDLE__, IRDA_CLEAR_OREF) +#define __HAL_IRDA_CLEAR_OREFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_OREF) /** @brief Clear the IRDA IDLE pending flag. * @param __HANDLE__: specifies the IRDA Handle. * @retval None */ -#define __HAL_IRDA_CLEAR_IDLEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG(__HANDLE__, IRDA_CLEAR_IDLEF) +#define __HAL_IRDA_CLEAR_IDLEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_IDLEF) /** @brief Check whether the specified IRDA flag is set or not. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. - * UART peripheral * @param __FLAG__: specifies the flag to check. * This parameter can be one of the following values: - * @arg IRDA_FLAG_REACK: Receive enable ackowledge flag - * @arg IRDA_FLAG_TEACK: Transmit enable ackowledge flag - * @arg IRDA_FLAG_BUSY: Busy flag - * @arg IRDA_FLAG_ABRF: Auto Baud rate detection flag - * @arg IRDA_FLAG_ABRE: Auto Baud rate detection error flag - * @arg IRDA_FLAG_TXE: Transmit data register empty flag - * @arg IRDA_FLAG_TC: Transmission Complete flag - * @arg IRDA_FLAG_RXNE: Receive data register not empty flag - * @arg IRDA_FLAG_IDLE: Idle Line detection flag - * @arg IRDA_FLAG_ORE: OverRun Error flag - * @arg IRDA_FLAG_NE: Noise Error flag - * @arg IRDA_FLAG_FE: Framing Error flag - * @arg IRDA_FLAG_PE: Parity Error flag + * @arg @ref IRDA_FLAG_REACK Receive enable acknowledge flag + * @arg @ref IRDA_FLAG_TEACK Transmit enable acknowledge flag + * @arg @ref IRDA_FLAG_BUSY Busy flag + * @arg @ref IRDA_FLAG_ABRF Auto Baud rate detection flag + * @arg @ref IRDA_FLAG_ABRE Auto Baud rate detection error flag + * @arg @ref IRDA_FLAG_TXE Transmit data register empty flag + * @arg @ref IRDA_FLAG_TC Transmission Complete flag + * @arg @ref IRDA_FLAG_RXNE Receive data register not empty flag + * @arg @ref IRDA_FLAG_ORE OverRun Error flag + * @arg @ref IRDA_FLAG_NE Noise Error flag + * @arg @ref IRDA_FLAG_FE Framing Error flag + * @arg @ref IRDA_FLAG_PE Parity Error flag * @retval The new state of __FLAG__ (TRUE or FALSE). */ -#define __HAL_IRDA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) +#define __HAL_IRDA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) + /** @brief Enable the specified IRDA interrupt. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. - * UART peripheral * @param __INTERRUPT__: specifies the IRDA interrupt source to enable. * This parameter can be one of the following values: - * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt - * @arg IRDA_IT_TC: Transmission complete interrupt - * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt - * @arg IRDA_IT_IDLE: Idle line detection interrupt - * @arg IRDA_IT_PE: Parity Error interrupt - * @arg IRDA_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @arg @ref IRDA_IT_TXE Transmit Data Register empty interrupt + * @arg @ref IRDA_IT_TC Transmission complete interrupt + * @arg @ref IRDA_IT_RXNE Receive Data register not empty interrupt + * @arg @ref IRDA_IT_IDLE Idle line detection interrupt + * @arg @ref IRDA_IT_PE Parity Error interrupt + * @arg @ref IRDA_IT_ERR Error interrupt(Frame error, noise error, overrun error) * @retval None */ -#define __HAL_IRDA_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 |= (1U << ((__INTERRUPT__) & IRDA_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & IRDA_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & IRDA_IT_MASK)))) +#define __HAL_IRDA_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 |= (1U << ((__INTERRUPT__) & IRDA_IT_MASK))): \ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & IRDA_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & IRDA_IT_MASK)))) /** @brief Disable the specified IRDA interrupt. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. * @param __INTERRUPT__: specifies the IRDA interrupt source to disable. * This parameter can be one of the following values: - * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt - * @arg IRDA_IT_TC: Transmission complete interrupt - * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt - * @arg IRDA_IT_IDLE: Idle line detection interrupt - * @arg IRDA_IT_PE: Parity Error interrupt - * @arg IRDA_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @arg @ref IRDA_IT_TXE Transmit Data Register empty interrupt + * @arg @ref IRDA_IT_TC Transmission complete interrupt + * @arg @ref IRDA_IT_RXNE Receive Data register not empty interrupt + * @arg @ref IRDA_IT_IDLE Idle line detection interrupt + * @arg @ref IRDA_IT_PE Parity Error interrupt + * @arg @ref IRDA_IT_ERR Error interrupt(Frame error, noise error, overrun error) * @retval None */ -#define __HAL_IRDA_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & IRDA_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & IRDA_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 &= ~ ((uint32_t)1 << ((__INTERRUPT__) & IRDA_IT_MASK)))) +#define __HAL_IRDA_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 &= ~ (1U << ((__INTERRUPT__) & IRDA_IT_MASK))): \ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 &= ~ (1U << ((__INTERRUPT__) & IRDA_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 &= ~ (1U << ((__INTERRUPT__) & IRDA_IT_MASK)))) + /** @brief Check whether the specified IRDA interrupt has occurred or not. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. * @param __IT__: specifies the IRDA interrupt source to check. * This parameter can be one of the following values: - * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt - * @arg IRDA_IT_TC: Transmission complete interrupt - * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt - * @arg IRDA_IT_IDLE: Idle line detection interrupt - * @arg IRDA_IT_ORE: OverRun Error interrupt - * @arg IRDA_IT_NE: Noise Error interrupt - * @arg IRDA_IT_FE: Framing Error interrupt - * @arg IRDA_IT_PE: Parity Error interrupt + * @arg @ref IRDA_IT_TXE Transmit Data Register empty interrupt + * @arg @ref IRDA_IT_TC Transmission complete interrupt + * @arg @ref IRDA_IT_RXNE Receive Data register not empty interrupt + * @arg @ref IRDA_IT_IDLE Idle line detection interrupt + * @arg @ref IRDA_IT_ORE OverRun Error interrupt + * @arg @ref IRDA_IT_NE Noise Error interrupt + * @arg @ref IRDA_IT_FE Framing Error interrupt + * @arg @ref IRDA_IT_PE Parity Error interrupt * @retval The new state of __IT__ (TRUE or FALSE). */ -#define __HAL_IRDA_GET_IT(__HANDLE__, __IT__) ((__HANDLE__)->Instance->ISR & ((uint32_t)1U << ((__IT__)>> 0x08U))) +#define __HAL_IRDA_GET_IT(__HANDLE__, __IT__) ((__HANDLE__)->Instance->ISR & ((uint32_t)1U << ((__IT__)>> 0x08U))) -/** @brief Check whether the specified IRDA interrupt source is enabled. +/** @brief Check whether the specified IRDA interrupt source is enabled or not. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. * @param __IT__: specifies the IRDA interrupt source to check. * This parameter can be one of the following values: - * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt - * @arg IRDA_IT_TC: Transmission complete interrupt - * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt - * @arg IRDA_IT_IDLE: Idle line detection interrupt - * @arg IRDA_IT_ORE: OverRun Error interrupt - * @arg IRDA_IT_NE: Noise Error interrupt - * @arg IRDA_IT_FE: Framing Error interrupt - * @arg IRDA_IT_PE: Parity Error interrupt + * @arg @ref IRDA_IT_TXE Transmit Data Register empty interrupt + * @arg @ref IRDA_IT_TC Transmission complete interrupt + * @arg @ref IRDA_IT_RXNE Receive Data register not empty interrupt + * @arg @ref IRDA_IT_IDLE Idle line detection interrupt + * @arg @ref IRDA_IT_ERR Framing, overrun or noise error interrupt + * @arg @ref IRDA_IT_PE Parity Error interrupt * @retval The new state of __IT__ (TRUE or FALSE). */ #define __HAL_IRDA_GET_IT_SOURCE(__HANDLE__, __IT__) ((((((uint8_t)(__IT__)) >> 5U) == 1U)? (__HANDLE__)->Instance->CR1:(((((uint8_t)(__IT__)) >> 5U) == 2U)? \ - (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & ((uint32_t)1U << (((uint16_t)(__IT__)) & IRDA_IT_MASK))) + (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & ((uint32_t)1U << (((uint16_t)(__IT__)) & IRDA_IT_MASK))) /** @brief Clear the specified IRDA ISR flag, in setting the proper ICR register flag. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. * @param __IT_CLEAR__: specifies the interrupt clear register flag that needs to be set * to clear the corresponding interrupt * This parameter can be one of the following values: - * @arg IRDA_CLEAR_PEF: Parity Error Clear Flag - * @arg IRDA_CLEAR_FEF: Framing Error Clear Flag - * @arg IRDA_CLEAR_NEF: Noise detected Clear Flag - * @arg IRDA_CLEAR_OREF: OverRun Error Clear Flag - * @arg IRDA_CLEAR_TCF: Transmission Complete Clear Flag + * @arg @ref IRDA_CLEAR_PEF Parity Error Clear Flag + * @arg @ref IRDA_CLEAR_FEF Framing Error Clear Flag + * @arg @ref IRDA_CLEAR_NEF Noise detected Clear Flag + * @arg @ref IRDA_CLEAR_OREF OverRun Error Clear Flag + * @arg @ref IRDA_CLEAR_TCF Transmission Complete Clear Flag * @retval None */ -#define __HAL_IRDA_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR |= (uint32_t)(__IT_CLEAR__)) +#define __HAL_IRDA_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) + /** @brief Set a specific IRDA request flag. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. * @param __REQ__: specifies the request flag to set * This parameter can be one of the following values: - * @arg IRDA_AUTOBAUD_REQUEST: Auto-Baud Rate Request - * @arg IRDA_RXDATA_FLUSH_REQUEST: Receive Data flush Request - * @arg IRDA_TXDATA_FLUSH_REQUEST: Transmit data flush Request + * @arg @ref IRDA_AUTOBAUD_REQUEST Auto-Baud Rate Request + * @arg @ref IRDA_RXDATA_FLUSH_REQUEST Receive Data flush Request + * @arg @ref IRDA_TXDATA_FLUSH_REQUEST Transmit data flush Request * * @retval None */ -#define __HAL_IRDA_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint32_t)(__REQ__)) +#define __HAL_IRDA_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__)) -/** @brief Enables the IRDA one bit sample method - * @param __HANDLE__: specifies the IRDA Handle. +/** @brief Enable the IRDA one bit sample method. + * @param __HANDLE__: specifies the IRDA Handle. * @retval None */ #define __HAL_IRDA_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) -/** @brief Disables the IRDA one bit sample method - * @param __HANDLE__: specifies the IRDA Handle. +/** @brief Disable the IRDA one bit sample method. + * @param __HANDLE__: specifies the IRDA Handle. * @retval None */ #define __HAL_IRDA_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT)) -/** @brief Enable UART/USART associated to IRDA Handle +/** @brief Enable UART/USART associated to IRDA Handle. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. * @retval None */ #define __HAL_IRDA_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) -/** @brief Disable UART/USART associated to IRDA Handle +/** @brief Disable UART/USART associated to IRDA Handle. * @param __HANDLE__: specifies the IRDA Handle. - * The Handle Instance which can be USART1 or USART2. * @retval None */ #define __HAL_IRDA_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) -/** @brief Ensure that IRDA Baud rate is less or equal to maximum value - * @param __BAUDRATE__: specifies the IRDA Baudrate set by the user. - * @retval True or False - */ -#define IS_IRDA_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 115201U) - -/** @brief Ensure that IRDA prescaler value is strictly larger than 0 - * @param __PRESCALER__: specifies the IRDA prescaler value set by the user. - * @retval True or False - */ -#define IS_IRDA_PRESCALER(__PRESCALER__) ((__PRESCALER__) > 0U) - -/** - * @} - */ - -/* Include IRDA HAL Extension module */ -#include "stm32l0xx_hal_irda_ex.h" - -/* Exported functions --------------------------------------------------------*/ -/** @defgroup IRDA_Exported_Functions IRDA Exported Functions - * @{ - */ - -/** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions - * @{ - */ -/* Exported functions --------------------------------------------------------*/ -/* Initialization/de-initialization methods **********************************/ -HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda); -HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda); -void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda); -void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda); /** * @} */ -/** @defgroup IRDA_Exported_Functions_Group2 IRDA IO operationfunctions +/* Private macros --------------------------------------------------------*/ +/** @defgroup IRDA_Private_Macros IRDA Private Macros * @{ */ -/* IO operation methods *******************************************************/ +/** @brief Compute the mask to apply to retrieve the received data + * according to the word length and to the parity bits activation. + * @param __HANDLE__: specifies the IRDA Handle. + * @retval None, the mask to apply to the associated UART RDR register is stored in (__HANDLE__)->Mask field. + */ +#define IRDA_MASK_COMPUTATION(__HANDLE__) \ + do { \ + if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_9B) \ + { \ + if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x01FFU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x00FFU ; \ + } \ + } \ + else if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_8B) \ + { \ + if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x00FFU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x007FU ; \ + } \ + } \ + else if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_7B) \ + { \ + if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x007FU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x003FU ; \ + } \ + } \ +} while(0) + +/** @brief Ensure that IRDA Baud rate is less or equal to maximum value. + * @param __BAUDRATE__: specifies the IRDA Baudrate set by the user. + * @retval True or False + */ +#define IS_IRDA_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 115201U) + +/** @brief Ensure that IRDA prescaler value is strictly larger than 0. + * @param __PRESCALER__: specifies the IRDA prescaler value set by the user. + * @retval True or False + */ +#define IS_IRDA_PRESCALER(__PRESCALER__) ((__PRESCALER__) > 0U) + +/** + * @brief Ensure that IRDA frame length is valid. + * @param __LENGTH__: IRDA frame length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_IRDA_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == IRDA_WORDLENGTH_7B) || \ + ((__LENGTH__) == IRDA_WORDLENGTH_8B) || \ + ((__LENGTH__) == IRDA_WORDLENGTH_9B)) + +/** + * @brief Ensure that IRDA frame parity is valid. + * @param __PARITY__: IRDA frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_IRDA_PARITY(__PARITY__) (((__PARITY__) == IRDA_PARITY_NONE) || \ + ((__PARITY__) == IRDA_PARITY_EVEN) || \ + ((__PARITY__) == IRDA_PARITY_ODD)) + +/** + * @brief Ensure that IRDA communication mode is valid. + * @param __MODE__: IRDA communication mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_IRDA_TX_RX_MODE(__MODE__) ((((__MODE__) & (~((uint32_t)(IRDA_MODE_TX_RX)))) == (uint32_t)0x00) && ((__MODE__) != (uint32_t)0x00)) + +/** + * @brief Ensure that IRDA power mode is valid. + * @param __MODE__: IRDA power mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_IRDA_POWERMODE(__MODE__) (((__MODE__) == IRDA_POWERMODE_LOWPOWER) || \ + ((__MODE__) == IRDA_POWERMODE_NORMAL)) + +/** + * @brief Ensure that IRDA state is valid. + * @param __STATE__: IRDA state mode. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_IRDA_STATE(__STATE__) (((__STATE__) == IRDA_STATE_DISABLE) || \ + ((__STATE__) == IRDA_STATE_ENABLE)) + +/** + * @brief Ensure that IRDA associated UART/USART mode is valid. + * @param __MODE__: IRDA associated UART/USART mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_IRDA_MODE(__MODE__) (((__MODE__) == IRDA_MODE_DISABLE) || \ + ((__MODE__) == IRDA_MODE_ENABLE)) + +/** + * @brief Ensure that IRDA sampling rate is valid. + * @param __ONEBIT__: IRDA sampling rate. + * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid) + */ +#define IS_IRDA_ONE_BIT_SAMPLE(__ONEBIT__) (((__ONEBIT__) == IRDA_ONE_BIT_SAMPLE_DISABLE) || \ + ((__ONEBIT__) == IRDA_ONE_BIT_SAMPLE_ENABLE)) + +/** + * @brief Ensure that IRDA DMA TX mode is valid. + * @param __DMATX__: IRDA DMA TX mode. + * @retval SET (__DMATX__ is valid) or RESET (__DMATX__ is invalid) + */ +#define IS_IRDA_DMA_TX(__DMATX__) (((__DMATX__) == IRDA_DMA_TX_DISABLE) || \ + ((__DMATX__) == IRDA_DMA_TX_ENABLE)) + +/** + * @brief Ensure that IRDA DMA RX mode is valid. + * @param __DMARX__: IRDA DMA RX mode. + * @retval SET (__DMARX__ is valid) or RESET (__DMARX__ is invalid) + */ +#define IS_IRDA_DMA_RX(__DMARX__) (((__DMARX__) == IRDA_DMA_RX_DISABLE) || \ + ((__DMARX__) == IRDA_DMA_RX_ENABLE)) + +/** + * @brief Ensure that IRDA request is valid. + * @param __PARAM__: IRDA request. + * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) + */ +#define IS_IRDA_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == IRDA_AUTOBAUD_REQUEST) || \ + ((__PARAM__) == IRDA_RXDATA_FLUSH_REQUEST) || \ + ((__PARAM__) == IRDA_TXDATA_FLUSH_REQUEST)) +/** + * @} + */ + +/* Include IRDA HAL Extended module */ +#include "stm32l0xx_hal_irda_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup IRDA_Exported_Functions IRDA Exported Functions + * @{ + */ + +/** @addtogroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda); + +/** + * @} + */ + +/** @addtogroup IRDA_Exported_Functions_Group2 IO operation functions + * @{ + */ + +/* IO operation functions *****************************************************/ HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size); @@ -638,40 +785,37 @@ HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda); HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda); HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda); +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda); + void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda); void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda); void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda); void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda); void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda); void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_AbortCpltCallback (IRDA_HandleTypeDef *hirda); +void HAL_IRDA_AbortTransmitCpltCallback (IRDA_HandleTypeDef *hirda); +void HAL_IRDA_AbortReceiveCpltCallback (IRDA_HandleTypeDef *hirda); + /** * @} */ -/** @defgroup IRDA_Exported_Functions_Group3 Peripheral Control functions +/* Peripheral Control functions ************************************************/ + +/** @addtogroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions * @{ */ -/* Peripheral State methods **************************************************/ + +/* Peripheral State and Error functions ***************************************/ HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda); -uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda); - -/** - * @} - */ - -/** - * @} - */ - -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup IRDA_Private IRDA Private - * @{ - */ -/** - * @} - */ -/**************************************************************/ +uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda); /** * @} @@ -680,6 +824,15 @@ uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda); /** * @} */ + +/** + * @} + */ + +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda_ex.h index 1c3fcb94a1..1a37b7d086 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_irda_ex.h @@ -2,13 +2,11 @@ ****************************************************************************** * @file stm32l0xx_hal_irda_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief Header file of IRDA HAL Extension module. + * @brief Header file of IRDA HAL Extended module. ****************************************************************************** * @attention - * - *

© COPYRIGHT(c) 2013 STMicroelectronics

+ * + *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -32,7 +30,7 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ @@ -50,42 +48,24 @@ * @{ */ -/** @defgroup IRDAEx IRDAEx +/** @addtogroup IRDAEx * @{ - */ + */ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ -/** @defgroup IRDAEx_Extended_Exported_Constants IRDAEx Exported Constants - * @{ - */ - -/** @defgroup IRDAEx_Word_Length IRDAEx Word length - * @{ - */ -#define IRDA_WORDLENGTH_7B ((uint32_t)USART_CR1_M1) -#define IRDA_WORDLENGTH_8B ((uint32_t)0x00000000U) -#define IRDA_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) -#define IS_IRDA_WORD_LENGTH(LENGTH) (((LENGTH) == IRDA_WORDLENGTH_7B) || \ - ((LENGTH) == IRDA_WORDLENGTH_8B) || \ - ((LENGTH) == IRDA_WORDLENGTH_9B)) -/** - * @} - */ - - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ -/** @defgroup IRDAEx_Extended_Exported_Macros IRDAEx Exported Macros +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup IRDAEx_Private_Macros IRDAEx Private Macros * @{ */ -/** @brief Reports the IRDA clock source. - * @param __HANDLE__: specifies the UART Handle - * @param __CLOCKSOURCE__ : output variable + +/** @brief Report the IRDA clock source. + * @param __HANDLE__: specifies the IRDA Handle. + * @param __CLOCKSOURCE__: output variable. * @retval IRDA clocking source, written in __CLOCKSOURCE__. */ #if defined (STM32L031xx) || defined (STM32L041xx) || defined (STM32L011xx) || defined (STM32L021xx) @@ -108,6 +88,7 @@ (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ @@ -128,6 +109,7 @@ (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ @@ -154,10 +136,11 @@ (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ - else if((__HANDLE__)->Instance == USART2) \ + else if((__HANDLE__)->Instance == USART2) \ { \ switch(__HAL_RCC_GET_USART2_SOURCE()) \ { \ @@ -174,6 +157,7 @@ (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ @@ -194,71 +178,27 @@ (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ } while(0) #endif /* (STM32L031xx) || (STM32L041xx) || (STM32L011xx) || (STM32L021xx) */ - -/** @brief Reports the mask to apply to retrieve the received data - * according to the word length and to the parity bits activation. - * @param __HANDLE__: specifies the IRDA Handle - * @retval mask to apply to USART RDR register value. - */ -#define IRDA_MASK_COMPUTATION(__HANDLE__) \ - do { \ - if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_9B) \ - { \ - if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ - { \ - (__HANDLE__)->Mask = 0x01FFU ; \ - } \ - else \ - { \ - (__HANDLE__)->Mask = 0x00FFU ; \ - } \ - } \ - else if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_8B) \ - { \ - if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ - { \ - (__HANDLE__)->Mask = 0x00FFU ; \ - } \ - else \ - { \ - (__HANDLE__)->Mask = 0x007FU ; \ - } \ - } \ - else if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_7B) \ - { \ - if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ - { \ - (__HANDLE__)->Mask = 0x007FU ; \ - } \ - else \ - { \ - (__HANDLE__)->Mask = 0x003FU ; \ - } \ - } \ -} while(0) + /** * @} */ - + /* Exported functions --------------------------------------------------------*/ -/* Initialization/de-initialization methods **********************************/ -/* IO operation methods *******************************************************/ -/* Peripheral Control methods ************************************************/ -/* Peripheral State methods **************************************************/ /** * @} - */ + */ /** * @} - */ - + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_iwdg.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_iwdg.c index cefc29a86c..6310686cd8 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_iwdg.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_iwdg.c @@ -2,37 +2,41 @@ ****************************************************************************** * @file stm32l0xx_hal_iwdg.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief IWDG HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Independent Watchdog (IWDG) peripheral: - * + Initialization and de-initialization functions + * + Initialization and Start functions * + IO operation functions - * + Peripheral State functions - * + * @verbatim ============================================================================== ##### IWDG Generic features ##### ============================================================================== - [..] + [..] (+) The IWDG can be started by either software or hardware (configurable - through option byte). + 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 is clocked by Low-Speed clock (LSI) and thus stays active even + if the main clock fails. - (+) The IWDG counter should be refreshed at regular intervals, otherwise the - watchdog generates an MCU reset when the counter reaches 0. + (+) Once the IWDG is started, the LSI is forced ON and both can not be + disabled. The counter starts counting down from the reset value (0xFFF). + When it reaches the end of count value (0x000) a reset signal is + generated (IWDG reset). + + (+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register, + the IWDG_RLR value is reloaded in the counter and the watchdog reset is + prevented. (+) 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 an IWDG - reset occurs. + in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY). + IWDGRST flag in RCC_CSR register can be used to inform when an IWDG + reset occurs. + + (+) Debug mode : When the microcontroller enters debug mode (core halted), + the IWDG counter either continues to work normally or stops, depending + on DBG_IWDG_STOP configuration bit in DBG module, accessible through + __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros [..] Min-max timeout value @32KHz (LSI): ~0.512ms / ~32.0s The IWDG timeout may vary due to LSI frequency dispersion. STM32L0xx @@ -40,46 +44,37 @@ connected internally to TIM5 CH4 input capture). The measured value can be used to have an IWDG timeout with an acceptable accuracy. - ##### How to use this driver ##### ============================================================================== - [..] - If Window option is disabled - - (+) Use IWDG using HAL_IWDG_Init() function to : - (++) Enable write access to IWDG_PR, IWDG_RLR. - (++) Configure the IWDG prescaler, counter reload value. - This reload value will be loaded in the IWDG counter each time the counter - is reloaded, then the IWDG will start counting down from this value. - (+) Use IWDG using HAL_IWDG_Start() function to : - (++) Reload IWDG counter with value defined in the IWDG_RLR register. - (++) Start the IWDG, 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 refresh the IWDG counter at regular - intervals during normal operation to prevent an MCU reset, using - HAL_IWDG_Refresh() function. - [..] - if Window option is enabled: - - (+) Use IWDG using HAL_IWDG_Start() function to enable IWDG downcounter - (+) Use IWDG using HAL_IWDG_Init() function to : - (++) Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers. - (++) Configure the IWDG prescaler, reload value and window value. - (+) Then the application program must refresh the IWDG counter at regular - intervals during normal operation to prevent an MCU reset, using - HAL_IWDG_Refresh() function. + [..] + (#) Use IWDG using HAL_IWDG_Init() function to : + (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI + clock is forced ON and IWDG counter starts downcounting. + (++) Enable write access to configuration register: IWDG_PR, IWDG_RLR & + IWDG_WINR. + (++) Configure the IWDG prescaler and counter reload value. This reload + value will be loaded in the IWDG counter each time the watchdog is + reloaded, then the IWDG will start counting down from this value. + (++) Wait for status flags to be reset + (++) Depending on window parameter: + (+++) If Window Init parameter is same as Window register value, + nothing more is done but reload counter value in order to exit + function withy exact time base. + (+++) Else modify Window register. This will automatically reload + watchdog counter. + + (#) Then the application program must refresh the IWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + HAL_IWDG_Refresh() function. *** IWDG HAL driver macros list *** ==================================== [..] - Below the list of most used macros in IWDG HAL driver. - + Below the list of most used macros in IWDG HAL driver: (+) __HAL_IWDG_START: Enable the IWDG peripheral - (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in the reload register - (+) IWDG_ENABLE_WRITE_ACCESS : Enable write access to IWDG_PR and IWDG_RLR registers - (+) __HAL_IWDG_DISABLE_WRITE_ACCESS : Disable write access to IWDG_PR and IWDG_RLR registers - (+) __HAL_IWDG_GET_FLAG: Get the selected IWDG's flag status - + (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in + the reload register + @endverbatim ****************************************************************************** * @attention @@ -119,60 +114,62 @@ */ #ifdef HAL_IWDG_MODULE_ENABLED - /** @addtogroup IWDG * @brief IWDG HAL module driver. * @{ */ -/** @addtogroup IWDG_Private +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup IWDG_Private_Defines IWDG Private Defines * @{ */ -/* TimeOut value */ -#define HAL_IWDG_DEFAULT_TIMEOUT (uint32_t)1000U - -/* Local define used to check the SR status register */ -#define IWDG_SR_FLAGS (IWDG_FLAG_PVU | IWDG_FLAG_RVU | IWDG_FLAG_WVU) +/* Status register need 5 RC LSI divided by prescaler clock to be updated. With + higher prescaler (256), and according to LSI variation, we need to wait at + least 6 cycles so 48 ms. */ +#define HAL_IWDG_DEFAULT_TIMEOUT 48U /** * @} */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + /** @addtogroup IWDG_Exported_Functions * @{ */ /** @addtogroup IWDG_Exported_Functions_Group1 - * @brief Initialization and Configuration functions. + * @brief Initialization and Start functions. * @verbatim =============================================================================== - ##### Initialization and de-initialization functions ##### + ##### Initialization and Start functions ##### =============================================================================== - [..] This section provides functions allowing to: - (+) Initialize the IWDG according to the specified parameters - in the IWDG_InitTypeDef and create the associated handle - (+) Manage Window option - (+) Initialize the IWDG MSP + [..] This section provides functions allowing to: + (+) Initialize the IWDG according to the specified parameters in the + IWDG_InitTypeDef of associated handle. + (+) Manage Window option. + (+) Once initialization is performed in HAL_IWDG_Init function, Watchdog + is reloaded in order to exit function with correct time base. @endverbatim * @{ */ /** - * @brief Initializes the IWDG according to the specified - * parameters in the IWDG_InitTypeDef and creates the associated handle. - * - * When using the 'window option', the function HAL_IWDG_Start() must - * be called before calling this function - * - * @param hiwdg : pointer to a IWDG_HandleTypeDef structure that contains - * the configuration information for the specified IWDG module. + * @brief Initialize the IWDG according to the specified parameters in the + * IWDG_InitTypeDef and start watchdog. Before exiting function, + * watchdog is refreshed in order to have correct time base. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. * @retval HAL status */ - HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) { - uint32_t tickstart = 0U; + uint32_t tickstart; /* Check the IWDG handle allocation */ if(hiwdg == NULL) @@ -181,229 +178,88 @@ HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) } /* Check the parameters */ + assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance)); assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler)); assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload)); assert_param(IS_IWDG_WINDOW(hiwdg->Init.Window)); - /* Check pending flag, if previous update not done, return error */ - if(((hiwdg->Instance->SR) & IWDG_SR_FLAGS) != 0U) - { - return HAL_ERROR; - } + /* Enable IWDG. LSI is turned on automaticaly */ + __HAL_IWDG_START(hiwdg); - if(hiwdg->State == HAL_IWDG_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - hiwdg->Lock = HAL_UNLOCKED; - - /* Init the low level hardware */ - HAL_IWDG_MspInit(hiwdg); - } - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_BUSY; - - /* Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers */ - /* by writing 0x5555 in KR */ + /* Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers by writing + 0x5555 in KR */ IWDG_ENABLE_WRITE_ACCESS(hiwdg); - /* Write to IWDG registers the IWDG_Prescaler & IWDG_Reload values to work with */ - MODIFY_REG(hiwdg->Instance->PR, (uint32_t)IWDG_PR_PR, hiwdg->Init.Prescaler); - MODIFY_REG(hiwdg->Instance->RLR, (uint32_t)IWDG_RLR_RL, hiwdg->Init.Reload); + /* Write to IWDG registers the Prescaler & Reload values to work with */ + hiwdg->Instance->PR = hiwdg->Init.Prescaler; + hiwdg->Instance->RLR = hiwdg->Init.Reload; - /* check if window option is enabled */ - if (((hiwdg->Init.Window) != IWDG_WINDOW_DISABLE) || ((hiwdg->Instance->WINR) != IWDG_WINDOW_DISABLE)) + /* Check pending flag, if previous update not done, return timeout */ + tickstart = HAL_GetTick(); + + /* Wait for register to be updated */ + while(hiwdg->Instance->SR != RESET) { - tickstart = HAL_GetTick(); - - /* Wait for register to be updated */ - while (((hiwdg->Instance->SR) & IWDG_SR_FLAGS) != 0U) - { - if((HAL_GetTick()-tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) - { - /* Set IWDG state */ - hiwdg->State = HAL_IWDG_STATE_TIMEOUT; - return HAL_TIMEOUT; - } + if((HAL_GetTick() - tickstart ) > HAL_IWDG_DEFAULT_TIMEOUT) + { + return HAL_TIMEOUT; } - - /* Write to IWDG WINR the IWDG_Window value to compare with */ - MODIFY_REG(hiwdg->Instance->WINR, (uint32_t)IWDG_WINR_WIN, hiwdg->Init.Window); - } - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_READY; + + /* If window parameter is different than current value, modify window + register */ + if(hiwdg->Instance->WINR != hiwdg->Init.Window) + { + /* Write to IWDG WINR the IWDG_Window value to compare with. In any case, + even if window feature is disabled, Watchdog will be reloaded by writing + windows register */ + hiwdg->Instance->WINR = hiwdg->Init.Window; + } + else + { + /* Reload IWDG counter with value defined in the reload register */ + __HAL_IWDG_RELOAD_COUNTER(hiwdg); + } /* Return function status */ return HAL_OK; } -/** - * @brief Initializes the IWDG MSP. - * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains - * the configuration information for the specified IWDG module. - * @retval None - */ -__weak void HAL_IWDG_MspInit(IWDG_HandleTypeDef *hiwdg) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hiwdg); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_IWDG_MspInit could be implemented in the user file - */ -} - /** * @} */ + /** @addtogroup IWDG_Exported_Functions_Group2 - * @brief IO operation functions + * @brief IO operation functions * @verbatim =============================================================================== ##### IO operation functions ##### =============================================================================== - [..] This section provides functions allowing to: - (+) Start the IWDG. + [..] This section provides functions allowing to: (+) Refresh the IWDG. @endverbatim * @{ */ -/** - * @brief Starts the IWDG. - * @param hiwdg : pointer to a IWDG_HandleTypeDef structure that contains - * the configuration information for the specified IWDG module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_IWDG_Start(IWDG_HandleTypeDef *hiwdg) -{ - uint32_t tickstart = 0U; - - /* Process locked */ - __HAL_LOCK(hiwdg); - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_BUSY; - - /* Enable the IWDG peripheral */ - __HAL_IWDG_START(hiwdg); - - /* Reload IWDG counter with value defined in the RLR register */ - if ((hiwdg->Init.Window) == IWDG_WINDOW_DISABLE) - { - __HAL_IWDG_RELOAD_COUNTER(hiwdg); - } - - tickstart = HAL_GetTick(); - - /* Wait until PVU, RVU, WVU flag are RESET */ - while (((hiwdg->Instance->SR) & IWDG_SR_FLAGS) != 0U) - { - if((HAL_GetTick()-tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) - { - /* Set IWDG state */ - hiwdg->State = HAL_IWDG_STATE_TIMEOUT; - - /* Process unlocked */ - __HAL_UNLOCK(hiwdg); - return HAL_TIMEOUT; - } - } - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hiwdg); - - /* Return function status */ - return HAL_OK; -} /** - * @brief Refreshes the IWDG. - * @param hiwdg : pointer to a IWDG_HandleTypeDef structure that contains - * the configuration information for the specified IWDG module. + * @brief Refresh the IWDG. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. * @retval HAL status */ HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg) { - uint32_t tickstart = 0U; - - /* Process Locked */ - __HAL_LOCK(hiwdg); - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_BUSY; - - tickstart = HAL_GetTick(); - - /* Wait until RVU flag is RESET */ - while(__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_RVU) != RESET) - { - if((HAL_GetTick()-tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) - { - /* Set IWDG state */ - hiwdg->State = HAL_IWDG_STATE_TIMEOUT; - - /* Process unlocked */ - __HAL_UNLOCK(hiwdg); - - return HAL_TIMEOUT; - } - } - /* Reload IWDG counter with value defined in the reload register */ __HAL_IWDG_RELOAD_COUNTER(hiwdg); - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hiwdg); - /* Return function status */ return HAL_OK; } -/** - * @} - */ - -/** @addtogroup IWDG_Exported_Functions_Group3 - * @brief Peripheral State functions. - * -@verbatim - =============================================================================== - ##### Peripheral State functions ##### - =============================================================================== - [..] - This subsection permits to get in run-time the status of the peripheral - and the data flow. - -@endverbatim - * @{ - */ - -/** - * @brief Returns the IWDG state. - * @param hiwdg : pointer to a IWDG_HandleTypeDef structure that contains - * the configuration information for the specified IWDG module. - * @retval HAL state - */ -HAL_IWDG_StateTypeDef HAL_IWDG_GetState(IWDG_HandleTypeDef *hiwdg) -{ - return hiwdg->State; -} - -/** - * @} - */ - /** * @} */ @@ -413,10 +269,12 @@ HAL_IWDG_StateTypeDef HAL_IWDG_GetState(IWDG_HandleTypeDef *hiwdg) */ #endif /* HAL_IWDG_MODULE_ENABLED */ +/** + * @} + */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_iwdg.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_iwdg.h index d8d0541023..8d2e2a77a0 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_iwdg.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_iwdg.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_iwdg.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of IWDG HAL module. ****************************************************************************** * @attention @@ -55,32 +53,10 @@ */ /* Exported types ------------------------------------------------------------*/ - /** @defgroup IWDG_Exported_Types IWDG Exported Types * @{ */ -/** @defgroup IWDG_State IWDG state definition - * @{ - */ -/** - * @brief IWDG HAL State Structure definition - */ -typedef enum -{ - HAL_IWDG_STATE_RESET = 0x00U, /*!< IWDG not yet initialized or disabled */ - HAL_IWDG_STATE_READY = 0x01U, /*!< IWDG initialized and ready for use */ - HAL_IWDG_STATE_BUSY = 0x02U, /*!< IWDG internal process is ongoing */ - HAL_IWDG_STATE_TIMEOUT = 0x03U, /*!< IWDG timeout state */ - HAL_IWDG_STATE_ERROR = 0x04U /*!< IWDG error state */ - -}HAL_IWDG_StateTypeDef; -/** - * @} - */ -/** @defgroup IWDG_Init IWDG init configuration structure - * @{ - */ /** * @brief IWDG Init structure definition */ @@ -96,13 +72,7 @@ typedef struct This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */ } IWDG_InitTypeDef; -/** - * @} - */ -/** @defgroup IWDG_handle IWDG handler - * @{ - */ /** * @brief IWDG Handle Structure definition */ @@ -112,88 +82,35 @@ typedef struct IWDG_InitTypeDef Init; /*!< IWDG required parameters */ - HAL_LockTypeDef Lock; /*!< IWDG Locking object */ - - __IO HAL_IWDG_StateTypeDef State; /*!< IWDG communication state */ - }IWDG_HandleTypeDef; -/** - * @} - */ - /** * @} */ /* Exported constants --------------------------------------------------------*/ - /** @defgroup IWDG_Exported_Constants IWDG Exported Constants * @{ */ -/** @defgroup IWDG_Registers_Key IWDG key - * @brief IWDG registers bit mask - * @{ - */ -/* --- KR Register ---*/ -/* KR register bit mask */ -#define IWDG_KEY_RELOAD ((uint32_t)0xAAAAU) /*!< IWDG Reload Counter Enable */ -#define IWDG_KEY_ENABLE ((uint32_t)0xCCCCU) /*!< IWDG Peripheral Enable */ -#define IWDG_KEY_WRITE_ACCESS_ENABLE ((uint32_t)0x5555U) /*!< IWDG KR Write Access Enable */ -#define IWDG_KEY_WRITE_ACCESS_DISABLE ((uint32_t)0x0000U) /*!< IWDG KR Write Access Disable */ -/** - * @} - */ - -#define IS_IWDG_KR(__KR__) (((__KR__) == IWDG_KEY_RELOAD) || \ - ((__KR__) == IWDG_KEY_ENABLE))|| \ - ((__KR__) == IWDG_KEY_WRITE_ACCESS_ENABLE)) || \ - ((__KR__) == IWDG_KEY_WRITE_ACCESS_DISABLE)) - - -/** @defgroup IWDG_Flag_definition IWDG Flag definition - * @{ - */ -#define IWDG_FLAG_PVU ((uint32_t)IWDG_SR_PVU) /*!< Watchdog counter prescaler value update flag */ -#define IWDG_FLAG_RVU ((uint32_t)IWDG_SR_RVU) /*!< Watchdog counter reload value update flag */ -#define IWDG_FLAG_WVU ((uint32_t)IWDG_SR_WVU) /*!< Watchdog counter window value update Flag */ -/** - * @} - */ - /** @defgroup IWDG_Prescaler IWDG Prescaler * @{ */ -#define IWDG_PRESCALER_4 ((uint8_t)0x00U) /*!< IWDG prescaler set to 4 */ -#define IWDG_PRESCALER_8 ((uint8_t)(IWDG_PR_PR_0)) /*!< IWDG prescaler set to 8 */ -#define IWDG_PRESCALER_16 ((uint8_t)(IWDG_PR_PR_1)) /*!< IWDG prescaler set to 16 */ -#define IWDG_PRESCALER_32 ((uint8_t)(IWDG_PR_PR_1 | IWDG_PR_PR_0)) /*!< IWDG prescaler set to 32 */ -#define IWDG_PRESCALER_64 ((uint8_t)(IWDG_PR_PR_2)) /*!< IWDG prescaler set to 64 */ -#define IWDG_PRESCALER_128 ((uint8_t)(IWDG_PR_PR_2 | IWDG_PR_PR_0)) /*!< IWDG prescaler set to 128 */ -#define IWDG_PRESCALER_256 ((uint8_t)(IWDG_PR_PR_2 | IWDG_PR_PR_1)) /*!< IWDG prescaler set to 256 */ +#define IWDG_PRESCALER_4 0x00000000U /*!< IWDG prescaler set to 4 */ +#define IWDG_PRESCALER_8 IWDG_PR_PR_0 /*!< IWDG prescaler set to 8 */ +#define IWDG_PRESCALER_16 IWDG_PR_PR_1 /*!< IWDG prescaler set to 16 */ +#define IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 32 */ +#define IWDG_PRESCALER_64 IWDG_PR_PR_2 /*!< IWDG prescaler set to 64 */ +#define IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 128 */ +#define IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< IWDG prescaler set to 256 */ /** * @} */ -#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)) -/* Check for reload value */ -#define IS_IWDG_RELOAD(__RELOAD__) ((__RELOAD__) <= 0xFFFU) - -/* Check for window value */ -#define IS_IWDG_WINDOW(__VALUE__) ((__VALUE__) <= 0xFFFU) - - -/** @defgroup IWDG_Disable IWDG Disable +/** @defgroup IWDG_Window_option IWDG Window option * @{ */ -#define IWDG_WINDOW_DISABLE 0xFFFU +#define IWDG_WINDOW_DISABLE IWDG_WINR_WIN /** * @} */ @@ -201,106 +118,120 @@ typedef struct /** * @} */ -/* Exported macro ------------------------------------------------------------*/ -/** @defgroup IWDG_Exported_Macro IWDG Exported Macros + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Macros IWDG Exported Macros * @{ */ -/** @brief Reset IWDG handle state - * @param __HANDLE__ : IWDG handle +/** + * @brief Enable the IWDG peripheral. + * @param __HANDLE__ IWDG handle * @retval None */ -#define __HAL_IWDG_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_IWDG_STATE_RESET) +#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE) /** - * @brief Enables the IWDG peripheral. - * @param __HANDLE__ : IWDG handle + * @brief Reload IWDG counter with value defined in the reload register + * (write access to IWDG_PR, IWDG_RLR & IWDG_WINR registers disabled). + * @param __HANDLE__ IWDG handle * @retval None */ -#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE) - -/** - * @brief Reloads IWDG counter with value defined in the reload register - * (write access to IWDG_PR and IWDG_RLR registers disabled). - * @param __HANDLE__ : IWDG handle - * @retval None - */ -#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD) - -/** - * @brief Enables write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers. - * @param __HANDLE__ : IWDG handle - * @retval None - */ -#define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_ENABLE) - -/** - * @brief Disables write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers. - * @param __HANDLE__ : IWDG handle - * @retval None - */ -#define IWDG_DISABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_DISABLE) - -/** - * @brief Gets the selected IWDG's flag status. - * @param __HANDLE__ : IWDG handle - * @param __FLAG__ : specifies the flag to check. - * This parameter can be one of the following values: - * @arg IWDG_FLAG_PVU: Watchdog counter reload value update flag - * @arg IWDG_FLAG_RVU: Watchdog counter prescaler value flag - * @arg IWDG_FLAG_WVU: Watchdog counter window value flag - * @retval The new state of __FLAG__ (TRUE or FALSE) . - */ -#define __HAL_IWDG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) +#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD) /** * @} */ /* Exported functions --------------------------------------------------------*/ -/** @defgroup IWDG_Exported_Functions IWDG Exported Functions +/** @defgroup IWDG_Exported_Functions IWDG Exported Functions * @{ */ -/** @defgroup IWDG_Exported_Functions_Group1 Initialization/de-initialization functions +/** @defgroup IWDG_Exported_Functions_Group1 Initialization and Start functions * @{ */ +/* Initialization/Start functions ********************************************/ HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg); -void HAL_IWDG_MspInit(IWDG_HandleTypeDef *hiwdg); /** * @} */ -/** @defgroup IWDG_Exported_Functions_Group2 I/O operation functions +/** @defgroup IWDG_Exported_Functions_Group2 IO operation functions * @{ */ -HAL_StatusTypeDef HAL_IWDG_Start(IWDG_HandleTypeDef *hiwdg); +/* I/O operation functions ****************************************************/ HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg); /** * @} */ -/** @defgroup IWDG_Exported_Functions_Group3 Peripheral State functions +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup IWDG_Private_Constants IWDG Private Constants * @{ */ -HAL_IWDG_StateTypeDef HAL_IWDG_GetState(IWDG_HandleTypeDef *hiwdg); + /** - * @} + * @brief IWDG Key Register BitMask */ +#define IWDG_KEY_RELOAD 0x0000AAAAU /*!< IWDG Reload Counter Enable */ +#define IWDG_KEY_ENABLE 0x0000CCCCU /*!< IWDG Peripheral Enable */ +#define IWDG_KEY_WRITE_ACCESS_ENABLE 0x00005555U /*!< IWDG KR Write Access Enable */ +#define IWDG_KEY_WRITE_ACCESS_DISABLE 0x00000000U /*!< IWDG KR Write Access Disable */ /** * @} */ -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup IWDG_Private IWDG Private +/* Private macros ------------------------------------------------------------*/ +/** @defgroup IWDG_Private_Macros IWDG Private Macros * @{ */ + /** - * @} + * @brief Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers. + * @param __HANDLE__ IWDG handle + * @retval None */ -/**************************************************************/ +#define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_ENABLE) + +/** + * @brief Disable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers. + * @param __HANDLE__ IWDG handle + * @retval None + */ +#define IWDG_DISABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_DISABLE) + +/** + * @brief Check IWDG prescaler value. + * @param __PRESCALER__ IWDG prescaler value + * @retval None + */ +#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)) + +/** + * @brief Check IWDG reload value. + * @param __RELOAD__ IWDG reload value + * @retval None + */ +#define IS_IWDG_RELOAD(__RELOAD__) ((__RELOAD__) <= IWDG_RLR_RL) + +/** + * @brief Check IWDG window value. + * @param __WINDOW__ IWDG window value + * @retval None + */ +#define IS_IWDG_WINDOW(__WINDOW__) ((__WINDOW__) <= IWDG_WINR_WIN) /** * @} @@ -310,6 +241,11 @@ HAL_IWDG_StateTypeDef HAL_IWDG_GetState(IWDG_HandleTypeDef *hiwdg); * @} */ +/** + * @} + */ + + #ifdef __cplusplus } #endif @@ -317,4 +253,3 @@ HAL_IWDG_StateTypeDef HAL_IWDG_GetState(IWDG_HandleTypeDef *hiwdg); #endif /* __STM32L0xx_HAL_IWDG_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lcd.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lcd.c index 9895942611..dac4d8cc21 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lcd.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lcd.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_lcd.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief LCD Controller HAL module driver. * This file provides firmware functions to manage the following * functionalities of the LCD Controller (LCD) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lcd.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lcd.h index bf6d0eb9e1..fa3c3a284a 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lcd.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lcd.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_lcd.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of LCD Controller HAL module. ****************************************************************************** * @attention @@ -35,7 +33,6 @@ ****************************************************************************** */ -#if defined (STM32L053xx) || defined (STM32L063xx) || defined (STM32L073xx) || defined (STM32L083xx) /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32L0xx_HAL_LCD_H @@ -45,6 +42,7 @@ extern "C" { #endif +#if defined (STM32L053xx) || defined (STM32L063xx) || defined (STM32L073xx) || defined (STM32L083xx) /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal_def.h" @@ -434,7 +432,7 @@ typedef struct /** * @} */ - + /** @defgroup LCD_BUFEN LCD Voltage output buffer enable * @{ */ @@ -794,14 +792,13 @@ HAL_StatusTypeDef LCD_WaitForSynchro(LCD_HandleTypeDef *hlcd); * @} */ +#endif /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx */ + #ifdef __cplusplus } #endif #endif /* __STM32L0xx_HAL_LCD_H */ - -#endif /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx */ - /******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim.c index 0202b86434..43c712edb8 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_lptim.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief LPTIM HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim.h index a290b1b1df..8bd6309c8c 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_lptim.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of LPTIM HAL module. ****************************************************************************** * @attention @@ -113,7 +111,7 @@ typedef struct typedef struct { uint32_t Source; /*!< Selects the Trigger source. - This parameter can be a value of @ref LPTIMEx_Trigger_Source */ + This parameter can be a value of @ref LPTIM_Trigger_Source */ uint32_t ActiveEdge; /*!< Selects the Trigger active edge. Note: This parameter is used only when an external trigger is used. diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim_ex.h index 03414db723..d38c9f4d75 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_lptim_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_lptim_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of LPTIM Extended HAL module. ****************************************************************************** * @attention @@ -61,7 +59,7 @@ */ -/** @defgroup LPTIMEx_Trigger_Source Trigger source +/** @defgroup LPTIM_Trigger_Source Trigger source * @{ */ #define LPTIM_TRIGSOURCE_SOFTWARE ((uint32_t)0x0000FFFFU) diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd.c index e942635e9b..9cf95a751e 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_pcd.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief PCD HAL module driver. * This file provides firmware functions to manage the following * functionalities of the USB Peripheral Controller: @@ -190,17 +188,28 @@ HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) /*Set Btable Adress*/ hpcd->Instance->BTABLE = BTABLE_ADDRESS; - - /*set wInterrupt_Mask global variable*/ - wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \ - | USB_CNTR_ESOFM | USB_CNTR_RESETM; - + + /*set wInterrupt_Mask global variable*/ + wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \ + | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM; + /*Set interrupt mask*/ - hpcd->Instance->CNTR = wInterrupt_Mask; + hpcd->Instance->CNTR = wInterrupt_Mask; + + hpcd->USB_Address = 0U; + hpcd->State= HAL_PCD_STATE_READY; - hpcd->USB_Address = 0U; - hpcd->State= HAL_PCD_STATE_READY; - + /* Activate LPM */ + if (hpcd->Init.lpm_enable ==1) + { + HAL_PCDEx_ActivateLPM(hpcd); + } + /* Activate Battery charging */ + if (hpcd->Init.battery_charging_enable ==1) + { + HAL_PCDEx_ActivateBCD(hpcd); + } + return HAL_OK; } @@ -354,16 +363,30 @@ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) /*set wInterrupt_Mask global variable*/ wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \ - | USB_CNTR_ESOFM | USB_CNTR_RESETM; - + | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM; + /*Set interrupt mask*/ hpcd->Instance->CNTR = wInterrupt_Mask; + + /* enable L1REQ interrupt */ + if (hpcd->Init.lpm_enable ==1) + { + wInterrupt_Mask |= USB_CNTR_L1REQM; + + /* Enable LPM support and enable ACK answer to LPM request*/ + USB_TypeDef *USBx = hpcd->Instance; + hpcd->lpm_active = ENABLE; + hpcd->LPM_State = LPM_L0; + + USBx->LPMCSR |= (USB_LPMCSR_LMPEN); + USBx->LPMCSR |= (USB_LPMCSR_LPMACK); + } HAL_PCD_ResumeCallback(hpcd); __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); } - + if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP)) { /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ @@ -378,6 +401,26 @@ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) HAL_PCD_SuspendCallback(hpcd); } } + + /* Handle LPM Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ)) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ); + if( hpcd->LPM_State == LPM_L0) + { + /* Force suspend and low-power mode before going to L1 state*/ + hpcd->Instance->CNTR |= USB_CNTR_LPMODE; + hpcd->Instance->CNTR |= USB_CNTR_FSUSP; + + hpcd->LPM_State = LPM_L1; + hpcd->BESL = (hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >>2 ; + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); + } + else + { + HAL_PCD_SuspendCallback(hpcd); + } + } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF)) { @@ -837,9 +880,7 @@ HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, u ep->xfer_count = 0U; ep->is_in = 0U; ep->num = ep_addr & 0x7FU; - - __HAL_LOCK(hpcd); - + /* Multi packet transfer*/ if (ep->xfer_len > ep->maxpacket) { @@ -865,9 +906,7 @@ HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, u } PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID); - - __HAL_UNLOCK(hpcd); - + return HAL_OK; } @@ -902,9 +941,7 @@ HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, ep->xfer_count = 0U; ep->is_in = 1U; ep->num = ep_addr & 0x7FU; - - __HAL_LOCK(hpcd); - + /*Multi packet transfer*/ if (ep->xfer_len > ep->maxpacket) { @@ -944,8 +981,6 @@ HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID); - __HAL_UNLOCK(hpcd); - return HAL_OK; } @@ -1050,11 +1085,20 @@ HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) * @brief HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling * @param hpcd: PCD handle * @retval status - */ +*/ HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) { - hpcd->Instance->CNTR |= USB_CNTR_RESUME; - return HAL_OK; + if (hpcd->Init.lpm_enable ==1) + { + /* Apply L1 Resume */ + hpcd->Instance->CNTR |= USB_CNTR_L1RESUME; + } + else + { + /* Apply L2 Resume */ + hpcd->Instance->CNTR |= USB_CNTR_RESUME; + } + return (HAL_OK); } /** @@ -1064,11 +1108,19 @@ HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) */ HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) { - hpcd->Instance->CNTR &= ((uint16_t) ~(USB_CNTR_RESUME)); - return HAL_OK; + if (hpcd->Init.lpm_enable ==1) + { + /* Release L1 Resume */ + hpcd->Instance->CNTR &= ~ USB_CNTR_L1RESUME; + } + else + { + /* Release L2 Resume */ + hpcd->Instance->CNTR &= ~ USB_CNTR_RESUME; + } + return (HAL_OK); } - /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd.h index 6b0507633e..d3af2f86f2 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_pcd.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of PCD HAL module. ****************************************************************************** * @attention @@ -74,6 +72,15 @@ typedef enum HAL_PCD_STATE_TIMEOUT = 0x04U } PCD_StateTypeDef; +/* Device LPM suspend state */ +typedef enum +{ + LPM_L0 = 0x00, /* on */ + LPM_L1 = 0x01, /* LPM L1 sleep */ + LPM_L2 = 0x02, /* suspend */ + LPM_L3 = 0x03, /* off */ +}PCD_LPM_StateTypeDef; + typedef enum { /* double buffered endpoint direction */ @@ -179,6 +186,15 @@ typedef struct HAL_LockTypeDef Lock; /*!< PCD peripheral status */ __IO PCD_StateTypeDef State; /*!< PCD communication state */ uint32_t Setup[12]; /*!< Setup packet buffer */ + PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */ + uint32_t BESL; + + + uint32_t lpm_active; /*!< Enable or disable the Link Power Management . + This parameter can be set to ENABLE or DISABLE */ + + uint32_t battery_charging_active; /*!< Enable or disable Battery charging. + This parameter can be set to ENABLE or DISABLE */ void *pData; /*!< Pointer to upper stack Handler */ } PCD_HandleTypeDef; diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd_ex.c index ba0309c8a2..99036a75bd 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_pcd_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Extended PCD HAL module driver. * This file provides firmware functions to manage the following * functionalities of the USB Peripheral Controller: @@ -132,6 +130,173 @@ HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, return HAL_OK; } + +/** + * @brief Activate BatteryCharging feature. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd) +{ + USB_TypeDef *USBx = hpcd->Instance; + hpcd->battery_charging_active = ENABLE; + + USBx->BCDR |= (USB_BCDR_BCDEN); + /* Enable DCD : Data Contact Detect */ + USBx->BCDR |= (USB_BCDR_DCDEN); + + return HAL_OK; +} + +/** + * @brief Deactivate BatteryCharging feature. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd) +{ + USB_TypeDef *USBx = hpcd->Instance; + hpcd->battery_charging_active = DISABLE; + + USBx->BCDR &= ~(USB_BCDR_BCDEN); + return HAL_OK; +} + +/** + * @brief Handle BatteryCharging Process. + * @param hpcd: PCD handle + * @retval HAL status + */ +void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd) +{ + USB_TypeDef *USBx = hpcd->Instance; + uint32_t tickstart = HAL_GetTick(); + + /* Wait Detect flag or a timeout is happen*/ + while ((USBx->BCDR & USB_BCDR_DCDET) == 0) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > 1000) + { + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR); + return; + } + } + + HAL_Delay(300); + + /* Data Pin Contact ? Check Detect flag */ + if (USBx->BCDR & USB_BCDR_DCDET) + { + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION); + } + /* Primary detection: checks if connected to Standard Downstream Port + (without charging capability) */ + USBx->BCDR &= ~(USB_BCDR_DCDEN); + USBx->BCDR |= (USB_BCDR_PDEN); + HAL_Delay(300); + + /* If Charger detect ? */ + if (USBx->BCDR & USB_BCDR_PDET) + { + /* Start secondary detection to check connection to Charging Downstream + Port or Dedicated Charging Port */ + USBx->BCDR &= ~(USB_BCDR_PDEN); + USBx->BCDR |= (USB_BCDR_SDEN); + HAL_Delay(300); + + /* If CDP ? */ + if (USBx->BCDR & USB_BCDR_SDET) + { + /* Dedicated Downstream Port DCP */ + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); + } + else + { + /* Charging Downstream Port CDP */ + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); + } + } + else + { + /* Standard Downstream Port */ + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); + } + /* Battery Charging capability discovery finished + Start Enumeration*/ + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); +} + +/** + * @brief Activate LPM feature. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) +{ + + USB_TypeDef *USBx = hpcd->Instance; + hpcd->lpm_active = ENABLE; + hpcd->LPM_State = LPM_L0; + + USBx->LPMCSR |= (USB_LPMCSR_LMPEN); + USBx->LPMCSR |= (USB_LPMCSR_LPMACK); + + + return HAL_OK; +} + +/** + * @brief Deactivate LPM feature. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd) +{ + USB_TypeDef *USBx = hpcd->Instance; + + hpcd->lpm_active = DISABLE; + + USBx->LPMCSR &= ~ (USB_LPMCSR_LMPEN); + USBx->LPMCSR &= ~ (USB_LPMCSR_LPMACK); + + return HAL_OK; +} + +/** + * @brief Send LPM message to user layer callback. + * @param hpcd: PCD handle + * @param msg: LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_LPM_Callback could be implemented in the user file + */ +} + +/** + * @brief Send BatteryCharging message to user layer callback. + * @param hpcd: PCD handle + * @param msg: LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_BCD_Callback could be implemented in the user file + */ +} + /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd_ex.h index 4e5f617280..e155f6724e 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pcd_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_pcd.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of PCD HAL module. ****************************************************************************** * @attention @@ -52,8 +50,27 @@ /** @defgroup PCDEx PCDEx * @{ - */ + */ +/* Exported types ------------------------------------------------------------*/ +typedef enum +{ + PCD_LPM_L0_ACTIVE = 0x00, /* on */ + PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */ +}PCD_LPM_MsgTypeDef; +typedef enum +{ + PCD_BCD_ERROR = 0xFF, + PCD_BCD_CONTACT_DETECTION = 0xFE, + PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD, + PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC, + PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB, + PCD_BCD_DISCOVERY_COMPLETED = 0x00, + +}PCD_BCD_MsgTypeDef; + +/* Exported constants --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ /** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions @@ -67,6 +84,14 @@ HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, uint16_t ep_kind, uint32_t pmaadress); +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd); +void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd); +void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); +void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); + /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr.c index cb88010464..cb0c885939 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_pwr.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief PWR HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr.h index f4ab593778..4de6152a39 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_pwr.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of PWR HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr_ex.c index 69534a393d..76991ca973 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_pwr_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Extended PWR HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Power Controller (PWR) peripheral: @@ -81,6 +79,16 @@ * @{ */ +/** + * @brief Return Voltage Scaling Range. + * @retval VOS bit field (PWR_REGULATOR_VOLTAGE_SCALE1, PWR_REGULATOR_VOLTAGE_SCALE2 or PWR_REGULATOR_VOLTAGE_SCALE3) + */ +uint32_t HAL_PWREx_GetVoltageRange(void) +{ + return (PWR->CR & PWR_CR_VOS); +} + + /** * @brief Enables the Fast WakeUp from Ultra Low Power mode. * @note This bit works in conjunction with ULP bit. diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr_ex.h index aa88fa8754..a994a83aac 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_pwr_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_pwr_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of PWR HAL Extension module. ****************************************************************************** * @attention @@ -78,6 +76,7 @@ /** @defgroup PWREx_Exported_Functions PWREx Exported Functions * @{ */ +uint32_t HAL_PWREx_GetVoltageRange(void); void HAL_PWREx_EnableFastWakeUp(void); void HAL_PWREx_DisableFastWakeUp(void); void HAL_PWREx_EnableUltraLowPower(void); diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.c index cf1597aa1b..8b08c3ee2b 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_rcc.c * @author MCD Application Team - * @version V1.4.0 - * @date 01-October-2015 * @brief RCC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Reset and Clock Control (RCC) peripheral: @@ -14,42 +12,39 @@ ============================================================================== ##### 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 SW-DP. - (+) 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 SW-DP pins which - are assigned to be used for debug purpose. + [..] + After reset the device is running from multispeed internal oscillator clock + (MSI 2.097MHz) with Flash 0 wait state and Flash prefetch buffer is disabled, + and all peripherals are off except internal SRAM, Flash and JTAG. + (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses; + all peripherals mapped on these buses 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, RNG and IWDG) + (+) 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 buses 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 (I2S, RTC, ADC, USB OTG FS/SDIO/RNG) + (*) SDIO only for STM32L0xxxD devices ##### RCC Limitations ##### ============================================================================== [..] A delay between an RCC peripheral clock enable and the effective peripheral enabling should be taken into account in order to manage the peripheral read/write - from/to registeres. + from/to registers. (+) This delay depends on the peripheral mapping. - (+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle - after the clock enable bit is set on the hardware register - (+) If peripheral is mapped on APB: the delay is 2 APB clock cycle - after the clock enable bit is set on the hardware register + (++) AHB & APB peripherals, 1 dummy read is necessary [..] - Possible Workarounds: - (#) Enable the peripheral clock sometimes before the peripheral read/write - register is required. - (#) For AHB peripheral, insert two dummy read to the peripheral register. - (#) For APB peripheral, insert a dummy read to the peripheral register. - + Workarounds: + (#) For AHB & APB peripherals, a dummy read to the peripheral register has been + inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro. + @endverbatim ****************************************************************************** * @attention @@ -79,7 +74,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ +*/ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal.h" @@ -88,155 +83,209 @@ * @{ */ -#ifdef HAL_RCC_MODULE_ENABLED - -/** @addtogroup RCC - * @brief RCC HAL module driver +/** @defgroup RCC RCC +* @brief RCC HAL module driver * @{ */ -/** @addtogroup RCC_Private - * @{ - */ -#define RCC_HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT -#define RCC_HSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ -#define RCC_LSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ -#define RCC_PLL_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ -#define RCC_HSI48_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ -#define RCC_MSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ -#define RCC_CLOCKSWITCH_TIMEOUT_VALUE ((uint32_t)5000U) /* 5 s */ +#ifdef HAL_RCC_MODULE_ENABLED -#define __MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup RCC_Private_Constants RCC Private Constants + * @{ + */ +/* Bits position in in the CFGR register */ +#define RCC_CFGR_PLLMUL_BITNUMBER RCC_CFGR_PLLMUL_Pos +#define RCC_CFGR_PLLDIV_BITNUMBER RCC_CFGR_PLLDIV_Pos +#define RCC_CFGR_HPRE_BITNUMBER RCC_CFGR_HPRE_Pos +#define RCC_CFGR_PPRE1_BITNUMBER RCC_CFGR_PPRE1_Pos +#define RCC_CFGR_PPRE2_BITNUMBER RCC_CFGR_PPRE2_Pos +/* Bits position in in the ICSCR register */ +#define RCC_ICSCR_MSIRANGE_BITNUMBER RCC_ICSCR_MSIRANGE_Pos +#define RCC_ICSCR_MSITRIM_BITNUMBER RCC_ICSCR_MSITRIM_Pos +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/** @defgroup RCC_Private_Macros RCC Private Macros + * @{ + */ + +#define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define MCO1_GPIO_PORT GPIOA #define MCO1_PIN GPIO_PIN_8 -#define __MCO2_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define MCO2_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define MCO2_GPIO_PORT GPIOA #define MCO2_PIN GPIO_PIN_9 -#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx) -#define __MCO3_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx) +#define MCO3_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() #define MCO3_GPIO_PORT GPIOB #define MCO3_PIN GPIO_PIN_13 #endif -extern const uint8_t PLLMulTable[]; /* Defined in CMSIS (system_stm32l0xx.c)*/ - /** * @} - */ + */ -/** @addtogroup RCC_Exported_Functions +/* Private variables ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Variables RCC Private Variables + * @{ + */ +extern const uint8_t PLLMulTable[]; /* Defined in CMSIS (system_stm32l0xx.c)*/ +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup RCC_Private_Functions RCC Private Functions + * @{ + */ +static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSIrange); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Functions RCC Exported Functions * @{ */ -/** @addtogroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== +/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + =============================================================================== ##### Initialization and de-initialization functions ##### - =============================================================================== - [..] - This section provide functions allowing to configure the internal/external - clocks, PLL, CSS and MCO. - [..] Internal/external clock and PLL configuration - (#) 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. - [..] System, AHB and APB busses clocks configuration - (#) 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 IOPORT, AHB bus (DMA,Flash...). 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 - "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks. + =============================================================================== + [..] + This section provides functions allowing to configure the internal/external oscillators + (MSI, HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1 + and APB2). - -@- All the peripheral clocks are derived from the System clock (SYSCLK) except: - (+@) I2S: the I2S clock can be derived from an external clock mapped on the I2S_CKIN pin. - - (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock - divided by 2 to 16. You have to use __HAL_RCC_RTC_CONFIG() and __HAL_RCC_RTC_ENABLE() - macros to configure this clock. - (+@) USB FS,and RNG require a frequency equal to 48 MHz to work correctly - This clock is derived from the main PLL or HSI48 RC oscillator. - (+@) IWDG clock which is always the LSI clock. - - (#) For the STM32L0xx devices, the maximum - frequency of the SYSCLK ,HCLK, APB1 and APB2 is 32 MHz. - Depending on the device voltage range, the maximum frequency should - be adapted accordingly. Refer to the Reference Manual for more details. + [..] Internal/external clock and PLL configuration + (#) MSI (Multispeed internal), Seven frequency ranges are available: 65.536 kHz, + 131.072 kHz, 262.144 kHz, 524.288 kHz, 1.048 MHz, 2.097 MHz (default value) and 4.194 MHz. -@endverbatim + (#) HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through + the PLL as System clock source. + (#) LSI (low-speed internal), ~37 KHz low consumption RC used as IWDG and/or RTC + clock source. - Table 1. HCLK clock frequency. - +----------------------------------------------------------------+ - | 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| - +----------------------------------------------------------------+ + (#) 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), featuring different output clocks: + (++) The first output is used to generate the high speed system clock (up to 32 MHz) + (++) The second output is used to generate the clock for the USB OTG FS (48 MHz) + + (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE() + and if a HSE clock failure occurs(HSE used directly or through PLL as System + clock source), the System clocks automatically switched to MSI and an interrupt + is generated if enabled. The interrupt is linked to the Cortex-M0+ NMI + (Non-Maskable Interrupt) exception vector. + + (#) MCO1/MCO2/MCO3 (microcontroller clock output), used to output SYSCLK, HSI, LSI, MSI, LSE, + HSE, HSI48 or PLL clock (through a configurable prescaler) on PA8/PA9/PB13 pins. + + [..] System, AHB and APB buses clocks configuration + (#) 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, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived + from AHB clock through configurable prescalers and used to clock + the peripherals mapped on these buses. You can use + "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks. + + -@- All the peripheral clocks are derived from the System clock (SYSCLK) except: + (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock + divided by 2 to 16. You have to use @ref __HAL_RCC_RTC_CONFIG() and @ref __HAL_RCC_RTC_ENABLE() + macros to configure this clock. + (+@) LCD: LCD clock can be derived either from the LSI, LSE or HSE clock + divided by 2 to 16. You have to use @ref __HAL_RCC_LCD_CONFIG() + macros to configure this clock. + (+@) USB FS and RNG: USB FS require a frequency equal to 48 MHz to work correctly. + This clock is derived of the main PLL through PLL Multiplier or HSI48 RC oscillator. + + (+@) IWDG clock which is always the LSI clock. + + (#) The maximum frequency of the SYSCLK and HCLK is 32 MHz, PCLK2 32 MHz + and PCLK1 32 MHz. Depending on the device voltage range, the maximum + frequency should be adapted accordingly. + @endverbatim * @{ */ + +/* + Additional consideration on the HCLK based on Latency settings: + +----------------------------------------------------------------------+ + | Latency | HCLK clock frequency (MHz) | + | |------------------------------------------------------| + | | voltage range 1 | voltage range 2 | voltage range 3 | + | | 1.8 V | 1.5 V | 1.2 V | + |---------------|------------------|-----------------|-----------------| + |0WS(1CPU cycle)| 0 < HCLK <= 16 | 0 < HCLK <= 8 | 0 < HCLK <= 2 | + |---------------|------------------|-----------------|-----------------| + |1WS(2CPU cycle)| 16 < HCLK <= 32 | 8 < HCLK <= 16 | 2 < HCLK <= 4 | + +----------------------------------------------------------------------+ + + The following table gives the different clock source frequencies depending on the product + voltage range: + +------------------------------------------------------------------------------------------+ + | Product voltage | Clock frequency | + | |------------------|-----------------------------|-----------------------| + | range | MSI | HSI | HSE | PLL | + |-----------------|---------|--------|-----------------------------|-----------------------| + | Range 1 (1.8 V) | 4.2 MHz | 16 MHz | HSE 32 MHz (external clock) | 32 MHz | + | | | | or 24 MHz (crystal) | (PLLVCO max = 96 MHz) | + |-----------------|---------|--------|-----------------------------|-----------------------| + | Range 2 (1.5 V) | 4.2 MHz | 16 MHz | 16 MHz | 16 MHz | + | | | | | (PLLVCO max = 48 MHz) | + |-----------------|---------|--------|-----------------------------|-----------------------| + | Range 3 (1.2 V) | 4.2 MHz | NA | 8 MHz | 4 MHz | + | | | | | (PLLVCO max = 24 MHz) | + +------------------------------------------------------------------------------------------+ + */ /** * @brief Resets the RCC clock configuration to the default reset state. * @note The default reset state of the clock configuration is given below: - * - MSI ON and used as system clock source (MSI range is not modified - * - by this function, it keep the value configured by user application) - * - HSI, HSI_OUT, HSE and PLL OFF - * - AHB, APB1 and APB2 prescaler set to 1. - * - CSS and MCO OFF - * - All interrupts disabled + * - MSI ON and used as system clock source + * - HSI, HSE and PLL OFF + * - AHB, APB1 and APB2 prescaler set to 1. + * - CSS and MCO1/MCO2/MCO3 OFF + * - All interrupts disabled * @note This function does not modify the configuration of the - * @note -Peripheral clocks - * @note -HSI48, LSI, LSE and RTC clocks + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * - HSI48 clock * @retval None */ void HAL_RCC_DeInit(void) { __IO uint32_t tmpreg; - + /* Set MSION bit */ - SET_BIT(RCC->CR, RCC_CR_MSION); + SET_BIT(RCC->CR, RCC_CR_MSION); -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) || \ - defined(STM32L031xx) || defined(STM32L041xx) + /* Switch SYSCLK to MSI*/ + CLEAR_BIT(RCC->CFGR, RCC_CFGR_SW); + /* Reset HSE, HSI, CSS, PLL */ +#if defined(RCC_CR_CSSHSEON) && defined(RCC_CR_HSIOUTEN) CLEAR_BIT(RCC->CR, RCC_CR_HSION| RCC_CR_HSIKERON| RCC_CR_HSIDIVEN | RCC_CR_HSIOUTEN | \ RCC_CR_HSEON | RCC_CR_CSSHSEON | RCC_CR_PLLON); -#elif defined(STM32L011xx) || defined(STM32L021xx) +#elif !defined(RCC_CR_CSSHSEON) && defined(RCC_CR_HSIOUTEN) CLEAR_BIT(RCC->CR, RCC_CR_HSION| RCC_CR_HSIKERON| RCC_CR_HSIDIVEN | RCC_CR_HSIOUTEN | \ RCC_CR_HSEON | RCC_CR_PLLON); -#else +#elif defined(RCC_CR_CSSHSEON) && !defined(RCC_CR_HSIOUTEN) CLEAR_BIT(RCC->CR, RCC_CR_HSION| RCC_CR_HSIKERON| RCC_CR_HSIDIVEN | \ RCC_CR_HSEON | RCC_CR_CSSHSEON | RCC_CR_PLLON); #endif @@ -251,17 +300,23 @@ void HAL_RCC_DeInit(void) /* Reset CFGR register */ CLEAR_REG(RCC->CFGR); + /* Set MSIClockRange & MSITRIM[4:0] bits to the reset value */ + MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_MSIRANGE | RCC_ICSCR_MSITRIM), (((uint32_t)0 << RCC_ICSCR_MSITRIM_BITNUMBER) | RCC_ICSCR_MSIRANGE_5)); + + /* Set HSITRIM bits to the reset value */ + MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSITRIM, ((uint32_t)0x10 << 8)); + /* Disable all interrupts */ CLEAR_REG(RCC->CIER); - + /* Update the SystemCoreClock global variable */ - SystemCoreClock = MSI_VALUE; + SystemCoreClock = MSI_VALUE; } /** * @brief Initializes the RCC Oscillators according to the specified parameters in the * RCC_OscInitTypeDef. - * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that + * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that * contains the configuration information for the RCC Oscillators. * @note The PLL is not disabled when used as system clock. * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not @@ -274,19 +329,21 @@ void HAL_RCC_DeInit(void) */ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) { - - uint32_t tickstart = 0U; - + uint32_t tickstart = 0U; + /* Check the parameters */ assert_param(RCC_OscInitStruct != NULL); assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + /*------------------------------- HSE Configuration ------------------------*/ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) { /* Check the parameters */ assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); - /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */ - if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && ((RCC->CFGR & RCC_CFGR_PLLSRC) == RCC_CFGR_PLLSRC_HSE))) + + /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) + || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE))) { if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) { @@ -298,33 +355,34 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) /* Set the new HSE configuration ---------------------------------------*/ __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); - /* Check the HSE State */ - if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF) + + /* Check the HSE State */ + if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF) { - /* Get timeout */ + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till HSE is ready */ + + /* Wait till HSE is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) { - if((HAL_GetTick() - tickstart ) > RCC_HSE_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } - } + } + } } else { - /* Get timeout */ + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till HSE is disabled */ + + /* Wait till HSE is disabled */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) { - if((HAL_GetTick() - tickstart ) > RCC_HSE_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } + } } } } @@ -336,8 +394,9 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); - /* When the HSI is used as system clock it will not disabled */ - if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && ((RCC->CFGR & RCC_CFGR_PLLSRC) == RCC_CFGR_PLLSRC_HSI))) + /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) + || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI))) { /* When HSI is used as system clock it will not disabled */ if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) @@ -354,22 +413,22 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) else { /* Check the HSI State */ - if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF) + if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF) { - /* Enable the Internal High Speed oscillator (HSI or HSIdiv4 */ + /* Enable the Internal High Speed oscillator (HSI or HSIdiv4) */ __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIState); - /* Get Start Tick*/ + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till HSI is ready */ + + /* Wait till HSI is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) { - if((HAL_GetTick() - tickstart ) > RCC_HSI_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } - } + } + } /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); @@ -377,26 +436,25 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) else { /* Disable the Internal High Speed oscillator (HSI). */ - __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIState); - - /* Get Start Tick*/ + __HAL_RCC_HSI_DISABLE(); + + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till HSI is ready */ + + /* Wait till HSI is disabled */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) { - if((HAL_GetTick() - tickstart ) > RCC_HSI_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } - } + } + } } } } /*----------------------------- MSI Configuration --------------------------*/ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) { - /* When the MSI is used as system clock it will not be disabled */ if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_MSI) ) { @@ -404,76 +462,103 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) { return HAL_ERROR; } - - /* Otherwise, just the calibration and MSI range change are allowed */ + /* Otherwise, just the calibration and MSI range change are allowed */ else { /* Check MSICalibrationValue and MSIClockRange input parameters */ assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue)); assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange)); - /* Selects the Multiple Speed oscillator (MSI) clock range .*/ - __HAL_RCC_MSI_RANGE_CONFIG (RCC_OscInitStruct->MSIClockRange); - /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ - __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + /* 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. */ + if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE()) + { + /* First increase number of wait states update if necessary */ + if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) + { + return HAL_ERROR; + } + + /* Selects the Multiple Speed oscillator (MSI) clock range .*/ + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + } + else + { + /* Else, keep current flash latency while decreasing applies */ + /* Selects the Multiple Speed oscillator (MSI) clock range .*/ + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + + /* Decrease number of wait states update if necessary */ + if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) + { + return HAL_ERROR; + } + } /* Update the SystemCoreClock global variable */ - SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; - + SystemCoreClock = (32768U * (1U << ((RCC_OscInitStruct->MSIClockRange >> RCC_ICSCR_MSIRANGE_BITNUMBER) + 1U))) + >> AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_BITNUMBER)]; + /* Configure the source of time base considering new system clocks settings*/ HAL_InitTick (TICK_INT_PRIORITY); } } else { - /* Check the MSI State */ + /* Check MSI State */ assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState)); - if((RCC_OscInitStruct->MSIState)!= RCC_MSI_OFF) + + /* Check the MSI State */ + if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF) { - /* Enable the Internal High Speed oscillator (MSI). */ + /* Enable the Multi Speed oscillator (MSI). */ __HAL_RCC_MSI_ENABLE(); - - /* Get timeout */ + + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till MSI is ready */ + + /* Wait till MSI is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == RESET) { - if((HAL_GetTick() - tickstart ) > RCC_MSI_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } + } } - /* Check MSICalibrationValue and MSIClockRange input parameters */ assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue)); assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange)); - /* Selects the Multiple Speed oscillator (MSI) clock range .*/ - __HAL_RCC_MSI_RANGE_CONFIG (RCC_OscInitStruct->MSIClockRange); + /* Selects the Multiple Speed oscillator (MSI) clock range .*/ + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); - + } else { - /* Disable the Internal High Speed oscillator (MSI). */ + /* Disable the Multi Speed oscillator (MSI). */ __HAL_RCC_MSI_DISABLE(); - - /* Get timeout */ + + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till MSI is ready */ + + /* Wait till MSI is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) != RESET) { - if((HAL_GetTick() - tickstart ) > RCC_MSI_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } - } + } + } } } - } + } /*------------------------------ LSI Configuration -------------------------*/ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) { @@ -481,99 +566,52 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); /* Check the LSI State */ - if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF) + if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF) { /* Enable the Internal Low Speed oscillator (LSI). */ __HAL_RCC_LSI_ENABLE(); - /* Get timeout */ + /* Get Start Tick */ tickstart = HAL_GetTick(); /* Wait till LSI is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) { - if((HAL_GetTick() - tickstart ) > RCC_LSI_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } - } + } + } } else { /* Disable the Internal Low Speed oscillator (LSI). */ __HAL_RCC_LSI_DISABLE(); - /* Get timeout */ + /* Get Start Tick */ tickstart = HAL_GetTick(); - /* Wait till LSI is ready */ + /* Wait till LSI is disabled */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) { - if((HAL_GetTick() - tickstart ) > RCC_LSI_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } - } + } + } } } - -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) - /*------------------------------ HSI48 Configuration -------------------------*/ - if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) - { - /* Check the parameters */ - assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State)); - - /* Check the HSI48 State */ - if((RCC_OscInitStruct->HSI48State)!= RCC_HSI48_OFF) - { - /* Enable the Internal Low Speed oscillator (HSI48). */ - __HAL_RCC_HSI48_ENABLE(); - - /* Get timeout */ - tickstart = HAL_GetTick(); - - /* Wait till HSI48 is ready */ - while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) - { - if((HAL_GetTick() - tickstart ) > RCC_HSI48_TIMEOUT_VALUE) - { - return HAL_TIMEOUT; - } - } - } - else - { - /* Disable the Internal Low Speed oscillator (HSI48). */ - __HAL_RCC_HSI48_DISABLE(); - - /* Get timeout */ - tickstart = HAL_GetTick(); - - /* Wait till HSI48 is ready */ - while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) - { - if((HAL_GetTick() - tickstart ) > RCC_HSI48_TIMEOUT_VALUE) - { - return HAL_TIMEOUT; - } - } - } - } -#endif /* !defined (STM32L011xx) && !defined (STM32L021xx) && !(STM32L031xx) && !(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx)*/ - /*------------------------------ LSE Configuration -------------------------*/ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) { FlagStatus pwrclkchanged = RESET; - FlagStatus backupchanged = RESET; /* Check the parameters */ assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); /* Update LSE configuration in Backup Domain control register */ /* Requires to enable write access to Backup Domain of necessary */ - if(HAL_IS_BIT_CLR(RCC->APB1ENR, RCC_APB1ENR_PWREN)) + if(__HAL_RCC_PWR_IS_CLK_DISABLED()) { __HAL_RCC_PWR_CLK_ENABLE(); pwrclkchanged = SET; @@ -583,7 +621,6 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) { /* Enable write access to Backup domain */ SET_BIT(PWR->CR, PWR_CR_DBP); - backupchanged = SET; /* Wait for Backup domain Write protection disable */ tickstart = HAL_GetTick(); @@ -596,14 +633,13 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) } } } - + /* Set the new LSE configuration -----------------------------------------*/ __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); - /* Check the LSE State */ - if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF) - { - /* Get timeout */ + if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF) + { + /* Get Start Tick */ tickstart = HAL_GetTick(); /* Wait till LSE is ready */ @@ -612,34 +648,76 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } + } } } else { - /* Get timeout */ + /* Get Start Tick */ tickstart = HAL_GetTick(); - /* Wait till LSE is ready */ + /* Wait till LSE is disabled */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) { if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } + } } } - /* Requires to disable write access to Backup Domain of necessary */ - if(backupchanged == SET) - { - CLEAR_BIT(PWR->CR, PWR_CR_DBP); - } + /* Require to disable power clock if necessary */ if(pwrclkchanged == SET) { __HAL_RCC_PWR_CLK_DISABLE(); } } + +#if defined(RCC_HSI48_SUPPORT) + /*----------------------------- HSI48 Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State)); + + /* Check the HSI48 State */ + if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF) + { + /* Enable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI48 is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + { + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI48 is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) + { + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } +#endif /* RCC_HSI48_SUPPORT */ + /*-------------------------------- PLL Configuration -----------------------*/ /* Check the parameters */ assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); @@ -654,22 +732,21 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL)); assert_param(IS_RCC_PLL_DIV(RCC_OscInitStruct->PLL.PLLDIV)); - - + /* Disable the main PLL. */ __HAL_RCC_PLL_DISABLE(); - /* Get timeout */ + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till PLL is ready */ - while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) { - if((HAL_GetTick() - tickstart ) > RCC_PLL_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } - } + } + } /* Configure the main PLL clock source, multiplication and division factors. */ __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, @@ -677,33 +754,34 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) RCC_OscInitStruct->PLL.PLLDIV); /* Enable the main PLL. */ __HAL_RCC_PLL_ENABLE(); - - /* Get timeout */ + + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till PLL is ready */ - while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) { - if((HAL_GetTick() - tickstart ) > RCC_PLL_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } + } } } else { /* Disable the main PLL. */ - __HAL_RCC_PLL_DISABLE(); - /* Get timeout */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick */ tickstart = HAL_GetTick(); - - /* Wait till PLL is ready */ - while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) { - if((HAL_GetTick() - tickstart ) > RCC_PLL_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } + } } } } @@ -724,45 +802,50 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) /* MBED patch - ST internal ticket 42806 */ } } + return HAL_OK; } - + /** - * @brief Initializes the CPU, AHB and APB busses clocks according to the specified + * @brief Initializes the CPU, AHB and APB buses clocks according to the specified * parameters in the RCC_ClkInitStruct. - * @param RCC_ClkInitStruct: pointer to an RCC_OscInitTypeDef structure that + * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that * contains the configuration information for the RCC peripheral. - * @param FLatency: FLASH Latency, this parameter depends on System Clock Frequency - * + * @param FLatency FLASH Latency + * The value of this parameter depend on device used within the same series * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency - * and updated by HAL_RCC_GetHCLKFreq() function called within this function - * + * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function + * * @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 + * start-up 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). + * clock source is ready (clock stable after start-up 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. - * @retval None + * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is + * currently used as system clock source. + * @note Depending on the device voltage range, the software has to set correctly + * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency + * (for more details refer to section above "Initialization/de-initialization functions") + * @retval HAL status */ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) { - uint32_t tickstart = 0U; - + /* Check the parameters */ assert_param(RCC_ClkInitStruct != NULL); assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType)); assert_param(IS_FLASH_LATENCY(FLatency)); - + /* 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. */ - - /* Increasing the CPU frequency */ + must be correctly programmed according to the frequency of the CPU clock + (HCLK) and the supply voltage of the device. */ + + /* Increasing the number of wait states because of higher CPU frequency */ if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY)) { /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ @@ -775,7 +858,7 @@ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, ui return HAL_ERROR; } } - + /*-------------------------- HCLK Configuration --------------------------*/ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) { @@ -787,7 +870,7 @@ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, ui if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) { assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); - + /* HSE is selected as System Clock Source */ if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) { @@ -797,16 +880,6 @@ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, ui return HAL_ERROR; } } - - /* MSI is selected as System Clock Source */ - else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI) - { - /* Check the MSI ready flag */ - if(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == RESET) - { - return HAL_ERROR; - } - } /* PLL is selected as System Clock Source */ else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) { @@ -817,7 +890,7 @@ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, ui } } /* HSI is selected as System Clock Source */ - else + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI) { /* Check the HSI ready flag */ if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) @@ -825,56 +898,64 @@ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, ui return HAL_ERROR; } } - MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource); - - /* Get timeout */ + /* MSI is selected as System Clock Source */ + else + { + /* Check the MSI ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == RESET) + { + return HAL_ERROR; + } + } + __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); + + /* Get Start Tick */ tickstart = HAL_GetTick(); - + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) { while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE) { - if((HAL_GetTick() - tickstart ) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) { return HAL_TIMEOUT; - } + } } } else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) { while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) { - if((HAL_GetTick() - tickstart ) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) - { - return HAL_TIMEOUT; - } - } - } - else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI) - { - while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_MSI) - { - if((HAL_GetTick() - tickstart ) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) - { - return HAL_TIMEOUT; - } - } - } - else - { - while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI) - { - if((HAL_GetTick() - tickstart ) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } } - } - - /* Decreasing the CPU frequency */ - if(FLatency <= (FLASH->ACR & FLASH_ACR_LATENCY)) - { + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_MSI) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + /* Decreasing the number of wait states because of lower CPU frequency */ + if(FLatency < (FLASH->ACR & FLASH_ACR_LATENCY)) + { /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ __HAL_FLASH_SET_LATENCY(FLatency); @@ -884,7 +965,7 @@ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, ui { return HAL_ERROR; } - } + } /*-------------------------- PCLK1 Configuration ---------------------------*/ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) @@ -899,10 +980,10 @@ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, ui assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider)); MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3)); } - + /* Update the SystemCoreClock global variable */ - SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; - + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_BITNUMBER]; + /* Configure the source of time base considering new system clocks settings*/ HAL_InitTick (TICK_INT_PRIORITY); @@ -913,97 +994,130 @@ HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, ui * @} */ -/** @addtogroup RCC_Exported_Functions_Group2 Peripheral Control functions - * @brief RCC clocks control functions - * -@verbatim - =============================================================================== - ##### Peripheral Control functions ##### - =============================================================================== +/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions + * @brief RCC clocks control functions + * + @verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== [..] This subsection provides a set of functions allowing to control the RCC Clocks frequencies. - -@endverbatim + + @endverbatim * @{ */ /** * @brief Selects the clock source to output on MCO pin. * @note MCO pin should be configured in alternate function mode. - * @param RCC_MCOx: specifies the output direction for the clock source. - * For STM32L0xx family this parameter can have only one value: - * @arg RCC_MCO1: Clock source to output on MCO pin(PA8). - * @arg RCC_MCO2: Clock source to output on MCO pin(PA9). - * @arg RCC_MCO3: Clock source to output on MCO pin(PB13) on STM32L03x/4x/7x/8x . - * @param RCC_MCOSource: specifies the clock source to output. + * @param RCC_MCOx specifies the output direction for the clock source. * This parameter can be one of the following values: - * @arg RCC_MCO1SOURCE_NOCLOCK: No clock selected - * @arg RCC_MCO1SOURCE_SYSCLK: System clock selected - * @arg RCC_MCO1SOURCE_HSI: HSI oscillator clock selected - * @arg RCC_MCO1SOURCE_MSI: MSI oscillator clock selected - * @arg RCC_MCO1SOURCE_HSE: HSE oscillator clock selected - * @arg RCC_MCO1SOURCE_PLLCLK: PLL clock selected - * @arg RCC_MCO1SOURCE_LSI: LSI clock selected - * @arg RCC_MCO1SOURCE_LSE: LSE clock selected - * and in STM32L052xx,STM32L053xx,STM32L062xx, STM32L063xx - * STM32L072xx,STM32L073xx,STM32L082xx, STM32L083xx - * @arg RCC_MCO1SOURCE_HSI48: HSI48 clock selected - * @param RCC_MCODiv: specifies the MCO DIV. - * 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 + * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8). + * @arg @ref RCC_MCO2 Clock source to output on MCO2 pin(PA9). + @if STM32L031xx + * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13) + @elseif STM32L041xx + * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13) + @elseif STM32L073xx + * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13) + @elseif STM32L083xx + * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13) + @elseif STM32L072xx + * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13) + @elseif STM32L082xx + * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13) + @elseif STM32L071xx + * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13) + @elseif STM32L081xx + * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13) + @endif + * @param RCC_MCOSource specifies the clock source to output. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_MSI MSI oscillator clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO clock + @if STM32L052xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L053xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L062xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L063xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L072xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L073xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L082xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L083xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @endif + * @param RCC_MCODiv specifies the MCO DIV. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 no division applied to MCO clock + * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock + * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock + * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock + * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock * @retval None */ -void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv) +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv) { - GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitTypeDef gpio = {0}; + /* Check the parameters */ assert_param(IS_RCC_MCO(RCC_MCOx)); assert_param(IS_RCC_MCODIV(RCC_MCODiv)); assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource)); - - /* Configure the MCO pin in alternate function mode */ - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Pull = GPIO_NOPULL; - + + /* Configure the MCO1 pin in alternate function mode */ + gpio.Mode = GPIO_MODE_AF_PP; + gpio.Speed = GPIO_SPEED_FREQ_HIGH; + gpio.Pull = GPIO_NOPULL; if(RCC_MCOx == RCC_MCO1) { - /* MCO Clock Enable */ - __MCO1_CLK_ENABLE(); - GPIO_InitStruct.Pin = MCO1_PIN; - GPIO_InitStruct.Alternate = GPIO_AF0_MCO; - HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + gpio.Pin = MCO1_PIN; + gpio.Alternate = GPIO_AF0_MCO; + + /* MCO1 Clock Enable */ + MCO1_CLK_ENABLE(); + HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio); } - else if (RCC_MCOx == RCC_MCO2) - { - /* MCO Clock Enable */ - __MCO2_CLK_ENABLE(); - GPIO_InitStruct.Pin = MCO2_PIN; - GPIO_InitStruct.Alternate = GPIO_AF0_MCO; - HAL_GPIO_Init(MCO2_GPIO_PORT, &GPIO_InitStruct); - } -#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx) - else +#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx) + else if (RCC_MCOx == RCC_MCO3) { - /* MCO Clock Enable */ - __MCO3_CLK_ENABLE(); - GPIO_InitStruct.Pin = MCO3_PIN; - GPIO_InitStruct.Alternate = GPIO_AF2_MCO; - HAL_GPIO_Init(MCO3_GPIO_PORT, &GPIO_InitStruct); + gpio.Pin = MCO3_PIN; + gpio.Alternate = GPIO_AF2_MCO; + + /* MCO3 Clock Enable */ + MCO3_CLK_ENABLE(); + HAL_GPIO_Init(MCO3_GPIO_PORT, &gpio); } -#endif - - /* Mask MCO and MCOPRE[2:0] bits then Select MCO clock source and prescaler */ - MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCO_PRE), ((RCC_MCOSource | RCC_MCODiv ))); +#endif + else + { + gpio.Pin = MCO2_PIN; + gpio.Alternate = GPIO_AF0_MCO; + + /* MCO2 Clock Enable */ + MCO2_CLK_ENABLE(); + HAL_GPIO_Init(MCO2_GPIO_PORT, &gpio); + } + + /* Configure the MCO clock source */ + __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv); } -#if !defined (STM32L011xx) && !defined (STM32L021xx) +#if defined(RCC_HSECSS_SUPPORT) /** * @brief Enables the Clock Security System. * @note If a failure is detected on the HSE oscillator clock, this oscillator @@ -1015,21 +1129,20 @@ void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_ */ void HAL_RCC_EnableCSS(void) { - SET_BIT(RCC->CR, RCC_CR_CSSHSEON) ; + SET_BIT(RCC->CR, RCC_CR_CSSON) ; } -#endif +#endif /* RCC_HSECSS_SUPPORT */ /** - * @brief Returns the SYSCLK frequency - * + * @brief Returns the SYSCLK frequency * @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: - * @note If SYSCLK source is MSI, function returns values based on MSI + * @note If SYSCLK source is MSI, function returns a value based on MSI * Value as defined by the MSI range. * @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(**) + * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE(**) + * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE(**) * or HSI_VALUE(*) multiplied/divided by the PLL factors. * @note (*) HSI_VALUE is a constant defined in stm32l0xx_hal_conf.h file (default value * 16 MHz) but the real value may vary depending on the variations @@ -1043,36 +1156,28 @@ void HAL_RCC_EnableCSS(void) * value for HSE crystal. * * @note This function can be used by the user application to compute the - * baudrate for the communication peripherals or configure other parameters. + * baud-rate for the communication peripherals or configure other parameters. * * @note Each time SYSCLK changes, this function must be called to update the * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. * - * * @retval SYSCLK frequency */ uint32_t HAL_RCC_GetSysClockFreq(void) { - uint32_t pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U; - uint32_t sysclockfreq = 0U; - - /* Get SYSCLK source -------------------------------------------------------*/ - - /*MSI frequency range in HZ*/ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; + uint32_t tmpreg = 0, pllm = 0, plld = 0, pllvco = 0, msiclkrange = 0; + uint32_t sysclockfreq = 0; - switch (RCC->CFGR & RCC_CFGR_SWS) + tmpreg = RCC->CFGR; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (tmpreg & RCC_CFGR_SWS) { - case RCC_CFGR_SWS_MSI: /* MSI used as system clock */ - { - sysclockfreq = (32768U * (1U << (msirange + 1U))); - break; - } - case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock */ + case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ { - if ((RCC->CR & RCC_CR_HSIDIVF) != 0U) + if ((RCC->CR & RCC_CR_HSIDIVF) != 0) { - sysclockfreq = (HSI_VALUE >> 2U); + sysclockfreq = (HSI_VALUE >> 2); } else { @@ -1087,36 +1192,32 @@ uint32_t HAL_RCC_GetSysClockFreq(void) } case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* 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 >> 18U)]; - plldiv = (plldiv >> 22U) + 1U; - - pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; - - if (pllsource == RCC_CFGR_PLLSRC_HSI) + pllm = PLLMulTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_BITNUMBER]; + plld = ((uint32_t)(tmpreg & RCC_CFGR_PLLDIV) >> RCC_CFGR_PLLDIV_BITNUMBER) + 1; + if (__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) { - /* HSI oscillator clock selected as PLL clock source */ - if ((RCC->CR & RCC_CR_HSIDIVF) != 0U) - { - sysclockfreq = (((HSI_VALUE >> 2U) * pllmul) / plldiv); - } - else - { - sysclockfreq =((HSI_VALUE * pllmul) / plldiv); - } + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE * pllm) / plld; } else { - /* HSE selected as PLL clock source */ - sysclockfreq = ((HSE_VALUE * pllmul) / plldiv); + if ((RCC->CR & RCC_CR_HSIDIVF) != 0) + { + pllvco = ((HSI_VALUE >> 2) * pllm) / plld; + } + else + { + pllvco = (HSI_VALUE * pllm) / plld; + } } + sysclockfreq = pllvco; break; } + case RCC_SYSCLKSOURCE_STATUS_MSI: /* MSI used as system clock source */ default: /* MSI used as system clock */ { - sysclockfreq = (32768U * (1U << (msirange + 1U))); + msiclkrange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> RCC_ICSCR_MSIRANGE_BITNUMBER; + sysclockfreq = (32768 * (1 << (msiclkrange + 1))); break; } } @@ -1127,14 +1228,14 @@ uint32_t HAL_RCC_GetSysClockFreq(void) * @brief Returns the HCLK frequency * @note Each time HCLK changes, this function must be called to update the * right HCLK value. Otherwise, any configuration based on this function will be incorrect. - * + * * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency - * and updated within this function + * and updated within this function * @retval HCLK frequency */ uint32_t HAL_RCC_GetHCLKFreq(void) { - return (SystemCoreClock); + return SystemCoreClock; } /** @@ -1145,9 +1246,8 @@ uint32_t HAL_RCC_GetHCLKFreq(void) */ uint32_t HAL_RCC_GetPCLK1Freq(void) { - - return ( HAL_RCC_GetHCLKFreq() >> APBPrescTable[((RCC->CFGR & RCC_CFGR_PPRE1) >> 8U)]); - + /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_BITNUMBER]); } /** @@ -1158,26 +1258,29 @@ uint32_t HAL_RCC_GetPCLK1Freq(void) */ uint32_t HAL_RCC_GetPCLK2Freq(void) { - - return ( HAL_RCC_GetHCLKFreq() >> APBPrescTable[((RCC->CFGR & RCC_CFGR_PPRE2) >> 11U)]); - + /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_BITNUMBER]); } /** * @brief Configures the RCC_OscInitStruct according to the internal * RCC configuration registers. - * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that + * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that * will be configured. * @retval None */ void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) { + /* Check the parameters */ + assert_param(RCC_OscInitStruct != NULL); + /* Set all possible values for the Oscillator type parameter ---------------*/ - RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_MSI | RCC_OSCILLATORTYPE_HSI | \ - RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI; -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI \ + | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_MSI; +#if defined(RCC_HSI48_SUPPORT) RCC_OscInitStruct->OscillatorType |= RCC_OSCILLATORTYPE_HSI48; -#endif +#endif /* RCC_HSI48_SUPPORT */ + /* Get the HSE configuration -----------------------------------------------*/ if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP) @@ -1192,6 +1295,18 @@ void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) { RCC_OscInitStruct->HSEState = RCC_HSE_OFF; } + + /* Get the HSI configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION) + { + RCC_OscInitStruct->HSIState = RCC_HSI_ON; + } + else + { + RCC_OscInitStruct->HSIState = RCC_HSI_OFF; + } + + RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> 8); /* Get the MSI configuration -----------------------------------------------*/ if((RCC->CR &RCC_CR_MSION) == RCC_CR_MSION) @@ -1203,32 +1318,8 @@ void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) RCC_OscInitStruct->MSIState = RCC_MSI_OFF; } - RCC_OscInitStruct->MSICalibrationValue = (uint32_t)((RCC->CR &RCC_ICSCR_MSITRIM) >> 24U); - RCC_OscInitStruct->MSIClockRange = (uint32_t)((RCC->ICSCR &RCC_ICSCR_MSIRANGE) >> 13U); - -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) - /* Get the HSI48 configuration -----------------------------------------------*/ - if((RCC->CRRCR &RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON) - { - RCC_OscInitStruct->HSI48State = RCC_HSI48_ON; - } - else - { - RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF; - } -#endif - - /* Get the HSI configuration -----------------------------------------------*/ - if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION) - { - RCC_OscInitStruct->HSIState = RCC_HSI_ON; - } - else - { - RCC_OscInitStruct->HSIState = RCC_HSI_OFF; - } - - RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->ICSCR &RCC_ICSCR_HSITRIM) >> 8U); + RCC_OscInitStruct->MSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_BITNUMBER); + RCC_OscInitStruct->MSIClockRange = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSIRANGE)); /* Get the LSE configuration -----------------------------------------------*/ if((RCC->CSR &RCC_CSR_LSEBYP) == RCC_CSR_LSEBYP) @@ -1254,6 +1345,11 @@ void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) RCC_OscInitStruct->LSIState = RCC_LSI_OFF; } +#if defined(RCC_HSI48_SUPPORT) + /* Get the HSI48 configuration if any-----------------------------------------*/ + RCC_OscInitStruct->HSI48State = __HAL_RCC_GET_HSI48_STATE(); +#endif /* RCC_HSI48_SUPPORT */ + /* Get the PLL configuration -----------------------------------------------*/ if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON) { @@ -1264,24 +1360,27 @@ void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; } RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC); - RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMUL) >> 18U; - RCC_OscInitStruct->PLL.PLLDIV = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLDIV) >> 22U; - + RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMUL); + RCC_OscInitStruct->PLL.PLLDIV = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLDIV); } /** - * @brief Configures the RCC_ClkInitStruct according to the internal + * @brief Get the RCC_ClkInitStruct according to the internal * RCC configuration registers. - * @param RCC_ClkInitStruct: pointer to an RCC_ClkInitTypeDef structure that - * will be configured. - * @param pFLatency: Pointer on the Flash Latency. + * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that + * contains the current clock configuration. + * @param pFLatency Pointer on the Flash Latency. * @retval None */ void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency) { + /* Check the parameters */ + assert_param(RCC_ClkInitStruct != NULL); + assert_param(pFLatency != NULL); + /* Set all possible values for the Clock type parameter --------------------*/ RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; - + /* Get the SYSCLK configuration --------------------------------------------*/ RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW); @@ -1292,13 +1391,13 @@ void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pF RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1); /* Get the APB2 configuration ----------------------------------------------*/ - RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3U); + RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3); /* Get the Flash Wait State (Latency) configuration ------------------------*/ *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY); } -#if !defined (STM32L011xx) && !defined (STM32L021xx) +#if defined(RCC_HSECSS_SUPPORT) /** * @brief This function handles the RCC CSS interrupt request. * @note This API should be called under the NMI_Handler(). @@ -1307,33 +1406,28 @@ void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pF void HAL_RCC_NMI_IRQHandler(void) { /* Check RCC CSSF flag */ - if(__HAL_RCC_GET_IT(RCC_IT_CSSHSE)) + if(__HAL_RCC_GET_IT(RCC_IT_CSS)) { /* RCC Clock Security System interrupt user callback */ HAL_RCC_CSSCallback(); - + /* Clear RCC CSS pending bit */ - __HAL_RCC_CLEAR_IT(RCC_IT_CSSHSE); + __HAL_RCC_CLEAR_IT(RCC_IT_CSS); } } /** * @brief RCC Clock Security System interrupt callback - * @retval None + * @retval none */ __weak void HAL_RCC_CSSCallback(void) { /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_RCC_CSSCallback could be implemented in the user file - */ + the HAL_RCC_CSSCallback could be implemented in the user file + */ } -#endif - -/** - * @} - */ - +#endif /* RCC_HSECSS_SUPPORT */ /** * @} */ @@ -1342,11 +1436,65 @@ __weak void HAL_RCC_CSSCallback(void) * @} */ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup RCC_Private_Functions + * @{ + */ +/** + * @brief Update number of Flash wait states in line with MSI range and current + voltage range + * @param MSIrange MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_6 + * @retval HAL status + */ +static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSIrange) +{ + uint32_t vos = 0; + uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */ + + /* HCLK can reach 4 MHz only if AHB prescaler = 1 */ + if (READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1) + { + if(__HAL_RCC_PWR_IS_CLK_ENABLED()) + { + vos = READ_BIT(PWR->CR, PWR_CR_VOS); + } + else + { + __HAL_RCC_PWR_CLK_ENABLE(); + vos = READ_BIT(PWR->CR, PWR_CR_VOS); + __HAL_RCC_PWR_CLK_DISABLE(); + } + + /* Check if need to set latency 1 only for Range 3 & HCLK = 4MHz */ + if((vos == PWR_REGULATOR_VOLTAGE_SCALE3) && (MSIrange == RCC_MSIRANGE_6)) + { + latency = FLASH_LATENCY_1; /* 1WS */ + } + } + + __HAL_FLASH_SET_LATENCY(latency); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if((FLASH->ACR & FLASH_ACR_LATENCY) != latency) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @} + */ + #endif /* HAL_RCC_MODULE_ENABLED */ +/** + * @} + */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.h index 28706b47f9..2e41784b25 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_rcc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of RCC HAL module. ****************************************************************************** * @attention @@ -50,74 +48,246 @@ * @{ */ -/** @defgroup RCC RCC +/** @addtogroup RCC * @{ */ +/** @addtogroup RCC_Private_Constants + * @{ + */ + +/** @defgroup RCC_Timeout RCC Timeout + * @{ + */ + +/* Disable Backup domain write protection state change timeout */ +#define RCC_DBP_TIMEOUT_VALUE (100U) /* 100 ms */ +/* LSE state change timeout */ +#define RCC_LSE_TIMEOUT_VALUE LSE_STARTUP_TIMEOUT +#define CLOCKSWITCH_TIMEOUT_VALUE (5000U) /* 5 s */ +#define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT +#define MSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define HSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define HSI48_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define LSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define PLL_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#if defined(RCC_HSI48_SUPPORT) +#define HSI48_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#endif /* RCC_HSI48_SUPPORT */ +/** + * @} + */ + + +/** @defgroup RCC_BitAddress_AliasRegion BitAddress AliasRegion + * @brief RCC registers bit address in the alias region + * @{ + */ +#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) +/* --- CR Register ---*/ +/* Alias word address of HSION bit */ +#define RCC_CR_OFFSET (RCC_OFFSET + 0x00U) +/* --- CFGR Register ---*/ +/* Alias word address of I2SSRC bit */ +#define RCC_CFGR_OFFSET (RCC_OFFSET + 0x08U) +/* --- CSR Register ---*/ +#define RCC_CSR_OFFSET (RCC_OFFSET + 0x74U) + +/* CR register byte 3 (Bits[23:16]) base address */ +#define RCC_CR_BYTE2_ADDRESS (0x40023802U) + +/* CIER register byte 0 (Bits[0:8]) base address */ +#define CIER_BYTE0_ADDRESS ((uint32_t)(RCC_BASE + 0x10U + 0x00U)) +/** + * @} + */ + + +/* Defines used for Flags */ +#define CR_REG_INDEX ((uint8_t)1) +#define CSR_REG_INDEX ((uint8_t)2) +#define CRRCR_REG_INDEX ((uint8_t)3) + +#define RCC_FLAG_MASK ((uint8_t)0x1F) + +/** + * @} + */ + +/** @addtogroup RCC_Private_Macros + * @{ + */ +#if defined(RCC_HSI48_SUPPORT) +#define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__) (((__OSCILLATOR__) == RCC_OSCILLATORTYPE_NONE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)) + +#define IS_RCC_HSI48(__HSI48__) (((__HSI48__) == RCC_HSI48_OFF) || ((__HSI48__) == RCC_HSI48_ON)) +#else +#define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__) (((__OSCILLATOR__) == RCC_OSCILLATORTYPE_NONE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)) +#endif /* RCC_HSI48_SUPPORT */ +#define IS_RCC_PLLSOURCE(__SOURCE__) (((__SOURCE__) == RCC_PLLSOURCE_HSI) || \ + ((__SOURCE__) == RCC_PLLSOURCE_HSE)) +#define IS_RCC_HSE(__HSE__) (((__HSE__) == RCC_HSE_OFF) || ((__HSE__) == RCC_HSE_ON) || \ + ((__HSE__) == RCC_HSE_BYPASS)) +#define IS_RCC_LSE(__LSE__) (((__LSE__) == RCC_LSE_OFF) || ((__LSE__) == RCC_LSE_ON) || \ + ((__LSE__) == RCC_LSE_BYPASS)) +#if defined(RCC_CR_HSIOUTEN) +#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON) || \ + ((__HSI__) == RCC_HSI_DIV4) || ((__HSI__) == RCC_HSI_OUTEN )) +#else +#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON) || \ + ((__HSI__) == RCC_HSI_DIV4)) +#endif /* RCC_CR_HSIOUTEN */ +#define IS_RCC_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0x1F) +#define IS_RCC_MSICALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0xFF) +#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)) +#define IS_RCC_LSI(__LSI__) (((__LSI__) == RCC_LSI_OFF) || ((__LSI__) == RCC_LSI_ON)) +#define IS_RCC_MSI(__MSI__) (((__MSI__) == RCC_MSI_OFF) || ((__MSI__) == RCC_MSI_ON)) + +#define IS_RCC_PLL(__PLL__) (((__PLL__) == RCC_PLL_NONE) || ((__PLL__) == RCC_PLL_OFF) || \ + ((__PLL__) == RCC_PLL_ON)) +#define IS_RCC_PLL_DIV(__DIV__) (((__DIV__) == RCC_PLL_DIV2) || \ + ((__DIV__) == RCC_PLL_DIV3) || ((__DIV__) == RCC_PLL_DIV4)) + +#define IS_RCC_PLL_MUL(__MUL__) (((__MUL__) == RCC_PLL_MUL3) || ((__MUL__) == RCC_PLL_MUL4) || \ + ((__MUL__) == RCC_PLL_MUL6) || ((__MUL__) == RCC_PLL_MUL8) || \ + ((__MUL__) == RCC_PLL_MUL12) || ((__MUL__) == RCC_PLL_MUL16) || \ + ((__MUL__) == RCC_PLL_MUL24) || ((__MUL__) == RCC_PLL_MUL32) || \ + ((__MUL__) == RCC_PLL_MUL48)) +#define IS_RCC_CLOCKTYPE(CLK) ((((CLK) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) || \ + (((CLK) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) || \ + (((CLK) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) || \ + (((CLK) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)) +#define IS_RCC_SYSCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_MSI) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_PLLCLK)) +#define IS_RCC_SYSCLKSOURCE_STATUS(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_MSI) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_HSI) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_HSE) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_PLLCLK)) +#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)) +#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)) +#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx) +#define IS_RCC_MCO(__MCO__) (((__MCO__) == RCC_MCO1) || ((__MCO__) == RCC_MCO2) || ((__MCO__) == RCC_MCO3)) +#else +#define IS_RCC_MCO(__MCO__) (((__MCO__) == RCC_MCO1) || ((__MCO__) == RCC_MCO2)) + +#endif +#define IS_RCC_MCODIV(__DIV__) (((__DIV__) == RCC_MCODIV_1) || ((__DIV__) == RCC_MCODIV_2) || \ + ((__DIV__) == RCC_MCODIV_4) || ((__DIV__) == RCC_MCODIV_8) || \ + ((__DIV__) == RCC_MCODIV_16)) +#if defined(RCC_CFGR_MCOSEL_HSI48) +#define IS_RCC_MCO1SOURCE(__SOURCE__) (((__SOURCE__) == RCC_MCO1SOURCE_NOCLOCK) || ((__SOURCE__) == RCC_MCO1SOURCE_SYSCLK) || \ + ((__SOURCE__) == RCC_MCO1SOURCE_HSI) || ((__SOURCE__) == RCC_MCO1SOURCE_MSI) || \ + ((__SOURCE__) == RCC_MCO1SOURCE_HSE) || ((__SOURCE__) == RCC_MCO1SOURCE_PLLCLK) || \ + ((__SOURCE__) == RCC_MCO1SOURCE_LSI) || ((__SOURCE__) == RCC_MCO1SOURCE_LSE) || \ + ((__SOURCE__) == RCC_MCO1SOURCE_HSI48)) +#else +#define IS_RCC_MCO1SOURCE(__SOURCE__) (((__SOURCE__) == RCC_MCO1SOURCE_NOCLOCK) || ((__SOURCE__) == RCC_MCO1SOURCE_SYSCLK) || \ + ((__SOURCE__) == RCC_MCO1SOURCE_HSI) || ((__SOURCE__) == RCC_MCO1SOURCE_MSI) || \ + ((__SOURCE__) == RCC_MCO1SOURCE_HSE) || ((__SOURCE__) == RCC_MCO1SOURCE_PLLCLK) || \ + ((__SOURCE__) == RCC_MCO1SOURCE_LSI) || ((__SOURCE__) == RCC_MCO1SOURCE_LSE)) +#endif /* RCC_CFGR_MCOSEL_HSI48 */ +#define IS_RCC_RTCCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_RTCCLKSOURCE_NO_CLK) || \ + ((__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)) + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ + /** @defgroup RCC_Exported_Types RCC Exported Types * @{ */ -/** - * @brief RCC PLL configuration structure definition +/** + * @brief RCC PLL configuration structure definition */ typedef struct { - uint32_t PLLState; /*!< The new state of the PLL. - This parameter can be a value of @ref RCC_PLL_Config */ + uint32_t PLLState; /*!< PLLState: The new state of the PLL. + This parameter can be a value of @ref RCC_PLL_Config */ - uint32_t PLLSource; /*!< RCC_PLLSource: PLL entry clock source. - This parameter must be a value of @ref RCC_PLL_Clock_Source */ + uint32_t PLLSource; /*!< PLLSource: PLL entry clock source. + This parameter must be a value of @ref RCC_PLL_Clock_Source */ - uint32_t PLLMUL; /*!< PLLMUL: Multiplication factor for PLL VCO output clock - This parameter must of @ref RCC_PLLMultiplication_Factor */ - - uint32_t PLLDIV; /*!< PLLDIV: Division factor for main system clock (SYSCLK) - This parameter must be a value of @ref RCC_PLLDivider_Factor */ - -}RCC_PLLInitTypeDef; + uint32_t PLLMUL; /*!< PLLMUL: Multiplication factor for PLL VCO input clock + This parameter must be a value of @ref RCC_PLL_Multiplication_Factor*/ + uint32_t PLLDIV; /*!< PLLDIV: Division factor for PLL VCO input clock + This parameter must be a value of @ref RCC_PLL_Division_Factor*/ +} RCC_PLLInitTypeDef; + /** * @brief RCC Internal/External Oscillator (HSE, HSI, LSE and LSI) configuration structure definition */ typedef struct { - uint32_t OscillatorType; /*!< The oscillators to be configured. - This parameter can be a value of @ref RCC_Oscillator_Type */ + uint32_t OscillatorType; /*!< The oscillators to be configured. + This parameter can be a value of @ref RCC_Oscillator_Type */ - uint32_t HSEState; /*!< The new state of the HSE. - This parameter can be a value of @ref RCC_HSE_Config */ + uint32_t HSEState; /*!< The new state of the HSE. + This parameter can be a value of @ref RCC_HSE_Config */ - uint32_t LSEState; /*!< The new state of the LSE. - This parameter can be a value of @ref RCC_LSE_Config */ + uint32_t LSEState; /*!< The new state of the LSE. + This parameter can be a value of @ref RCC_LSE_Config */ - uint32_t HSIState; /*!< The new state of the HSI. - This parameter can be a value of @ref RCC_HSI_Config */ + uint32_t HSIState; /*!< The new state of the HSI. + This parameter can be a value of @ref RCC_HSI_Config */ - uint32_t HSICalibrationValue; /*!< The calibration trimming value. - This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x1F */ + uint32_t HSICalibrationValue; /*!< The HSI calibration trimming value (default is RCC_HSICALIBRATION_DEFAULT). + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x1F */ - uint32_t LSIState; /*!< The new state of the LSI. - This parameter can be a value of @ref RCC_LSI_Config */ + uint32_t LSIState; /*!< The new state of the LSI. + This parameter can be a value of @ref RCC_LSI_Config */ -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - uint32_t HSI48State; /*!< The new state of the HSI48. - This parameter can be a value of @ref RCC_HSI48_Config */ -#endif +#if defined(RCC_HSI48_SUPPORT) + uint32_t HSI48State; /*!< The new state of the HSI48. + This parameter can be a value of @ref RCC_HSI48_Config */ - uint32_t MSIState; /*!< The new state of the MSI. - This parameter can be a value of @ref RCC_MSI_Config */ +#endif /* RCC_HSI48_SUPPORT */ + uint32_t MSIState; /*!< The new state of the MSI. + This parameter can be a value of @ref RCC_MSI_Config */ - uint32_t MSICalibrationValue; /*!< The calibration trimming value. - This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */ + uint32_t MSICalibrationValue; /*!< The MSI calibration trimming value. (default is RCC_MSICALIBRATION_DEFAULT). + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */ uint32_t MSIClockRange; /*!< The MSI frequency range. - This parameter can be a value of @ref RCC_MSI_Clock_Range */ + This parameter can be a value of @ref RCC_MSI_Clock_Range */ - RCC_PLLInitTypeDef PLL; /*!< PLL structure parameters */ + RCC_PLLInitTypeDef PLL; /*!< PLL structure parameters */ -}RCC_OscInitTypeDef; +} RCC_OscInitTypeDef; /** * @brief RCC System, AHB and APB busses clock configuration structure definition @@ -138,184 +308,82 @@ typedef struct uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK). This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */ - -}RCC_ClkInitTypeDef; +} RCC_ClkInitTypeDef; /** * @} */ - -/* Private constants --------------------------------------------------------*/ -/** @addtogroup RCC_Private - * @brief RCC registers bit address in the alias region - * @{ - */ -#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) -/* --- CR Register ---*/ -/* Alias word address of HSION bit */ -#define RCC_CR_OFFSET (RCC_OFFSET + 0x00U) -/* --- CFGR Register ---*/ -/* Alias word address of I2SSRC bit */ -#define RCC_CFGR_OFFSET (RCC_OFFSET + 0x08U) -/* --- CSR Register ---*/ -#define RCC_CSR_OFFSET (RCC_OFFSET + 0x74U) -/* CR register byte 3 (Bits[23:16]) base address */ -#define RCC_CR_BYTE2_ADDRESS ((uint32_t)0x40023802U) - -/* CIER register byte 0 (Bits[0:8]) base address */ -#define CIER_BYTE0_ADDRESS ((uint32_t)(RCC_BASE + 0x10U + 0x00U)) - -/** - * @} - */ - /* Exported constants --------------------------------------------------------*/ /** @defgroup RCC_Exported_Constants RCC Exported Constants * @{ */ -/** @defgroup RCC_Timeout_Value Timeout Values +/** @defgroup RCC_PLL_Clock_Source PLL Clock Source * @{ */ -#define RCC_DBP_TIMEOUT_VALUE ((uint32_t)100U) /* 100 ms */ -#define RCC_LSE_TIMEOUT_VALUE LSE_STARTUP_TIMEOUT -#define RCC_HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT + +#define RCC_PLLSOURCE_HSI RCC_CFGR_PLLSRC_HSI /*!< HSI clock selected as PLL entry clock source */ +#define RCC_PLLSOURCE_HSE RCC_CFGR_PLLSRC_HSE /*!< HSE clock selected as PLL entry clock source */ + /** * @} */ - + /** @defgroup RCC_Oscillator_Type Oscillator Type * @{ */ -#define RCC_OSCILLATORTYPE_NONE ((uint32_t)0x00000000U) /*!< Oscillator configuration unchanged */ -#define RCC_OSCILLATORTYPE_HSE ((uint32_t)0x00000001U) /*!< HSE to configure */ -#define RCC_OSCILLATORTYPE_HSI ((uint32_t)0x00000002U) /*!< HSI to configure */ -#define RCC_OSCILLATORTYPE_LSE ((uint32_t)0x00000004U) /*!< LSE to configure */ -#define RCC_OSCILLATORTYPE_LSI ((uint32_t)0x00000008U) /*!< LSI to configure */ -#define RCC_OSCILLATORTYPE_MSI ((uint32_t)0x00000010U) /*!< MSI to configure */ -#if !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define RCC_OSCILLATORTYPE_HSI48 ((uint32_t)0x00000020U) -#endif /* !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) */ - +#define RCC_OSCILLATORTYPE_NONE ((uint32_t)0x00000000) +#define RCC_OSCILLATORTYPE_HSE ((uint32_t)0x00000001) +#define RCC_OSCILLATORTYPE_HSI ((uint32_t)0x00000002) +#define RCC_OSCILLATORTYPE_LSE ((uint32_t)0x00000004) +#define RCC_OSCILLATORTYPE_LSI ((uint32_t)0x00000008) +#define RCC_OSCILLATORTYPE_MSI ((uint32_t)0x00000010) +#if defined(RCC_HSI48_SUPPORT) +#define RCC_OSCILLATORTYPE_HSI48 ((uint32_t)0x00000020) +#endif /* RCC_HSI48_SUPPORT */ /** * @} */ -/** @defgroup RCC_HSE_Config RCC HSE Config +/** @defgroup RCC_HSE_Config HSE Config * @{ */ -#define RCC_HSE_OFF ((uint32_t)0x00000000U) -#define RCC_HSE_ON RCC_CR_HSEON -#define RCC_HSE_BYPASS ((uint32_t)(RCC_CR_HSEBYP | RCC_CR_HSEON)) - +#define RCC_HSE_OFF ((uint32_t)0x00000000) /*!< HSE clock deactivation */ +#define RCC_HSE_ON RCC_CR_HSEON /*!< HSE clock activation */ +#define RCC_HSE_BYPASS ((uint32_t)(RCC_CR_HSEBYP | RCC_CR_HSEON)) /*!< External clock source for HSE clock */ /** * @} */ -/** @defgroup RCC_LSE_Config RCC LSE Config +/** @defgroup RCC_LSE_Config LSE Config * @{ */ -#define RCC_LSE_OFF ((uint32_t)0x00000000U) -#define RCC_LSE_ON RCC_CSR_LSEON -#define RCC_LSE_BYPASS ((uint32_t)(RCC_CSR_LSEBYP | RCC_CSR_LSEON)) +#define RCC_LSE_OFF ((uint32_t)0x00000000) /*!< LSE clock deactivation */ +#define RCC_LSE_ON RCC_CSR_LSEON /*!< LSE clock activation */ +#define RCC_LSE_BYPASS ((uint32_t)(RCC_CSR_LSEBYP | RCC_CSR_LSEON)) /*!< External clock source for LSE clock */ /** * @} */ - - -/** @defgroup RCC_LSI_Config RCC LSI Config +/** @defgroup RCC_HSI_Config HSI Config * @{ */ -#define RCC_LSI_OFF ((uint8_t)0x00U) -#define RCC_LSI_ON ((uint8_t)0x01U) +#define RCC_HSI_OFF ((uint32_t)0x00000000) /*!< HSI clock deactivation */ +#define RCC_HSI_ON RCC_CR_HSION /*!< HSI clock activation */ +#define RCC_HSI_DIV4 (RCC_CR_HSIDIVEN | RCC_CR_HSION) /*!< HSI_DIV4 clock activation */ +#if defined(RCC_CR_HSIOUTEN) +#define RCC_HSI_OUTEN RCC_CR_HSIOUTEN /*!< HSI_OUTEN clock activation */ +#endif /* RCC_CR_HSIOUTEN */ -#define RCC_MSICALIBRATION_DEFAULT ((uint32_t)0) /* Default MSI calibration trimming value */ +#define RCC_HSICALIBRATION_DEFAULT ((uint32_t)0x10) /* Default HSI calibration trimming value */ /** * @} */ - -/** @defgroup RCC_MSI_Config RCC MSI Config - * @{ - */ -#define RCC_MSI_OFF ((uint8_t)0x00U) -#define RCC_MSI_ON ((uint8_t)0x01U) - -#define RCC_HSICALIBRATION_DEFAULT ((uint32_t)0x10U) /* Default HSI calibration trimming value */ - -/** - * @} - */ - -#if !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -/** @defgroup RCC_HSI48_Config RCC HSI48 Configuration - * @{ - */ -#define RCC_HSI48_OFF ((uint8_t)0x00U) -#define RCC_HSI48_ON ((uint8_t)0x01U) - -/** - * @} - */ -#endif /* !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) */ - -/** @defgroup RCC_PLL_Config RCC PLL Config - * @{ - */ -#define RCC_PLL_NONE ((uint8_t)0x00U) -#define RCC_PLL_OFF ((uint8_t)0x01U) -#define RCC_PLL_ON ((uint8_t)0x02U) - -/** - * @} - */ - -/** @defgroup RCC_PLL_Clock_Source RCC PLL Clock Source - * @{ - */ -#define RCC_PLLSOURCE_HSI RCC_CFGR_PLLSRC_HSI -#define RCC_PLLSOURCE_HSE RCC_CFGR_PLLSRC_HSE - - -/** - * @} - */ - -/** @defgroup RCC_PLLMultiplication_Factor RCC PLL Multipliers - * @{ - */ - -#define RCC_PLLMUL_3 RCC_CFGR_PLLMUL3 -#define RCC_PLLMUL_4 RCC_CFGR_PLLMUL4 -#define RCC_PLLMUL_6 RCC_CFGR_PLLMUL6 -#define RCC_PLLMUL_8 RCC_CFGR_PLLMUL8 -#define RCC_PLLMUL_12 RCC_CFGR_PLLMUL12 -#define RCC_PLLMUL_16 RCC_CFGR_PLLMUL16 -#define RCC_PLLMUL_24 RCC_CFGR_PLLMUL24 -#define RCC_PLLMUL_32 RCC_CFGR_PLLMUL32 -#define RCC_PLLMUL_48 RCC_CFGR_PLLMUL48 - -/** - * @} - */ - -/** @defgroup RCC_PLLDivider_Factor RCC PLL Dividers - * @{ - */ - -#define RCC_PLLDIV_2 RCC_CFGR_PLLDIV2 -#define RCC_PLLDIV_3 RCC_CFGR_PLLDIV3 -#define RCC_PLLDIV_4 RCC_CFGR_PLLDIV4 - -/** - * @} - */ - -/** @defgroup RCC_MSI_Clock_Range RCC MSI Clock Range +/** @defgroup RCC_MSI_Clock_Range MSI Clock Range * @{ */ @@ -327,211 +395,291 @@ typedef struct #define RCC_MSIRANGE_5 RCC_ICSCR_MSIRANGE_5 /*!< MSI = 2.097 MHz */ #define RCC_MSIRANGE_6 RCC_ICSCR_MSIRANGE_6 /*!< MSI = 4.194 MHz */ +/** + * @} + */ + +/** @defgroup RCC_LSI_Config LSI Config + * @{ + */ +#define RCC_LSI_OFF ((uint32_t)0x00000000) /*!< LSI clock deactivation */ +#define RCC_LSI_ON RCC_CSR_LSION /*!< LSI clock activation */ /** * @} */ -/** @defgroup RCC_System_Clock_Type RCC System Clock Type +/** @defgroup RCC_MSI_Config MSI Config * @{ */ -#define RCC_CLOCKTYPE_SYSCLK ((uint32_t)0x00000001U) /*!< SYSCLK to configure */ -#define RCC_CLOCKTYPE_HCLK ((uint32_t)0x00000002U) /*!< HCLK to configure */ -#define RCC_CLOCKTYPE_PCLK1 ((uint32_t)0x00000004U) /*!< PCLK1 to configure */ -#define RCC_CLOCKTYPE_PCLK2 ((uint32_t)0x00000008U) /*!< PCLK2 to configure */ -/** - * @} - */ +#define RCC_MSI_OFF ((uint32_t)0x00000000) +#define RCC_MSI_ON ((uint32_t)0x00000001) -/** @defgroup RCC_System_Clock_Source RCC System Clock Source - * @{ - */ -#define RCC_SYSCLKSOURCE_MSI RCC_CFGR_SW_MSI /*!< MSI selection as system clock */ -#define RCC_SYSCLKSOURCE_HSI RCC_CFGR_SW_HSI /*!< HSI selection as system clock */ -#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_HSE /*!< HSE selection as system clock */ -#define RCC_SYSCLKSOURCE_PLLCLK RCC_CFGR_SW_PLL /*!< PLL selection as system clock */ -/** - * @} - */ - -/** @defgroup RCC_System_Clock_SOURCE_Status RCC System Clock Source Status - * @{ - */ -#define RCC_SYSCLKSOURCE_STATUS_MSI RCC_CFGR_SWS_MSI /*!< MSI used as system clock */ -#define RCC_SYSCLKSOURCE_STATUS_HSI RCC_CFGR_SWS_HSI /*!< HSI used as system clock */ -#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_HSE /*!< HSE used as system clock */ -#define RCC_SYSCLKSOURCE_STATUS_PLLCLK RCC_CFGR_SWS_PLL /*!< PLL used as system clock */ -/** - * @} - */ - -/** @defgroup RCC_AHB_Clock_Source RCC AHB Clock Source - * @{ - */ -#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1 /*!< SYSCLK not divided */ -#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2 /*!< SYSCLK divided by 2 */ -#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4 /*!< SYSCLK divided by 4 */ -#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8 /*!< SYSCLK divided by 8 */ -#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16 /*!< SYSCLK divided by 16 */ -#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64 /*!< SYSCLK divided by 64 */ -#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128 /*!< SYSCLK divided by 128 */ -#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256 /*!< SYSCLK divided by 256 */ -#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512 /*!< SYSCLK divided by 512 */ -/** - * @} - */ - -/** @defgroup RCC_APB1_APB2_Clock_Source RCC APB1 APB2 Clock Source - * @{ - */ -#define RCC_HCLK_DIV1 RCC_CFGR_PPRE1_DIV1 /*!< HCLK not divided */ -#define RCC_HCLK_DIV2 RCC_CFGR_PPRE1_DIV2 /*!< HCLK divided by 2 */ -#define RCC_HCLK_DIV4 RCC_CFGR_PPRE1_DIV4 /*!< HCLK divided by 4 */ -#define RCC_HCLK_DIV8 RCC_CFGR_PPRE1_DIV8 /*!< HCLK divided by 8 */ -#define RCC_HCLK_DIV16 RCC_CFGR_PPRE1_DIV16 /*!< HCLK divided by 16 */ -/** - * @} - */ - -/** @defgroup RCC_RTC_Clock_Source RCC RTC Clock Source - * @{ - */ -#define RCC_RTCCLKSOURCE_NO_CLK ((uint32_t)0x00000000U) -#define RCC_RTCCLKSOURCE_LSE RCC_CSR_RTCSEL_LSE -#define RCC_RTCCLKSOURCE_LSI RCC_CSR_RTCSEL_LSI -#define RCC_RTCCLKSOURCE_HSE_DIVX RCC_CSR_RTCSEL_HSE - -#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 RCC_RTC_HSE_DIV_2 (uint32_t)0x00000000U /*!< HSE is divided by 2 for RTC clock */ -#define RCC_RTC_HSE_DIV_4 RCC_CR_RTCPRE_0 /*!< HSE is divided by 4 for RTC clock */ -#define RCC_RTC_HSE_DIV_8 RCC_CR_RTCPRE_1 /*!< HSE is divided by 8 for RTC clock */ -#define RCC_RTC_HSE_DIV_16 RCC_CR_RTCPRE /*!< HSE is divided by 16 for RTC clock */ +#define RCC_MSICALIBRATION_DEFAULT ((uint32_t)0x00000000U) /* Default MSI calibration trimming value */ /** * @} */ -/** @defgroup RCC_MCO1_Clock_Source RCC MCO1 Clock Source +#if defined(RCC_HSI48_SUPPORT) +/** @defgroup RCC_HSI48_Config HSI48 Config * @{ */ +#define RCC_HSI48_OFF ((uint8_t)0x00) +#define RCC_HSI48_ON ((uint8_t)0x01) + +/** + * @} + */ +#endif /* RCC_HSI48_SUPPORT */ + +/** @defgroup RCC_PLL_Config PLL Config + * @{ + */ +#define RCC_PLL_NONE ((uint32_t)0x00000000) /*!< PLL is not configured */ +#define RCC_PLL_OFF ((uint32_t)0x00000001) /*!< PLL deactivation */ +#define RCC_PLL_ON ((uint32_t)0x00000002) /*!< PLL activation */ -#define RCC_MCO1SOURCE_NOCLOCK RCC_CFGR_MCO_NOCLOCK -#define RCC_MCO1SOURCE_SYSCLK RCC_CFGR_MCO_SYSCLK -#define RCC_MCO1SOURCE_HSI RCC_CFGR_MCO_HSI -#define RCC_MCO1SOURCE_MSI RCC_CFGR_MCO_MSI -#define RCC_MCO1SOURCE_HSE RCC_CFGR_MCO_HSE -#define RCC_MCO1SOURCE_PLLCLK RCC_CFGR_MCO_PLL -#define RCC_MCO1SOURCE_LSI RCC_CFGR_MCO_LSI -#define RCC_MCO1SOURCE_LSE RCC_CFGR_MCO_LSE -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) \ - && !defined (STM32L011xx) && !defined (STM32L021xx) -#define RCC_MCO1SOURCE_HSI48 RCC_CFGR_MCO_HSI48 -#endif - - /** * @} */ -/** @defgroup RCC_MCOPrescaler RCC MCO Prescaler +/** @defgroup RCC_System_Clock_Type System Clock Type * @{ */ - -#define RCC_MCODIV_1 RCC_CFGR_MCO_PRE_1 -#define RCC_MCODIV_2 RCC_CFGR_MCO_PRE_2 -#define RCC_MCODIV_4 RCC_CFGR_MCO_PRE_4 -#define RCC_MCODIV_8 RCC_CFGR_MCO_PRE_8 -#define RCC_MCODIV_16 RCC_CFGR_MCO_PRE_16 +#define RCC_CLOCKTYPE_SYSCLK ((uint32_t)0x00000001) /*!< SYSCLK to configure */ +#define RCC_CLOCKTYPE_HCLK ((uint32_t)0x00000002) /*!< HCLK to configure */ +#define RCC_CLOCKTYPE_PCLK1 ((uint32_t)0x00000004) /*!< PCLK1 to configure */ +#define RCC_CLOCKTYPE_PCLK2 ((uint32_t)0x00000008) /*!< PCLK2 to configure */ /** * @} - */ + */ -/** @defgroup RCC_MCO_Index RCC MCO Index +/** @defgroup RCC_System_Clock_Source System Clock Source * @{ */ -#define RCC_MCO1 ((uint32_t)0x00000000U) -#define RCC_MCO2 ((uint32_t)0x00000001U) -#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx) -#define RCC_MCO3 ((uint32_t)0x00000002U) +#define RCC_SYSCLKSOURCE_MSI RCC_CFGR_SW_MSI /*!< MSI selected as system clock */ +#define RCC_SYSCLKSOURCE_HSI RCC_CFGR_SW_HSI /*!< HSI selected as system clock */ +#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_HSE /*!< HSE selected as system clock */ +#define RCC_SYSCLKSOURCE_PLLCLK RCC_CFGR_SW_PLL /*!< PLL selected as system clock */ + +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status + * @{ + */ +#define RCC_SYSCLKSOURCE_STATUS_MSI RCC_CFGR_SWS_MSI /*!< MSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_HSI RCC_CFGR_SWS_HSI /*!< HSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_HSE /*!< HSE used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_PLLCLK RCC_CFGR_SWS_PLL /*!< PLL used as system clock */ + +/** + * @} + */ + +/** @defgroup RCC_AHB_Clock_Source AHB Clock Source + * @{ + */ +#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1 /*!< SYSCLK not divided */ +#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2 /*!< SYSCLK divided by 2 */ +#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4 /*!< SYSCLK divided by 4 */ +#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8 /*!< SYSCLK divided by 8 */ +#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16 /*!< SYSCLK divided by 16 */ +#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64 /*!< SYSCLK divided by 64 */ +#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128 /*!< SYSCLK divided by 128 */ +#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256 /*!< SYSCLK divided by 256 */ +#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512 /*!< SYSCLK divided by 512 */ + +/** + * @} + */ + +/** @defgroup RCC_APB1_APB2_Clock_Source APB1 APB2 Clock Source + * @{ + */ +#define RCC_HCLK_DIV1 RCC_CFGR_PPRE1_DIV1 /*!< HCLK not divided */ +#define RCC_HCLK_DIV2 RCC_CFGR_PPRE1_DIV2 /*!< HCLK divided by 2 */ +#define RCC_HCLK_DIV4 RCC_CFGR_PPRE1_DIV4 /*!< HCLK divided by 4 */ +#define RCC_HCLK_DIV8 RCC_CFGR_PPRE1_DIV8 /*!< HCLK divided by 8 */ +#define RCC_HCLK_DIV16 RCC_CFGR_PPRE1_DIV16 /*!< HCLK divided by 16 */ + +/** + * @} + */ + +/** @defgroup RCC_HAL_EC_RTC_HSE_DIV RTC HSE Prescaler + * @{ + */ +#define RCC_RTC_HSE_DIV_2 (uint32_t)0x00000000U /*!< HSE is divided by 2 for RTC clock */ +#define RCC_RTC_HSE_DIV_4 RCC_CR_RTCPRE_0 /*!< HSE is divided by 4 for RTC clock */ +#define RCC_RTC_HSE_DIV_8 RCC_CR_RTCPRE_1 /*!< HSE is divided by 8 for RTC clock */ +#define RCC_RTC_HSE_DIV_16 RCC_CR_RTCPRE /*!< HSE is divided by 16 for RTC clock */ +/** + * @} + */ + +/** @defgroup RCC_RTC_LCD_Clock_Source RTC LCD Clock Source + * @{ + */ +#define RCC_RTCCLKSOURCE_NO_CLK ((uint32_t)0x00000000) /*!< No clock */ +#define RCC_RTCCLKSOURCE_LSE RCC_CSR_RTCSEL_LSE /*!< LSE oscillator clock used as RTC clock */ +#define RCC_RTCCLKSOURCE_LSI RCC_CSR_RTCSEL_LSI /*!< LSI oscillator clock used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIVX RCC_CSR_RTCSEL_HSE /*!< HSE oscillator clock divided by X used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV2 (RCC_RTC_HSE_DIV_2 | RCC_CSR_RTCSEL_HSE) /*!< HSE oscillator clock divided by 2 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV4 (RCC_RTC_HSE_DIV_4 | RCC_CSR_RTCSEL_HSE) /*!< HSE oscillator clock divided by 4 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV8 (RCC_RTC_HSE_DIV_8 | RCC_CSR_RTCSEL_HSE) /*!< HSE oscillator clock divided by 8 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV16 (RCC_RTC_HSE_DIV_16 | RCC_CSR_RTCSEL_HSE) /*!< HSE oscillator clock divided by 16 used as RTC clock */ +/** + * @} + */ + +/** @defgroup RCC_PLL_Division_Factor PLL Division Factor + * @{ + */ + +#define RCC_PLL_DIV2 RCC_CFGR_PLLDIV2 +#define RCC_PLL_DIV3 RCC_CFGR_PLLDIV3 +#define RCC_PLL_DIV4 RCC_CFGR_PLLDIV4 + +/** + * @} + */ + +/** @defgroup RCC_PLL_Multiplication_Factor PLL Multiplication Factor + * @{ + */ + +#define RCC_PLL_MUL3 RCC_CFGR_PLLMUL3 +#define RCC_PLL_MUL4 RCC_CFGR_PLLMUL4 +#define RCC_PLL_MUL6 RCC_CFGR_PLLMUL6 +#define RCC_PLL_MUL8 RCC_CFGR_PLLMUL8 +#define RCC_PLL_MUL12 RCC_CFGR_PLLMUL12 +#define RCC_PLL_MUL16 RCC_CFGR_PLLMUL16 +#define RCC_PLL_MUL24 RCC_CFGR_PLLMUL24 +#define RCC_PLL_MUL32 RCC_CFGR_PLLMUL32 +#define RCC_PLL_MUL48 RCC_CFGR_PLLMUL48 + +/** + * @} + */ + +/** @defgroup RCC_MCO_Index MCO Index + * @{ + */ +#define RCC_MCO1 ((uint32_t)0x00000000) +#define RCC_MCO2 ((uint32_t)0x00000001) +#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx) +#define RCC_MCO3 ((uint32_t)0x00000002) #endif /** * @} */ -/** @defgroup RCC_Interrupt RCC Interruptions +/** @defgroup RCC_MCOx_Clock_Prescaler MCO Clock Prescaler * @{ */ -#define RCC_IT_LSIRDY RCC_CIFR_LSIRDYF -#define RCC_IT_LSERDY RCC_CIFR_LSERDYF -#define RCC_IT_HSIRDY RCC_CIFR_HSIRDYF -#define RCC_IT_HSERDY RCC_CIFR_HSERDYF -#define RCC_IT_PLLRDY RCC_CIFR_PLLRDYF -#define RCC_IT_MSIRDY RCC_CIFR_MSIRDYF +#define RCC_MCODIV_1 RCC_CFGR_MCO_PRE_1 +#define RCC_MCODIV_2 RCC_CFGR_MCO_PRE_2 +#define RCC_MCODIV_4 RCC_CFGR_MCO_PRE_4 +#define RCC_MCODIV_8 RCC_CFGR_MCO_PRE_8 +#define RCC_MCODIV_16 RCC_CFGR_MCO_PRE_16 -#define RCC_IT_CSSLSE RCC_CIFR_CSSLSEF -#define RCC_IT_CSSHSE RCC_CIFR_CSSHSEF - -#if !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define RCC_IT_HSI48RDY RCC_CIFR_HSI48RDYF -#endif /* !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) */ /** * @} */ -/** @defgroup RCC_Flag RCC Flag - * Elements values convention: 0XXYYYYYb - * - YYYYY : Flag position in the register - * - 0XX : Register index - * - 01: CR register - * - 10: CSR register - * - 11: CRRCR register +/** @defgroup RCC_MCO1_Clock_Source MCO1 Clock Source * @{ */ -/* Flags in the CR register */ -#define RCC_FLAG_HSIRDY ((uint8_t)0x22U) -#define RCC_FLAG_HSIDIV ((uint8_t)0x24U) -#define RCC_FLAG_MSIRDY ((uint8_t)0x29U) -#define RCC_FLAG_HSERDY ((uint8_t)0x31U) -#define RCC_FLAG_PLLRDY ((uint8_t)0x39U) - -/* Flags in the CSR register */ -#define RCC_FLAG_LSERDY ((uint8_t)0x49U) -#define RCC_FLAG_LSECSS ((uint8_t)0x4EU) -#define RCC_FLAG_LSIRDY ((uint8_t)0x41U) -#define RCC_FLAG_FWRST ((uint8_t)0x58U) -#define RCC_FLAG_OBLRST ((uint8_t)0x59U) -#define RCC_FLAG_PINRST ((uint8_t)0x5AU) -#define RCC_FLAG_PORRST ((uint8_t)0x5BU) -#define RCC_FLAG_SFTRST ((uint8_t)0x5CU) -#define RCC_FLAG_IWDGRST ((uint8_t)0x5DU) -#define RCC_FLAG_WWDGRST ((uint8_t)0x5EU) -#define RCC_FLAG_LPWRRST ((uint8_t)0x5FU) - -#if !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -/* Flags in the CRRCR register */ -#define RCC_FLAG_HSI48RDY ((uint8_t)0x61U) -#endif /* !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) */ - +#define RCC_MCO1SOURCE_NOCLOCK RCC_CFGR_MCO_NOCLOCK +#define RCC_MCO1SOURCE_SYSCLK RCC_CFGR_MCO_SYSCLK +#define RCC_MCO1SOURCE_MSI RCC_CFGR_MCO_MSI +#define RCC_MCO1SOURCE_HSI RCC_CFGR_MCO_HSI +#define RCC_MCO1SOURCE_LSE RCC_CFGR_MCO_LSE +#define RCC_MCO1SOURCE_LSI RCC_CFGR_MCO_LSI +#define RCC_MCO1SOURCE_HSE RCC_CFGR_MCO_HSE +#define RCC_MCO1SOURCE_PLLCLK RCC_CFGR_MCO_PLL +#if defined(RCC_CFGR_MCOSEL_HSI48) +#define RCC_MCO1SOURCE_HSI48 RCC_CFGR_MCO_HSI48 +#endif /* RCC_CFGR_MCOSEL_HSI48 */ +/** + * @} + */ +/** @defgroup RCC_Interrupt Interrupts + * @{ + */ +#define RCC_IT_LSIRDY RCC_CIFR_LSIRDYF /*!< LSI Ready Interrupt flag */ +#define RCC_IT_LSERDY RCC_CIFR_LSERDYF /*!< LSE Ready Interrupt flag */ +#define RCC_IT_HSIRDY RCC_CIFR_HSIRDYF /*!< HSI Ready Interrupt flag */ +#define RCC_IT_HSERDY RCC_CIFR_HSERDYF /*!< HSE Ready Interrupt flag */ +#define RCC_IT_PLLRDY RCC_CIFR_PLLRDYF /*!< PLL Ready Interrupt flag */ +#define RCC_IT_MSIRDY RCC_CIFR_MSIRDYF /*!< MSI Ready Interrupt flag */ +#define RCC_IT_LSECSS RCC_CIFR_CSSLSEF /*!< LSE Clock Security System Interrupt flag */ +#if defined(RCC_HSECSS_SUPPORT) +#define RCC_IT_CSS RCC_CIFR_CSSHSEF /*!< Clock Security System Interrupt flag */ +#endif /* RCC_HSECSS_SUPPORT */ +#if defined(RCC_HSI48_SUPPORT) +#define RCC_IT_HSI48RDY RCC_CIFR_HSI48RDYF /*!< HSI48 Ready Interrupt flag */ +#endif /* RCC_HSI48_SUPPORT */ /** * @} */ + +/** @defgroup RCC_Flag Flags + * Elements values convention: XXXYYYYYb + * - YYYYY : Flag position in the register + * - XXX : Register index + * - 001: CR register + * - 010: CSR register + * - 011: CRRCR register (*) + * (*) Applicable only for STM32L052xx, STM32L053xx, (...), STM32L073xx & STM32L082xx + * @{ + */ +/* Flags in the CR register */ +#define RCC_FLAG_HSIRDY ((uint8_t)((CR_REG_INDEX << 5) | 2)) /*!< Internal High Speed clock ready flag */ +#define RCC_FLAG_HSIDIV ((uint8_t)((CR_REG_INDEX << 5) | 4)) /*!< HSI16 divider flag */ +#define RCC_FLAG_MSIRDY ((uint8_t)((CR_REG_INDEX << 5) | 9)) /*!< MSI clock ready flag */ +#define RCC_FLAG_HSERDY ((uint8_t)((CR_REG_INDEX << 5) | 17)) /*!< External High Speed clock ready flag */ +#define RCC_FLAG_PLLRDY ((uint8_t)((CR_REG_INDEX << 5) | 25)) /*!< PLL clock ready flag */ +/* Flags in the CSR register */ +#define RCC_FLAG_LSIRDY ((uint8_t)((CSR_REG_INDEX << 5) | 1)) /*!< Internal Low Speed oscillator Ready */ +#define RCC_FLAG_LSERDY ((uint8_t)((CSR_REG_INDEX << 5) | 9)) /*!< External Low Speed oscillator Ready */ +#define RCC_FLAG_LSECSS ((uint8_t)((CSR_REG_INDEX << 5) | 14)) /*!< CSS on LSE failure Detection */ +#define RCC_FLAG_OBLRST ((uint8_t)((CSR_REG_INDEX << 5) | 25)) /*!< Options bytes loading reset flag */ +#define RCC_FLAG_PINRST ((uint8_t)((CSR_REG_INDEX << 5) | 26)) /*!< PIN reset flag */ +#define RCC_FLAG_PORRST ((uint8_t)((CSR_REG_INDEX << 5) | 27)) /*!< POR/PDR reset flag */ +#define RCC_FLAG_SFTRST ((uint8_t)((CSR_REG_INDEX << 5) | 28)) /*!< Software Reset flag */ +#define RCC_FLAG_IWDGRST ((uint8_t)((CSR_REG_INDEX << 5) | 29)) /*!< Independent Watchdog reset flag */ +#define RCC_FLAG_WWDGRST ((uint8_t)((CSR_REG_INDEX << 5) | 30)) /*!< Window watchdog reset flag */ +#define RCC_FLAG_LPWRRST ((uint8_t)((CSR_REG_INDEX << 5) | 31)) /*!< Low-Power reset flag */ +#if defined(RCC_CSR_FWRSTF) +#define RCC_FLAG_FWRST ((uint8_t)((CSR_REG_INDEX << 5) | 8)) /*!< RCC flag FW reset */ +#endif /* RCC_CSR_FWRSTF */ +/* Flags in the CRRCR register */ +#if defined(RCC_HSI48_SUPPORT) +#define RCC_FLAG_HSI48RDY ((uint8_t)((CRRCR_REG_INDEX << 5) | 1)) /*!< HSI48 clock ready flag */ +#endif /* RCC_HSI48_SUPPORT */ /** * @} - */ + */ + +/** + * @} + */ + /* Exported macro ------------------------------------------------------------*/ + /** @defgroup RCC_Exported_Macros RCC Exported Macros - * @{ - */ - + * @{ + */ + /** @defgroup RCC_AHB_Peripheral_Clock_Enable_Disable AHB Peripheral Clock Enable Disable * @brief Enable or disable the AHB peripheral clock. * @note After reset, the peripheral clock (used for registers read/write access) @@ -664,6 +812,9 @@ typedef struct #define __HAL_RCC_DMA1_IS_CLK_ENABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN) != RESET) #define __HAL_RCC_MIF_IS_CLK_ENABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_MIFEN) != RESET) #define __HAL_RCC_CRC_IS_CLK_ENABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN) != RESET) +#define __HAL_RCC_DMA1_IS_CLK_DISABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN) == RESET) +#define __HAL_RCC_MIF_IS_CLK_DISABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_MIFEN) == RESET) +#define __HAL_RCC_CRC_IS_CLK_DISABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN) == RESET) /** * @} @@ -681,6 +832,10 @@ typedef struct #define __HAL_RCC_GPIOB_IS_CLK_ENABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOBEN) != RESET) #define __HAL_RCC_GPIOC_IS_CLK_ENABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOCEN) != RESET) #define __HAL_RCC_GPIOH_IS_CLK_ENABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOHEN) != RESET) +#define __HAL_RCC_GPIOA_IS_CLK_DISABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN) == RESET) +#define __HAL_RCC_GPIOB_IS_CLK_DISABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOBEN) == RESET) +#define __HAL_RCC_GPIOC_IS_CLK_DISABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOCEN) == RESET) +#define __HAL_RCC_GPIOH_IS_CLK_DISABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOHEN) == RESET) /** * @} @@ -695,6 +850,8 @@ typedef struct */ #define __HAL_RCC_WWDG_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN) != RESET) #define __HAL_RCC_PWR_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN) != RESET) +#define __HAL_RCC_WWDG_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN) == RESET) +#define __HAL_RCC_PWR_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN) == RESET) /** * @} @@ -709,6 +866,8 @@ typedef struct */ #define __HAL_RCC_SYSCFG_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN) != RESET) #define __HAL_RCC_DBGMCU_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_DBGMCUEN) != RESET) +#define __HAL_RCC_SYSCFG_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN) == RESET) +#define __HAL_RCC_DBGMCU_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_DBGMCUEN) == RESET) /** * @} @@ -723,7 +882,7 @@ typedef struct #define __HAL_RCC_MIF_FORCE_RESET() SET_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_MIFRST)) #define __HAL_RCC_CRC_FORCE_RESET() SET_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_CRCRST)) -#define __HAL_RCC_AHB_RELEASE_RESET() (RCC->AHBRSTR = 0x00U) +#define __HAL_RCC_AHB_RELEASE_RESET() (RCC->AHBRSTR = 0x00000000U) #define __HAL_RCC_CRC_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_CRCRST)) #define __HAL_RCC_DMA1_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_DMA1RST)) #define __HAL_RCC_MIF_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_MIFRST)) @@ -741,7 +900,7 @@ typedef struct #define __HAL_RCC_GPIOC_FORCE_RESET() SET_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIOCRST)) #define __HAL_RCC_GPIOH_FORCE_RESET() SET_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIOHRST)) -#define __HAL_RCC_IOP_RELEASE_RESET() (RCC->IOPRSTR = 0x00U) +#define __HAL_RCC_IOP_RELEASE_RESET() (RCC->IOPRSTR = 0x00000000U) #define __HAL_RCC_GPIOA_RELEASE_RESET() CLEAR_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIOARST)) #define __HAL_RCC_GPIOB_RELEASE_RESET() CLEAR_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIOBRST)) #define __HAL_RCC_GPIOC_RELEASE_RESET() CLEAR_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIOCRST)) @@ -759,7 +918,7 @@ typedef struct #define __HAL_RCC_WWDG_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_WWDGRST)) #define __HAL_RCC_PWR_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_PWRRST)) -#define __HAL_RCC_APB1_RELEASE_RESET() (RCC->APB1RSTR = 0x00U) +#define __HAL_RCC_APB1_RELEASE_RESET() (RCC->APB1RSTR = 0x00000000U) #define __HAL_RCC_WWDG_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_WWDGRST)) #define __HAL_RCC_PWR_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_PWRRST)) @@ -775,7 +934,7 @@ typedef struct #define __HAL_RCC_DBGMCU_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_DBGMCURST)) #define __HAL_RCC_SYSCFG_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SYSCFGRST)) -#define __HAL_RCC_APB2_RELEASE_RESET() (RCC->APB2RSTR = 0x00U) +#define __HAL_RCC_APB2_RELEASE_RESET() (RCC->APB2RSTR = 0x00000000U) #define __HAL_RCC_DBGMCU_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_DBGMCURST)) #define __HAL_RCC_SYSCFG_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SYSCFGRST)) /** @@ -874,6 +1033,10 @@ typedef struct #define __HAL_RCC_MIF_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_MIFSMEN) != RESET) #define __HAL_RCC_SRAM_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_SRAMSMEN) != RESET) #define __HAL_RCC_DMA1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_DMA1SMEN) != RESET) +#define __HAL_RCC_CRC_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_CRCSMEN) == RESET) +#define __HAL_RCC_MIF_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_MIFSMEN) == RESET) +#define __HAL_RCC_SRAM_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_SRAMSMEN) == RESET) +#define __HAL_RCC_DMA1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_DMA1SMEN) == RESET) /** * @} @@ -891,6 +1054,10 @@ typedef struct #define __HAL_RCC_GPIOB_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOBSMEN) != RESET) #define __HAL_RCC_GPIOC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOCSMEN) != RESET) #define __HAL_RCC_GPIOH_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOHSMEN) != RESET) +#define __HAL_RCC_GPIOA_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOASMEN) == RESET) +#define __HAL_RCC_GPIOB_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOBSMEN) == RESET) +#define __HAL_RCC_GPIOC_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOCSMEN) == RESET) +#define __HAL_RCC_GPIOH_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOHSMEN) == RESET) /** * @} @@ -906,6 +1073,8 @@ typedef struct */ #define __HAL_RCC_WWDG_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_WWDGSMEN) != RESET) #define __HAL_RCC_PWR_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_PWRSMEN) != RESET) +#define __HAL_RCC_WWDG_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_WWDGSMEN) == RESET) +#define __HAL_RCC_PWR_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_PWRSMEN) == RESET) /** * @} @@ -921,41 +1090,35 @@ typedef struct */ #define __HAL_RCC_SYSCFG_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_SYSCFGSMEN) != RESET) #define __HAL_RCC_DBGMCU_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_DBGMCUSMEN) != RESET) +#define __HAL_RCC_SYSCFG_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_SYSCFGSMEN) == RESET) +#define __HAL_RCC_DBGMCU_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_DBGMCUSMEN) == RESET) /** * @} */ - -/** @defgroup RCC_Backup_Domain_Reset RCC Backup Domain Reset +/** @defgroup RCC_HSI_Configuration HSI Configuration * @{ - */ - -/** @brief Macros to force or release the Backup domain reset. - * @note This function resets the RTC peripheral (including the backup registers) - * and the RTC clock source selection in RCC_CSR register. - * @note The BKPSRAM is not affected by this reset. - */ -#define __HAL_RCC_BACKUPRESET_FORCE() SET_BIT(RCC->CSR, RCC_CSR_RTCRST) -#define __HAL_RCC_BACKUPRESET_RELEASE() CLEAR_BIT(RCC->CSR, RCC_CSR_RTCRST) - -/** - * @} */ -/** @defgroup RCC_RTC_Clock_Configuration RCC RTC Clock Configuration - * @{ - */ - -/** @brief Macros to enable or disable the the RTC clock. - * @note These macros must be used only after the RTC clock source was selected. +/** @brief Macro to enable or disable 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 __STATE__ specifies the new state of the HSI. + * This parameter can be one of the following values: + * @arg @ref RCC_HSI_OFF turn OFF the HSI oscillator + * @arg @ref RCC_HSI_ON turn ON the HSI oscillator + * @arg @ref RCC_HSI_DIV4 turn ON the HSI oscillator and divide it by 4 + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. */ -#define __HAL_RCC_RTC_ENABLE() SET_BIT(RCC->CSR, RCC_CSR_RTCEN) -#define __HAL_RCC_RTC_DISABLE() CLEAR_BIT(RCC->CSR, RCC_CSR_RTCEN) +#define __HAL_RCC_HSI_CONFIG(__STATE__) \ + MODIFY_REG(RCC->CR, RCC_CR_HSION | RCC_CR_HSIDIVEN , (uint32_t)(__STATE__)) -/** - * @} - */ - /** @brief Macros to enable or disable the Internal High Speed oscillator (HSI). * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. * It is used (enabled by hardware) as system clock source after startup @@ -966,7 +1129,7 @@ typedef struct * you have to select another source of the system clock then stop the 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 as - * system clock source. + * system clock source. * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator * clock cycles. */ @@ -976,107 +1139,43 @@ typedef struct /** @brief Macro to adjust 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. - * @param __HSICalibrationValue__: specifies the calibration trimming value. + * @param _HSICALIBRATIONVALUE_ specifies the calibration trimming value. + * (default is RCC_HSICALIBRATION_DEFAULT). * This parameter must be a number between 0 and 0x1F. - */ -#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(__HSICalibrationValue__) (MODIFY_REG(RCC->ICSCR,\ - RCC_ICSCR_HSITRIM, (uint32_t)(__HSICalibrationValue__) << 8U)) - -/** @brief Macro to enable or disable 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 __STATE__: specifies the new state of the HSI. - * This parameter can be one of the following values: - * @arg RCC_HSI_OFF: turn OFF the HSI oscillator - * @arg RCC_HSI_ON: turn ON the HSI oscillator - * @arg RCC_HSI_DIV4: turn ON the HSI oscillator and divide it by 4 - * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator - * clock cycles. - */ -#define __HAL_RCC_HSI_CONFIG(__STATE__) \ - MODIFY_REG(RCC->CR, RCC_CR_HSION | RCC_CR_HSIDIVEN , (uint32_t)(__STATE__)) - -/** - * @brief Macros to enable or disable 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. - * @note When the MSI is stopped, MSIRDY flag goes low after 6 MSI oscillator - * clock cycles. - */ -#define __HAL_RCC_MSI_ENABLE() SET_BIT(RCC->CR, RCC_CR_MSION) -#define __HAL_RCC_MSI_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_MSION) - - -/** @brief Macro 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 calibration trimming value. - * This parameter must be a number between 0 and 0xFF. - */ -#define __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(__MSICalibrationValue__) (MODIFY_REG(RCC->ICSCR,\ - RCC_ICSCR_MSITRIM, (uint32_t)(__MSICalibrationValue__) << 24U)) + */ +#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(_HSICALIBRATIONVALUE_) \ + (MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSITRIM, (uint32_t)(_HSICALIBRATIONVALUE_) << 8)) /** - * @brief Macro to 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 + * @} */ -#define __HAL_RCC_MSI_RANGE_CONFIG(__RCC_MSIRange__) (MODIFY_REG(RCC->ICSCR,\ - RCC_ICSCR_MSIRANGE, (uint32_t)(__RCC_MSIRange__) )) - -/** @brief Macro to get the Internal Multi Speed oscillator (__MSI__) clock range in run mode - * @retval 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 +/** @defgroup RCC_LSI_Configuration LSI Configuration + * @{ */ -#define __HAL_RCC_GET_MSI_RANGE() \ - ((uint32_t)(READ_BIT(RCC->ICSCR, RCC_ICSCR_MSIRANGE) >> 12U)) -/** @brief Macros to enable or disable the Internal Low Speed oscillator (LSI). +/** @brief Macro to enable 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. + */ +#define __HAL_RCC_LSI_ENABLE() SET_BIT(RCC->CSR, RCC_CSR_LSION) + +/** @brief Macro to disable the Internal Low Speed oscillator (LSI). + * @note LSI can not be disabled if the IWDG is running. * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator * clock cycles. */ -#define __HAL_RCC_LSI_ENABLE() SET_BIT(RCC->CSR, RCC_CSR_LSION) #define __HAL_RCC_LSI_DISABLE() CLEAR_BIT(RCC->CSR, RCC_CSR_LSION) +/** + * @} + */ + +/** @defgroup RCC_HSE_Configuration HSE Configuration + * @{ + */ + /** * @brief Macro to configure the External High Speed oscillator (HSE). * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not @@ -1088,203 +1187,235 @@ typedef struct * @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 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 __STATE__: 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 + * function. + * @param __STATE__ specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg @ref 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. + * @arg @ref RCC_HSE_ON turn ON the HSE oscillator + * @arg @ref RCC_HSE_BYPASS HSE oscillator bypassed with external clock + */ +#define __HAL_RCC_HSE_CONFIG(__STATE__) \ + do{ \ + __IO uint32_t tmpreg; \ + if ((__STATE__) == RCC_HSE_ON) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else if ((__STATE__) == RCC_HSE_BYPASS) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEBYP); \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else \ + { \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ + /* Delay after an RCC peripheral clock */ \ + tmpreg = READ_BIT(RCC->CR, RCC_CR_HSEON); \ + UNUSED(tmpreg); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \ + } \ + }while(0) + +/** + * @} + */ + +/** @defgroup RCC_LSE_Configuration LSE Configuration + * @{ */ -#define __HAL_RCC_HSE_CONFIG(__STATE__) \ - do { \ - __IO uint32_t tmpreg; \ - if((__STATE__) == RCC_HSE_ON) \ - { \ - SET_BIT(RCC->CR, RCC_CR_HSEON); \ - } \ - else if((__STATE__) == RCC_HSE_BYPASS) \ - { \ - CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ - SET_BIT(RCC->CR, RCC_CR_HSEBYP); \ - SET_BIT(RCC->CR, RCC_CR_HSEON); \ - } \ - else \ - { \ - CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ - /* Delay after an RCC peripheral clock */ \ - tmpreg = READ_BIT(RCC->CR, RCC_CR_HSEON); \ - UNUSED(tmpreg); \ - CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \ - } \ - } while(0) /** * @brief Macro to configure the External Low Speed oscillator (LSE). - * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not - * supported by this macro. User should request a transition to LSE Off - * first and then LSE On or LSE Bypass. + * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not supported by this macro. * @note As the LSE is in the Backup domain and write access is denied to - * this domain after reset, you have to enable write access using - * HAL_PWR_EnableBkUpAccess() function before to configure the LSE - * (to be done once after reset). + * this domain after reset, you have to enable write access using + * @ref HAL_PWR_EnableBkUpAccess() 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 __STATE__: specifies the new state of the LSE. + * @param __STATE__ 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 + * @arg @ref 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. + * @arg @ref RCC_LSE_ON turn ON the LSE oscillator. + * @arg @ref RCC_LSE_BYPASS LSE oscillator bypassed with external clock. */ -#define __HAL_RCC_LSE_CONFIG(__STATE__) \ - do { \ - if((__STATE__) == RCC_LSE_ON) \ - { \ - SET_BIT(RCC->CSR, RCC_CSR_LSEON); \ - } \ - else if((__STATE__) == RCC_LSE_OFF) \ - { \ - CLEAR_BIT(RCC->CSR, RCC_CSR_LSEON); \ - CLEAR_BIT(RCC->CSR, RCC_CSR_LSEBYP); \ - } \ - else if((__STATE__) == RCC_LSE_BYPASS) \ - { \ - CLEAR_BIT(RCC->CSR, RCC_CSR_LSEON); \ - SET_BIT(RCC->CSR, RCC_CSR_LSEBYP); \ - SET_BIT(RCC->CSR, RCC_CSR_LSEON); \ - } \ - else \ - { \ - CLEAR_BIT(RCC->CSR, RCC_CSR_LSEON); \ - CLEAR_BIT(RCC->CSR, RCC_CSR_LSEBYP); \ - } \ - } while(0) - - +#define __HAL_RCC_LSE_CONFIG(__STATE__) \ + do{ \ + if ((__STATE__) == RCC_LSE_ON) \ + { \ + SET_BIT(RCC->CSR, RCC_CSR_LSEON); \ + } \ + else if ((__STATE__) == RCC_LSE_OFF) \ + { \ + CLEAR_BIT(RCC->CSR, RCC_CSR_LSEON); \ + CLEAR_BIT(RCC->CSR, RCC_CSR_LSEBYP); \ + } \ + else if ((__STATE__) == RCC_LSE_BYPASS) \ + { \ + SET_BIT(RCC->CSR, RCC_CSR_LSEBYP); \ + SET_BIT(RCC->CSR, RCC_CSR_LSEON); \ + } \ + else \ + { \ + CLEAR_BIT(RCC->CSR, RCC_CSR_LSEON); \ + CLEAR_BIT(RCC->CSR, RCC_CSR_LSEBYP); \ + } \ + }while(0) /** - * @brief Configures or Get 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 cannot 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 __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). + * @} */ - -#define __HAL_RCC_RTC_CLKPRESCALER(__RTCCLKSOURCE__) (((__RTCCLKSOURCE__) & RCC_CSR_RTCSEL) == RCC_CSR_RTCSEL) ? \ - MODIFY_REG(RCC->CR, RCC_CR_RTCPRE, (uint32_t)((__RTCCLKSOURCE__) & RCC_CR_RTCPRE)) : \ - CLEAR_BIT(RCC->CR, RCC_CR_RTCPRE) -#define __HAL_RCC_RTC_CONFIG(__RTCCLKSOURCE__) do { __HAL_RCC_RTC_CLKPRESCALER(__RTCCLKSOURCE__); \ - MODIFY_REG( RCC->CSR, RCC_CSR_RTCSEL, (uint32_t)((__RTCCLKSOURCE__) & RCC_CSR_RTCSEL)); \ - } while (0) - - - /** - * @brief Get the RTC and LCD clock (RTCCLK / LCDCLK). - * - * @retval The clock source can be one of the following values: - * @arg RCC_RTCCLKSOURCE_NO_CLK: No clock selected as RTC clock - * @arg RCC_RTCCLKSOURCE_LSE: LSE selected as RTC clock - * @arg RCC_RTCCLKSOURCE_LSI: LSI selected as RTC clock - * @arg RCC_RTCCLKSOURCE_HSE_DIVX: HSE divided by X selected as RTC clock (X can be retrieved thanks to @ref __HAL_RCC_GET_RTC_HSE_PRESCALER() - * - */ -#define __HAL_RCC_GET_RTC_SOURCE() ((uint32_t)(READ_BIT(RCC->CSR, RCC_CSR_RTCSEL))) - - /** - * @brief Get the RTC and LCD HSE clock divider (RTCCLK / LCDCLK). - * - * @retval Returned value can be one of the following values: - * @arg RCC_RTC_HSE_DIV_2: HSE divided by 2 selected as RTC clock - * @arg RCC_RTC_HSE_DIV_4: HSE divided by 4 selected as RTC clock - * @arg RCC_RTC_HSE_DIV_8: HSE divided by 8 selected as RTC clock - * @arg RCC_RTC_HSE_DIV_16: HSE divided by 16 selected as RTC clock - * +/** @defgroup RCC_MSI_Configuration MSI Configuration + * @{ */ -#define __HAL_RCC_GET_RTC_HSE_PRESCALER() ((uint32_t)(READ_BIT(RCC->CR, RCC_CR_RTCPRE))) - -/** @brief Macros to enable or disable the main PLL. +/** @brief Macro to enable Internal Multi Speed oscillator (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. + */ +#define __HAL_RCC_MSI_ENABLE() SET_BIT(RCC->CR, RCC_CR_MSION) + +/** @brief Macro to disable 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 When the MSI is stopped, MSIRDY flag goes low after 6 MSI oscillator + * clock cycles. + */ +#define __HAL_RCC_MSI_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_MSION) + +/** @brief Macro adjusts 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 calibration trimming value. + * (default is RCC_MSICALIBRATION_DEFAULT). + * This parameter must be a number between 0 and 0xFF. + */ +#define __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(_MSICALIBRATIONVALUE_) \ + (MODIFY_REG(RCC->ICSCR, RCC_ICSCR_MSITRIM, (uint32_t)(_MSICALIBRATIONVALUE_) << 24)) + +/* @brief Macro to 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 _MSIRANGEVALUE_ specifies the MSI Clock range. + * This parameter must be one of the following values: + * @arg @ref RCC_MSIRANGE_0 MSI clock is around 65.536 KHz + * @arg @ref RCC_MSIRANGE_1 MSI clock is around 131.072 KHz + * @arg @ref RCC_MSIRANGE_2 MSI clock is around 262.144 KHz + * @arg @ref RCC_MSIRANGE_3 MSI clock is around 524.288 KHz + * @arg @ref RCC_MSIRANGE_4 MSI clock is around 1.048 MHz + * @arg @ref RCC_MSIRANGE_5 MSI clock is around 2.097 MHz (default after Reset or wake-up from STANDBY) + * @arg @ref RCC_MSIRANGE_6 MSI clock is around 4.194 MHz + */ +#define __HAL_RCC_MSI_RANGE_CONFIG(_MSIRANGEVALUE_) (MODIFY_REG(RCC->ICSCR, \ + RCC_ICSCR_MSIRANGE, (uint32_t)(_MSIRANGEVALUE_))) + +/** @brief Macro to get the Internal Multi Speed oscillator (MSI) clock range in run mode + * @retval MSI clock range. + * This parameter must be one of the following values: + * @arg @ref RCC_MSIRANGE_0 MSI clock is around 65.536 KHz + * @arg @ref RCC_MSIRANGE_1 MSI clock is around 131.072 KHz + * @arg @ref RCC_MSIRANGE_2 MSI clock is around 262.144 KHz + * @arg @ref RCC_MSIRANGE_3 MSI clock is around 524.288 KHz + * @arg @ref RCC_MSIRANGE_4 MSI clock is around 1.048 MHz + * @arg @ref RCC_MSIRANGE_5 MSI clock is around 2.097 MHz (default after Reset or wake-up from STANDBY) + * @arg @ref RCC_MSIRANGE_6 MSI clock is around 4.194 MHz + */ +#define __HAL_RCC_GET_MSI_RANGE() (uint32_t)(READ_BIT(RCC->ICSCR, RCC_ICSCR_MSIRANGE)) + +/** + * @} + */ + +/** @defgroup RCC_PLL_Configuration PLL Configuration + * @{ + */ + +/** @brief Macro to enable the main PLL. * @note After enabling the main 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 main PLL can not be disabled if it is used as system clock source * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes. */ -#define __HAL_RCC_PLL_ENABLE() SET_BIT(RCC->CR, RCC_CR_PLLON) +#define __HAL_RCC_PLL_ENABLE() SET_BIT(RCC->CR, RCC_CR_PLLON) + +/** @brief Macro to disable the main PLL. + * @note The main PLL can not be disabled if it is used as system clock source + */ #define __HAL_RCC_PLL_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_PLLON) -/** @brief Macro to configure the main PLL clock source, multiplication and division factors. +/** @brief Macro to configure the main PLL clock source, multiplication and division factors. * @note This function must be used only when the main 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 entry - * @arg RCC_PLLSOURCE_HSE: HSE oscillator clock selected as PLL clock entry - * @param __PLLMUL__: specifies the multiplication factor to generate the PLL VCO clock - * This parameter must be one of the following values: - * @arg RCC_CFGR_PLLMUL3: PLLVCO = PLL clock entry x 3 - * @arg RCC_CFGR_PLLMUL4: PLLVCO = PLL clock entry x 4 - * @arg RCC_CFGR_PLLMUL6: PLLVCO = PLL clock entry x 6 - * @arg RCC_CFGR_PLLMUL8: PLLVCO = PLL clock entry x 8 - * @arg RCC_CFGR_PLLMUL12: PLLVCO = PLL clock entry x 12 - * @arg RCC_CFGR_PLLMUL16: PLLVCO = PLL clock entry x 16 - * @arg RCC_CFGR_PLLMUL24: PLLVCO = PLL clock entry x 24 - * @arg RCC_CFGR_PLLMUL32: PLLVCO = PLL clock entry x 32 - * @arg RCC_CFGR_PLLMUL48: PLLVCO = PLL clock entry x 48 - * @note The PLL VCO clock frequency must not exceed 96 MHz when the product is in - * Range 1, 48 MHz when the product is in Range 2 and 24 MHz when the product is - * in Range 3. - * @param __PLLDIV__: specifies the PLL output clock division from PLL VCO clock - * This parameter must be one of the following values: - * @arg RCC_PLLDIV_2: PLL clock output = PLLVCO / 2 - * @arg RCC_PLLDIV_3: PLL clock output = PLLVCO / 3 - * @arg RCC_PLLDIV_4: PLL clock output = PLLVCO / 4 + * + * @param __RCC_PLLSOURCE__ specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_PLLSOURCE_HSI HSI oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL clock entry + * @param __PLLMUL__ specifies the multiplication factor for PLL VCO output clock + * This parameter can be one of the following values: + * @arg @ref RCC_PLL_MUL3 PLLVCO = PLL clock entry x 3 + * @arg @ref RCC_PLL_MUL4 PLLVCO = PLL clock entry x 4 + * @arg @ref RCC_PLL_MUL6 PLLVCO = PLL clock entry x 6 + * @arg @ref RCC_PLL_MUL8 PLLVCO = PLL clock entry x 8 + * @arg @ref RCC_PLL_MUL12 PLLVCO = PLL clock entry x 12 + * @arg @ref RCC_PLL_MUL16 PLLVCO = PLL clock entry x 16 + * @arg @ref RCC_PLL_MUL24 PLLVCO = PLL clock entry x 24 + * @arg @ref RCC_PLL_MUL32 PLLVCO = PLL clock entry x 32 + * @arg @ref RCC_PLL_MUL48 PLLVCO = PLL clock entry x 48 + * @note The PLL VCO clock frequency must not exceed 96 MHz when the product is in + * Range 1, 48 MHz when the product is in Range 2 and 24 MHz when the product is + * in Range 3. + * + * @param __PLLDIV__ specifies the division factor for PLL VCO input clock + * This parameter can be one of the following values: + * @arg @ref RCC_PLL_DIV2 PLL clock output = PLLVCO / 2 + * @arg @ref RCC_PLL_DIV3 PLL clock output = PLLVCO / 3 + * @arg @ref RCC_PLL_DIV4 PLL clock output = PLLVCO / 4 + * */ +#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSOURCE__, __PLLMUL__, __PLLDIV__)\ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_PLLSRC|RCC_CFGR_PLLMUL|RCC_CFGR_PLLDIV),((__RCC_PLLSOURCE__) | (__PLLMUL__) | (__PLLDIV__))) -#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSOURCE__ , __PLLMUL__ ,__PLLDIV__ ) \ - MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLMUL | RCC_CFGR_PLLDIV | RCC_CFGR_PLLSRC, (uint32_t)((__PLLMUL__)| (__PLLDIV__)| (__RCC_PLLSOURCE__))) - - /** @brief Macro to get the oscillator used as PLL clock source. - * @retval The oscillator used as PLL clock source. The returned value can be one +/** @brief Get oscillator clock selected as PLL input clock + * @retval The clock source used for PLL entry. The returned value can be one * of the following: - * - RCC_PLLSOURCE_HSI: HSI oscillator is used as PLL clock source. - * - RCC_PLLSOURCE_HSE: HSE oscillator is used as PLL clock source. + * @arg @ref RCC_PLLSOURCE_HSI HSI oscillator clock selected as PLL input clock + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL input clock + */ +#define __HAL_RCC_GET_PLL_OSCSOURCE() ((uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PLLSRC))) + +/** + * @} + */ + +/** @defgroup RCC_Get_Clock_source Get Clock source + * @{ */ -#define __HAL_RCC_GET_PLL_OSCSOURCE() ((uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC)) /** * @brief Macro to configure the system clock source. - * @param __SYSCLKSOURCE__: specifies the system clock source. + * @param __SYSCLKSOURCE__ specifies the system clock source. * This parameter can be one of the following values: - * - RCC_SYSCLKSOURCE_MSI: MSI oscillator is used as system clock source. - * - RCC_SYSCLKSOURCE_HSI: HSI oscillator is used as system clock source. - * - RCC_SYSCLKSOURCE_HSE: HSE oscillator is used as system clock source. - * - RCC_SYSCLKSOURCE_PLLCLK: PLL output is used as system clock source. - * @retval None + * @arg @ref RCC_SYSCLKSOURCE_MSI MSI oscillator is used as system clock source. + * @arg @ref RCC_SYSCLKSOURCE_HSI HSI oscillator is used as system clock source. + * @arg @ref RCC_SYSCLKSOURCE_HSE HSE oscillator is used as system clock source. + * @arg @ref RCC_SYSCLKSOURCE_PLLCLK PLL output is used as system clock source. */ #define __HAL_RCC_SYSCLK_CONFIG(__SYSCLKSOURCE__) \ MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, (__SYSCLKSOURCE__)) @@ -1292,263 +1423,266 @@ typedef struct /** @brief Macro to get the clock source used as system clock. * @retval The clock source used as system clock. The returned value can be one * of the following: - * - RCC_SYSCLKSOURCE_STATUS_MSI: MSI used as system clock. - * - RCC_SYSCLKSOURCE_STATUS_HSI: HSI used as system clock. - * - RCC_SYSCLKSOURCE_STATUS_HSE: HSE used as system clock. - * - RCC_SYSCLKSOURCE_STATUS_PLLCLK: PLL used as system clock. + * @arg @ref RCC_SYSCLKSOURCE_STATUS_MSI MSI used as system clock + * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSI HSI used as system clock + * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSE HSE used as system clock + * @arg @ref RCC_SYSCLKSOURCE_STATUS_PLLCLK PLL used as system clock */ -#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(RCC->CFGR & RCC_CFGR_SWS)) +#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR,RCC_CFGR_SWS))) +/** + * @} + */ + +/** @defgroup RCCEx_MCOx_Clock_Config RCC Extended MCOx Clock Config + * @{ + */ /** @brief Macro to configure the MCO clock. * @param __MCOCLKSOURCE__ specifies the MCO clock source. * This parameter can be one of the following values: - * @arg RCC_CFGR_MCO_HSI: HSI clock selected as MCO source - * @arg RCC_CFGR_MCO_MSI: MSI clock selected as MCO source - * @arg RCC_CFGR_MCO_HSE: HSE clock selected as MCO source - * @arg RCC_CFGR_MCO_PLL: PLL clock selected as MCO source - * @arg RCC_CFGR_MCO_LSI: LSI clock selected as MCO source - * @arg RCC_CFGR_MCO_LSE: LSE clock selected as MCO source + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_SYSCLK System Clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI oscillator clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_MSI MSI oscillator clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE oscillator clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO clock + @if STM32L052xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L053xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L062xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L063xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L072xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L073xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L082xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @elseif STM32L083xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock + @endif * @param __MCODIV__ specifies the MCO clock prescaler. * This parameter can be one of the following values: - * @arg RCC_CFGR_MCO_PRE_1: no division applied to MCO clock - * @arg RCC_CFGR_MCO_PRE_2: division by 2 applied to MCO clock - * @arg RCC_CFGR_MCO_PRE_4: division by 4 applied to MCO clock - * @arg RCC_CFGR_MCO_PRE_8: division by 8 applied to MCO clock - * @arg RCC_CFGR_MCO_PRE_16: division by 16 applied to MCO clock + * @arg @ref RCC_MCODIV_1 MCO clock source is divided by 1 + * @arg @ref RCC_MCODIV_2 MCO clock source is divided by 2 + * @arg @ref RCC_MCODIV_4 MCO clock source is divided by 4 + * @arg @ref RCC_MCODIV_8 MCO clock source is divided by 8 + * @arg @ref RCC_MCODIV_16 MCO clock source is divided by 16 */ - #define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCO_PRE), ((__MCOCLKSOURCE__) | (__MCODIV__))) +/** + * @} + */ -/** @defgroup RCC_Flags_Interrupts_Management RCC Flags Interrupts Management + /** @defgroup RCC_RTC_Clock_Configuration RCC RTC Clock Configuration + * @{ + */ + +/** @brief Macro to configure the RTC clock (RTCCLK). + * @note As the RTC clock configuration bits are in the Backup domain and write + * access is denied to this domain after reset, you have to enable write + * access using the Power Backup Access macro before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it cannot be changed unless the + * Backup domain is reset using @ref __HAL_RCC_BACKUPRESET_FORCE() macro, or by + * a Power On Reset (POR). + * @note RTC prescaler cannot be modified if HSE is enabled (HSEON = 1). + * + * @param __RTC_CLKSOURCE__ specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV2 HSE divided by 2 selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV4 HSE divided by 4 selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV8 HSE divided by 8 selected as RTC clock + * @arg @ref 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). + */ +#define __HAL_RCC_RTC_CLKPRESCALER(__RTC_CLKSOURCE__) do { \ + if(((__RTC_CLKSOURCE__) & RCC_CSR_RTCSEL_HSE) == RCC_CSR_RTCSEL_HSE) \ + { \ + MODIFY_REG(RCC->CR, RCC_CR_RTCPRE, ((__RTC_CLKSOURCE__) & RCC_CR_RTCPRE)); \ + } \ + } while (0) + +#define __HAL_RCC_RTC_CONFIG(__RTC_CLKSOURCE__) do { \ + __HAL_RCC_RTC_CLKPRESCALER(__RTC_CLKSOURCE__); \ + RCC->CSR |= ((__RTC_CLKSOURCE__) & RCC_CSR_RTCSEL); \ + } while (0) + +/** @brief Macro to get the RTC clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIVX HSE divided by X selected as RTC clock (X can be retrieved thanks to @ref __HAL_RCC_GET_RTC_HSE_PRESCALER() + */ +#define __HAL_RCC_GET_RTC_SOURCE() (READ_BIT(RCC->CSR, RCC_CSR_RTCSEL)) + +/** + * @brief Get the RTC and LCD HSE clock divider (RTCCLK / LCDCLK). + * + * @retval Returned value can be one of the following values: + * @arg @ref RCC_RTC_HSE_DIV_2 HSE divided by 2 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV_4 HSE divided by 4 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV_8 HSE divided by 8 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV_16 HSE divided by 16 selected as RTC clock + * + */ +#define __HAL_RCC_GET_RTC_HSE_PRESCALER() ((uint32_t)(READ_BIT(RCC->CR, RCC_CR_RTCPRE))) + +/** @brief Macro to enable the the RTC clock. + * @note These macros must be used only after the RTC clock source was selected. + */ +#define __HAL_RCC_RTC_ENABLE() SET_BIT(RCC->CSR, RCC_CSR_RTCEN) + +/** @brief Macro to disable the the RTC clock. + * @note These macros must be used only after the RTC clock source was selected. + */ +#define __HAL_RCC_RTC_DISABLE() CLEAR_BIT(RCC->CSR, RCC_CSR_RTCEN) + +/** @brief Macro to force the Backup domain reset. + * @note This function resets the RTC peripheral (including the backup registers) + * and the RTC clock source selection in RCC_CSR register. + * @note The BKPSRAM is not affected by this reset. + */ +#define __HAL_RCC_BACKUPRESET_FORCE() SET_BIT(RCC->CSR, RCC_CSR_RTCRST) + +/** @brief Macros to release the Backup domain reset. + */ +#define __HAL_RCC_BACKUPRESET_RELEASE() CLEAR_BIT(RCC->CSR, RCC_CSR_RTCRST) + +/** + * @} + */ + +/** @defgroup RCC_Flags_Interrupts_Management Flags Interrupts Management * @brief macros to manage the specified RCC Flags and interrupts. * @{ */ -/** @brief Enable RCC interrupt (Perform Byte access to RCC_CIER[0:7] bits to enable - * the selected interrupts). +/** @brief Enable RCC interrupt. * @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 __INTERRUPT__: specifies the RCC interrupt sources to be enabled. - * 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_CSSLSE: LSE CSS interrupt - * @arg RCC_IT_HSI48RDY: HSI48 ready interrupt + * @param __INTERRUPT__ specifies the RCC interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt + * @arg @ref RCC_IT_MSIRDY MSI ready interrupt + * @arg @ref RCC_IT_LSECSS LSE CSS interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt (not available on all devices) */ #define __HAL_RCC_ENABLE_IT(__INTERRUPT__) SET_BIT(RCC->CIER, (__INTERRUPT__)) -/** @brief Disable RCC interrupt (Perform Byte access to RCC_CIER[0:7] bits to disable - * the selected interrupts). +/** @brief Disable RCC interrupt. * @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 __INTERRUPT__: specifies the RCC interrupt sources to be 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_HSI48RDY: HSI48 ready interrupt - * @arg RCC_IT_CSSLSE: LSE CSS interrupt - + * pending bit is cleared. + * @param __INTERRUPT__ specifies the RCC interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt + * @arg @ref RCC_IT_MSIRDY MSI ready interrupt + * @arg @ref RCC_IT_LSECSS LSE CSS interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt (not available on all devices) */ #define __HAL_RCC_DISABLE_IT(__INTERRUPT__) CLEAR_BIT(RCC->CIER, (__INTERRUPT__)) -/** @brief Clear the RCC's interrupt pending bits (Perform Byte access to RCC_CIR[23:16] - * bits to clear the selected interrupt pending bits. - * @param __INTERRUPT__: 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_HSI48RDY: HSI48 ready interrupt - * @arg RCC_IT_CSSLSE: LSE CSS interrupt - * @arg RCC_IT_CSSHSE: Clock Security System interrupt +/** @brief Clear the RCC's interrupt pending bits. + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt. + * @arg @ref RCC_IT_LSERDY LSE ready interrupt. + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt. + * @arg @ref RCC_IT_HSERDY HSE ready interrupt. + * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt. + * @arg @ref RCC_IT_MSIRDY MSI ready interrupt + * @arg @ref RCC_IT_LSECSS LSE CSS interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt (not available on all devices) + * @arg @ref RCC_IT_CSS Clock Security System interrupt */ - #define __HAL_RCC_CLEAR_IT(__INTERRUPT__) (RCC->CICR = (__INTERRUPT__)) +#define __HAL_RCC_CLEAR_IT(__INTERRUPT__) (RCC->CICR = (__INTERRUPT__)) /** @brief Check the RCC's interrupt has occurred or not. - * @param __INTERRUPT__: specifies the RCC interrupt source to check. + * @param __INTERRUPT__ 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_CSSLSE: LSE CSS interrupt - * @arg RCC_IT_CSSHSE: Clock Security System interrupt + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLLRDY PLL ready interrupt + * @arg @ref RCC_IT_MSIRDY MSI ready interrupt + * @arg @ref RCC_IT_LSECSS LSE CSS interrupt + * @arg @ref RCC_IT_CSS Clock Security System interrupt * @retval The new state of __INTERRUPT__ (TRUE or FALSE). */ #define __HAL_RCC_GET_IT(__INTERRUPT__) ((RCC->CIFR & (__INTERRUPT__)) == (__INTERRUPT__)) /** @brief Set RMVF bit to clear the 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. + * The reset flags are RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, + * RCC_FLAG_OBLRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST */ #define __HAL_RCC_CLEAR_RESET_FLAGS() (RCC->CSR |= RCC_CSR_RMVF) /** @brief Check RCC flag is set or not. - * @param __FLAG__: specifies the flag to check. + * @param __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_HSIDIV: HSI clock divider flag - * @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_FWRST: Firewall reset - * @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 + * @arg @ref RCC_FLAG_HSIRDY HSI oscillator clock ready + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready (not available on all devices) + * @arg @ref RCC_FLAG_HSIDIV HSI16 divider flag + * @arg @ref RCC_FLAG_MSIRDY MSI oscillator clock ready + * @arg @ref RCC_FLAG_HSERDY HSE oscillator clock ready + * @arg @ref RCC_FLAG_PLLRDY PLL clock ready + * @arg @ref RCC_FLAG_LSECSS LSE oscillator clock CSS detected + * @arg @ref RCC_FLAG_LSERDY LSE oscillator clock ready + * @arg @ref RCC_FLAG_FWRST Firewall reset + * @arg @ref RCC_FLAG_LSIRDY LSI oscillator clock ready + * @arg @ref RCC_FLAG_OBLRST Option Byte Loader (OBL) reset + * @arg @ref RCC_FLAG_PINRST Pin reset + * @arg @ref RCC_FLAG_PORRST POR/PDR reset + * @arg @ref RCC_FLAG_SFTRST Software reset + * @arg @ref RCC_FLAG_IWDGRST Independent Watchdog reset + * @arg @ref RCC_FLAG_WWDGRST Window Watchdog reset + * @arg @ref RCC_FLAG_LPWRRST Low Power reset * @retval The new state of __FLAG__ (TRUE or FALSE). */ -#define __HAL_RCC_GET_FLAG(__FLAG__) (((((((__FLAG__) >> 5U) == 1U)? RCC->CR :((((__FLAG__) >> 5U) == 2U) ? RCC->CSR :((((__FLAG__) >> 5U) == 3U)? \ - RCC->CRRCR :RCC->CIFR))) & ((uint32_t)1U << ((__FLAG__) & RCC_FLAG_MASK))) != 0U ) ? 1U : 0U ) +#if defined(RCC_HSI48_SUPPORT) +#define __HAL_RCC_GET_FLAG(__FLAG__) (((((((((__FLAG__) >> 5) == CR_REG_INDEX)? RCC->CR :((((__FLAG__) >> 5) == CSR_REG_INDEX) ? RCC->CSR :RCC->CRRCR)))) & ((uint32_t)1 << ((__FLAG__) & RCC_FLAG_MASK))) != 0 ) ? 1 : 0 ) +#else +#define __HAL_RCC_GET_FLAG(__FLAG__) (((((((((__FLAG__) >> 5) == CR_REG_INDEX)? RCC->CR : RCC->CSR))) & ((uint32_t)1 << ((__FLAG__) & RCC_FLAG_MASK))) != 0 ) ? 1 : 0 ) +#endif /* RCC_HSI48_SUPPORT */ /** * @} */ -/** - * @} - */ - - -/* Private constants ---------------------------------------------------------*/ -/** @defgroup RCC_Private_Constants RCC Private Constants - * @{ - */ -/* Defines used for Flags */ -#define RCC_FLAG_MASK ((uint8_t)0x1FU) - -/** - * @} - */ - -/* Private macros ------------------------------------------------------------*/ -/** @addtogroup RCC_Private_Macros - * @{ - */ - -#if !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__) ((__OSCILLATOR__) <= 0x3FU) -#else -#define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__) ((__OSCILLATOR__) <= 0x1FU) -#endif /* !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) */ - -#define IS_RCC_HSE(__HSE__) (((__HSE__) == RCC_HSE_OFF) || ((__HSE__) == RCC_HSE_ON) || \ - ((__HSE__) == RCC_HSE_BYPASS)) -#define IS_RCC_LSE(__LSE__) (((__LSE__) == RCC_LSE_OFF) || ((__LSE__) == RCC_LSE_ON) || \ - ((__LSE__) == RCC_LSE_BYPASS)) - -#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)) - -#define IS_RCC_LSI(__LSI__) (((__LSI__) == RCC_LSI_OFF) || ((__LSI__) == RCC_LSI_ON)) -#define IS_RCC_MSI(__MSI__) (((__MSI__) == RCC_MSI_OFF) || ((__MSI__) == RCC_MSI_ON)) -#define IS_RCC_HSI48(__HSI48__) (((__HSI48__) == RCC_HSI48_OFF) || ((__HSI48__) == RCC_HSI48_ON)) - -#define IS_RCC_PLL(__PLL__) (((__PLL__) == RCC_PLL_NONE) ||((__PLL__) == RCC_PLL_OFF) || ((__PLL__) == RCC_PLL_ON)) - -#define IS_RCC_PLLSOURCE(__SOURCE__) (((__SOURCE__) == RCC_PLLSOURCE_HSI) || \ - ((__SOURCE__) == RCC_PLLSOURCE_HSE)) - -#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)) - -#define IS_RCC_PLL_DIV(__DIV__) (((__DIV__) == RCC_PLLDIV_2) || ((__DIV__) == RCC_PLLDIV_3) || \ - ((__DIV__) == RCC_PLLDIV_4)) - -#define IS_RCC_CLOCKTYPE(__CLK__) ((1U <= (__CLK__)) && ((__CLK__) <= 15U)) - -#define IS_RCC_SYSCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_HSI) || \ - ((__SOURCE__) == RCC_SYSCLKSOURCE_HSE) || \ - ((__SOURCE__) == RCC_SYSCLKSOURCE_MSI) || \ - ((__SOURCE__) == RCC_SYSCLKSOURCE_PLLCLK)) - -#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)) - -#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)) - -#define IS_RCC_RTCCLKSOURCE(__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)) - -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) \ - && !defined (STM32L011xx) && !defined (STM32L021xx) -#define IS_RCC_MCO1SOURCE(__SOURCE__) (((__SOURCE__) == RCC_MCO1SOURCE_NOCLOCK) || ((__SOURCE__) == RCC_MCO1SOURCE_SYSCLK) || \ - ((__SOURCE__) == RCC_MCO1SOURCE_HSI) || ((__SOURCE__) == RCC_MCO1SOURCE_MSI) || \ - ((__SOURCE__) == RCC_MCO1SOURCE_HSE) || ((__SOURCE__) == RCC_MCO1SOURCE_PLLCLK) || \ - ((__SOURCE__) == RCC_MCO1SOURCE_LSI) || ((__SOURCE__) == RCC_MCO1SOURCE_LSE) || \ - ((__SOURCE__) == RCC_MCO1SOURCE_HSI48)) -#else -#define IS_RCC_MCO1SOURCE(__SOURCE__) (((__SOURCE__) == RCC_MCO1SOURCE_NOCLOCK) || ((__SOURCE__) == RCC_MCO1SOURCE_SYSCLK) || \ - ((__SOURCE__) == RCC_MCO1SOURCE_HSI) || ((__SOURCE__) == RCC_MCO1SOURCE_MSI) || \ - ((__SOURCE__) == RCC_MCO1SOURCE_HSE) || ((__SOURCE__) == RCC_MCO1SOURCE_PLLCLK) || \ - ((__SOURCE__) == RCC_MCO1SOURCE_LSI) || ((__SOURCE__) == RCC_MCO1SOURCE_LSE)) -#endif - -#define IS_RCC_MCODIV(__DIV__) (((__DIV__) == RCC_MCODIV_1) || \ - ((__DIV__) == RCC_MCODIV_2) || \ - ((__DIV__) == RCC_MCODIV_4) || \ - ((__DIV__) == RCC_MCODIV_8) || \ - ((__DIV__) == RCC_MCODIV_16)) - -#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx) -#define IS_RCC_MCO(__MCOx__) (((__MCOx__) == RCC_MCO1) || ((__MCOx__) == RCC_MCO2) || ((__MCOx__) == RCC_MCO3)) -#else -#define IS_RCC_MCO(__MCOx__) (((__MCOx__) == RCC_MCO1) || ((__MCOx__) == RCC_MCO2)) - -#endif - -#define IS_RCC_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0x1F) -#define IS_RCC_MSICALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0xFF) - /** * @} */ @@ -1556,60 +1690,65 @@ typedef struct /* Include RCC HAL Extension module */ #include "stm32l0xx_hal_rcc_ex.h" -/** @defgroup RCC_Exported_Functions RCC Exported Functions +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCC_Exported_Functions * @{ */ -/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions +/** @addtogroup RCC_Exported_Functions_Group1 * @{ */ -void HAL_RCC_DeInit(void); -HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); -HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency); + +/* Initialization and de-initialization functions ******************************/ +void HAL_RCC_DeInit(void); +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); +HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency); + /** * @} */ -/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions +/** @addtogroup RCC_Exported_Functions_Group2 * @{ */ -void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv); -#if !defined (STM32L011xx) && !defined (STM32L021xx) -void HAL_RCC_EnableCSS(void); -#endif -uint32_t HAL_RCC_GetSysClockFreq(void); -uint32_t HAL_RCC_GetHCLKFreq(void); -uint32_t HAL_RCC_GetPCLK1Freq(void); -uint32_t HAL_RCC_GetPCLK2Freq(void); -void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); -void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency); -/* CSS NMI IRQ handler */ -void HAL_RCC_NMI_IRQHandler(void); -/* User Callbacks in non blocking mode (IT mode) */ -void HAL_RCC_CSSCallback(void); +/* Peripheral Control functions ************************************************/ +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv); +#if defined(RCC_HSECSS_SUPPORT) +void HAL_RCC_EnableCSS(void); +/* CSS NMI IRQ handler */ +void HAL_RCC_NMI_IRQHandler(void); +/* User Callbacks in non blocking mode (IT mode) */ +void HAL_RCC_CSSCallback(void); +#endif /* RCC_HSECSS_SUPPORT */ +uint32_t HAL_RCC_GetSysClockFreq(void); +uint32_t HAL_RCC_GetHCLKFreq(void); +uint32_t HAL_RCC_GetPCLK1Freq(void); +uint32_t HAL_RCC_GetPCLK2Freq(void); +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + /** * @} */ -/** - * @} - */ - - -/** - * @} - */ - -/** - * @} - */ - #ifdef __cplusplus } #endif -#endif /* __STM32l0xx_HAL_RCC_H */ +#endif /* __STM32L0xx_HAL_RCC_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc_ex.c index 69eca7e257..c65dd93c6d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc_ex.c @@ -2,61 +2,12 @@ ****************************************************************************** * @file stm32l0xx_hal_rcc_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Extended RCC HAL module driver. - * * This file provides firmware functions to manage the following * functionalities RCC extension peripheral: * + Extended Peripheral Control functions - * - @verbatim - ============================================================================== - ##### RCC specific features ##### - ============================================================================== - For CRS, RCC Extension HAL driver can be used as follows: - - (#) In System clock configuration, HSI48 need to be enabled - - (#] Enable CRS clock in IP MSP init which will use CRS functions - - (#) Call CRS functions like this - (##) Prepare synchronization configuration necessary for HSI48 calibration - (+++) Default values can be set for frequency Error Measurement (reload and error limit) - and also HSI48 oscillator smooth trimming. - (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate - directly reload value with target and synchronization frequencies values - (##) Call function HAL_RCCEx_CRSConfig which - (+++) Reset CRS registers to their default values. - (+++) Configure CRS registers with synchronization configuration - (+++) Enable automatic calibration and frequency error counter feature - - (##) A polling function is provided to wait for complete Synchronization - (+++) Call function 'HAL_RCCEx_CRSWaitSynchronization()' - (+++) According to CRS status, user can decide to adjust again the calibration or continue - application if synchronization is OK - - (#) User can retrieve information related to synchronization in calling function - HAL_RCCEx_CRSGetSynchronizationInfo() - - (#) Regarding synchronization status and synchronization information, user can try a new calibration - in changing synchronization configuration and call again HAL_RCCEx_CRSConfig. - Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value), - it means that the actual frequency is lower than the target (and so, that the TRIM value should be - incremented), while when it is detected during the upcounting phase it means that the actual frequency - is higher (and that the TRIM value should be decremented). - - (#) To use IT mode, user needs to handle it in calling different macros available to do it - (__HAL_RCC_CRS_XXX_IT). Interruptions will go through RCC Handler (RCC_IRQn/RCC_CRS_IRQHandler) - (+++) Call function HAL_RCCEx_CRSConfig() - (+++) Enable RCC_IRQn (thnaks to NVIC functions) - (+++) Enable CRS IT (__HAL_RCC_CRS_ENABLE_IT) - [+++) Implement CRS status management in RCC_CRS_IRQHandler - - (#) To force a SYNC EVENT, user can use function 'HAL_RCCEx_CRSSoftwareSynchronizationGenerate()'. Function can be - called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler) - - @endverbatim + * + Extended Clock Recovery System Control functions + * ****************************************************************************** * @attention * @@ -96,124 +47,175 @@ #ifdef HAL_RCC_MODULE_ENABLED -/** @addtogroup RCCEx +/** @defgroup RCCEx RCCEx * @brief RCC Extension HAL module driver * @{ */ -/** @addtogroup RCCEx_Private +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup RCCEx_Private_Constants RCCEx Private Constants * @{ */ +#if defined (CRS) /* Bit position in register */ -#define CRS_CFGR_FELIM_BITNUMBER 16U -#define CRS_CR_TRIM_BITNUMBER 8U -#define CRS_ISR_FECAP_BITNUMBER 16U +#define CRS_CFGR_FELIM_BITNUMBER CRS_CFGR_FELIM_Pos +#define CRS_CR_TRIM_BITNUMBER CRS_CR_TRIM_Pos +#define CRS_ISR_FECAP_BITNUMBER CRS_ISR_FECAP_Pos +#endif /* CRS */ #if defined(USB) extern const uint8_t PLLMulTable[]; -#endif //USB +#endif /* USB */ +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup RCCEx_Private_Macros RCCEx Private Macros + * @{ + */ /** * @} */ -/** @addtogroup RCCEx_Exported_Functions +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions * @{ */ -/** @addtogroup RCCEx_Exported_Functions_Group1 - * @brief Extended Peripheral Initialization and Control functions +/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions + * @brief Extended Peripheral Control functions * @verbatim =============================================================================== - ##### Extended Peripheral Control functions ##### + ##### Extended Peripheral Control functions ##### =============================================================================== [..] This subsection provides a set of functions allowing to control the RCC Clocks frequencies. + [..] + (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to + select the RTC clock source; in this case the Backup domain will be reset in + order to modify the RTC Clock source, as consequence RTC registers (including + the backup registers) are set to their reset values. @endverbatim * @{ */ /** - * @brief Initializes the RCC extended peripherals clocks - * @note Initializes the RCC extended peripherals clocks according to the specified parameters in the - * RCC_PeriphCLKInitTypeDef. - * @note If HAL_ERROR returned, first switch-OFF HSE clock oscillator with HAL_RCC_OscConfig() - * to possibly update HSE divider. - * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * @brief Initializes the RCC extended peripherals clocks according to the specified + * parameters in the RCC_PeriphCLKInitTypeDef. + * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that * contains the configuration information for the Extended Peripherals clocks(USART1,USART2, LPUART1, * I2C1, I2C3, RTC, USB/RNG and LPTIM1 clocks). * @retval HAL status + * @note If HAL_ERROR returned, first switch-OFF HSE clock oscillator with @ref HAL_RCC_OscConfig() + * to possibly update HSE divider. */ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) { uint32_t tickstart = 0U; - uint32_t tmpreg = 0U; - + uint32_t temp_reg = 0U; + /* Check the parameters */ assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); - - /*---------------------------- RTC/LCD configuration -------------------------------*/ - if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) -#if defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) - || (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD) -#endif /* defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) */ - ) + + /*------------------------------- RTC/LCD Configuration ------------------------*/ + if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) +#if defined(LCD) + || (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD) +#endif /* LCD */ + ) { - /* Reset the Backup domain only if the RTC Clock source selection is modified */ - if( ((RCC->CR & RCC_CR_RTCPRE) != (PeriphClkInit->RTCClockSelection & RCC_CR_RTCPRE)) -#if defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) - || ((RCC->CR & RCC_CR_RTCPRE) != (PeriphClkInit->LCDClockSelection & RCC_CR_RTCPRE)) -#endif /* defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) */ - ) + /* check for RTC Parameters used to output RTCCLK */ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) + { + assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); + } + +#if defined(LCD) + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD) + { + assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->LCDClockSelection)); + } +#endif /* LCD */ + + FlagStatus pwrclkchanged = RESET; + + /* As soon as function is called to change RTC clock source, activation of the + power domain is done. */ + /* Requires to enable write access to Backup Domain of necessary */ + if(__HAL_RCC_PWR_IS_CLK_DISABLED()) + { + __HAL_RCC_PWR_CLK_ENABLE(); + pwrclkchanged = SET; + } + + if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR, PWR_CR_DBP); + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + { + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Check if user wants to change HSE RTC prescaler whereas HSE is enabled */ + temp_reg = (RCC->CR & RCC_CR_RTCPRE); + if ((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CR_RTCPRE)) +#if defined (LCD) + || (temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CR_RTCPRE)) +#endif /* LCD */ + ) { /* Check HSE State */ if (((PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL) == RCC_CSR_RTCSEL_HSE) && HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) { - /*To update HSE divider, first switch-OFF HSE clock oscillator*/ - return HAL_ERROR; + /* To update HSE divider, first switch-OFF HSE clock oscillator*/ + return HAL_ERROR; } } - /* Enable Power Clock*/ - __HAL_RCC_PWR_CLK_ENABLE(); - - /* Enable write access to Backup domain */ - SET_BIT(PWR->CR, PWR_CR_DBP); - - /* Wait for Backup domain Write protection disable */ - tickstart = HAL_GetTick(); - - while((PWR->CR & PWR_CR_DBP) == RESET) - { - if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) - { - return HAL_TIMEOUT; - } - } - - /* Reset the Backup domain only if the RTC Clock source selection is modified */ - if( ((RCC->CSR & RCC_CSR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL)) -#if defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) - || ((RCC->CSR & RCC_CSR_RTCSEL) != (PeriphClkInit->LCDClockSelection & RCC_CSR_RTCSEL)) -#endif /* defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) */ - ) + /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ + temp_reg = (RCC->CSR & RCC_CSR_RTCSEL); + + if((temp_reg != 0x00000000U) && (((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL)) \ + && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)) +#if defined(LCD) + || ((temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CSR_RTCSEL)) \ + && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD)) +#endif /* LCD */ + )) { /* Store the content of CSR register before the reset of Backup Domain */ - tmpreg = (RCC->CSR & ~(RCC_CSR_RTCSEL)); + temp_reg = (RCC->CSR & ~(RCC_CSR_RTCSEL)); + /* RTC Clock selection can be changed only if the Backup Domain is reset */ __HAL_RCC_BACKUPRESET_FORCE(); __HAL_RCC_BACKUPRESET_RELEASE(); - /* Restore the Content of CSR register */ - RCC->CSR = tmpreg; - - /* Wait for LSERDY if LSE was enabled */ - if (HAL_IS_BIT_SET(tmpreg, RCC_CSR_LSERDY)) - { - /* Get timeout */ - tickstart = HAL_GetTick(); - /* Wait till LSE is ready */ + /* Restore the Content of CSR register */ + RCC->CSR = temp_reg; + + /* Wait for LSERDY if LSE was enabled */ + if (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSEON)) + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) { if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) @@ -222,14 +224,17 @@ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClk } } } - - /* RTC Clock update*/ - __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + } + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + /* Require to disable power clock if necessary */ + if(pwrclkchanged == SET) + { + __HAL_RCC_PWR_CLK_DISABLE(); } } -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) +#if defined (RCC_CCIPR_USART1SEL) /*------------------------------- USART1 Configuration ------------------------*/ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) { @@ -239,7 +244,7 @@ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClk /* Configure the USART1 clock source */ __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection); } -#endif +#endif /* RCC_CCIPR_USART1SEL */ /*----------------------------- USART2 Configuration --------------------------*/ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2) @@ -271,8 +276,7 @@ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClk __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection); } -#if defined (STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || \ - defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) +#if defined (RCC_CCIPR_I2C3SEL) /*------------------------------ I2C3 Configuration ------------------------*/ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3) { @@ -282,16 +286,16 @@ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClk /* Configure the I2C3 clock source */ __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection); } -#endif /* defined (STM32L071xx) (STM32L072xx)|| (STM32L073xx)|| (STM32L081xx)|| (STM32L082xx) || (STM32L083xx) */ +#endif /* RCC_CCIPR_I2C3SEL */ -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) +#if defined(USB) /*---------------------------- USB and RNG configuration --------------------*/ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB)) { assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection)); __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); } -#endif +#endif /* USB */ /*---------------------------- LPTIM1 configuration ------------------------*/ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1)) @@ -299,135 +303,134 @@ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClk assert_param(IS_RCC_LPTIMCLK(PeriphClkInit->LptimClockSelection)); __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->LptimClockSelection); } + return HAL_OK; } - - /** - * @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers. - * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * @brief Get the PeriphClkInit according to the internal RCC configuration registers. + * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that * returns the configuration information for the Extended Peripherals clocks(USART1,USART2, LPUART1, * I2C1, I2C3, RTC, USB/RNG and LPTIM1 clocks). * @retval None */ void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) { + uint32_t srcclk = 0; + /* Set all possible values for the extended clock type parameter -----------*/ /* Common part first */ -#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) - PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | \ - RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_LPTIM1; -#endif -#if defined(STM32L052xx) || defined(STM32L062xx) - PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USB | \ - RCC_PERIPHCLK_LPTIM1 ; -#endif -#if defined(STM32L053xx) || defined(STM32L063xx) - PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USB | \ - RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LCD; -#endif -#if defined(STM32L072xx) || defined(STM32L082xx) - PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1 ; -#endif -#if defined(STM32L073xx) || defined(STM32L083xx) - PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LCD; - -#endif -#if defined(STM32L051xx) || defined(STM32L061xx) - PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_LPTIM1; -#endif -#if defined(STM32L071xx) || defined(STM32L081xx) - PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_RTC | \ + PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | \ RCC_PERIPHCLK_LPTIM1; -#endif +#if defined(RCC_CCIPR_USART1SEL) + PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART1; +#endif /* RCC_CCIPR_USART1SEL */ +#if defined(RCC_CCIPR_I2C3SEL) + PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C3; +#endif /* RCC_CCIPR_I2C3SEL */ +#if defined(USB) + PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB; +#endif /* USB */ +#if defined(LCD) + PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LCD; +#endif /* LCD */ -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) + /* Get the RTC/LCD configuration -----------------------------------------------*/ + srcclk = __HAL_RCC_GET_RTC_SOURCE(); + if (srcclk != RCC_RTCCLKSOURCE_HSE_DIV2) + { + /* Source clock is LSE or LSI*/ + PeriphClkInit->RTCClockSelection = srcclk; + } + else + { + /* Source clock is HSE. Need to get the prescaler value*/ + PeriphClkInit->RTCClockSelection = srcclk | (READ_BIT(RCC->CR, RCC_CR_RTCPRE)); + } +#if defined(LCD) + PeriphClkInit->LCDClockSelection = PeriphClkInit->RTCClockSelection; +#endif /* LCD */ +#if defined(RCC_CCIPR_USART1SEL) /* Get the USART1 configuration --------------------------------------------*/ PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE(); -#endif +#endif /* RCC_CCIPR_USART1SEL */ /* Get the USART2 clock source ---------------------------------------------*/ PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE(); /* Get the LPUART1 clock source ---------------------------------------------*/ PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE(); /* Get the I2C1 clock source -----------------------------------------------*/ PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE(); -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || \ - defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) +#if defined(RCC_CCIPR_I2C3SEL) /* Get the I2C3 clock source -----------------------------------------------*/ PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE(); -#endif /* defined (STM32L071xx) || (STM32L073xx) || (STM32L082xx) || (STM32L082xx) || (STM32L083xx) */ +#endif /* RCC_CCIPR_I2C3SEL */ /* Get the LPTIM1 clock source -----------------------------------------------*/ PeriphClkInit->LptimClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE(); /* Get the RTC clock source -----------------------------------------------*/ PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE(); -#if defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) - PeriphClkInit->LCDClockSelection = PeriphClkInit->RTCClockSelection; -#endif /* defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) */ - -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) +#if defined(USB) /* Get the USB/RNG clock source -----------------------------------------------*/ - PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE(); -#endif + PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE(); +#endif /* USB */ } /** - * @brief Return the peripheral clock frequency for some peripherals - * @note Return 0 if peripheral clock identifier not managed by this API - * @param PeriphClk: Peripheral clock identifier + * @brief Return the peripheral clock frequency + * @note Return 0 if peripheral clock is unknown + * @param PeriphClk Peripheral clock identifier * This parameter can be one of the following values: - * @arg RCC_PERIPHCLK_RTC: RTC peripheral clock - * @arg RCC_PERIPHCLK_LCD: LCD peripheral clock (*) - * @arg RCC_PERIPHCLK_USB: USB or RNG peripheral clock (*) - * @arg RCC_PERIPHCLK_USART1: USART1 peripheral clock (*) - * @arg RCC_PERIPHCLK_USART2: USART2 peripheral clock - * @arg RCC_PERIPHCLK_LPUART1: LPUART1 peripheral clock - * @arg RCC_PERIPHCLK_I2C1: I2C1 peripheral clock - * @arg RCC_PERIPHCLK_I2C2: I2C2 peripheral clock (*) - * @arg RCC_PERIPHCLK_I2C3: I2C3 peripheral clock (*) - * @note (*) means that this peripheral is not present on all the STM32L0xx devices + * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock + * @arg @ref RCC_PERIPHCLK_LCD LCD peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USB USB or RNG peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock (*) + * @note (*) means that this peripheral is not present on all the devices * @retval Frequency in Hz (0: means that no available frequency for the peripheral) */ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) -{ - uint32_t srcclk = 0U, clkprediv = 0U, frequency = 0U; -#if defined(USB) +{ + uint32_t temp_reg = 0U, clkprediv = 0U, frequency = 0U; + uint32_t srcclk = 0U; +#if defined(USB) uint32_t pllmul = 0U, plldiv = 0U, pllvco = 0U; #endif /* USB */ /* Check the parameters */ assert_param(IS_RCC_PERIPHCLOCK(PeriphClk)); - - switch(PeriphClk) + + switch (PeriphClk) { - case RCC_PERIPHCLK_RTC: - { + case RCC_PERIPHCLK_RTC: +#if defined(LCD) + case RCC_PERIPHCLK_LCD: +#endif /* LCD */ + { + /* Get RCC CSR configuration ------------------------------------------------------*/ + temp_reg = RCC->CSR; + /* Get the current RTC source */ srcclk = __HAL_RCC_GET_RTC_SOURCE(); - - /* Check if LSE is ready and if RTC clock selection is LSE */ - if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSERDY))) + + /* Check if LSE is ready if RTC clock selection is LSE */ + if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSERDY))) { frequency = LSE_VALUE; } - /* Check if LSI is ready and if RTC clock selection is LSI */ - else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))) + /* Check if LSI is ready if RTC clock selection is LSI */ + else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSIRDY))) { frequency = LSI_VALUE; } - /* Check if HSE is ready and if RTC clock selection is HSE*/ + /* Check if HSE is ready and if RTC clock selection is HSE */ else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIVX) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))) { - /* Get the current HSE clock divider*/ - clkprediv=__HAL_RCC_GET_RTC_HSE_PRESCALER(); + /* Get the current HSE clock divider */ + clkprediv = __HAL_RCC_GET_RTC_HSE_PRESCALER(); switch (clkprediv) { @@ -436,88 +439,30 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) frequency = HSE_VALUE / 16U; break; } - case RCC_RTC_HSE_DIV_8: /* HSE DIV8 has been selected */ + case RCC_RTC_HSE_DIV_8: /* HSE DIV8 has been selected */ { frequency = HSE_VALUE / 8U; break; } - case RCC_RTC_HSE_DIV_4: /* HSE DIV4 has been selected */ + case RCC_RTC_HSE_DIV_4: /* HSE DIV4 has been selected */ { frequency = HSE_VALUE / 4U; break; } - default: + default: /* HSE DIV2 has been selected */ { frequency = HSE_VALUE / 2U; break; } - } - } - /* Clock not enabled for RTC*/ - else - { - frequency = 0U; - } - break; - } - -#if defined(LCD) - - case RCC_PERIPHCLK_LCD: - { - /* Get the current LCD source */ - srcclk = __HAL_RCC_GET_LCD_SOURCE(); - - /* Check if LSE is ready and if LCD clock selection is LSE */ - if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSERDY))) - { - frequency = LSE_VALUE; + } } - /* Check if LSI is ready and if LCD clock selection is LSI */ - else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))) - { - frequency = LSI_VALUE; - } - /* Check if HSE is ready and if LCD clock selection is HSE*/ - else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIVX) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))) - { - /* Get the current HSE clock divider*/ - clkprediv=__HAL_RCC_GET_RTC_HSE_PRESCALER(); - - switch (clkprediv) - { - case RCC_RTC_HSE_DIV_16: /* HSE DIV16 has been selected */ - { - frequency = HSE_VALUE / 16U; - break; - } - case RCC_RTC_HSE_DIV_8: /* HSE DIV8 has been selected */ - { - frequency = HSE_VALUE / 8U; - break; - } - case RCC_RTC_HSE_DIV_4: /* HSE DIV4 has been selected */ - { - frequency = HSE_VALUE / 4U; - break; - } - default: - { - frequency = HSE_VALUE / 2U; - break; - } - } - } - /* Clock not enabled for LCD*/ + /* Clock not enabled for RTC */ else { frequency = 0U; } break; - } -#endif /* LCD */ - - + } #if defined(USB) case RCC_PERIPHCLK_USB: { @@ -529,8 +474,8 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) /* Get PLL clock source and multiplication factor ----------------------*/ pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; - pllmul = PLLMulTable[(pllmul >> 18U)]; - plldiv = (plldiv >> 22U) + 1U; + pllmul = PLLMulTable[(pllmul >> RCC_CFGR_PLLMUL_Pos)]; + plldiv = (plldiv >> RCC_CFGR_PLLDIV_Pos) + 1U; /* Compute PLL clock input */ if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI) @@ -564,7 +509,7 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) break; } #endif /* USB */ -#if defined(USART1) +#if defined(RCC_CCIPR_USART1SEL) case RCC_PERIPHCLK_USART1: { /* Get the current USART1 source */ @@ -597,7 +542,7 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) } break; } -#endif /* USART1 */ +#endif /* RCC_CCIPR_USART1SEL */ case RCC_PERIPHCLK_USART2: { /* Get the current USART2 source */ @@ -689,7 +634,7 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) } break; } -#if defined(I2C2) +#if defined(I2C2) case RCC_PERIPHCLK_I2C2: { @@ -704,9 +649,9 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) } break; } -#endif /* I2C2 */ +#endif /* I2C2 */ -#if defined(I2C3) +#if defined(RCC_CCIPR_I2C3SEL) case RCC_PERIPHCLK_I2C3: { /* Get the current I2C1 source */ @@ -734,9 +679,13 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) } break; } -#endif /* I2C3 */ +#endif /* RCC_CCIPR_I2C3SEL */ + default: + { + break; } - return(frequency); + } + return(frequency); } /** @@ -745,11 +694,14 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) */ void HAL_RCCEx_EnableLSECSS(void) { - SET_BIT(RCC->CSR, RCC_CSR_LSECSSON) ; + SET_BIT(RCC->CSR, RCC_CSR_LSECSSON) ; } /** * @brief Disables the LSE Clock Security System. + * @note Once enabled this bit cannot be disabled, except after an LSE failure detection + * (LSECSSD=1). In that case the software MUST disable the LSECSSON bit. + * Reset by power on reset and RTC software reset (RTCRST bit). * @retval None */ void HAL_RCCEx_DisableLSECSS(void) @@ -758,7 +710,7 @@ void HAL_RCCEx_DisableLSECSS(void) CLEAR_BIT(RCC->CSR, RCC_CSR_LSECSSON) ; /* Disable LSE CSS IT */ - __HAL_RCC_DISABLE_IT(RCC_IT_CSSLSE); + __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS); } /** @@ -772,7 +724,7 @@ void HAL_RCCEx_EnableLSECSS_IT(void) SET_BIT(RCC->CSR, RCC_CSR_LSECSSON) ; /* Enable LSE CSS IT */ - __HAL_RCC_ENABLE_IT(RCC_IT_CSSLSE); + __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS); /* Enable IT on EXTI Line 19 */ __HAL_RCC_LSECSS_EXTI_ENABLE_IT(); @@ -786,13 +738,13 @@ void HAL_RCCEx_EnableLSECSS_IT(void) void HAL_RCCEx_LSECSS_IRQHandler(void) { /* Check RCC LSE CSSF flag */ - if(__HAL_RCC_GET_IT(RCC_IT_CSSLSE)) + if(__HAL_RCC_GET_IT(RCC_IT_LSECSS)) { /* RCC LSE Clock Security System interrupt user callback */ HAL_RCCEx_LSECSS_Callback(); /* Clear RCC LSE CSS pending bit */ - __HAL_RCC_CLEAR_IT(RCC_IT_CSSLSE); + __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS); } } @@ -806,16 +758,111 @@ __weak void HAL_RCCEx_LSECSS_Callback(void) the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file */ } - -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) - + +#if defined(SYSCFG_CFGR3_ENREF_HSI48) /** - * @brief Start automatic synchronization using polling mode + * @brief Enables Vrefint for the HSI48. + * @note This is functional only if the LOCK is not set + * @retval None + */ +void HAL_RCCEx_EnableHSI48_VREFINT(void) +{ + /* Enable the Buffer for the ADC by setting SYSCFG_CFGR3_ENREF_HSI48 bit in SYSCFG_CFGR3 register */ + SET_BIT (SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48); +} + +/** + * @brief Disables the Vrefint for the HSI48. + * @note This is functional only if the LOCK is not set + * @retval None + */ +void HAL_RCCEx_DisableHSI48_VREFINT(void) +{ + /* Disable the Vrefint by resetting SYSCFG_CFGR3_ENREF_HSI48 bit in SYSCFG_CFGR3 register */ + CLEAR_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48); +} + +#endif /* SYSCFG_CFGR3_ENREF_HSI48 */ + +/** + * @} + */ + +#if defined (CRS) + +/** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions + * @brief Extended Clock Recovery System Control functions + * +@verbatim + =============================================================================== + ##### Extended Clock Recovery System Control functions ##### + =============================================================================== + [..] + For devices with Clock Recovery System feature (CRS), RCC Extention HAL driver can be used as follows: + + (#) In System clock config, HSI48 needs to be enabled + + (#) Enable CRS clock in IP MSP init which will use CRS functions + + (#) Call CRS functions as follows: + (##) Prepare synchronization configuration necessary for HSI48 calibration + (+++) Default values can be set for frequency Error Measurement (reload and error limit) + and also HSI48 oscillator smooth trimming. + (+++) Macro @ref __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate + directly reload value with target and synchronization frequencies values + (##) Call function @ref HAL_RCCEx_CRSConfig which + (+++) Reset CRS registers to their default values. + (+++) Configure CRS registers with synchronization configuration + (+++) Enable automatic calibration and frequency error counter feature + Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the + periodic USB SOF will not be generated by the host. No SYNC signal will therefore be + provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock + precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs + should be used as SYNC signal. + + (##) A polling function is provided to wait for complete synchronization + (+++) Call function @ref HAL_RCCEx_CRSWaitSynchronization() + (+++) According to CRS status, user can decide to adjust again the calibration or continue + application if synchronization is OK + + (#) User can retrieve information related to synchronization in calling function + @ref HAL_RCCEx_CRSGetSynchronizationInfo() + + (#) Regarding synchronization status and synchronization information, user can try a new calibration + in changing synchronization configuration and call again HAL_RCCEx_CRSConfig. + Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value), + it means that the actual frequency is lower than the target (and so, that the TRIM value should be + incremented), while when it is detected during the upcounting phase it means that the actual frequency + is higher (and that the TRIM value should be decremented). + + (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go + through CRS Handler (RCC_IRQn/RCC_IRQHandler) + (++) Call function @ref HAL_RCCEx_CRSConfig() + (++) Enable RCC_IRQn (thanks to NVIC functions) + (++) Enable CRS interrupt (@ref __HAL_RCC_CRS_ENABLE_IT) + (++) Implement CRS status management in the following user callbacks called from + HAL_RCCEx_CRS_IRQHandler(): + (+++) @ref HAL_RCCEx_CRS_SyncOkCallback() + (+++) @ref HAL_RCCEx_CRS_SyncWarnCallback() + (+++) @ref HAL_RCCEx_CRS_ExpectedSyncCallback() + (+++) @ref HAL_RCCEx_CRS_ErrorCallback() + + (#) To force a SYNC EVENT, user can use the function @ref HAL_RCCEx_CRSSoftwareSynchronizationGenerate(). + This function can be called before calling @ref HAL_RCCEx_CRSConfig (for instance in Systick handler) + +@endverbatim + * @{ + */ + +/** + * @brief Start automatic synchronization for polling mode * @param pInit Pointer on RCC_CRSInitTypeDef structure * @retval None */ void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit) { + uint32_t value = 0; + /* Check the parameters */ assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler)); assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source)); @@ -824,52 +871,30 @@ void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit) assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue)); assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue)); - /* CONFIGURATION */ /* Before configuration, reset CRS registers to their default values*/ __HAL_RCC_CRS_FORCE_RESET(); __HAL_RCC_CRS_RELEASE_RESET(); - /* Configure Synchronization input */ - /* Clear SYNCDIV[2:0], SYNCSRC[1:0] & SYNCSPOL bits */ - CRS->CFGR &= ~(CRS_CFGR_SYNCDIV | CRS_CFGR_SYNCSRC | CRS_CFGR_SYNCPOL); - - /* Set the CRS_CFGR_SYNCDIV[2:0] bits according to Prescaler value */ - CRS->CFGR |= pInit->Prescaler; - + /* Set the SYNCDIV[2:0] bits according to Prescaler value */ /* Set the SYNCSRC[1:0] bits according to Source value */ - CRS->CFGR |= pInit->Source; - - /* Set the SYNCSPOL bits according to Polarity value */ - CRS->CFGR |= pInit->Polarity; - - /* Configure Frequency Error Measurement */ - /* Clear RELOAD[15:0] & FELIM[7:0] bits*/ - CRS->CFGR &= ~(CRS_CFGR_RELOAD | CRS_CFGR_FELIM); - + /* Set the SYNCSPOL bit according to Polarity value */ + value = (pInit->Prescaler | pInit->Source | pInit->Polarity); /* Set the RELOAD[15:0] bits according to ReloadValue value */ - CRS->CFGR |= pInit->ReloadValue; - + value |= pInit->ReloadValue; /* Set the FELIM[7:0] bits according to ErrorLimitValue value */ - CRS->CFGR |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_BITNUMBER); + value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_BITNUMBER); + WRITE_REG(CRS->CFGR, value); /* Adjust HSI48 oscillator smooth trimming */ - /* Clear TRIM[5:0] bits */ - CRS->CR &= ~CRS_CR_TRIM; - /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */ - CRS->CR |= (pInit->HSI48CalibrationValue << CRS_CR_TRIM_BITNUMBER); - - + MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_BITNUMBER)); + /* START AUTOMATIC SYNCHRONIZATION*/ - /* Enable Automatic trimming */ - __HAL_RCC_CRS_AUTOMATIC_CALIB_ENABLE(); - - /* Enable Frequency error counter */ - __HAL_RCC_CRS_FREQ_ERROR_COUNTER_ENABLE(); - + /* Enable Automatic trimming & Frequency error counter */ + SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN); } /** @@ -878,12 +903,11 @@ void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit) */ void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void) { - CRS->CR |= CRS_CR_SWSYNC; + SET_BIT(CRS->CR, CRS_CR_SWSYNC); } - /** - * @brief Function to return synchronization info + * @brief Return synchronization info * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure * @retval None */ @@ -893,34 +917,32 @@ void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo assert_param(pSynchroInfo != NULL); /* Get the reload value */ - pSynchroInfo->ReloadValue = (uint32_t)(CRS->CFGR & CRS_CFGR_RELOAD); + pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD)); /* Get HSI48 oscillator smooth trimming */ - pSynchroInfo->HSI48CalibrationValue = (uint32_t)((CRS->CR & CRS_CR_TRIM) >> CRS_CR_TRIM_BITNUMBER); + pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_BITNUMBER); /* Get Frequency error capture */ - pSynchroInfo->FreqErrorCapture = (uint32_t)((CRS->ISR & CRS_ISR_FECAP) >> CRS_ISR_FECAP_BITNUMBER); + pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_BITNUMBER); /* Get Frequency error direction */ - pSynchroInfo->FreqErrorDirection = (uint32_t)(CRS->ISR & CRS_ISR_FEDIR); - - + pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR)); } /** -* @brief This function handles CRS Synchronization Timeout. -* @param Timeout: Duration of the timeout +* @brief Wait for CRS Synchronization status. +* @param Timeout Duration of the timeout * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization * frequency. * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned. * @retval Combination of Synchronization status * This parameter can be a combination of the following values: -* @arg RCC_CRS_TIMEOUT -* @arg RCC_CRS_SYNCOK -* @arg RCC_CRS_SYNCWARN -* @arg RCC_CRS_SYNCERR -* @arg RCC_CRS_SYNCMISS -* @arg RCC_CRS_TRIMOVF +* @arg @ref RCC_CRS_TIMEOUT +* @arg @ref RCC_CRS_SYNCOK +* @arg @ref RCC_CRS_SYNCWARN +* @arg @ref RCC_CRS_SYNCERR +* @arg @ref RCC_CRS_SYNCMISS +* @arg @ref RCC_CRS_TRIMOVF */ uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout) { @@ -930,12 +952,12 @@ uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout) /* Get timeout */ tickstart = HAL_GetTick(); - /* Check that if one of CRS flags have been set */ - while(RCC_CRS_NONE == crsstatus) + /* Wait for CRS flag or timeout detection */ + do { if(Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) { crsstatus = RCC_CRS_TIMEOUT; } @@ -996,37 +1018,133 @@ uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout) /* frequency error counter reached a zero value */ __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC); } - } + } while(RCC_CRS_NONE == crsstatus); return crsstatus; -} -/** - * @brief Enables Vrefint for the HSI48. - * @note This is functional only if the LOCK is not set - * @retval None - */ -void HAL_RCCEx_EnableHSI48_VREFINT(void) -{ - /* Enable the Buffer for the ADC by setting SYSCFG_CFGR3_ENREF_HSI48 bit in SYSCFG_CFGR3 register */ - SET_BIT (SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48); } /** - * @brief Disables the Vrefint for the HSI48. - * @note This is functional only if the LOCK is not set + * @brief Handle the Clock Recovery System interrupt request. * @retval None */ -void HAL_RCCEx_DisableHSI48_VREFINT(void) +void HAL_RCCEx_CRS_IRQHandler(void) { - /* Disable the Vrefint by resetting SYSCFG_CFGR3_ENREF_HSI48 bit in SYSCFG_CFGR3 register */ - CLEAR_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48); + uint32_t crserror = RCC_CRS_NONE; + /* Get current IT flags and IT sources values */ + uint32_t itflags = READ_REG(CRS->ISR); + uint32_t itsources = READ_REG(CRS->CR); + + /* Check CRS SYNCOK flag */ + if(((itflags & RCC_CRS_FLAG_SYNCOK) != RESET) && ((itsources & RCC_CRS_IT_SYNCOK) != RESET)) + { + /* Clear CRS SYNC event OK flag */ + WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC); + + /* user callback */ + HAL_RCCEx_CRS_SyncOkCallback(); + } + /* Check CRS SYNCWARN flag */ + else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != RESET) && ((itsources & RCC_CRS_IT_SYNCWARN) != RESET)) + { + /* Clear CRS SYNCWARN flag */ + WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC); + + /* user callback */ + HAL_RCCEx_CRS_SyncWarnCallback(); + } + /* Check CRS Expected SYNC flag */ + else if(((itflags & RCC_CRS_FLAG_ESYNC) != RESET) && ((itsources & RCC_CRS_IT_ESYNC) != RESET)) + { + /* frequency error counter reached a zero value */ + WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC); + + /* user callback */ + HAL_RCCEx_CRS_ExpectedSyncCallback(); + } + /* Check CRS Error flags */ + else + { + if(((itflags & RCC_CRS_FLAG_ERR) != RESET) && ((itsources & RCC_CRS_IT_ERR) != RESET)) + { + if((itflags & RCC_CRS_FLAG_SYNCERR) != RESET) + { + crserror |= RCC_CRS_SYNCERR; + } + if((itflags & RCC_CRS_FLAG_SYNCMISS) != RESET) + { + crserror |= RCC_CRS_SYNCMISS; + } + if((itflags & RCC_CRS_FLAG_TRIMOVF) != RESET) + { + crserror |= RCC_CRS_TRIMOVF; + } + + /* Clear CRS Error flags */ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); + + /* user error callback */ + HAL_RCCEx_CRS_ErrorCallback(crserror); + } + } +} + +/** + * @brief RCCEx Clock Recovery System SYNCOK interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_SyncOkCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_SyncWarnCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System Error interrupt callback. + * @param Error Combination of Error status. + * This parameter can be a combination of the following values: + * @arg @ref RCC_CRS_SYNCERR + * @arg @ref RCC_CRS_SYNCMISS + * @arg @ref RCC_CRS_TRIMOVF + * @retval none + */ +__weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Error); + + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file + */ } -#endif /* !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) */ /** * @} */ +#endif /* CRS */ /** * @} */ @@ -1040,10 +1158,8 @@ void HAL_RCCEx_DisableHSI48_VREFINT(void) */ #endif /* HAL_RCC_MODULE_ENABLED */ - /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc_ex.h index 255e3f41e9..73a1ce4ce0 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_rcc_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of RCC HAL Extension module. ****************************************************************************** * @attention @@ -33,7 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32L0xx_HAL_RCC_EX_H @@ -50,26 +48,163 @@ * @{ */ -/** @defgroup RCCEx RCCEx +/** @addtogroup RCCEx * @{ */ +/** @addtogroup RCCEx_Private_Constants + * @{ + */ + + +#if defined(CRS) +/* CRS IT Error Mask */ +#define RCC_CRS_IT_ERROR_MASK ((uint32_t)(RCC_CRS_IT_TRIMOVF | RCC_CRS_IT_SYNCERR | RCC_CRS_IT_SYNCMISS)) + +/* CRS Flag Error Mask */ +#define RCC_CRS_FLAG_ERROR_MASK ((uint32_t)(RCC_CRS_FLAG_TRIMOVF | RCC_CRS_FLAG_SYNCERR | RCC_CRS_FLAG_SYNCMISS)) + +#endif /* CRS */ +/** + * @} + */ + +/** @addtogroup RCCEx_Private_Macros + * @{ + */ +#if defined (STM32L052xx) || defined(STM32L062xx) +#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1)) +#elif defined (STM32L053xx) || defined(STM32L063xx) +#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LCD)) +#elif defined (STM32L072xx) || defined(STM32L082xx) +#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_I2C3 )) +#elif defined (STM32L073xx) || defined(STM32L083xx) +#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_I2C3 | \ + RCC_PERIPHCLK_LCD)) +#endif + +#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) +#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= ( RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_LPTIM1)) +#elif defined(STM32L051xx) || defined(STM32L061xx) +#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_LPTIM1)) +#elif defined(STM32L071xx) || defined(STM32L081xx) +#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_I2C3)) +#endif + +#if defined (RCC_CCIPR_USART1SEL) +#define IS_RCC_USART1CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_USART1CLKSOURCE_PCLK2) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_SYSCLK) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_HSI)) +#endif /* RCC_CCIPR_USART1SEL */ + +#define IS_RCC_USART2CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_USART2CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_SYSCLK) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_HSI)) + +#define IS_RCC_LPUART1CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_LPUART1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_SYSCLK) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_HSI)) + +#define IS_RCC_I2C1CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_I2C1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_SYSCLK)|| \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_HSI)) + +#if defined(RCC_CCIPR_I2C3SEL) +#define IS_RCC_I2C3CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_I2C3CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I2C3CLKSOURCE_SYSCLK)|| \ + ((__SOURCE__) == RCC_I2C3CLKSOURCE_HSI)) +#endif /* RCC_CCIPR_I2C3SEL */ + +#if defined(USB) +#define IS_RCC_USBCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_USBCLKSOURCE_HSI48) || \ + ((__SOURCE__) == RCC_USBCLKSOURCE_PLL)) +#endif /* USB */ + +#if defined(RNG) +#define IS_RCC_RNGCLKSOURCE(_SOURCE_) (((_SOURCE_) == RCC_RNGCLKSOURCE_HSI48) || \ + ((_SOURCE_) == RCC_RNGCLKSOURCE_PLLCLK)) +#endif /* RNG */ + +#if defined(RCC_CCIPR_HSI48SEL) +#define IS_RCC_HSI48MCLKSOURCE(__HSI48MCLK__) (((__HSI48MCLK__) == RCC_HSI48M_PLL) || ((__HSI48MCLK__) == RCC_HSI48M_HSI48)) +#endif /* RCC_CCIPR_HSI48SEL */ + +#define IS_RCC_LPTIMCLK(__LPTIMCLK_) (((__LPTIMCLK_) == RCC_LPTIM1CLKSOURCE_PCLK) || \ + ((__LPTIMCLK_) == RCC_LPTIM1CLKSOURCE_LSI) || \ + ((__LPTIMCLK_) == RCC_LPTIM1CLKSOURCE_HSI) || \ + ((__LPTIMCLK_) == RCC_LPTIM1CLKSOURCE_LSE)) + +#define IS_RCC_STOPWAKEUP_CLOCK(__SOURCE__) (((__SOURCE__) == RCC_STOP_WAKEUPCLOCK_MSI) || \ + ((__SOURCE__) == RCC_STOP_WAKEUPCLOCK_HSI)) + +#define IS_RCC_LSE_DRIVE(__DRIVE__) (((__DRIVE__) == RCC_LSEDRIVE_LOW) || ((__SOURCE__) == RCC_LSEDRIVE_MEDIUMLOW) || \ + ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMHIGH) || ((__SOURCE__) == RCC_LSEDRIVE_HIGH)) + +#if defined(CRS) + +#define IS_RCC_CRS_SYNC_SOURCE(_SOURCE_) (((_SOURCE_) == RCC_CRS_SYNC_SOURCE_GPIO) || \ + ((_SOURCE_) == RCC_CRS_SYNC_SOURCE_LSE) || \ + ((_SOURCE_) == RCC_CRS_SYNC_SOURCE_USB)) +#define IS_RCC_CRS_SYNC_DIV(_DIV_) (((_DIV_) == RCC_CRS_SYNC_DIV1) || ((_DIV_) == RCC_CRS_SYNC_DIV2) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV4) || ((_DIV_) == RCC_CRS_SYNC_DIV8) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV16) || ((_DIV_) == RCC_CRS_SYNC_DIV32) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV64) || ((_DIV_) == RCC_CRS_SYNC_DIV128)) +#define IS_RCC_CRS_SYNC_POLARITY(_POLARITY_) (((_POLARITY_) == RCC_CRS_SYNC_POLARITY_RISING) || \ + ((_POLARITY_) == RCC_CRS_SYNC_POLARITY_FALLING)) +#define IS_RCC_CRS_RELOADVALUE(_VALUE_) (((_VALUE_) <= 0xFFFF)) +#define IS_RCC_CRS_ERRORLIMIT(_VALUE_) (((_VALUE_) <= 0xFF)) +#define IS_RCC_CRS_HSI48CALIBRATION(_VALUE_) (((_VALUE_) <= 0x3F)) +#define IS_RCC_CRS_FREQERRORDIR(_DIR_) (((_DIR_) == RCC_CRS_FREQERRORDIR_UP) || \ + ((_DIR_) == RCC_CRS_FREQERRORDIR_DOWN)) +#endif /* CRS */ +/** + * @} + */ + /* Exported types ------------------------------------------------------------*/ - /** @defgroup RCCEx_Exported_Types RCCEx Exported Types + +/** @defgroup RCCEx_Exported_Types RCCEx Exported Types * @{ */ /** * @brief RCC extended clocks structure definition */ -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) typedef struct { - uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. - This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< specifies the RTC clock source. + This parameter can be a value of @ref RCC_RTC_LCD_Clock_Source */ + +#if defined(LCD) + + uint32_t LCDClockSelection; /*!< specifies the LCD clock source. + This parameter can be a value of @ref RCC_RTC_LCD_Clock_Source */ + +#endif /* LCD */ +#if defined(RCC_CCIPR_USART1SEL) uint32_t Usart1ClockSelection; /*!< USART1 clock source This parameter can be a value of @ref RCCEx_USART1_Clock_Source */ - +#endif /* RCC_CCIPR_USART1SEL */ uint32_t Usart2ClockSelection; /*!< USART2 clock source This parameter can be a value of @ref RCCEx_USART2_Clock_Source */ @@ -78,96 +213,20 @@ typedef struct uint32_t I2c1ClockSelection; /*!< I2C1 clock source This parameter can be a value of @ref RCCEx_I2C1_Clock_Source */ -#if defined (STM32L072xx) || defined(STM32L073xx) || defined(STM32L082xx) || defined(STM32L083xx) + +#if defined(RCC_CCIPR_I2C3SEL) uint32_t I2c3ClockSelection; /*!< I2C3 clock source This parameter can be a value of @ref RCCEx_I2C3_Clock_Source */ -#endif - - uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection - This parameter can be a value of @ref RCC_RTC_Clock_Source */ -#if defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) - uint32_t LCDClockSelection; /*!< specifies the LCD clock source. - This parameter can be a value of @ref RCC_RTC_Clock_Source */ -#endif - +#endif /* RCC_CCIPR_I2C3SEL */ + uint32_t LptimClockSelection; /*!< LPTIM1 clock source + This parameter can be a value of @ref RCCEx_LPTIM1_Clock_Source */ +#if defined(USB) uint32_t UsbClockSelection; /*!< Specifies USB and RNG Clock Selection This parameter can be a value of @ref RCCEx_USB_Clock_Source */ +#endif /* USB */ +} RCC_PeriphCLKInitTypeDef; - uint32_t LptimClockSelection; /*!< LPTIM1 clock source - This parameter can be a value of @ref RCCEx_LPTIM1_Clock_Source */ - -}RCC_PeriphCLKInitTypeDef; - - -#else /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx) && !(STM32L041xx) && !(STM32L051xx) && !(STM32L061xx) && !(STM32L071xx) && !(STM32L081xx) */ - -typedef struct -{ - uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. - This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) - uint32_t Usart1ClockSelection; /*!< USART1 clock source - This parameter can be a value of @ref RCCEx_USART1_Clock_Source */ -#endif - uint32_t Usart2ClockSelection; /*!< USART2 clock source - This parameter can be a value of @ref RCCEx_USART2_Clock_Source */ - - uint32_t Lpuart1ClockSelection; /*!< LPUART1 clock source - This parameter can be a value of @ref RCCEx_LPUART1_Clock_Source */ - - uint32_t I2c1ClockSelection; /*!< I2C1 clock source - This parameter can be a value of @ref RCCEx_I2C1_Clock_Source */ - -#if defined (STM32L071xx) || defined(STM32L081xx) - uint32_t I2c3ClockSelection; /*!< I2C3 clock source - This parameter can be a value of @ref RCCEx_I2C3_Clock_Source */ -#endif - - uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection - This parameter can be a value of @ref RCC_RTC_Clock_Source */ - - uint32_t LptimClockSelection; /*!< LPTIM1 clock source - This parameter can be a value of @ref RCCEx_LPTIM1_Clock_Source */ - -}RCC_PeriphCLKInitTypeDef; - -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx) && !(STM32L041xx) && !(STM32L051xx) && !(STM32L061xx) && !(STM32L071xx) && !(STM32L081xx) */ - -/** - * @} - */ - -/** @defgroup RCCEx_Exported_Constants RCCEx Exported Constants - * @{ - */ -/** - * @} - */ - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) - -/** @addtogroup RCCEx_Exported_Constants - * @{ - */ -/** - * @brief RCC CRS Status definition - */ - -#define RCC_CRS_NONE ((uint32_t) 0x00000000U) -#define RCC_CRS_TIMEOUT ((uint32_t) 0x00000001U) -#define RCC_CRS_SYNCOK ((uint32_t) 0x00000002U) -#define RCC_CRS_SYNCWARN ((uint32_t) 0x00000004U) -#define RCC_CRS_SYNCERR ((uint32_t) 0x00000008U) -#define RCC_CRS_SYNCMISS ((uint32_t) 0x00000010U) -#define RCC_CRS_TRIMOVF ((uint32_t) 0x00000020U) - -/** - * @} - */ - - /** @defgroup RCCEx_Exported_Types RCCEx Exported Types - * @{ - */ +#if defined (CRS) /** * @brief RCC_CRS Init structure definition */ @@ -183,7 +242,7 @@ typedef struct This parameter can be a value of @ref RCCEx_CRS_SynchroPolarity */ uint32_t ReloadValue; /*!< Specifies the value to be loaded in the frequency error counter with each SYNC event. - It can be calculated in using macro __HAL_RCC_CRS_CALCULATE_RELOADVALUE(_FTARGET_, _FSYNC_) + It can be calculated in using macro @ref __HAL_RCC_CRS_RELOADVALUE_CALCULATE(__FTARGET__, __FSYNC__) This parameter must be a number between 0 and 0xFFFF or a value of @ref RCCEx_CRS_ReloadValueDefault .*/ uint32_t ErrorLimitValue; /*!< Specifies the value to be used to evaluate the captured frequency error value. @@ -191,7 +250,7 @@ typedef struct uint32_t HSI48CalibrationValue; /*!< Specifies a user-programmable trimming value to the HSI48 oscillator. This parameter must be a number between 0 and 0x3F or a value of @ref RCCEx_CRS_HSI48CalibrationDefault */ - + }RCC_CRSInitTypeDef; /** @@ -200,15 +259,15 @@ typedef struct typedef struct { uint32_t ReloadValue; /*!< Specifies the value loaded in the Counter reload value. - This parameter must be a number between 0 and 0xFFFF*/ + This parameter must be a number between 0 and 0xFFFF */ uint32_t HSI48CalibrationValue; /*!< Specifies value loaded in HSI48 oscillator smooth trimming. This parameter must be a number between 0 and 0x3F */ - + uint32_t FreqErrorCapture; /*!< Specifies the value loaded in the .FECAP, the frequency error counter - value latched in the time of the last SYNC event. + value latched in the time of the last SYNC event. This parameter must be a number between 0 and 0xFFFF */ - + uint32_t FreqErrorDirection; /*!< Specifies the value loaded in the .FEDIR, the counting direction of the frequency error counter latched in the time of the last SYNC event. It shows whether the actual frequency is below or above the target. @@ -216,218 +275,18 @@ typedef struct }RCC_CRSSynchroInfoTypeDef; +#endif /* CRS */ + /** * @} */ -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ - /* Exported constants --------------------------------------------------------*/ -/** @addtogroup RCCEx_Exported_Constants + +/** @defgroup RCCEx_Exported_Constants RCCEx Exported Constants * @{ */ -/** @defgroup RCCEx_Periph_Clock_Selection RCC Periph Clock Selection - * @{ - */ -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) - -#define RCC_PERIPHCLK_USART1 ((uint32_t)0x00000001U) -#define RCC_PERIPHCLK_USART2 ((uint32_t)0x00000002U) -#define RCC_PERIPHCLK_LPUART1 ((uint32_t)0x00000004U) -#define RCC_PERIPHCLK_I2C1 ((uint32_t)0x00000008U) -#define RCC_PERIPHCLK_I2C2 ((uint32_t)0x00000010U) -#define RCC_PERIPHCLK_RTC ((uint32_t)0x00000020U) -#define RCC_PERIPHCLK_USB ((uint32_t)0x00000040U) -#define RCC_PERIPHCLK_LPTIM1 ((uint32_t)0x00000080U) -#if defined (STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) -#define RCC_PERIPHCLK_LCD ((uint32_t)0x00000800U) -#endif -#if defined (STM32L072xx) || defined(STM32L073xx) || defined(STM32L082xx) || defined(STM32L083xx) -#define RCC_PERIPHCLK_I2C3 ((uint32_t)0x00000100U) -#endif - - -#else /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx) && !(STM32L041xx) && !(STM32L051xx) && !(STM32L061xx) && !(STM32L071xx) && !(STM32L081xx) */ - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) -#define RCC_PERIPHCLK_USART1 ((uint32_t)0x00000001U) -#endif -#define RCC_PERIPHCLK_USART2 ((uint32_t)0x00000002U) -#define RCC_PERIPHCLK_LPUART1 ((uint32_t)0x00000004U) -#define RCC_PERIPHCLK_I2C1 ((uint32_t)0x00000008U) -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) -#define RCC_PERIPHCLK_I2C2 ((uint32_t)0x00000010U) -#endif -#define RCC_PERIPHCLK_RTC ((uint32_t)0x00000020U) -#define RCC_PERIPHCLK_LPTIM1 ((uint32_t)0x00000080U) -#if defined(STM32L071xx) || defined(STM32L081xx) -#define RCC_PERIPHCLK_I2C3 ((uint32_t)0x00000100U) -#endif - -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx) && !(STM32L041xx) && !(STM32L061xx) && !(STM32L071xx) && !(STM32L081xx) */ -/** - * @} - */ - -/** @defgroup RCCEx_USART1_Clock_Source RCC USART1 Clock Source - * @{ - */ -#define RCC_USART1CLKSOURCE_PCLK2 ((uint32_t)0x00000000U) -#define RCC_USART1CLKSOURCE_SYSCLK RCC_CCIPR_USART1SEL_0 -#define RCC_USART1CLKSOURCE_HSI RCC_CCIPR_USART1SEL_1 -#define RCC_USART1CLKSOURCE_LSE (RCC_CCIPR_USART1SEL_0 | RCC_CCIPR_USART1SEL_1) - -/** - * @} - */ - -/** @defgroup RCCEx_USART2_Clock_Source RCC USART2 Clock Source - * @{ - */ -#define RCC_USART2CLKSOURCE_PCLK1 ((uint32_t)0x00000000U) -#define RCC_USART2CLKSOURCE_SYSCLK RCC_CCIPR_USART2SEL_0 -#define RCC_USART2CLKSOURCE_HSI RCC_CCIPR_USART2SEL_1 -#define RCC_USART2CLKSOURCE_LSE (RCC_CCIPR_USART2SEL_0 | RCC_CCIPR_USART2SEL_1) - -/** - * @} - */ - -/** @defgroup RCCEx_LPUART1_Clock_Source RCC LPUART Clock Source - * @{ - */ -#define RCC_LPUART1CLKSOURCE_PCLK1 ((uint32_t)0x00000000U) -#define RCC_LPUART1CLKSOURCE_SYSCLK RCC_CCIPR_LPUART1SEL_0 -#define RCC_LPUART1CLKSOURCE_HSI RCC_CCIPR_LPUART1SEL_1 -#define RCC_LPUART1CLKSOURCE_LSE (RCC_CCIPR_LPUART1SEL_0 | RCC_CCIPR_LPUART1SEL_1) - -/** - * @} - */ - -/** @defgroup RCCEx_I2C1_Clock_Source RCC I2C1 Clock Source - * @{ - */ -#define RCC_I2C1CLKSOURCE_PCLK1 ((uint32_t)0x00000000U) -#define RCC_I2C1CLKSOURCE_SYSCLK RCC_CCIPR_I2C1SEL_0 -#define RCC_I2C1CLKSOURCE_HSI RCC_CCIPR_I2C1SEL_1 - -/** - * @} - */ - -#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx)|| defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx) - -/** @defgroup RCCEx_I2C3_Clock_Source RCC I2C3 Clock Source - * @{ - */ -#define RCC_I2C3CLKSOURCE_PCLK1 ((uint32_t)0x00000000U) -#define RCC_I2C3CLKSOURCE_SYSCLK RCC_CCIPR_I2C3SEL_0 -#define RCC_I2C3CLKSOURCE_HSI RCC_CCIPR_I2C3SEL_1 - -/** - * @} - */ -#endif /* defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx)|| defined(STM32L082xx) || defined(STM32L083xx) */ - - - -/** @defgroup RCCEx_TIM_PRescaler_Selection RCC TIM Prescaler Selection - * @{ - */ -#define RCC_TIMPRES_DESACTIVATED ((uint8_t)0x00U) -#define RCC_TIMPRES_ACTIVATED ((uint8_t)0x01U) -/** - * @} - */ - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -/** @defgroup RCCEx_USB_Clock_Source RCC USB Clock Source - * @{ - */ -#define RCC_USBCLKSOURCE_HSI48 RCC_CCIPR_HSI48SEL -#define RCC_USBCLKSOURCE_PLL ((uint32_t)0x00000000U) - -/** - * @} - */ - -/** @defgroup RCCEx_RNG_Clock_Source RCC RNG Clock Source - * @{ - */ -#define RCC_RNGCLKSOURCE_HSI48 RCC_CCIPR_HSI48SEL -#define RCC_RNGCLKSOURCE_PLLCLK ((uint32_t)0x00000000U) - -/** - * @} - */ - -/** @defgroup RCCEx_HSI48M_Clock_Source RCC HSI48M Clock Source - * @{ - */ -#define RCC_FLAG_HSI48 SYSCFG_CFGR3_VREFINT_RDYF - -#define RCC_HSI48M_PLL ((uint32_t)0x00000000U) -#define RCC_HSI48M_HSI48 RCC_CCIPR_HSI48SEL - - -/** - * @} - */ -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ - -/** @defgroup RCC_HSI_Config RCC HSI Configuration - * @{ - */ -#define RCC_HSI_OFF ((uint8_t)0x00U) -#define RCC_HSI_ON RCC_CR_HSION -#define RCC_HSI_DIV4 (RCC_CR_HSIDIVEN | RCC_CR_HSION) -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -#define RCC_HSI_OUTEN RCC_CR_HSIOUTEN -#endif - -/** - * @} - */ - -/** @defgroup RCCEx_LPTIM1_Clock_Source RCC LPTIM1 Clock Source - * @{ - */ -#define RCC_LPTIM1CLKSOURCE_PCLK ((uint32_t)0x00000000U) -#define RCC_LPTIM1CLKSOURCE_LSI RCC_CCIPR_LPTIM1SEL_0 -#define RCC_LPTIM1CLKSOURCE_HSI RCC_CCIPR_LPTIM1SEL_1 -#define RCC_LPTIM1CLKSOURCE_LSE RCC_CCIPR_LPTIM1SEL - -/** - * @} - */ - -/** @defgroup RCCEx_StopWakeUp_Clock RCC StopWakeUp Clock - * @{ - */ - -#define RCC_STOP_WAKEUPCLOCK_MSI ((uint32_t)0x00U) -#define RCC_STOP_WAKEUPCLOCK_HSI RCC_CFGR_STOPWUCK - -/** - * @} - */ - -/** @defgroup RCCEx_LSEDrive_Configuration RCC LSE Drive Configuration - * @{ - */ - -#define RCC_LSEDRIVE_LOW ((uint32_t)0x00000000U) -#define RCC_LSEDRIVE_MEDIUMLOW RCC_CSR_LSEDRV_0 -#define RCC_LSEDRIVE_MEDIUMHIGH RCC_CSR_LSEDRV_1 -#define RCC_LSEDRIVE_HIGH RCC_CSR_LSEDRV - -/** - * @} - */ /** @defgroup RCCEx_EXTI_LINE_LSECSS RCC LSE CSS external interrupt line * @{ @@ -437,22 +296,199 @@ typedef struct * @} */ -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -/** @defgroup RCCEx_CRS_SynchroSource RCC CRS Synchro Source +/** @defgroup RCCEx_Periph_Clock_Selection RCCEx Periph Clock Selection * @{ */ -#define RCC_CRS_SYNC_SOURCE_GPIO ((uint32_t)0x00U) /*!< Synchro Signal source GPIO */ -#define RCC_CRS_SYNC_SOURCE_LSE CRS_CFGR_SYNCSRC_0 /*!< Synchro Signal source LSE */ -#define RCC_CRS_SYNC_SOURCE_USB CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source USB SOF (default)*/ - +#if defined(RCC_CCIPR_USART1SEL) +#define RCC_PERIPHCLK_USART1 ((uint32_t)0x00000001) +#endif /* RCC_CCIPR_USART1SEL */ +#define RCC_PERIPHCLK_USART2 ((uint32_t)0x00000002) +#define RCC_PERIPHCLK_LPUART1 ((uint32_t)0x00000004) +#define RCC_PERIPHCLK_I2C1 ((uint32_t)0x00000008) +#define RCC_PERIPHCLK_I2C2 ((uint32_t)0x00000010) +#define RCC_PERIPHCLK_RTC ((uint32_t)0x00000020) +#if defined(USB) +#define RCC_PERIPHCLK_USB ((uint32_t)0x00000040) +#endif /* USB */ +#define RCC_PERIPHCLK_LPTIM1 ((uint32_t)0x00000080) +#if defined(LCD) +#define RCC_PERIPHCLK_LCD ((uint32_t)0x00000800) +#endif /* LCD */ +#if defined(RCC_CCIPR_I2C3SEL) +#define RCC_PERIPHCLK_I2C3 ((uint32_t)0x00000100) +#endif /* RCC_CCIPR_I2C3SEL */ + /** * @} */ -/** @defgroup RCCEx_CRS_SynchroDivider RCC CRS Synchro Divider +#if defined (RCC_CCIPR_USART1SEL) +/** @defgroup RCCEx_USART1_Clock_Source RCCEx USART1 Clock Source * @{ */ -#define RCC_CRS_SYNC_DIV1 ((uint32_t)0x00U) /*!< Synchro Signal not divided (default) */ +#define RCC_USART1CLKSOURCE_PCLK2 (0x00000000U) +#define RCC_USART1CLKSOURCE_SYSCLK RCC_CCIPR_USART1SEL_0 +#define RCC_USART1CLKSOURCE_HSI RCC_CCIPR_USART1SEL_1 +#define RCC_USART1CLKSOURCE_LSE (RCC_CCIPR_USART1SEL_0 | RCC_CCIPR_USART1SEL_1) +/** + * @} + */ +#endif /* RCC_CCIPR_USART1SEL */ + +/** @defgroup RCCEx_USART2_Clock_Source RCCEx USART2 Clock Source + * @{ + */ +#define RCC_USART2CLKSOURCE_PCLK1 (0x00000000U) +#define RCC_USART2CLKSOURCE_SYSCLK RCC_CCIPR_USART2SEL_0 +#define RCC_USART2CLKSOURCE_HSI RCC_CCIPR_USART2SEL_1 +#define RCC_USART2CLKSOURCE_LSE (RCC_CCIPR_USART2SEL_0 | RCC_CCIPR_USART2SEL_1) +/** + * @} + */ + +/** @defgroup RCCEx_LPUART1_Clock_Source RCCEx LPUART1 Clock Source + * @{ + */ +#define RCC_LPUART1CLKSOURCE_PCLK1 (0x00000000U) +#define RCC_LPUART1CLKSOURCE_SYSCLK RCC_CCIPR_LPUART1SEL_0 +#define RCC_LPUART1CLKSOURCE_HSI RCC_CCIPR_LPUART1SEL_1 +#define RCC_LPUART1CLKSOURCE_LSE (RCC_CCIPR_LPUART1SEL_0 | RCC_CCIPR_LPUART1SEL_1) +/** + * @} + */ + +/** @defgroup RCCEx_I2C1_Clock_Source RCCEx I2C1 Clock Source + * @{ + */ +#define RCC_I2C1CLKSOURCE_PCLK1 (0x00000000U) +#define RCC_I2C1CLKSOURCE_SYSCLK RCC_CCIPR_I2C1SEL_0 +#define RCC_I2C1CLKSOURCE_HSI RCC_CCIPR_I2C1SEL_1 +/** + * @} + */ + +#if defined(RCC_CCIPR_I2C3SEL) + +/** @defgroup RCCEx_I2C3_Clock_Source RCCEx I2C3 Clock Source + * @{ + */ +#define RCC_I2C3CLKSOURCE_PCLK1 (0x00000000U) +#define RCC_I2C3CLKSOURCE_SYSCLK RCC_CCIPR_I2C3SEL_0 +#define RCC_I2C3CLKSOURCE_HSI RCC_CCIPR_I2C3SEL_1 +/** + * @} + */ +#endif /* RCC_CCIPR_I2C3SEL */ + +/** @defgroup RCCEx_TIM_PRescaler_Selection RCCEx TIM Prescaler Selection + * @{ + */ +#define RCC_TIMPRES_DESACTIVATED ((uint8_t)0x00) +#define RCC_TIMPRES_ACTIVATED ((uint8_t)0x01) +/** + * @} + */ + +#if defined(USB) +/** @defgroup RCCEx_USB_Clock_Source RCCEx USB Clock Source + * @{ + */ +#define RCC_USBCLKSOURCE_HSI48 RCC_CCIPR_HSI48SEL +#define RCC_USBCLKSOURCE_PLL (0x00000000U) +/** + * @} + */ +#endif /* USB */ + +#if defined(RNG) +/** @defgroup RCCEx_RNG_Clock_Source RCCEx RNG Clock Source + * @{ + */ +#define RCC_RNGCLKSOURCE_HSI48 RCC_CCIPR_HSI48SEL +#define RCC_RNGCLKSOURCE_PLLCLK (0x00000000U) +/** + * @} + */ +#endif /* RNG */ + +#if defined(RCC_CCIPR_HSI48SEL) +/** @defgroup RCCEx_HSI48M_Clock_Source RCCEx HSI48M Clock Source + * @{ + */ +#define RCC_FLAG_HSI48 SYSCFG_CFGR3_VREFINT_RDYF + +#define RCC_HSI48M_PLL (0x00000000U) +#define RCC_HSI48M_HSI48 RCC_CCIPR_HSI48SEL + +/** + * @} + */ +#endif /* RCC_CCIPR_HSI48SEL */ + +/** @defgroup RCCEx_LPTIM1_Clock_Source RCCEx LPTIM1 Clock Source + * @{ + */ +#define RCC_LPTIM1CLKSOURCE_PCLK (0x00000000U) +#define RCC_LPTIM1CLKSOURCE_LSI RCC_CCIPR_LPTIM1SEL_0 +#define RCC_LPTIM1CLKSOURCE_HSI RCC_CCIPR_LPTIM1SEL_1 +#define RCC_LPTIM1CLKSOURCE_LSE RCC_CCIPR_LPTIM1SEL +/** + * @} + */ + +/** @defgroup RCCEx_StopWakeUp_Clock RCCEx StopWakeUp Clock + * @{ + */ + +#define RCC_STOP_WAKEUPCLOCK_MSI (0x00000000U) +#define RCC_STOP_WAKEUPCLOCK_HSI RCC_CFGR_STOPWUCK +/** + * @} + */ + +/** @defgroup RCCEx_LSEDrive_Configuration RCCEx LSE Drive Configuration + * @{ + */ + +#define RCC_LSEDRIVE_LOW (0x00000000U) +#define RCC_LSEDRIVE_MEDIUMLOW RCC_CSR_LSEDRV_0 +#define RCC_LSEDRIVE_MEDIUMHIGH RCC_CSR_LSEDRV_1 +#define RCC_LSEDRIVE_HIGH RCC_CSR_LSEDRV +/** + * @} + */ + +#if defined(CRS) + +/** @defgroup RCCEx_CRS_Status RCCEx CRS Status + * @{ + */ +#define RCC_CRS_NONE (0x00000000U) +#define RCC_CRS_TIMEOUT ((uint32_t)0x00000001) +#define RCC_CRS_SYNCOK ((uint32_t)0x00000002) +#define RCC_CRS_SYNCWARN ((uint32_t)0x00000004) +#define RCC_CRS_SYNCERR ((uint32_t)0x00000008) +#define RCC_CRS_SYNCMISS ((uint32_t)0x00000010) +#define RCC_CRS_TRIMOVF ((uint32_t)0x00000020) + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroSource RCCEx CRS Synchronization Source + * @{ + */ +#define RCC_CRS_SYNC_SOURCE_GPIO ((uint32_t)0x00000000U) /*!< Synchro Signal source GPIO */ +#define RCC_CRS_SYNC_SOURCE_LSE CRS_CFGR_SYNCSRC_0 /*!< Synchro Signal source LSE */ +#define RCC_CRS_SYNC_SOURCE_USB CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source USB SOF (default)*/ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroDivider RCCEx CRS Synchronization Divider + * @{ + */ +#define RCC_CRS_SYNC_DIV1 ((uint32_t)0x00000000U) /*!< Synchro Signal not divided (default) */ #define RCC_CRS_SYNC_DIV2 CRS_CFGR_SYNCDIV_0 /*!< Synchro Signal divided by 2 */ #define RCC_CRS_SYNC_DIV4 CRS_CFGR_SYNCDIV_1 /*!< Synchro Signal divided by 4 */ #define RCC_CRS_SYNC_DIV8 (CRS_CFGR_SYNCDIV_1 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 8 */ @@ -460,100 +496,96 @@ typedef struct #define RCC_CRS_SYNC_DIV32 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 32 */ #define RCC_CRS_SYNC_DIV64 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_1) /*!< Synchro Signal divided by 64 */ #define RCC_CRS_SYNC_DIV128 CRS_CFGR_SYNCDIV /*!< Synchro Signal divided by 128 */ - /** * @} */ -/** @defgroup RCCEx_CRS_SynchroPolarity RCC CRS Synchro Polarity +/** @defgroup RCCEx_CRS_SynchroPolarity RCCEx CRS Synchronization Polarity * @{ */ -#define RCC_CRS_SYNC_POLARITY_RISING ((uint32_t)0x00U) /*!< Synchro Active on rising edge (default) */ -#define RCC_CRS_SYNC_POLARITY_FALLING CRS_CFGR_SYNCPOL /*!< Synchro Active on falling edge */ - -/** - * @} - */ - -/** @defgroup RCCEx_CRS_ReloadValueDefault RCC CRS Reload Default Value - * @{ - */ -#define RCC_CRS_RELOADVALUE_DEFAULT ((uint32_t)0xBB7FU) /*!< The reset value of the RELOAD field corresponds - to a target frequency of 48 MHz and a synchronization signal frequency of 1 kHz (SOF signal from USB). */ - -/** - * @} - */ - -/** @defgroup RCCEx_CRS_ErrorLimitDefault RCC CRS Error Limit Default - * @{ - */ -#define RCC_CRS_ERRORLIMIT_DEFAULT ((uint32_t)0x22U) /*!< Default Frequency error limit */ - +#define RCC_CRS_SYNC_POLARITY_RISING ((uint32_t)0x00000000U) /*!< Synchro Active on rising edge (default) */ +#define RCC_CRS_SYNC_POLARITY_FALLING CRS_CFGR_SYNCPOL /*!< Synchro Active on falling edge */ /** * @} */ -/** @defgroup RCCEx_CRS_HSI48CalibrationDefault RCC CRS HSI48 Calibration Default +/** @defgroup RCCEx_CRS_ReloadValueDefault RCCEx CRS Default Reload Value * @{ */ -#define RCC_CRS_HSI48CALIBRATION_DEFAULT ((uint32_t)0x20U) /*!< The default value is 32, which corresponds to the middle of the trimming interval. - The trimming step is around 67 kHz between two consecutive TRIM steps. A higher TRIM value - corresponds to a higher output frequency */ - +#define RCC_CRS_RELOADVALUE_DEFAULT ((uint32_t)0x0000BB7FU) /*!< The reset value of the RELOAD field corresponds + to a target frequency of 48 MHz and a synchronization signal frequency of 1 kHz (SOF signal from USB). */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_ErrorLimitDefault RCCEx CRS Default Error Limit Value + * @{ + */ +#define RCC_CRS_ERRORLIMIT_DEFAULT ((uint32_t)0x00000022U) /*!< Default Frequency error limit */ /** * @} */ -/** @defgroup RCCEx_CRS_FreqErrorDirection RCC CRS Frequency Error Direction +/** @defgroup RCCEx_CRS_HSI48CalibrationDefault RCCEx CRS Default HSI48 Calibration vakye * @{ */ -#define RCC_CRS_FREQERRORDIR_UP ((uint32_t)0x00U) /*!< Upcounting direction, the actual frequency is above the target */ -#define RCC_CRS_FREQERRORDIR_DOWN ((uint32_t)CRS_ISR_FEDIR) /*!< Downcounting direction, the actual frequency is below the target */ - +#define RCC_CRS_HSI48CALIBRATION_DEFAULT ((uint32_t)0x00000020U) /*!< The default value is 32, which corresponds to the middle of the trimming interval. + The trimming step is around 67 kHz between two consecutive TRIM steps. A higher TRIM value + corresponds to a higher output frequency */ /** * @} */ -/** @defgroup RCCEx_CRS_Interrupt_Sources RCC CRS Interrupt Sources +/** @defgroup RCCEx_CRS_FreqErrorDirection RCCEx CRS Frequency Error Direction * @{ */ -#define RCC_CRS_IT_SYNCOK CRS_CR_SYNCOKIE /*!< SYNC event OK */ -#define RCC_CRS_IT_SYNCWARN CRS_CR_SYNCWARNIE /*!< SYNC warning */ -#define RCC_CRS_IT_ERR CRS_CR_ERRIE /*!< error */ -#define RCC_CRS_IT_ESYNC CRS_CR_ESYNCIE /*!< Expected SYNC */ -#define RCC_CRS_IT_TRIMOVF CRS_CR_ERRIE /*!< Trimming overflow or underflow */ -#define RCC_CRS_IT_SYNCERR CRS_CR_ERRIE /*!< SYNC error */ -#define RCC_CRS_IT_SYNCMISS CRS_CR_ERRIE /*!< SYNC missed*/ +#define RCC_CRS_FREQERRORDIR_UP ((uint32_t)0x00000000U) /*!< Upcounting direction, the actual frequency is above the target */ +#define RCC_CRS_FREQERRORDIR_DOWN ((uint32_t)CRS_ISR_FEDIR) /*!< Downcounting direction, the actual frequency is below the target */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Interrupt_Sources RCCEx CRS Interrupt Sources + * @{ + */ +#define RCC_CRS_IT_SYNCOK CRS_CR_SYNCOKIE /*!< SYNC event OK */ +#define RCC_CRS_IT_SYNCWARN CRS_CR_SYNCWARNIE /*!< SYNC warning */ +#define RCC_CRS_IT_ERR CRS_CR_ERRIE /*!< Error */ +#define RCC_CRS_IT_ESYNC CRS_CR_ESYNCIE /*!< Expected SYNC */ +#define RCC_CRS_IT_SYNCERR CRS_CR_ERRIE /*!< SYNC error */ +#define RCC_CRS_IT_SYNCMISS CRS_CR_ERRIE /*!< SYNC missed */ +#define RCC_CRS_IT_TRIMOVF CRS_CR_ERRIE /*!< Trimming overflow or underflow */ /** * @} */ -/** @defgroup RCCEx_CRS_Flags RCC CRS Flags +/** @defgroup RCCEx_CRS_Flags RCCEx CRS Flags * @{ */ -#define RCC_CRS_FLAG_SYNCOK CRS_ISR_SYNCOKF /* SYNC event OK flag */ -#define RCC_CRS_FLAG_SYNCWARN CRS_ISR_SYNCWARNF /* SYNC warning flag */ -#define RCC_CRS_FLAG_ERR CRS_ISR_ERRF /* Error flag */ -#define RCC_CRS_FLAG_ESYNC CRS_ISR_ESYNCF /* Expected SYNC flag */ -#define RCC_CRS_FLAG_TRIMOVF CRS_ISR_TRIMOVF /*!< Trimming overflow or underflow */ -#define RCC_CRS_FLAG_SYNCERR CRS_ISR_SYNCERR /*!< SYNC error */ -#define RCC_CRS_FLAG_SYNCMISS CRS_ISR_SYNCMISS /*!< SYNC missed*/ +#define RCC_CRS_FLAG_SYNCOK CRS_ISR_SYNCOKF /*!< SYNC event OK flag */ +#define RCC_CRS_FLAG_SYNCWARN CRS_ISR_SYNCWARNF /*!< SYNC warning flag */ +#define RCC_CRS_FLAG_ERR CRS_ISR_ERRF /*!< Error flag */ +#define RCC_CRS_FLAG_ESYNC CRS_ISR_ESYNCF /*!< Expected SYNC flag */ +#define RCC_CRS_FLAG_SYNCERR CRS_ISR_SYNCERR /*!< SYNC error */ +#define RCC_CRS_FLAG_SYNCMISS CRS_ISR_SYNCMISS /*!< SYNC missed*/ +#define RCC_CRS_FLAG_TRIMOVF CRS_ISR_TRIMOVF /*!< Trimming overflow or underflow */ /** * @} */ -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ +#endif /* CRS */ + /** * @} - */ + */ /* Exported macro ------------------------------------------------------------*/ /** @defgroup RCCEx_Exported_Macros RCCEx Exported Macros - * @{ - */ + * @{ + */ + /** @defgroup RCCEx_Peripheral_Clock_Enable_Disable AHB Peripheral Clock Enable Disable * @brief Enable or disable the AHB peripheral clock. * @note After reset, the peripheral clock (used for registers read/write access) @@ -563,18 +595,796 @@ typedef struct */ #if defined(STM32L062xx) || defined(STM32L063xx)|| defined(STM32L082xx) || defined(STM32L083xx) || defined(STM32L041xx) || defined(STM32L021xx) -#define __HAL_RCC_AES_CLK_ENABLE() SET_BIT(RCC->AHBENR, (RCC_AHBENR_CRYPEN)) +#define __HAL_RCC_AES_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_CRYPEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_CRYPEN);\ + UNUSED(tmpreg); \ + } while(0) #define __HAL_RCC_AES_CLK_DISABLE() CLEAR_BIT(RCC->AHBENR, (RCC_AHBENR_CRYPEN)) + +#define __HAL_RCC_AES_IS_CLK_ENABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_CRYPEN) != RESET) +#define __HAL_RCC_AES_IS_CLK_DISABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_CRYPEN) == RESET) + #endif /* STM32L062xx || STM32L063xx || STM32L072xx || STM32L073xx || STM32L082xx || STM32L083xx || STM32L041xx || STM32L021xx */ #if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define __HAL_RCC_TSC_CLK_ENABLE() SET_BIT(RCC->AHBENR, (RCC_AHBENR_TSCEN)) +#define __HAL_RCC_TSC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_TSCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_TSCEN);\ + UNUSED(tmpreg); \ + } while(0) #define __HAL_RCC_TSC_CLK_DISABLE() CLEAR_BIT(RCC->AHBENR, (RCC_AHBENR_TSCEN)) -#define __HAL_RCC_RNG_CLK_ENABLE() SET_BIT(RCC->AHBENR, (RCC_AHBENR_RNGEN)) +#define __HAL_RCC_TSC_IS_CLK_ENABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_TSCEN) != RESET) +#define __HAL_RCC_TSC_IS_CLK_DISABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_TSCEN) == RESET) + +#define __HAL_RCC_RNG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_RNGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_RNGEN);\ + UNUSED(tmpreg); \ + } while(0) #define __HAL_RCC_RNG_CLK_DISABLE() CLEAR_BIT(RCC->AHBENR, (RCC_AHBENR_RNGEN)) + +#define __HAL_RCC_RNG_IS_CLK_ENABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_RNGEN) != RESET) +#define __HAL_RCC_RNG_IS_CLK_DISABLED() (READ_BIT(RCC->AHBENR, RCC_AHBENR_RNGEN) == RESET) #endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ +/** + * @} + */ + +/** @defgroup RCCEx_IOPORT_Clock_Enable_Disable IOPORT Peripheral Clock Enable Disable + * @brief Enable or disable the IOPORT 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. + * @{ + */ +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOEEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOEEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOE_CLK_DISABLE() CLEAR_BIT(RCC->IOPENR,(RCC_IOPENR_GPIOEEN)) + +#define __HAL_RCC_GPIOE_IS_CLK_ENABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOEEN) != RESET) +#define __HAL_RCC_GPIOE_IS_CLK_DISABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOEEN) == RESET) + +#endif /* GPIOE */ +#if defined(GPIOD) +#define __HAL_RCC_GPIOD_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIODEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIODEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOD_CLK_DISABLE() CLEAR_BIT(RCC->IOPENR,(RCC_IOPENR_GPIODEN)) + +#define __HAL_RCC_GPIOD_IS_CLK_ENABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIODEN) != RESET) +#define __HAL_RCC_GPIOD_IS_CLK_DISABLED() (READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIODEN) == RESET) + +#endif /* GPIOD */ +/** + * @} + */ + +/** @defgroup RCCEx_APB1_Clock_Enable_Disable APB1 Peripheral Clock Enable Disable + * @brief Enable or disable the 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. + * @{ + */ + +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) +#define __HAL_RCC_USB_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USBEN)) +#define __HAL_RCC_USB_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USBEN)) + +#define __HAL_RCC_USB_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USBEN) != RESET) +#define __HAL_RCC_USB_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USBEN) == RESET) + +#define __HAL_RCC_CRS_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_CRSEN)) +#define __HAL_RCC_CRS_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR,(RCC_APB1ENR_CRSEN)) + +#define __HAL_RCC_CRS_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CRSEN) != RESET) +#define __HAL_RCC_CRS_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CRSEN) == RESET) + +#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ + + +#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) +#define __HAL_RCC_LCD_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LCDEN)) +#define __HAL_RCC_LCD_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LCDEN)) + +#define __HAL_RCC_LCD_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LCDEN) != RESET) +#define __HAL_RCC_LCD_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LCDEN) == RESET) + +#endif /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx */ + +#if defined(STM32L053xx) || defined(STM32L063xx) \ + || defined(STM32L052xx) || defined(STM32L062xx) \ + || defined(STM32L051xx) || defined(STM32L061xx) +#define __HAL_RCC_TIM2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) +#define __HAL_RCC_TIM6_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_SPI2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_SPI2EN)) +#define __HAL_RCC_USART2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) +#define __HAL_RCC_LPUART1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) +#define __HAL_RCC_I2C1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_I2C2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN)) +#define __HAL_RCC_DAC_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_DACEN)) +#define __HAL_RCC_LPTIM1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) + +#define __HAL_RCC_TIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) +#define __HAL_RCC_TIM6_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_SPI2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_SPI2EN)) +#define __HAL_RCC_USART2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) +#define __HAL_RCC_LPUART1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) +#define __HAL_RCC_I2C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_I2C2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN)) +#define __HAL_RCC_DAC_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_DACEN)) +#define __HAL_RCC_LPTIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) + +#define __HAL_RCC_TIM2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN) != RESET) +#define __HAL_RCC_TIM6_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN) != RESET) +#define __HAL_RCC_SPI2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN) != RESET) +#define __HAL_RCC_USART2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN) != RESET) +#define __HAL_RCC_LPUART1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPUART1EN) != RESET) +#define __HAL_RCC_I2C1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN) != RESET) +#define __HAL_RCC_I2C2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN) != RESET) +#define __HAL_RCC_DAC_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN) != RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPTIM1EN) != RESET) +#define __HAL_RCC_TIM2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN) == RESET) +#define __HAL_RCC_TIM6_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN) == RESET) +#define __HAL_RCC_SPI2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN) == RESET) +#define __HAL_RCC_USART2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN) == RESET) +#define __HAL_RCC_LPUART1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPUART1EN) == RESET) +#define __HAL_RCC_I2C1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN) == RESET) +#define __HAL_RCC_I2C2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN) == RESET) +#define __HAL_RCC_DAC_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN) == RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPTIM1EN) == RESET) + +#endif /* STM32L051xx || STM32L061xx || */ + /* STM32L052xx || STM32L062xx || */ + /* STM32L053xx || STM32L063xx || */ + +#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) +#define __HAL_RCC_TIM2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) +#define __HAL_RCC_USART2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) +#define __HAL_RCC_LPUART1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) +#define __HAL_RCC_I2C1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_LPTIM1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) + +#define __HAL_RCC_TIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) +#define __HAL_RCC_USART2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) +#define __HAL_RCC_LPUART1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) +#define __HAL_RCC_I2C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_LPTIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) + +#define __HAL_RCC_TIM2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN) != RESET) +#define __HAL_RCC_USART2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN) != RESET) +#define __HAL_RCC_LPUART1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPUART1EN) != RESET) +#define __HAL_RCC_I2C1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN) != RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPTIM1EN) != RESET) +#define __HAL_RCC_TIM2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN) == RESET) +#define __HAL_RCC_USART2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN) == RESET) +#define __HAL_RCC_LPUART1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPUART1EN) == RESET) +#define __HAL_RCC_I2C1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN) == RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPTIM1EN) == RESET) + +#endif /* STM32L011xx || STM32L021xx || STM32L031xx || STM32L041xx */ + + +#if defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) \ + || defined(STM32L071xx) || defined(STM32L081xx) +#define __HAL_RCC_TIM2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) +#define __HAL_RCC_TIM3_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM3EN)) +#define __HAL_RCC_TIM6_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_TIM7_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM7EN)) +#define __HAL_RCC_SPI2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_SPI2EN)) +#define __HAL_RCC_USART2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) +#define __HAL_RCC_USART4_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART4EN)) +#define __HAL_RCC_USART5_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART5EN)) +#define __HAL_RCC_LPUART1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) +#define __HAL_RCC_I2C1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_I2C2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN)) +#define __HAL_RCC_I2C3_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C3EN)) +#define __HAL_RCC_DAC_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_DACEN)) +#define __HAL_RCC_LPTIM1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) + +#define __HAL_RCC_TIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) +#define __HAL_RCC_TIM3_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM3EN)) +#define __HAL_RCC_TIM6_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_TIM7_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM7EN)) +#define __HAL_RCC_SPI2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_SPI2EN)) +#define __HAL_RCC_USART2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) +#define __HAL_RCC_USART4_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART4EN)) +#define __HAL_RCC_USART5_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART5EN)) +#define __HAL_RCC_LPUART1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) +#define __HAL_RCC_I2C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_I2C2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN)) +#define __HAL_RCC_I2C3_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C3EN)) +#define __HAL_RCC_DAC_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_DACEN)) +#define __HAL_RCC_LPTIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) + +#define __HAL_RCC_TIM2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN) != RESET) +#define __HAL_RCC_TIM3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN) != RESET) +#define __HAL_RCC_TIM6_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN) != RESET) +#define __HAL_RCC_TIM7_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN) != RESET) +#define __HAL_RCC_SPI2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN) != RESET) +#define __HAL_RCC_USART2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN) != RESET) +#define __HAL_RCC_USART4_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART4EN) != RESET) +#define __HAL_RCC_USART5_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART5EN) != RESET) +#define __HAL_RCC_LPUART1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPUART1EN) != RESET) +#define __HAL_RCC_I2C1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN) != RESET) +#define __HAL_RCC_I2C2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN) != RESET) +#define __HAL_RCC_I2C3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN) != RESET) +#define __HAL_RCC_DAC_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN) != RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPTIM1EN) != RESET) +#define __HAL_RCC_TIM2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN) == RESET) +#define __HAL_RCC_TIM3_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN) == RESET) +#define __HAL_RCC_TIM6_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN) == RESET) +#define __HAL_RCC_TIM7_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN) == RESET) +#define __HAL_RCC_SPI2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN) == RESET) +#define __HAL_RCC_USART2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN) == RESET) +#define __HAL_RCC_USART4_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART4EN) == RESET) +#define __HAL_RCC_USART5_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART5EN) == RESET) +#define __HAL_RCC_LPUART1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPUART1EN) == RESET) +#define __HAL_RCC_I2C1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN) == RESET) +#define __HAL_RCC_I2C2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN) == RESET) +#define __HAL_RCC_I2C3_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN) == RESET) +#define __HAL_RCC_DAC_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN) == RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1ENR, RCC_APB1ENR_LPTIM1EN) == RESET) + +#endif /* STM32L071xx || STM32L081xx || */ + /* STM32L072xx || STM32L082xx || */ + /* STM32L073xx || STM32L083xx */ + + /** + * @} + */ + +#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L052xx) || defined(STM32L062xx) || defined(STM32L072xx) || defined(STM32L082xx) \ + || defined(STM32L051xx) || defined(STM32L061xx) || defined(STM32L071xx) || defined(STM32L081xx) \ + || defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L011xx) || defined(STM32L021xx) +/** @defgroup RCCEx_APB2_Clock_Enable_Disable APB2 Peripheral Clock Enable Disable + * @brief Enable or disable the 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. + * @{ + */ +#define __HAL_RCC_TIM21_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM21EN)) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM22EN)) +#endif +#define __HAL_RCC_ADC1_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_ADC1EN)) +#define __HAL_RCC_SPI1_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_SPI1EN)) +#define __HAL_RCC_USART1_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_USART1EN)) + +#define __HAL_RCC_TIM21_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM21EN)) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM22EN)) +#endif +#define __HAL_RCC_ADC1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_ADC1EN)) +#define __HAL_RCC_SPI1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_SPI1EN)) +#define __HAL_RCC_USART1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_USART1EN)) +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) +#define __HAL_RCC_FIREWALL_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_MIFIEN)) +#define __HAL_RCC_FIREWALL_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_MIFIEN)) +#endif /* !(STM32L011xx) && !(STM32L021xx) && !STM32L031xx && !STM32L041xx */ + +#define __HAL_RCC_TIM21_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM21EN) != RESET) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM22EN) != RESET) +#endif +#define __HAL_RCC_ADC1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN) != RESET) +#define __HAL_RCC_SPI1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN) != RESET) +#define __HAL_RCC_USART1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN) != RESET) + +#define __HAL_RCC_TIM21_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM21EN) == RESET) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM22EN) == RESET) +#endif +#define __HAL_RCC_ADC1_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, (RCC_APB2ENR_ADC1EN) == RESET) +#define __HAL_RCC_SPI1_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, (RCC_APB2ENR_SPI1EN) == RESET) +#define __HAL_RCC_USART1_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, (RCC_APB2ENR_USART1EN) == RESET) +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) +#define __HAL_RCC_FIREWALL_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_MIFIEN) != RESET) +#define __HAL_RCC_FIREWALL_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, (RCC_APB2ENR_MIFIEN) == RESET) +#endif /* !(STM32L011xx) && !(STM32L021xx) && !STM32L031xx && !STM32L041xx */ + +#endif /* STM32L051xx || STM32L061xx || STM32L071xx || STM32L081xx || */ + /* STM32L052xx || STM32L062xx || STM32L072xx || STM32L082xx || */ + /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx || */ + /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx */ + +/** + * @} + */ + +/** @defgroup RCCEx_AHB_Force_Release_Reset AHB Peripheral Force Release Reset + * @brief Force or release AHB peripheral reset. + * @{ + */ +#if defined(STM32L062xx) || defined(STM32L063xx)|| defined(STM32L082xx) || defined(STM32L083xx) || defined(STM32L041xx) || defined(STM32L021xx) +#define __HAL_RCC_AES_FORCE_RESET() SET_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_CRYPRST)) +#define __HAL_RCC_AES_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_CRYPRST)) +#endif /* STM32L062xx || STM32L063xx || STM32L072xx || STM32L073xx || STM32L082xx || STM32L083xx || STM32L041xx || STM32L021xx*/ + +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) +#define __HAL_RCC_TSC_FORCE_RESET() SET_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_TSCRST)) +#define __HAL_RCC_TSC_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_TSCRST)) +#define __HAL_RCC_RNG_FORCE_RESET() SET_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_RNGRST)) +#define __HAL_RCC_RNG_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_RNGRST)) +#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ + +/** + * @} + */ + +/** @defgroup RCCEx_IOPORT_Force_Release_Reset IOPORT Peripheral Force Release Reset + * @brief Force or release IOPORT peripheral reset. + * @{ + */ +#if defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) \ + || defined(STM32L071xx) || defined(STM32L081xx) +#define __HAL_RCC_GPIOE_FORCE_RESET() SET_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIOERST)) + +#define __HAL_RCC_GPIOE_RELEASE_RESET() CLEAR_BIT(RCC->IOPRSTR,(RCC_IOPRSTR_GPIOERST)) + +#endif /* STM32L071xx || STM32L081xx || */ + /* STM32L072xx || STM32L082xx || */ + /* STM32L073xx || STM32L083xx */ +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) +#define __HAL_RCC_GPIOD_FORCE_RESET() SET_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIODRST)) +#define __HAL_RCC_GPIOD_RELEASE_RESET() CLEAR_BIT(RCC->IOPRSTR,(RCC_IOPRSTR_GPIODRST)) +#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) */ +/** + * @} + */ + +/** @defgroup RCCEx_APB1_Force_Release_Reset APB1 Peripheral Force Release Reset + * @brief Force or release APB1 peripheral reset. + * @{ + */ + +#if defined(STM32L053xx) || defined(STM32L063xx) \ + || defined(STM32L052xx) || defined(STM32L062xx) \ + || defined(STM32L051xx) || defined(STM32L061xx) +#define __HAL_RCC_TIM2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) +#define __HAL_RCC_TIM6_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_LPTIM1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) +#define __HAL_RCC_I2C1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_I2C2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C2RST)) +#define __HAL_RCC_USART2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_LPUART1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) +#define __HAL_RCC_SPI2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_SPI2RST)) +#define __HAL_RCC_DAC_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_DACRST)) + +#define __HAL_RCC_TIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) +#define __HAL_RCC_TIM6_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_LPTIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) +#define __HAL_RCC_I2C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_I2C2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C2RST)) +#define __HAL_RCC_USART2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_LPUART1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) +#define __HAL_RCC_SPI2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_SPI2RST)) +#define __HAL_RCC_DAC_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_DACRST)) +#endif /* STM32L051xx || STM32L061xx || */ + /* STM32L052xx || STM32L062xx || */ + /* STM32L053xx || STM32L063xx */ +#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) +#define __HAL_RCC_TIM2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) +#define __HAL_RCC_LPTIM1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) +#define __HAL_RCC_I2C1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_USART2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_LPUART1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) + +#define __HAL_RCC_TIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) +#define __HAL_RCC_LPTIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) +#define __HAL_RCC_I2C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_USART2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_LPUART1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) +#endif /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx */ + +#if defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) \ + || defined(STM32L071xx) || defined(STM32L081xx) +#define __HAL_RCC_TIM2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) +#define __HAL_RCC_TIM3_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM3RST)) +#define __HAL_RCC_TIM6_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_TIM7_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_LPTIM1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) +#define __HAL_RCC_I2C1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_I2C2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C2RST)) +#define __HAL_RCC_I2C3_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C3RST)) +#define __HAL_RCC_USART2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_USART4_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART4RST)) +#define __HAL_RCC_USART5_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART5RST)) +#define __HAL_RCC_LPUART1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) +#define __HAL_RCC_SPI2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_SPI2RST)) +#define __HAL_RCC_DAC_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_DACRST)) + +#define __HAL_RCC_TIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) +#define __HAL_RCC_TIM3_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM3RST)) +#define __HAL_RCC_TIM6_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_TIM7_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_LPTIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) +#define __HAL_RCC_I2C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_I2C2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C2RST)) +#define __HAL_RCC_I2C3_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C3RST)) +#define __HAL_RCC_USART2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_USART4_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART4RST)) +#define __HAL_RCC_USART5_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART5RST)) +#define __HAL_RCC_LPUART1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) +#define __HAL_RCC_SPI2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_SPI2RST)) +#define __HAL_RCC_DAC_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_DACRST)) +#endif /* STM32L071xx || STM32L081xx || */ + /* STM32L072xx || STM32L082xx || */ + /* STM32L073xx || STM32L083xx || */ + +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) +#define __HAL_RCC_USB_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USBRST)) +#define __HAL_RCC_USB_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USBRST)) +#define __HAL_RCC_CRS_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_CRSRST)) +#define __HAL_RCC_CRS_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR,(RCC_APB1RSTR_CRSRST)) +#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ + +#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) +#define __HAL_RCC_LCD_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LCDRST)) +#define __HAL_RCC_LCD_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LCDRST)) +#endif /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx */ + +/** + * @} + */ + +#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L052xx) || defined(STM32L062xx) || defined(STM32L072xx) || defined(STM32L082xx) \ + || defined(STM32L051xx) || defined(STM32L061xx) || defined(STM32L071xx) || defined(STM32L081xx) + +/** @defgroup RCCEx_APB2_Force_Release_Reset APB2 Peripheral Force Release Reset + * @brief Force or release APB2 peripheral reset. + * @{ + */ +#define __HAL_RCC_USART1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_USART1RST)) +#define __HAL_RCC_ADC1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_ADC1RST)) +#define __HAL_RCC_SPI1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_TIM21_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM21RST)) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM22RST)) +#endif + +#define __HAL_RCC_USART1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_USART1RST)) +#define __HAL_RCC_ADC1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_ADC1RST)) +#define __HAL_RCC_SPI1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_TIM21_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM21RST)) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM22RST)) +#endif +#endif /* STM32L051xx || STM32L061xx || STM32L071xx || STM32L081xx || */ + /* STM32L052xx || STM32L062xx || STM32L072xx || STM32L082xx || */ + /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx || */ +#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) +#define __HAL_RCC_ADC1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_ADC1RST)) +#define __HAL_RCC_SPI1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_TIM21_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM21RST)) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM22RST)) +#endif +#define __HAL_RCC_ADC1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_ADC1RST)) +#define __HAL_RCC_SPI1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_TIM21_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM21RST)) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM22RST)) +#endif +#endif /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx*/ + +/** + * @} + */ + +/** @defgroup RCCEx_AHB_Clock_Sleep_Enable_Disable AHB Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the AHB peripheral clock during Low Power (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. + * @{ + */ + +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) +#define __HAL_RCC_TSC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHBSMENR, (RCC_AHBSMENR_TSCSMEN)) +#define __HAL_RCC_RNG_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHBSMENR, (RCC_AHBSMENR_RNGSMEN)) +#define __HAL_RCC_TSC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHBSMENR, (RCC_AHBSMENR_TSCSMEN)) +#define __HAL_RCC_RNG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHBSMENR, (RCC_AHBSMENR_RNGSMEN)) + +#define __HAL_RCC_TSC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_TSCSMEN) != RESET) +#define __HAL_RCC_RNG_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_RNGSMEN) != RESET) +#define __HAL_RCC_TSC_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_TSCSMEN) == RESET) +#define __HAL_RCC_RNG_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->AHBSMENR, RCC_AHBSMENR_RNGSMEN) == RESET) +#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ + +#if defined(STM32L062xx) || defined(STM32L063xx)|| defined(STM32L082xx) || defined(STM32L083xx) || defined(STM32L041xx) +#define __HAL_RCC_AES_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHBLPENR, (RCC_AHBSMENR_CRYPSMEN)) +#define __HAL_RCC_AES_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHBLPENR, (RCC_AHBSMENR_CRYPSMEN)) + +#define __HAL_RCC_AES_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHBLPENR, RCC_AHBSMENR_CRYPSMEN) != RESET) +#define __HAL_RCC_AES_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->AHBLPENR, RCC_AHBSMENR_CRYPSMEN) == RESET) +#endif /* STM32L062xx || STM32L063xx || STM32L072xx || STM32L073xx || STM32L082xx || STM32L083xx || STM32L041xx */ + +/** + * @} + */ + +/** @defgroup RCCEx_IOPORT_Clock_Sleep_Enable_Disable IOPORT Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the IOPORT peripheral clock during Low Power (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. + * @{ + */ +#if defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) \ + || defined(STM32L071xx) || defined(STM32L081xx) +#define __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE() SET_BIT(RCC->IOPSMENR, (RCC_IOPSMENR_GPIOESMEN)) +#define __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->IOPSMENR,(RCC_IOPSMENR_GPIOESMEN)) + +#define __HAL_RCC_GPIOE_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOESMEN) != RESET) +#define __HAL_RCC_GPIOE_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIOESMEN) == RESET) +#endif /* STM32L071xx || STM32L081xx || */ + /* STM32L072xx || STM32L082xx || */ + /* STM32L073xx || STM32L083xx || */ +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) +#define __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE() SET_BIT(RCC->IOPSMENR, (RCC_IOPSMENR_GPIODSMEN)) +#define __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->IOPSMENR,(RCC_IOPSMENR_GPIODSMEN)) + +#define __HAL_RCC_GPIOD_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIODSMEN) != RESET) +#define __HAL_RCC_GPIOD_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->IOPSMENR, RCC_IOPSMENR_GPIODSMEN) == RESET) +#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) */ +/** + * @} + */ + + +/** @defgroup RCCEx_APB1_Clock_Sleep_Enable_Disable APB1 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the APB1 peripheral clock during Low Power (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. + * @{ + */ + +#if defined(STM32L053xx) || defined(STM32L063xx) \ + || defined(STM32L052xx) || defined(STM32L062xx) \ + || defined(STM32L051xx) || defined(STM32L061xx) +#define __HAL_RCC_TIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) +#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM6SMEN)) +#define __HAL_RCC_SPI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_SPI2SMEN)) +#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) +#define __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) +#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) +#define __HAL_RCC_I2C2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C2SMEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_DACSMEN)) +#define __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) + +#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) +#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM6SMEN)) +#define __HAL_RCC_SPI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_SPI2SMEN)) +#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) +#define __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) +#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) +#define __HAL_RCC_I2C2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C2SMEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_DACSMEN)) +#define __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) + +#define __HAL_RCC_TIM2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM2SMEN) != RESET) +#define __HAL_RCC_TIM6_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM6SMEN) != RESET) +#define __HAL_RCC_SPI2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_SPI2SMEN) != RESET) +#define __HAL_RCC_USART2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART2SMEN) != RESET) +#define __HAL_RCC_LPUART1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPUART1SMEN) != RESET) +#define __HAL_RCC_I2C1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C1SMEN) != RESET) +#define __HAL_RCC_I2C2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C2SMEN) != RESET) +#define __HAL_RCC_DAC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_DACSMEN) != RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPTIM1SMEN) != RESET) +#define __HAL_RCC_TIM2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM2SMEN) == RESET) +#define __HAL_RCC_TIM6_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM6SMEN) == RESET) +#define __HAL_RCC_SPI2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_SPI2SMEN) == RESET) +#define __HAL_RCC_USART2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART2SMEN) == RESET) +#define __HAL_RCC_LPUART1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPUART1SMEN) == RESET) +#define __HAL_RCC_I2C1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C1SMEN) == RESET) +#define __HAL_RCC_I2C2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C2SMEN) == RESET) +#define __HAL_RCC_DAC_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_DACSMEN) == RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPTIM1SMEN) == RESET) +#endif /* STM32L051xx || STM32L061xx || */ + /* STM32L052xx || STM32L062xx || */ + /* STM32L053xx || STM32L063xx */ + +#if defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L072xx) || defined(STM32L082xx) \ + || defined(STM32L071xx) || defined(STM32L081xx) +#define __HAL_RCC_TIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) +#define __HAL_RCC_TIM3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM3SMEN)) +#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM6SMEN)) +#define __HAL_RCC_TIM7_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM7SMEN)) +#define __HAL_RCC_SPI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_SPI2SMEN)) +#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) +#define __HAL_RCC_USART4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART4SMEN)) +#define __HAL_RCC_USART5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART5SMEN)) +#define __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) +#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) +#define __HAL_RCC_I2C2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C2SMEN)) +#define __HAL_RCC_I2C3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C3SMEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_DACSMEN)) +#define __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) + +#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) +#define __HAL_RCC_TIM3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM3SMEN)) +#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM6SMEN)) +#define __HAL_RCC_TIM7_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM7SMEN)) +#define __HAL_RCC_SPI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_SPI2SMEN)) +#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) +#define __HAL_RCC_USART4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART4SMEN)) +#define __HAL_RCC_USART5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART5SMEN)) +#define __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) +#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) +#define __HAL_RCC_I2C2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C2SMEN)) +#define __HAL_RCC_I2C3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C3SMEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_DACSMEN)) +#define __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) + +#define __HAL_RCC_TIM2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM2SMEN) != RESET) +#define __HAL_RCC_TIM3_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM3SMEN) != RESET) +#define __HAL_RCC_TIM6_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM6SMEN) != RESET) +#define __HAL_RCC_TIM7_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM7SMEN) != RESET) +#define __HAL_RCC_SPI2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_SPI2SMEN) != RESET) +#define __HAL_RCC_USART2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART2SMEN) != RESET) +#define __HAL_RCC_USART4_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART4SMEN) != RESET) +#define __HAL_RCC_USART5_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART5SMEN) != RESET) +#define __HAL_RCC_LPUART1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPUART1SMEN) != RESET) +#define __HAL_RCC_I2C1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C1SMEN) != RESET) +#define __HAL_RCC_I2C2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C2SMEN) != RESET) +#define __HAL_RCC_I2C3_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C3SMEN) != RESET) +#define __HAL_RCC_DAC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_DACSMEN) != RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPTIM1SMEN) != RESET) +#define __HAL_RCC_TIM2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM2SMEN) == RESET) +#define __HAL_RCC_TIM3_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM3SMEN) == RESET) +#define __HAL_RCC_TIM6_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM6SMEN) == RESET) +#define __HAL_RCC_TIM7_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM7SMEN) == RESET) +#define __HAL_RCC_SPI2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_SPI2SMEN) == RESET) +#define __HAL_RCC_USART2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART2SMEN) == RESET) +#define __HAL_RCC_USART4_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART4SMEN) == RESET) +#define __HAL_RCC_USART5_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART5SMEN) == RESET) +#define __HAL_RCC_LPUART1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPUART1SMEN) == RESET) +#define __HAL_RCC_I2C1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C1SMEN) == RESET) +#define __HAL_RCC_I2C2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C2SMEN) == RESET) +#define __HAL_RCC_I2C3_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C3SMEN) == RESET) +#define __HAL_RCC_DAC_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_DACSMEN) == RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPTIM1SMEN) == RESET) +#endif /* STM32L071xx || STM32L081xx || */ + /* STM32L072xx || STM32L082xx || */ + /* STM32L073xx || STM32L083xx || */ + +#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) +#define __HAL_RCC_TIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) +#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) +#define __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) +#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) +#define __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) + +#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) +#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) +#define __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) +#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) +#define __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) + +#define __HAL_RCC_TIM2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM2SMEN) != RESET) +#define __HAL_RCC_USART2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART2SMEN) != RESET) +#define __HAL_RCC_LPUART1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPUART1SMEN) != RESET) +#define __HAL_RCC_I2C1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C1SMEN) != RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPTIM1SMEN) != RESET) +#define __HAL_RCC_TIM2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_TIM2SMEN) == RESET) +#define __HAL_RCC_USART2_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USART2SMEN) == RESET) +#define __HAL_RCC_LPUART1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPUART1SMEN) == RESET) +#define __HAL_RCC_I2C1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_I2C1SMEN) == RESET) +#define __HAL_RCC_LPTIM1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LPTIM1SMEN) == RESET) + +#endif /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx */ + +#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) +#define __HAL_RCC_USB_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USBSMEN)) +#define __HAL_RCC_USB_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USBSMEN)) +#define __HAL_RCC_CRS_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_CRSSMEN)) +#define __HAL_RCC_CRS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_CRSSMEN)) + +#define __HAL_RCC_USB_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USBSMEN) != RESET) +#define __HAL_RCC_USB_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_USBSMEN) == RESET) +#define __HAL_RCC_CRS_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_CRSSMEN) != RESET) +#define __HAL_RCC_CRS_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_CRSSMEN) == RESET) +#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ + +#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) +#define __HAL_RCC_LCD_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LCDSMEN)) +#define __HAL_RCC_LCD_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LCDSMEN)) + +#define __HAL_RCC_LCD_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LCDSMEN) != RESET) +#define __HAL_RCC_LCD_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB1SMENR, RCC_APB1SMENR_LCDSMEN) == RESET) +#endif /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx */ + +/** + * @} + */ + +#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) \ + || defined(STM32L052xx) || defined(STM32L062xx) || defined(STM32L072xx) || defined(STM32L082xx) \ + || defined(STM32L051xx) || defined(STM32L061xx) || defined(STM32L071xx) || defined(STM32L081xx) \ + || defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L011xx) || defined(STM32L021xx) + +/** @defgroup RCCEx_APB2_Clock_Sleep_Enable_Disable APB2 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the APB2 peripheral clock during Low Power (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. + * @{ + */ +#define __HAL_RCC_TIM21_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM21SMEN)) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM22SMEN)) +#endif +#define __HAL_RCC_ADC1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_ADC1SMEN)) +#define __HAL_RCC_SPI1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_SPI1SMEN)) +#define __HAL_RCC_USART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_USART1SMEN)) + +#define __HAL_RCC_TIM21_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM21SMEN)) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM22SMEN)) +#endif +#define __HAL_RCC_ADC1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_ADC1SMEN)) +#define __HAL_RCC_SPI1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_SPI1SMEN)) +#define __HAL_RCC_USART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_USART1SMEN)) + +#define __HAL_RCC_TIM21_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_TIM21SMEN) != RESET) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_TIM22SMEN) != RESET) +#endif +#define __HAL_RCC_ADC1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_ADC1SMEN) != RESET) +#define __HAL_RCC_SPI1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_SPI1SMEN) != RESET) +#define __HAL_RCC_USART1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2SMENR, RCC_APB2SMENR_USART1SMEN) != RESET) + +#define __HAL_RCC_TIM21_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM21SMEN) == RESET) +#if !defined (STM32L011xx) && !defined (STM32L021xx) +#define __HAL_RCC_TIM22_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM22SMEN) == RESET) +#endif +#define __HAL_RCC_ADC1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_ADC1SMEN) == RESET) +#define __HAL_RCC_SPI1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_SPI1SMEN) == RESET) +#define __HAL_RCC_USART1_IS_CLK_SLEEP_DISABLED() (READ_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_USART1SMEN) == RESET) + +/** + * @} + */ + +#endif /* STM32L051xx || STM32L061xx || STM32L071xx || STM32L081xx || */ + /* STM32L052xx || STM32L062xx || STM32L072xx || STM32L082xx || */ + /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx || */ + /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx */ + /** * @brief Enable interrupt on RCC LSE CSS EXTI Line 19. @@ -666,563 +1476,17 @@ typedef struct #define __HAL_RCC_LSECSS_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER, RCC_EXTI_LINE_LSECSS) - -/** - * @} - */ - -/** @defgroup RCCEx_IOPORT_Clock_Enable_Disable IOPORT Peripheral Clock Enable Disable - * @brief Enable or disable the IOPORT 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. +#if defined(LCD) + +/** @defgroup RCCEx_LCD_Configuration LCD Configuration + * @brief Macros to configure clock source of LCD peripherals. * @{ - */ -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -#define __HAL_RCC_GPIOE_CLK_ENABLE() do { \ - __IO uint32_t tmpreg; \ - SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOEEN);\ - /* Delay after an RCC peripheral clock enabling */ \ - tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOEEN);\ - UNUSED(tmpreg); \ - } while(0) - -#define __HAL_RCC_GPIOE_CLK_DISABLE() CLEAR_BIT(RCC->IOPENR,(RCC_IOPENR_GPIOEEN)) - -#endif /* STM32L071xx || STM32L081xx || */ - /* STM32L072xx || STM32L082xx || */ - /* STM32L073xx || STM32L083xx */ -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) -#define __HAL_RCC_GPIOD_CLK_ENABLE() do { \ - __IO uint32_t tmpreg; \ - SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIODEN);\ - /* Delay after an RCC peripheral clock enabling */ \ - tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIODEN);\ - UNUSED(tmpreg); \ - } while(0) -#define __HAL_RCC_GPIOD_CLK_DISABLE() CLEAR_BIT(RCC->IOPENR,(RCC_IOPENR_GPIODEN)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) */ -/** - * @} - */ - -/** @defgroup RCCEx_APB1_Clock_Enable_Disable APB1 Peripheral Clock Enable Disable - * @brief Enable or disable the 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. - * @{ - */ - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define __HAL_RCC_USB_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USBEN)) -#define __HAL_RCC_USB_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USBEN)) - -#define __HAL_RCC_CRS_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_CRSEN)) -#define __HAL_RCC_CRS_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR,(RCC_APB1ENR_CRSEN)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ - - -#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) -#define __HAL_RCC_LCD_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LCDEN)) -#define __HAL_RCC_LCD_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LCDEN)) -#endif /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx */ - -#if defined(STM32L053xx) || defined(STM32L063xx) || \ - defined(STM32L052xx) || defined(STM32L062xx) || \ - defined(STM32L051xx) || defined(STM32L061xx) -#define __HAL_RCC_TIM2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) -#define __HAL_RCC_TIM6_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM6EN)) -#define __HAL_RCC_SPI2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_SPI2EN)) -#define __HAL_RCC_USART2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) -#define __HAL_RCC_LPUART1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) -#define __HAL_RCC_I2C1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) -#define __HAL_RCC_I2C2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN)) -#define __HAL_RCC_DAC_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_DACEN)) -#define __HAL_RCC_LPTIM1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) - -#define __HAL_RCC_TIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) -#define __HAL_RCC_TIM6_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM6EN)) -#define __HAL_RCC_SPI2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_SPI2EN)) -#define __HAL_RCC_USART2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) -#define __HAL_RCC_LPUART1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) -#define __HAL_RCC_I2C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) -#define __HAL_RCC_I2C2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN)) -#define __HAL_RCC_DAC_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_DACEN)) -#define __HAL_RCC_LPTIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) -#endif /* STM32L051xx || STM32L061xx || */ - /* STM32L052xx || STM32L062xx || */ - /* STM32L053xx || STM32L063xx || */ - -#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) -#define __HAL_RCC_TIM2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) -#define __HAL_RCC_USART2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) -#define __HAL_RCC_LPUART1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) -#define __HAL_RCC_I2C1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) -#define __HAL_RCC_LPTIM1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) - -#define __HAL_RCC_TIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) -#define __HAL_RCC_USART2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) -#define __HAL_RCC_LPUART1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) -#define __HAL_RCC_I2C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) -#define __HAL_RCC_LPTIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) -#endif /* STM32L011xx || STM32L021xx || STM32L031xx || STM32L041xx */ - - -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -#define __HAL_RCC_TIM2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) -#define __HAL_RCC_TIM3_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM3EN)) -#define __HAL_RCC_TIM6_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM6EN)) -#define __HAL_RCC_TIM7_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM7EN)) -#define __HAL_RCC_SPI2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_SPI2EN)) -#define __HAL_RCC_USART2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) -#define __HAL_RCC_USART4_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART4EN)) -#define __HAL_RCC_USART5_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART5EN)) -#define __HAL_RCC_LPUART1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) -#define __HAL_RCC_I2C1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) -#define __HAL_RCC_I2C2_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN)) -#define __HAL_RCC_I2C3_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C3EN)) -#define __HAL_RCC_DAC_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_DACEN)) -#define __HAL_RCC_LPTIM1_CLK_ENABLE() SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) - -#define __HAL_RCC_TIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM2EN)) -#define __HAL_RCC_TIM3_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM3EN)) -#define __HAL_RCC_TIM6_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM6EN)) -#define __HAL_RCC_TIM7_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_TIM7EN)) -#define __HAL_RCC_SPI2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_SPI2EN)) -#define __HAL_RCC_USART2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN)) -#define __HAL_RCC_USART4_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART4EN)) -#define __HAL_RCC_USART5_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART5EN)) -#define __HAL_RCC_LPUART1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPUART1EN)) -#define __HAL_RCC_I2C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C1EN)) -#define __HAL_RCC_I2C2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN)) -#define __HAL_RCC_I2C3_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C3EN)) -#define __HAL_RCC_DAC_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_DACEN)) -#define __HAL_RCC_LPTIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR, (RCC_APB1ENR_LPTIM1EN)) -#endif /* STM32L071xx || STM32L081xx || */ - /* STM32L072xx || STM32L082xx || */ - /* STM32L073xx || STM32L083xx */ - -#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L052xx) || defined(STM32L062xx) || defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L051xx) || defined(STM32L061xx) || defined(STM32L071xx) || defined(STM32L081xx) || \ - defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L011xx) || defined(STM32L021xx) - /** - * @} - */ - -/** @defgroup RCCEx_APB2_Clock_Enable_Disable APB2 Peripheral Clock Enable Disable - * @brief Enable or disable the 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. - * @{ - */ -#define __HAL_RCC_TIM21_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM21EN)) -#if !defined (STM32L011xx) && !defined (STM32L021xx) -#define __HAL_RCC_TIM22_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM22EN)) -#endif -#define __HAL_RCC_ADC1_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_ADC1EN)) -#define __HAL_RCC_SPI1_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_SPI1EN)) -#define __HAL_RCC_USART1_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_USART1EN)) - -#define __HAL_RCC_TIM21_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM21EN)) -#if !defined (STM32L011xx) && !defined (STM32L021xx) -#define __HAL_RCC_TIM22_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_TIM22EN)) -#endif -#define __HAL_RCC_ADC1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_ADC1EN)) -#define __HAL_RCC_SPI1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_SPI1EN)) -#define __HAL_RCC_USART1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_USART1EN)) -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) -#define __HAL_RCC_FIREWALL_CLK_ENABLE() SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_MIFIEN)) -#define __HAL_RCC_FIREWALL_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, (RCC_APB2ENR_MIFIEN)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !STM32L031xx && !STM32L041xx */ -#endif /* STM32L051xx || STM32L061xx || STM32L071xx || STM32L081xx || */ - /* STM32L052xx || STM32L062xx || STM32L072xx || STM32L082xx || */ - /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx || */ - /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx */ - -/** - * @} - */ - -/** @defgroup RCCEx_AHB_Force_Release_Reset AHB Peripheral Force Release Reset - * @brief Force or release AHB peripheral reset. - * @{ - */ -#if defined(STM32L062xx) || defined(STM32L063xx)|| defined(STM32L082xx) || defined(STM32L083xx) || defined(STM32L041xx) || defined(STM32L021xx) -#define __HAL_RCC_AES_FORCE_RESET() SET_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_CRYPRST)) -#define __HAL_RCC_AES_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_CRYPRST)) -#endif /* STM32L062xx || STM32L063xx || STM32L072xx || STM32L073xx || STM32L082xx || STM32L083xx || STM32L041xx || STM32L021xx*/ - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define __HAL_RCC_TSC_FORCE_RESET() SET_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_TSCRST)) -#define __HAL_RCC_TSC_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_TSCRST)) -#define __HAL_RCC_RNG_FORCE_RESET() SET_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_RNGRST)) -#define __HAL_RCC_RNG_RELEASE_RESET() CLEAR_BIT(RCC->AHBRSTR, (RCC_AHBRSTR_RNGRST)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ - -/** - * @} - */ - -/** @defgroup RCCEx_IOPORT_Force_Release_Reset IOPORT Peripheral Force Release Reset - * @brief Force or release IOPORT peripheral reset. - * @{ - */ -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -#define __HAL_RCC_GPIOE_FORCE_RESET() SET_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIOERST)) - -#define __HAL_RCC_GPIOE_RELEASE_RESET() CLEAR_BIT(RCC->IOPRSTR,(RCC_IOPRSTR_GPIOERST)) - -#endif /* STM32L071xx || STM32L081xx || */ - /* STM32L072xx || STM32L082xx || */ - /* STM32L073xx || STM32L083xx */ -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) -#define __HAL_RCC_GPIOD_FORCE_RESET() SET_BIT(RCC->IOPRSTR, (RCC_IOPRSTR_GPIODRST)) -#define __HAL_RCC_GPIOD_RELEASE_RESET() CLEAR_BIT(RCC->IOPRSTR,(RCC_IOPRSTR_GPIODRST)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) */ -/** - * @} - */ - -/** @defgroup RCCEx_APB1_Force_Release_Reset APB1 Peripheral Force Release Reset - * @brief Force or release APB1 peripheral reset. - * @{ - */ - -#if defined(STM32L053xx) || defined(STM32L063xx) || \ - defined(STM32L052xx) || defined(STM32L062xx) || \ - defined(STM32L051xx) || defined(STM32L061xx) -#define __HAL_RCC_TIM2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) -#define __HAL_RCC_TIM6_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM6RST)) -#define __HAL_RCC_LPTIM1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) -#define __HAL_RCC_I2C1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) -#define __HAL_RCC_I2C2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C2RST)) -#define __HAL_RCC_USART2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) -#define __HAL_RCC_LPUART1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) -#define __HAL_RCC_SPI2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_SPI2RST)) -#define __HAL_RCC_DAC_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_DACRST)) - -#define __HAL_RCC_TIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) -#define __HAL_RCC_TIM6_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM6RST)) -#define __HAL_RCC_LPTIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) -#define __HAL_RCC_I2C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) -#define __HAL_RCC_I2C2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C2RST)) -#define __HAL_RCC_USART2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) -#define __HAL_RCC_LPUART1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) -#define __HAL_RCC_SPI2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_SPI2RST)) -#define __HAL_RCC_DAC_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_DACRST)) -#endif /* STM32L051xx || STM32L061xx || */ - /* STM32L052xx || STM32L062xx || */ - /* STM32L053xx || STM32L063xx */ -#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) -#define __HAL_RCC_TIM2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) -#define __HAL_RCC_LPTIM1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) -#define __HAL_RCC_I2C1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) -#define __HAL_RCC_USART2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) -#define __HAL_RCC_LPUART1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) - -#define __HAL_RCC_TIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) -#define __HAL_RCC_LPTIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) -#define __HAL_RCC_I2C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) -#define __HAL_RCC_USART2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) -#define __HAL_RCC_LPUART1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) -#endif /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx */ - -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -#define __HAL_RCC_TIM2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) -#define __HAL_RCC_TIM3_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM3RST)) -#define __HAL_RCC_TIM6_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM6RST)) -#define __HAL_RCC_TIM7_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM7RST)) -#define __HAL_RCC_LPTIM1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) -#define __HAL_RCC_I2C1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) -#define __HAL_RCC_I2C2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C2RST)) -#define __HAL_RCC_I2C3_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C3RST)) -#define __HAL_RCC_USART2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) -#define __HAL_RCC_USART4_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART4RST)) -#define __HAL_RCC_USART5_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART5RST)) -#define __HAL_RCC_LPUART1_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) -#define __HAL_RCC_SPI2_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_SPI2RST)) -#define __HAL_RCC_DAC_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_DACRST)) - -#define __HAL_RCC_TIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM2RST)) -#define __HAL_RCC_TIM3_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM3RST)) -#define __HAL_RCC_TIM6_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM6RST)) -#define __HAL_RCC_TIM7_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_TIM7RST)) -#define __HAL_RCC_LPTIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPTIM1RST)) -#define __HAL_RCC_I2C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C1RST)) -#define __HAL_RCC_I2C2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C2RST)) -#define __HAL_RCC_I2C3_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_I2C3RST)) -#define __HAL_RCC_USART2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART2RST)) -#define __HAL_RCC_USART4_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART4RST)) -#define __HAL_RCC_USART5_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USART5RST)) -#define __HAL_RCC_LPUART1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LPUART1RST)) -#define __HAL_RCC_SPI2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_SPI2RST)) -#define __HAL_RCC_DAC_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_DACRST)) -#endif /* STM32L071xx || STM32L081xx || */ - /* STM32L072xx || STM32L082xx || */ - /* STM32L073xx || STM32L083xx || */ - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define __HAL_RCC_USB_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USBRST)) -#define __HAL_RCC_USB_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_USBRST)) -#define __HAL_RCC_CRS_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_CRSRST)) -#define __HAL_RCC_CRS_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR,(RCC_APB1RSTR_CRSRST)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ - -#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) -#define __HAL_RCC_LCD_FORCE_RESET() SET_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LCDRST)) -#define __HAL_RCC_LCD_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR, (RCC_APB1RSTR_LCDRST)) -#endif /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx */ - -#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L052xx) || defined(STM32L062xx) || defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L051xx) || defined(STM32L061xx) || defined(STM32L071xx) || defined(STM32L081xx) - -/** - * @} - */ - -/** @defgroup RCCEx_APB2_Force_Release_Reset APB2 Peripheral Force Release Reset - * @brief Force or release APB2 peripheral reset. - * @{ - */ -#define __HAL_RCC_USART1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_USART1RST)) -#define __HAL_RCC_ADC1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_ADC1RST)) -#define __HAL_RCC_SPI1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SPI1RST)) -#define __HAL_RCC_TIM21_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM21RST)) -#if !defined (STM32L011xx) && !defined (STM32L021xx) -#define __HAL_RCC_TIM22_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM22RST)) -#endif - -#define __HAL_RCC_USART1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_USART1RST)) -#define __HAL_RCC_ADC1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_ADC1RST)) -#define __HAL_RCC_SPI1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SPI1RST)) -#define __HAL_RCC_TIM21_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM21RST)) -#if !defined (STM32L011xx) && !defined (STM32L021xx) -#define __HAL_RCC_TIM22_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM22RST)) -#endif -#endif /* STM32L051xx || STM32L061xx || STM32L071xx || STM32L081xx || */ - /* STM32L052xx || STM32L062xx || STM32L072xx || STM32L082xx || */ - /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx || */ -#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) -#define __HAL_RCC_ADC1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_ADC1RST)) -#define __HAL_RCC_SPI1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SPI1RST)) -#define __HAL_RCC_TIM21_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM21RST)) -#if !defined (STM32L011xx) && !defined (STM32L021xx) -#define __HAL_RCC_TIM22_FORCE_RESET() SET_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM22RST)) -#endif -#define __HAL_RCC_ADC1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_ADC1RST)) -#define __HAL_RCC_SPI1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_SPI1RST)) -#define __HAL_RCC_TIM21_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM21RST)) -#if !defined (STM32L011xx) && !defined (STM32L021xx) -#define __HAL_RCC_TIM22_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, (RCC_APB2RSTR_TIM22RST)) -#endif -#endif /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx*/ - - -/** - * @} - */ - -/** @defgroup RCCEx_AHB_Clock_Sleep_Enable_Disable AHB Peripheral Clock Sleep Enable Disable - * @brief Enable or disable the AHB peripheral clock during Low Power (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. - * @{ - */ - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define __HAL_RCC_TSC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHBSMENR, (RCC_AHBSMENR_TSCSMEN)) -#define __HAL_RCC_RNG_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHBSMENR, (RCC_AHBSMENR_RNGSMEN)) -#define __HAL_RCC_TSC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHBSMENR, (RCC_AHBSMENR_TSCSMEN)) -#define __HAL_RCC_RNG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHBSMENR, (RCC_AHBSMENR_RNGSMEN)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ - -#if defined(STM32L062xx) || defined(STM32L063xx)|| defined(STM32L082xx) || defined(STM32L083xx) || defined(STM32L041xx) -#define __HAL_RCC_AES_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHBLPENR, (RCC_AHBSMENR_CRYPSMEN)) -#define __HAL_RCC_AES_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHBLPENR, (RCC_AHBSMENR_CRYPSMEN)) -#endif /* STM32L062xx || STM32L063xx || STM32L072xx || STM32L073xx || STM32L082xx || STM32L083xx || STM32L041xx */ - -/** - * @} - */ - -/** @defgroup RCCEx_IOPORT_Clock_Sleep_Enable_Disable IOPORT Peripheral Clock Sleep Enable Disable - * @brief Enable or disable the IOPORT peripheral clock during Low Power (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. - * @{ - */ -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -#define __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE() SET_BIT(RCC->IOPSMENR, (RCC_IOPSMENR_GPIOESMEN)) -#define __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->IOPSMENR,(RCC_IOPSMENR_GPIOESMEN)) - -#endif /* STM32L071xx || STM32L081xx || */ - /* STM32L072xx || STM32L082xx || */ - /* STM32L073xx || STM32L083xx || */ -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) -#define __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE() SET_BIT(RCC->IOPSMENR, (RCC_IOPSMENR_GPIODSMEN)) -#define __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->IOPSMENR,(RCC_IOPSMENR_GPIODSMEN)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) */ -/** - * @} - */ - - -/** @defgroup RCCEx_APB1_Clock_Sleep_Enable_Disable APB1 Peripheral Clock Sleep Enable Disable - * @brief Enable or disable the APB1 peripheral clock during Low Power (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. - * @{ - */ - -#if defined(STM32L053xx) || defined(STM32L063xx) || \ - defined(STM32L052xx) || defined(STM32L062xx) || \ - defined(STM32L051xx) || defined(STM32L061xx) -#define __HAL_RCC_TIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) -#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM6SMEN)) -#define __HAL_RCC_SPI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_SPI2SMEN)) -#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) -#define __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) -#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) -#define __HAL_RCC_I2C2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C2SMEN)) -#define __HAL_RCC_DAC_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_DACSMEN)) -#define __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) - -#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) -#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM6SMEN)) -#define __HAL_RCC_SPI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_SPI2SMEN)) -#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) -#define __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) -#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) -#define __HAL_RCC_I2C2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C2SMEN)) -#define __HAL_RCC_DAC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_DACSMEN)) -#define __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) -#endif /* STM32L051xx || STM32L061xx || */ - /* STM32L052xx || STM32L062xx || */ - /* STM32L053xx || STM32L063xx */ - -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -#define __HAL_RCC_TIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) -#define __HAL_RCC_TIM3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM3SMEN)) -#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM6SMEN)) -#define __HAL_RCC_TIM7_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM7SMEN)) -#define __HAL_RCC_SPI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_SPI2SMEN)) -#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) -#define __HAL_RCC_USART4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART4SMEN)) -#define __HAL_RCC_USART5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART5SMEN)) -#define __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) -#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) -#define __HAL_RCC_I2C2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C2SMEN)) -#define __HAL_RCC_I2C3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C3SMEN)) -#define __HAL_RCC_DAC_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_DACSMEN)) -#define __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) - -#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) -#define __HAL_RCC_TIM3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM3SMEN)) -#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM6SMEN)) -#define __HAL_RCC_TIM7_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM7SMEN)) -#define __HAL_RCC_SPI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_SPI2SMEN)) -#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) -#define __HAL_RCC_USART4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART4SMEN)) -#define __HAL_RCC_USART5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART5SMEN)) -#define __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) -#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) -#define __HAL_RCC_I2C2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C2SMEN)) -#define __HAL_RCC_I2C3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C3SMEN)) -#define __HAL_RCC_DAC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_DACSMEN)) -#define __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) -#endif /* STM32L071xx || STM32L081xx || */ - /* STM32L072xx || STM32L082xx || */ - /* STM32L073xx || STM32L083xx || */ - -#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) -#define __HAL_RCC_TIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) -#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) -#define __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) -#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) -#define __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) - -#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_TIM2SMEN)) -#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USART2SMEN)) -#define __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPUART1SMEN)) -#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_I2C1SMEN)) -#define __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LPTIM1SMEN)) -#endif /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx */ - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -#define __HAL_RCC_USB_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USBSMEN)) -#define __HAL_RCC_USB_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_USBSMEN)) -#define __HAL_RCC_CRS_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_CRSSMEN)) -#define __HAL_RCC_CRS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_CRSSMEN)) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ - -#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) -#define __HAL_RCC_LCD_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LCDSMEN)) -#define __HAL_RCC_LCD_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1SMENR, (RCC_APB1SMENR_LCDSMEN)) -#endif /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx */ - -#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L052xx) || defined(STM32L062xx) || defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L051xx) || defined(STM32L061xx) || defined(STM32L071xx) || defined(STM32L081xx) || \ - defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L011xx) || defined(STM32L021xx) - -/** - * @} - */ - -/** @defgroup RCCEx_APB2_Clock_Sleep_Enable_Disable APB2 Peripheral Clock Sleep Enable Disable - * @brief Enable or disable the APB2 peripheral clock during Low Power (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. - * @{ - */ -#define __HAL_RCC_TIM21_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM21SMEN)) -#if !defined (STM32L011xx) && !defined (STM32L021xx) -#define __HAL_RCC_TIM22_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM22SMEN)) -#endif -#define __HAL_RCC_ADC1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_ADC1SMEN)) -#define __HAL_RCC_SPI1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_SPI1SMEN)) -#define __HAL_RCC_USART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_USART1SMEN)) - -#define __HAL_RCC_TIM21_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM21SMEN)) -#if !defined (STM32L011xx) && !defined (STM32L021xx) -#define __HAL_RCC_TIM22_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_TIM22SMEN)) -#endif -#define __HAL_RCC_ADC1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_ADC1SMEN)) -#define __HAL_RCC_SPI1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_SPI1SMEN)) -#define __HAL_RCC_USART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2SMENR, (RCC_APB2SMENR_USART1SMEN)) -#endif /* STM32L051xx || STM32L061xx || STM32L071xx || STM32L081xx || */ - /* STM32L052xx || STM32L062xx || STM32L072xx || STM32L082xx || */ - /* STM32L053xx || STM32L063xx || STM32L073xx || STM32L083xx || */ - /* STM32L031xx || STM32L041xx || STM32L011xx || STM32L021xx */ + */ /** @brief Macro to configures LCD clock (LCDCLK). * @note LCD and RTC use the same configuration * @note LCD can however be used in the Stop low power mode if the LSE or LSI is used as the - * LCD clock source. + * LCD clock source. * * @param __LCD_CLKSOURCE__ specifies the LCD clock source. * This parameter can be one of the following values: @@ -1235,330 +1499,342 @@ typedef struct */ #define __HAL_RCC_LCD_CONFIG(__LCD_CLKSOURCE__) __HAL_RCC_RTC_CONFIG(__LCD_CLKSOURCE__) -/** @brief macros to get the LCD clock source. +/** @brief Macro to get the LCD clock source. */ #define __HAL_RCC_GET_LCD_SOURCE() __HAL_RCC_GET_RTC_SOURCE() -/** @brief macros to get the LCD clock pre-scaler. +/** @brief Macro to get the LCD clock pre-scaler. */ #define __HAL_RCC_GET_LCD_HSE_PRESCALER() __HAL_RCC_GET_RTC_HSE_PRESCALER() + /** * @} */ - -/** @brief Macro to configure the I2C1 clock (I2C1CLK). + +#endif /* LCD */ + +/** @brief Macro to configure the I2C1 clock (I2C1CLK). * - * @param __I2C1_CLKSOURCE__: specifies the I2C1 clock source. + * @param __I2C1_CLKSOURCE__ specifies the I2C1 clock source. * This parameter can be one of the following values: - * @arg RCC_I2C1CLKSOURCE_PCLK1: PCLK1 selected as I2C1 clock - * @arg RCC_I2C1CLKSOURCE_HSI: HSI selected as I2C1 clock - * @arg RCC_I2C1CLKSOURCE_SYSCLK: System Clock selected as I2C1 clock - * @retval None + * @arg @ref RCC_I2C1CLKSOURCE_PCLK1 PCLK1 selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_HSI HSI selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_SYSCLK System Clock selected as I2C1 clock */ #define __HAL_RCC_I2C1_CONFIG(__I2C1_CLKSOURCE__) \ MODIFY_REG(RCC->CCIPR, RCC_CCIPR_I2C1SEL, (uint32_t)(__I2C1_CLKSOURCE__)) /** @brief Macro to get the I2C1 clock source. * @retval The clock source can be one of the following values: - * @arg RCC_I2C1CLKSOURCE_PCLK1: PCLK1 selected as I2C1 clock - * @arg RCC_I2C1CLKSOURCE_HSI: HSI selected as I2C1 clock - * @arg RCC_I2C1CLKSOURCE_SYSCLK: System Clock selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_PCLK1 PCLK1 selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_HSI HSI selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_SYSCLK System Clock selected as I2C1 clock */ #define __HAL_RCC_GET_I2C1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_I2C1SEL))) -#if defined (STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -/** @brief Macro to configure the I2C3 clock (I2C3CLK). +#if defined(RCC_CCIPR_I2C3SEL) +/** @brief Macro to configure the I2C3 clock (I2C3CLK). * - * @param __I2C3_CLKSOURCE__: specifies the I2C3 clock source. + * @param __I2C3_CLKSOURCE__ specifies the I2C3 clock source. * This parameter can be one of the following values: - * @arg RCC_I2C3CLKSOURCE_PCLK1: PCLK1 selected as I2C3 clock - * @arg RCC_I2C3CLKSOURCE_HSI: HSI selected as I2C3 clock - * @arg RCC_I2C3CLKSOURCE_SYSCLK: System Clock selected as I2C3 clock - * @retval None + * @arg @ref RCC_I2C3CLKSOURCE_PCLK1 PCLK1 selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_HSI HSI selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_SYSCLK System Clock selected as I2C3 clock */ #define __HAL_RCC_I2C3_CONFIG(__I2C3_CLKSOURCE__) \ MODIFY_REG(RCC->CCIPR, RCC_CCIPR_I2C3SEL, (uint32_t)(__I2C3_CLKSOURCE__)) /** @brief Macro to get the I2C3 clock source. * @retval The clock source can be one of the following values: - * @arg RCC_I2C3CLKSOURCE_PCLK1: PCLK1 selected as I2C3 clock - * @arg RCC_I2C3CLKSOURCE_HSI: HSI selected as I2C3 clock - * @arg RCC_I2C3CLKSOURCE_SYSCLK: System Clock selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_PCLK1 PCLK1 selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_HSI HSI selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_SYSCLK System Clock selected as I2C3 clock */ #define __HAL_RCC_GET_I2C3_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_I2C3SEL))) -#endif /* STM32L071xx || STM32L081xx || */ - /* STM32L072xx || STM32L082xx || */ - /* STM32L073xx || STM32L083xx || */ +#endif /* RCC_CCIPR_I2C3SEL */ -/** @brief Macro to configure the USART1 clock (USART1CLK). +#if defined (RCC_CCIPR_USART1SEL) +/** @brief Macro to configure the USART1 clock (USART1CLK). * - * @param __USART1_CLKSOURCE__: specifies the USART1 clock source. + * @param __USART1_CLKSOURCE__ specifies the USART1 clock source. * This parameter can be one of the following values: - * @arg RCC_USART1CLKSOURCE_PCLK2: PCLK2 selected as USART1 clock - * @arg RCC_USART1CLKSOURCE_HSI: HSI selected as USART1 clock - * @arg RCC_USART1CLKSOURCE_SYSCLK: System Clock selected as USART1 clock - * @arg RCC_USART1CLKSOURCE_LSE: LSE selected as USART1 clock - * @retval None + * @arg @ref RCC_USART1CLKSOURCE_PCLK2 PCLK2 selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_SYSCLK System Clock selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock */ #define __HAL_RCC_USART1_CONFIG(__USART1_CLKSOURCE__) \ MODIFY_REG(RCC->CCIPR, RCC_CCIPR_USART1SEL, (uint32_t)(__USART1_CLKSOURCE__)) /** @brief Macro to get the USART1 clock source. * @retval The clock source can be one of the following values: - * @arg RCC_USART1CLKSOURCE_PCLK2: PCLK2 selected as USART1 clock - * @arg RCC_USART1CLKSOURCE_HSI: HSI selected as USART1 clock - * @arg RCC_USART1CLKSOURCE_SYSCLK: System Clock selected as USART1 clock - * @arg RCC_USART1CLKSOURCE_LSE: LSE selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_PCLK2 PCLK2 selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_SYSCLK System Clock selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock */ #define __HAL_RCC_GET_USART1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_USART1SEL))) +#endif /* RCC_CCIPR_USART1SEL */ -/** @brief Macro to configure the USART2 clock (USART2CLK). +/** @brief Macro to configure the USART2 clock (USART2CLK). * - * @param __USART2_CLKSOURCE__: specifies the USART2 clock source. + * @param __USART2_CLKSOURCE__ specifies the USART2 clock source. * This parameter can be one of the following values: - * @arg RCC_USART2CLKSOURCE_PCLK1: PCLK1 selected as USART2 clock - * @arg RCC_USART2CLKSOURCE_HSI: HSI selected as USART2 clock - * @arg RCC_USART2CLKSOURCE_SYSCLK: System Clock selected as USART2 clock - * @arg RCC_USART2CLKSOURCE_LSE: LSE selected as USART2 clock - * @retval None + * @arg @ref RCC_USART2CLKSOURCE_PCLK1 PCLK1 selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_HSI HSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_SYSCLK System Clock selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_LSE LSE selected as USART2 clock */ #define __HAL_RCC_USART2_CONFIG(__USART2_CLKSOURCE__) \ MODIFY_REG(RCC->CCIPR, RCC_CCIPR_USART2SEL, (uint32_t)(__USART2_CLKSOURCE__)) /** @brief Macro to get the USART2 clock source. * @retval The clock source can be one of the following values: - * @arg RCC_USART2CLKSOURCE_PCLK1: PCLK1 selected as USART2 clock - * @arg RCC_USART2CLKSOURCE_HSI: HSI selected as USART2 clock - * @arg RCC_USART2CLKSOURCE_SYSCLK: System Clock selected as USART2 clock - * @arg RCC_USART2CLKSOURCE_LSE: LSE selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_PCLK1 PCLK1 selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_HSI HSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_SYSCLK System Clock selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_LSE LSE selected as USART2 clock */ #define __HAL_RCC_GET_USART2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_USART2SEL))) -/** @brief Macro to configure the LPUART1 clock (LPUART1CLK). +/** @brief Macro to configure the LPUART1 clock (LPUART1CLK). * - * @param __LPUART1_CLKSOURCE__: specifies the LPUART1 clock source. + * @param __LPUART1_CLKSOURCE__ specifies the LPUART1 clock source. * This parameter can be one of the following values: - * @arg RCC_LPUART1CLKSOURCE_PCLK1: PCLK1 selected as LPUART1 clock - * @arg RCC_LPUART1CLKSOURCE_HSI: HSI selected as LPUART1 clock - * @arg RCC_LPUART1CLKSOURCE_SYSCLK: System Clock selected as LPUART1 clock - * @arg RCC_LPUART1CLKSOURCE_LSE: LSE selected as LPUART1 clock - * @retval None + * @arg @ref RCC_LPUART1CLKSOURCE_PCLK1 PCLK1 selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_HSI HSI selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_SYSCLK System Clock selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_LSE LSE selected as LPUART1 clock */ #define __HAL_RCC_LPUART1_CONFIG(__LPUART1_CLKSOURCE__) \ MODIFY_REG(RCC->CCIPR, RCC_CCIPR_LPUART1SEL, (uint32_t)(__LPUART1_CLKSOURCE__)) /** @brief Macro to get the LPUART1 clock source. * @retval The clock source can be one of the following values: - * @arg RCC_LPUART1CLKSOURCE_PCLK1: PCLK1 selected as LPUART1 clock - * @arg RCC_LPUART1CLKSOURCE_HSI: HSI selected as LPUART1 clock - * @arg RCC_LPUART1CLKSOURCE_SYSCLK: System Clock selected as LPUART1 clock - * @arg RCC_LPUART1CLKSOURCE_LSE: LSE selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_PCLK1 PCLK1 selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_HSI HSI selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_SYSCLK System Clock selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_LSE LSE selected as LPUART1 clock */ #define __HAL_RCC_GET_LPUART1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_LPUART1SEL))) -/** @brief Macro to configure the LPTIM1 clock (LPTIM1CLK). +/** @brief Macro to configure the LPTIM1 clock (LPTIM1CLK). * - * @param __LPTIM1_CLKSOURCE__: specifies the LPTIM1 clock source. + * @param __LPTIM1_CLKSOURCE__ specifies the LPTIM1 clock source. * This parameter can be one of the following values: - * @arg RCC_LPTIM1CLKSOURCE_PCLK: PCLK selected as LPTIM1 clock - * @arg RCC_LPTIM1CLKSOURCE_LSI : HSI selected as LPTIM1 clock - * @arg RCC_LPTIM1CLKSOURCE_HSI : LSI selected as LPTIM1 clock - * @arg RCC_LPTIM1CLKSOURCE_LSE : LSE selected as LPTIM1 clock - * @retval None + * @arg @ref RCC_LPTIM1CLKSOURCE_PCLK PCLK selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_LSI HSI selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_HSI LSI selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_LSE LSE selected as LPTIM1 clock */ #define __HAL_RCC_LPTIM1_CONFIG(__LPTIM1_CLKSOURCE__) \ MODIFY_REG(RCC->CCIPR, RCC_CCIPR_LPTIM1SEL, (uint32_t)(__LPTIM1_CLKSOURCE__)) /** @brief Macro to get the LPTIM1 clock source. * @retval The clock source can be one of the following values: - * @arg RCC_LPTIM1CLKSOURCE_PCLK: PCLK selected as LPUART1 clock - * @arg RCC_LPTIM1CLKSOURCE_LSI : HSI selected as LPUART1 clock - * @arg RCC_LPTIM1CLKSOURCE_HSI : System Clock selected as LPUART1 clock - * @arg RCC_LPTIM1CLKSOURCE_LSE : LSE selected as LPUART1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_PCLK PCLK selected as LPUART1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_LSI HSI selected as LPUART1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_HSI System Clock selected as LPUART1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_LSE LSE selected as LPUART1 clock */ #define __HAL_RCC_GET_LPTIM1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_LPTIM1SEL))) -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) +#if defined(USB) /** @brief Macro to configure the USB clock (USBCLK). - * @param __USBCLKSource__: specifies the USB clock source. + * @param __USB_CLKSOURCE__ specifies the USB clock source. * This parameter can be one of the following values: - * @arg RCC_USBCLKSOURCE_HSI48: HSI48 selected as USB clock - * @arg RCC_USBCLKSOURCE_PLL: PLL Clock selected as USB clock + * @arg @ref RCC_USBCLKSOURCE_HSI48 HSI48 selected as USB clock + * @arg @ref RCC_USBCLKSOURCE_PLL PLL Clock selected as USB clock */ -#define __HAL_RCC_USB_CONFIG(__USBCLKSource__) \ - MODIFY_REG(RCC->CCIPR, RCC_CCIPR_HSI48SEL, (uint32_t)(__USBCLKSource__)) +#define __HAL_RCC_USB_CONFIG(__USB_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR, RCC_CCIPR_HSI48SEL, (uint32_t)(__USB_CLKSOURCE__)) /** @brief Macro to get the USB clock source. * @retval The clock source can be one of the following values: - * @arg RCC_USBCLKSOURCE_HSI48: HSI48 selected as USB clock - * @arg RCC_USBCLKSOURCE_PLL: PLL Clock selected as USB clock + * @arg @ref RCC_USBCLKSOURCE_HSI48 HSI48 selected as USB clock + * @arg @ref RCC_USBCLKSOURCE_PLL PLL Clock selected as USB clock */ #define __HAL_RCC_GET_USB_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_HSI48SEL))) +#endif /* USB */ +#if defined(RNG) /** @brief Macro to configure the RNG clock (RNGCLK). - * @param __RNGCLKSource__: specifies the USB clock source. + * @param __RNG_CLKSOURCE__ specifies the USB clock source. * This parameter can be one of the following values: - * @arg RCC_RNGCLKSOURCE_HSI48: HSI48 selected as RNG clock - * @arg RCC_RNGCLKSOURCE_PLLCLK: PLL Clock selected as RNG clock + * @arg @ref RCC_RNGCLKSOURCE_HSI48 HSI48 selected as RNG clock + * @arg @ref RCC_RNGCLKSOURCE_PLLCLK PLL Clock selected as RNG clock */ -#define __HAL_RCC_RNG_CONFIG(__RNGCLKSource__) \ - MODIFY_REG(RCC->CCIPR, RCC_CCIPR_HSI48SEL, (uint32_t)(__RNGCLKSource__)) +#define __HAL_RCC_RNG_CONFIG(__RNG_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR, RCC_CCIPR_HSI48SEL, (uint32_t)(__RNG_CLKSOURCE__)) /** @brief Macro to get the RNG clock source. * @retval The clock source can be one of the following values: - * @arg RCC_RNGCLKSOURCE_HSI48: HSI48 selected as RNG clock - * @arg RCC_RNGCLKSOURCE_PLLCLK: PLL Clock selected as RNG clock + * @arg @ref RCC_RNGCLKSOURCE_HSI48 HSI48 selected as RNG clock + * @arg @ref RCC_RNGCLKSOURCE_PLLCLK PLL Clock selected as RNG clock */ #define __HAL_RCC_GET_RNG_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_HSI48SEL))) +#endif /* RNG */ -/** @brief macro to select the HSI48M clock source +#if defined(RCC_CCIPR_HSI48SEL) +/** @brief Macro to select the HSI48M clock source * @note This macro can be replaced by either __HAL_RCC_RNG_CONFIG or * __HAL_RCC_USB_CONFIG to configure respectively RNG or UBS clock sources. * - * @param __HSI48MCLKSource__: specifies the HSI48M clock source dedicated for + * @param __HSI48M_CLKSOURCE__ specifies the HSI48M clock source dedicated for * USB an RNG peripherals. * This parameter can be one of the following values: - * @arg RCC_HSI48M_PLL: A dedicated 48MHZ PLL output. - * @arg RCC_HSI48M_HSI48: 48MHZ issued from internal HSI48 oscillator. + * @arg @ref RCC_HSI48M_PLL A dedicated 48MHZ PLL output. + * @arg @ref RCC_HSI48M_HSI48 48MHZ issued from internal HSI48 oscillator. */ -#define __HAL_RCC_HSI48M_CONFIG(__HSI48MCLKSource__) \ - MODIFY_REG(RCC->CCIPR, RCC_CCIPR_HSI48SEL, (uint32_t)(__HSI48MCLKSource__)) +#define __HAL_RCC_HSI48M_CONFIG(__HSI48M_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR, RCC_CCIPR_HSI48SEL, (uint32_t)(__HSI48M_CLKSOURCE__)) -/** @brief macro to get the HSI48M clock source. +/** @brief Macro to get the HSI48M clock source. * @note This macro can be replaced by either __HAL_RCC_GET_RNG_SOURCE or * __HAL_RCC_GET_USB_SOURCE to get respectively RNG or UBS clock sources. * @retval The clock source can be one of the following values: - * @arg RCC_HSI48M_PLL: A dedicated 48MHZ PLL output. - * @arg RCC_HSI48M_HSI48: 48MHZ issued from internal HSI48 oscillator. + * @arg @ref RCC_HSI48M_PLL A dedicated 48MHZ PLL output. + * @arg @ref RCC_HSI48M_HSI48 48MHZ issued from internal HSI48 oscillator. */ #define __HAL_RCC_GET_HSI48M_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR, RCC_CCIPR_HSI48SEL))) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx ) && !(STM32L041xx ) && !(STM32L051xx ) && !(STM32L061xx ) && !(STM32L071xx ) && !(STM32L081xx ) */ +#endif /* RCC_CCIPR_HSI48SEL */ /** - * @brief Macros to enable or disable the force of the Internal High Speed oscillator (HSI) + * @brief Macro to enable the force of the Internal High Speed oscillator (HSI) * in STOP mode to be quickly available as kernel clock for USART and I2C. * @note The Enable of this function has not effect on the HSION bit. - * @retval None */ #define __HAL_RCC_HSISTOP_ENABLE() SET_BIT(RCC->CR, RCC_CR_HSIKERON) + +/** + * @brief Macro to disable the force of the Internal High Speed oscillator (HSI) + * in STOP mode to be quickly available as kernel clock for USART and I2C. + * @retval None + */ #define __HAL_RCC_HSISTOP_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_HSIKERON) /** * @brief Macro to configures the External Low Speed oscillator (LSE) drive capability. - * @param __RCC_LSEDrive__: specifies the new state of the LSE drive capability. + * @param __RCC_LSEDRIVE__ specifies the new state of the LSE drive capability. * This parameter can be one of the following values: - * @arg RCC_LSEDRIVE_LOW: LSE oscillator low drive capability. - * @arg RCC_LSEDRIVE_MEDIUMLOW: LSE oscillator medium low drive capability. - * @arg RCC_LSEDRIVE_MEDIUMHIGH: LSE oscillator medium high drive capability. - * @arg RCC_LSEDRIVE_HIGH: LSE oscillator high drive capability. + * @arg @ref RCC_LSEDRIVE_LOW LSE oscillator low drive capability. + * @arg @ref RCC_LSEDRIVE_MEDIUMLOW LSE oscillator medium low drive capability. + * @arg @ref RCC_LSEDRIVE_MEDIUMHIGH LSE oscillator medium high drive capability. + * @arg @ref RCC_LSEDRIVE_HIGH LSE oscillator high drive capability. * @retval None */ -#define __HAL_RCC_LSEDRIVE_CONFIG(__RCC_LSEDrive__) (MODIFY_REG(RCC->CSR,\ - RCC_CSR_LSEDRV, (uint32_t)(__RCC_LSEDrive__) )) +#define __HAL_RCC_LSEDRIVE_CONFIG(__RCC_LSEDRIVE__) (MODIFY_REG(RCC->CSR,\ + RCC_CSR_LSEDRV, (uint32_t)(__RCC_LSEDRIVE__) )) /** * @brief Macro to configures the wake up from stop clock. - * @param __RCC_STOPWUCLK__: specifies the clock source used after wake up from stop + * @param __RCC_STOPWUCLK__ specifies the clock source used after wake up from stop * This parameter can be one of the following values: - * @arg RCC_STOP_WAKEUPCLOCK_MSI: MSI selected as system clock source - * @arg RCC_STOP_WAKEUPCLOCK_HSI: HSI selected as system clock source + * @arg @ref RCC_STOP_WAKEUPCLOCK_MSI MSI selected as system clock source + * @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI selected as system clock source * @retval None */ #define __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(__RCC_STOPWUCLK__) (MODIFY_REG(RCC->CFGR,\ RCC_CFGR_STOPWUCK, (uint32_t)(__RCC_STOPWUCLK__) )) - -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) + +#if defined(CRS) /** * @brief Enables the specified CRS interrupts. - * @param __INTERRUPT__: specifies the CRS interrupt sources to be enabled. + * @param __INTERRUPT__ specifies the CRS interrupt sources to be enabled. * This parameter can be any combination of the following values: - * @arg RCC_CRS_IT_SYNCOK - * @arg RCC_CRS_IT_SYNCWARN - * @arg RCC_CRS_IT_ERR - * @arg RCC_CRS_IT_ESYNC + * @arg @ref RCC_CRS_IT_SYNCOK + * @arg @ref RCC_CRS_IT_SYNCWARN + * @arg @ref RCC_CRS_IT_ERR + * @arg @ref RCC_CRS_IT_ESYNC * @retval None */ #define __HAL_RCC_CRS_ENABLE_IT(__INTERRUPT__) SET_BIT(CRS->CR, (__INTERRUPT__)) /** * @brief Disables the specified CRS interrupts. - * @param __INTERRUPT__: specifies the CRS interrupt sources to be disabled. + * @param __INTERRUPT__ specifies the CRS interrupt sources to be disabled. * This parameter can be any combination of the following values: - * @arg RCC_CRS_IT_SYNCOK - * @arg RCC_CRS_IT_SYNCWARN - * @arg RCC_CRS_IT_ERR - * @arg RCC_CRS_IT_ESYNC + * @arg @ref RCC_CRS_IT_SYNCOK + * @arg @ref RCC_CRS_IT_SYNCWARN + * @arg @ref RCC_CRS_IT_ERR + * @arg @ref RCC_CRS_IT_ESYNC * @retval None */ #define __HAL_RCC_CRS_DISABLE_IT(__INTERRUPT__) CLEAR_BIT(CRS->CR,(__INTERRUPT__)) /** @brief Check the CRS interrupt has occurred or not. - * @param __INTERRUPT__: specifies the CRS interrupt source to check. + * @param __INTERRUPT__ specifies the CRS interrupt source to check. * This parameter can be one of the following values: - * @arg RCC_CRS_IT_SYNCOK - * @arg RCC_CRS_IT_SYNCWARN - * @arg RCC_CRS_IT_ERR - * @arg RCC_CRS_IT_ESYNC + * @arg @ref RCC_CRS_IT_SYNCOK + * @arg @ref RCC_CRS_IT_SYNCWARN + * @arg @ref RCC_CRS_IT_ERR + * @arg @ref RCC_CRS_IT_ESYNC * @retval The new state of __INTERRUPT__ (SET or RESET). */ #define __HAL_RCC_CRS_GET_IT_SOURCE(__INTERRUPT__) ((CRS->CR & (__INTERRUPT__))? SET : RESET) /** @brief Clear the CRS interrupt pending bits * bits to clear the selected interrupt pending bits. - * @param __INTERRUPT__: specifies the interrupt pending bit to clear. + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. * This parameter can be any combination of the following values: - * @arg RCC_CRS_IT_SYNCOK - * @arg RCC_CRS_IT_SYNCWARN - * @arg RCC_CRS_IT_ERR - * @arg RCC_CRS_IT_ESYNC - * @arg RCC_CRS_IT_TRIMOVF - * @arg RCC_CRS_IT_SYNCERR - * @arg RCC_CRS_IT_SYNCMISS + * @arg @ref RCC_CRS_IT_SYNCOK + * @arg @ref RCC_CRS_IT_SYNCWARN + * @arg @ref RCC_CRS_IT_ERR + * @arg @ref RCC_CRS_IT_ESYNC + * @arg @ref RCC_CRS_IT_TRIMOVF + * @arg @ref RCC_CRS_IT_SYNCERR + * @arg @ref RCC_CRS_IT_SYNCMISS */ -/* CRS IT Error Mask */ -#define RCC_CRS_IT_ERROR_MASK ((uint32_t)(RCC_CRS_IT_TRIMOVF | RCC_CRS_IT_SYNCERR | RCC_CRS_IT_SYNCMISS)) - -#define __HAL_RCC_CRS_CLEAR_IT(__INTERRUPT__) ((((__INTERRUPT__) & RCC_CRS_IT_ERROR_MASK)!= 0) ? (CRS->ICR |= CRS_ICR_ERRC) : \ - (CRS->ICR = (__INTERRUPT__))) +#define __HAL_RCC_CRS_CLEAR_IT(__INTERRUPT__) do { \ + if(((__INTERRUPT__) & RCC_CRS_IT_ERROR_MASK) != RESET) \ + { \ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC | ((__INTERRUPT__) & ~RCC_CRS_IT_ERROR_MASK)); \ + } \ + else \ + { \ + WRITE_REG(CRS->ICR, (__INTERRUPT__)); \ + } \ + } while(0) /** * @brief Checks whether the specified CRS flag is set or not. - * @param __FLAG__: specifies the flag to check. + * @param __FLAG__ specifies the flag to check. * This parameter can be one of the following values: - * @arg RCC_CRS_FLAG_SYNCOK - * @arg RCC_CRS_FLAG_SYNCWARN - * @arg RCC_CRS_FLAG_ERR - * @arg RCC_CRS_FLAG_ESYNC - * @arg RCC_CRS_FLAG_TRIMOVF - * @arg RCC_CRS_FLAG_SYNCERR - * @arg RCC_CRS_FLAG_SYNCMISS - * @retval The new state of _FLAG_ (TRUE or FALSE). + * @arg @ref RCC_CRS_FLAG_SYNCOK + * @arg @ref RCC_CRS_FLAG_SYNCWARN + * @arg @ref RCC_CRS_FLAG_ERR + * @arg @ref RCC_CRS_FLAG_ESYNC + * @arg @ref RCC_CRS_FLAG_TRIMOVF + * @arg @ref RCC_CRS_FLAG_SYNCERR + * @arg @ref RCC_CRS_FLAG_SYNCMISS + * @retval The new state of __FLAG__ (TRUE or FALSE). */ #define __HAL_RCC_CRS_GET_FLAG(__FLAG__) ((CRS->ISR & (__FLAG__)) == (__FLAG__)) /** * @brief Clears the CRS specified FLAG. - * @param _FLAG_: specifies the flag to clear. + * @param __FLAG__ specifies the flag to clear. * This parameter can be one of the following values: - * @arg RCC_CRS_FLAG_SYNCOK - * @arg RCC_CRS_FLAG_SYNCWARN - * @arg RCC_CRS_FLAG_ERR - * @arg RCC_CRS_FLAG_ESYNC - * @arg RCC_CRS_FLAG_TRIMOVF - * @arg RCC_CRS_FLAG_SYNCERR - * @arg RCC_CRS_FLAG_SYNCMISS + * @arg @ref RCC_CRS_FLAG_SYNCOK + * @arg @ref RCC_CRS_FLAG_SYNCWARN + * @arg @ref RCC_CRS_FLAG_ERR + * @arg @ref RCC_CRS_FLAG_ESYNC + * @arg @ref RCC_CRS_FLAG_TRIMOVF + * @arg @ref RCC_CRS_FLAG_SYNCERR + * @arg @ref RCC_CRS_FLAG_SYNCMISS * @retval None */ - -/* CRS Flag Error Mask */ -#define RCC_CRS_FLAG_ERROR_MASK ((uint32_t)(RCC_CRS_FLAG_TRIMOVF | RCC_CRS_FLAG_SYNCERR | RCC_CRS_FLAG_SYNCMISS)) - -#define __HAL_RCC_CRS_CLEAR_FLAG(__FLAG__) ((((__FLAG__) & RCC_CRS_FLAG_ERROR_MASK)!= 0) ? (CRS->ICR |= CRS_ICR_ERRC) : \ - (CRS->ICR = (__FLAG__))) - +#define __HAL_RCC_CRS_CLEAR_FLAG(__FLAG__) do { \ + if(((__FLAG__) & RCC_CRS_FLAG_ERROR_MASK) != RESET) \ + { \ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC | ((__FLAG__) & ~RCC_CRS_FLAG_ERROR_MASK)); \ + } \ + else \ + { \ + WRITE_REG(CRS->ICR, (__FLAG__)); \ + } \ + } while(0) /** * @brief Enables the oscillator clock for frequency error counter. @@ -1571,7 +1847,7 @@ typedef struct * @brief Disables the oscillator clock for frequency error counter. * @retval None */ -#define __HAL_RCC_CRS_FREQ_ERROR_COUNTER_DISABLE() CLEAR_BIT(CRS->CR,CRS_CR_CEN) +#define __HAL_RCC_CRS_FREQ_ERROR_COUNTER_DISABLE() CLEAR_BIT(CRS->CR, CRS_CR_CEN) /** * @brief Enables the automatic hardware adjustment of TRIM bits. @@ -1584,7 +1860,7 @@ typedef struct * @brief Enables or disables the automatic hardware adjustment of TRIM bits. * @retval None */ -#define __HAL_RCC_CRS_AUTOMATIC_CALIB_DISABLE() CLEAR_BIT(CRS->CR,CRS_CR_AUTOTRIMEN) +#define __HAL_RCC_CRS_AUTOMATIC_CALIB_DISABLE() CLEAR_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) /** * @brief Macro to calculate reload value to be set in CRS register according to target and sync frequencies @@ -1593,44 +1869,58 @@ typedef struct * reach the expected synchronization on the zero value. The formula is the following: * RELOAD = (fTARGET / fSYNC) -1 * @param __FTARGET__ Target frequency (value in Hz) - * @param __FSYNC__ Synchronization signal frequency (value in Hz) + * @param __FSYNC__ Synchronization signal frequency (value in Hz) * @retval None */ #define __HAL_RCC_CRS_RELOADVALUE_CALCULATE(__FTARGET__, __FSYNC__) (((__FTARGET__) / (__FSYNC__)) - 1) -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx) && !(STM32L041xx) && !(STM32L051xx) && !(STM32L061xx) && !(STM32L071xx) && !(STM32L081xx) */ +#endif /* CRS */ -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) -/** @brief Enable or disable the HSI OUT . + +#if defined(RCC_CR_HSIOUTEN) +/** @brief Enable he HSI OUT . * @note After reset, the HSI output is not available */ #define __HAL_RCC_HSI_OUT_ENABLE() SET_BIT(RCC->CR, RCC_CR_HSIOUTEN) + +/** @brief Disable the HSI OUT . + * @note After reset, the HSI output is not available + */ + #define __HAL_RCC_HSI_OUT_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_HSIOUTEN) -#endif /* STM32L071xx || STM32L081xx || */ - /* STM32L072xx || STM32L082xx || */ - /* STM32L073xx || STM32L083xx */ +#endif /* RCC_CR_HSIOUTEN */ -#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx) ||\ - defined(STM32L052xx) || defined(STM32L062xx) || defined(STM32L072xx) || defined(STM32L082xx) +#if defined(STM32L053xx) || defined(STM32L063xx) || defined(STM32L073xx) || defined(STM32L083xx)\ + || defined(STM32L052xx) || defined(STM32L062xx) || defined(STM32L072xx) || defined(STM32L082xx) /** - * @brief Macro to enable or disable the Internal High Speed oscillator for USB (HSI48). + * @brief Enable the Internal High Speed oscillator for USB (HSI48). * @note After enabling the HSI48, the application software should wait on * HSI48RDY flag to be set indicating that HSI48 clock is stable and can * be used to clock the USB. * @note The HSI48 is stopped by hardware when entering STOP and STANDBY modes. */ -#define __HAL_RCC_HSI48_ENABLE() do { SET_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON); \ - RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; \ - SYSCFG->CFGR3 |= (SYSCFG_CFGR3_ENREF_HSI48); \ - } while (0) +#define __HAL_RCC_HSI48_ENABLE() do { SET_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON); \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN); \ + SET_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48); \ + } while (0) +/** + * @brief Disable the Internal High Speed oscillator for USB (HSI48). + */ #define __HAL_RCC_HSI48_DISABLE() do { CLEAR_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON); \ - SYSCFG->CFGR3 &= (uint32_t)~((uint32_t)(SYSCFG_CFGR3_ENREF_HSI48)); \ - } while (0) + CLEAR_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48); \ + } while (0) + +/** @brief Macro to get the Internal 48Mhz High Speed oscillator (HSI48) state. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_HSI48_ON HSI48 enabled + * @arg @ref RCC_HSI48_OFF HSI48 disabled + */ +#define __HAL_RCC_GET_HSI48_STATE() \ + (((uint32_t)(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON)) != RESET) ? RCC_HSI48_ON : RCC_HSI48_OFF) + /** @brief Enable or disable the HSI48M DIV6 OUT . * @note After reset, the HSI48Mhz (divided by 6) output is not available */ @@ -1642,170 +1932,71 @@ typedef struct /* STM32L072xx || STM32L082xx || */ /* STM32L073xx || STM32L083xx */ + /** * @} */ -/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCCEx_Exported_Functions * @{ */ - -/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions - - * @{ - */ -HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); -void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); -uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk); -void HAL_RCCEx_EnableLSECSS(void); -void HAL_RCCEx_DisableLSECSS(void); -void HAL_RCCEx_EnableLSECSS_IT(void); -void HAL_RCCEx_LSECSS_IRQHandler(void); -void HAL_RCCEx_LSECSS_Callback(void); -#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) -void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit); -void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void); -void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo); -uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout); +/** @addtogroup RCCEx_Exported_Functions_Group1 + * @{ + */ + +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk); + + +void HAL_RCCEx_EnableLSECSS(void); +void HAL_RCCEx_DisableLSECSS(void); +void HAL_RCCEx_EnableLSECSS_IT(void); +void HAL_RCCEx_LSECSS_IRQHandler(void); +void HAL_RCCEx_LSECSS_Callback(void); + + +#if defined(SYSCFG_CFGR3_ENREF_HSI48) void HAL_RCCEx_EnableHSI48_VREFINT(void); void HAL_RCCEx_DisableHSI48_VREFINT(void); -#endif /* !(STM32L011xx) && !(STM32L021xx) && !(STM32L031xx) && !(STM32L041xx) && !(STM32L051xx) && !(STM32L061xx) && !(STM32L071xx) && !(STM32L081xx) */ +#endif /* SYSCFG_CFGR3_ENREF_HSI48 */ /** * @} - */ -/** - * @} - */ + */ +#if defined(CRS) -/* Private macros ------------------------------------------------------------*/ -/** @addtogroup RCCEx_Private_Macros +/** @addtogroup RCCEx_Exported_Functions_Group3 * @{ */ -#if defined (STM32L052xx) || defined(STM32L062xx) -#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1)) -#elif defined (STM32L053xx) || defined(STM32L063xx) -#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LCD)) -#elif defined (STM32L072xx) || defined(STM32L082xx) -#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_I2C3 )) -#elif defined (STM32L073xx) || defined(STM32L083xx) -#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_USB | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_I2C3 | \ - RCC_PERIPHCLK_LCD)) -#endif +void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit); +void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void); +void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo); +uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout); +void HAL_RCCEx_CRS_IRQHandler(void); +void HAL_RCCEx_CRS_SyncOkCallback(void); +void HAL_RCCEx_CRS_SyncWarnCallback(void); +void HAL_RCCEx_CRS_ExpectedSyncCallback(void); +void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error); -#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx) -#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= ( RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_LPTIM1)) -#elif defined(STM32L051xx) || defined(STM32L061xx) -#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_LPTIM1)) -#elif defined(STM32L071xx) || defined(STM32L081xx) -#define IS_RCC_PERIPHCLOCK(__CLK__) ((__CLK__) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \ - RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_RTC | \ - RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_I2C3)) -#endif - -#define IS_RCC_USART1CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_USART1CLKSOURCE_PCLK2) || \ - ((__SOURCE__) == RCC_USART1CLKSOURCE_SYSCLK) || \ - ((__SOURCE__) == RCC_USART1CLKSOURCE_LSE) || \ - ((__SOURCE__) == RCC_USART1CLKSOURCE_HSI)) - - -#define IS_RCC_USART2CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_USART2CLKSOURCE_PCLK1) || \ - ((__SOURCE__) == RCC_USART2CLKSOURCE_SYSCLK) || \ - ((__SOURCE__) == RCC_USART2CLKSOURCE_LSE) || \ - ((__SOURCE__) == RCC_USART2CLKSOURCE_HSI)) - -#define IS_RCC_LPUART1CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_LPUART1CLKSOURCE_PCLK1) || \ - ((__SOURCE__) == RCC_LPUART1CLKSOURCE_SYSCLK) || \ - ((__SOURCE__) == RCC_LPUART1CLKSOURCE_LSE) || \ - ((__SOURCE__) == RCC_LPUART1CLKSOURCE_HSI)) - -#define IS_RCC_I2C1CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_I2C1CLKSOURCE_PCLK1) || \ - ((__SOURCE__) == RCC_I2C1CLKSOURCE_SYSCLK)|| \ - ((__SOURCE__) == RCC_I2C1CLKSOURCE_HSI)) - -#define IS_RCC_I2C3CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_I2C3CLKSOURCE_PCLK1) || \ - ((__SOURCE__) == RCC_I2C3CLKSOURCE_SYSCLK)|| \ - ((__SOURCE__) == RCC_I2C3CLKSOURCE_HSI)) - -#define IS_RCC_USBCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_USBCLKSOURCE_HSI48) || \ - ((__SOURCE__) == RCC_USBCLKSOURCE_PLL)) - -#define IS_RCC_RNGCLKSOURCE(_SOURCE_) (((_SOURCE_) == RCC_RNGCLKSOURCE_HSI48) || \ - ((_SOURCE_) == RCC_RNGCLKSOURCE_PLLCLK)) - -#define IS_RCC_HSI48MCLKSOURCE(__HSI48MCLK__) (((__HSI48MCLK__) == RCC_HSI48M_PLL) || ((__HSI48MCLK__) == RCC_HSI48M_HSI48)) - -#if defined(STM32L073xx) || defined(STM32L083xx) || \ - defined(STM32L072xx) || defined(STM32L082xx) || \ - defined(STM32L071xx) || defined(STM32L081xx) - -#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON) || \ - ((__HSI__) == RCC_HSI_DIV4) || ((__HSI__) == RCC_HSI_OUTEN )) -#else -#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON) || \ - ((__HSI__) == RCC_HSI_DIV4)) -#endif - -#define IS_RCC_LPTIMCLK(__LPTIMCLK_) (((__LPTIMCLK_) == RCC_LPTIM1CLKSOURCE_PCLK) || \ - ((__LPTIMCLK_) == RCC_LPTIM1CLKSOURCE_LSI) || \ - ((__LPTIMCLK_) == RCC_LPTIM1CLKSOURCE_HSI) || \ - ((__LPTIMCLK_) == RCC_LPTIM1CLKSOURCE_LSE)) - -#define IS_RCC_STOPWAKEUP_CLOCK(__SOURCE__) (((__SOURCE__) == RCC_StopWakeUpClock_MSI) || \ - ((__SOURCE__) == RCC_StopWakeUpClock_HSI)) - -#define IS_RCC_LSE_DRIVE(__DRIVE__) (((__DRIVE__) == RCC_LSEDRIVE_LOW) || ((__SOURCE__) == RCC_LSEDRIVE_MEDIUMLOW) || \ - ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMHIGH) || ((__SOURCE__) == RCC_LSEDRIVE_HIGH)) - -#define IS_RCC_CRS_SYNC_SOURCE(__SOURCE__) (((__SOURCE__) == RCC_CRS_SYNC_SOURCE_GPIO) || \ - ((__SOURCE__) == RCC_CRS_SYNC_SOURCE_LSE) ||\ - ((__SOURCE__) == RCC_CRS_SYNC_SOURCE_USB)) - -#define IS_RCC_CRS_SYNC_DIV(__DIV__) (((__DIV__) == RCC_CRS_SYNC_DIV1) || ((__DIV__) == RCC_CRS_SYNC_DIV2) ||\ - ((__DIV__) == RCC_CRS_SYNC_DIV4) || ((__DIV__) == RCC_CRS_SYNC_DIV8) || \ - ((__DIV__) == RCC_CRS_SYNC_DIV16) || ((__DIV__) == RCC_CRS_SYNC_DIV32) || \ - ((__DIV__) == RCC_CRS_SYNC_DIV64) || ((__DIV__) == RCC_CRS_SYNC_DIV128)) - -#define IS_RCC_CRS_SYNC_POLARITY(__POLARITY__) (((__POLARITY__) == RCC_CRS_SYNC_POLARITY_RISING) || \ - ((__POLARITY__) == RCC_CRS_SYNC_POLARITY_FALLING)) - -#define IS_RCC_CRS_RELOADVALUE(__VALUE__) (((__VALUE__) <= 0xFFFFU)) - -#define IS_RCC_CRS_ERRORLIMIT(__VALUE__) (((__VALUE__) <= 0xFFU)) - -#define IS_RCC_CRS_HSI48CALIBRATION(__VALUE__) (((__VALUE__) <= 0x3FU)) - -#define IS_RCC_CRS_FREQERRORDIR(__DIR__) (((__DIR__) == RCC_CRS_FREQERRORDIR_UP) || \ - ((__DIR__) == RCC_CRS_FREQERRORDIR_DOWN)) - /** * @} */ - - + +#endif /* CRS */ + /** * @} */ /** * @} - */ - + */ + /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rng.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rng.c index 7fbf06bd29..d368aed77b 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rng.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rng.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_rng.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief RNG HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Random Number Generator (RNG) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rng.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rng.h index d5f54c58d9..544702f67f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rng.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rng.h @@ -3,8 +3,6 @@ * @file stm32l0xx_hal_rng.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of RNG HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc.c index 98f55a03b7..ca8490a492 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_rtc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief RTC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Real Time Clock (RTC) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc.h index a189a43d35..597d1f70f9 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_rtc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of RTC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc_ex.c index d728e41c63..766f500c50 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_rtc_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Extended RTC HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc_ex.h index 35f7aff352..e428201d15 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rtc_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_rtc_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of RTC HAL Extended module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard.c index a33f92310c..9df3f37b71 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard.c @@ -2,59 +2,102 @@ ****************************************************************************** * @file stm32l0xx_hal_smartcard.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief SMARTCARD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the SMARTCARD peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Error functions * - * This file provides firmware functions to manage the following - * functionalities of the SmartCard. - * + Initialization and de-initialization methods - * + IO operation methods - * + Peripheral Control methods - * - * - @verbatim - =============================================================================== + @verbatim + ============================================================================== ##### How to use this driver ##### - =============================================================================== - [..] - The SMARTCARD HAL driver can be used as follow: - - (#) Declare a SMARTCARD_HandleTypeDef handle structure. - (#) Associate a USART to the SMARTCARD handle hsc. - (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit ()API: - (##) Enable the USARTx interface clock. - (##) USART pins configuration: - (+) Enable the clock for the USART GPIOs. - (+) Configure these USART pins as alternate function pull-up. - (##) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT() + ============================================================================== + [..] + The SMARTCARD HAL driver can be used as follows: + + (#) Declare a SMARTCARD_HandleTypeDef handle structure (eg. SMARTCARD_HandleTypeDef hsmartcard). + (#) Associate a USART to the SMARTCARD handle hsmartcard. + (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit() API: + (++) Enable the USARTx interface clock. + (++) USART pins configuration: + (+++) Enable the clock for the USART GPIOs. + (+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input). + (++) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT() and HAL_SMARTCARD_Receive_IT() APIs): - (+) Configure the USARTx interrupt priority. - (+) Enable the NVIC USART IRQ handle. - (@) The specific USART interrupts (Transmission complete interrupt, - RXNE interrupt and Error Interrupts) will be managed using the macros - __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process. - (##) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA() + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (++) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA() and HAL_SMARTCARD_Receive_DMA() APIs): - (+) Declare a DMA handle structure for the Tx/Rx stream. - (+) Enable the DMAx interface clock. - (+) Configure the declared DMA handle structure with the required Tx/Rx parameters. - (+) Configure the DMA Tx/Rx Stream. - (+) Associate the initialized DMA handle to the SMARTCARD DMA Tx/Rx handle. - (+) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream. + (+++) Declare a DMA handle structure for the Tx/Rx channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx channel. + (+++) Associate the initialized DMA handle to the SMARTCARD DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. (#) Program the Baud Rate, Parity, Mode(Receiver/Transmitter), clock enabling/disabling and accordingly, the clock parameters (parity, phase, last bit), prescaler value, guard time and NACK on transmission - error enabling or disabling in the hsc Init structure. - - (#) If required, program SMARTCARD advanced features (TX/RX pins swap, TimeOut, auto-retry counter,...) - in the hsc AdvancedInit structure. + error enabling or disabling in the hsmartcard handle Init structure. - (#) Initialize the SMARTCARD associated USART registers by calling - the HAL_SMARTCARD_Init() API. - - (@) HAL_SMARTCARD_Init() API also configure also the low level Hardware GPIO, CLOCK, CORTEX...etc) by - calling the customized HAL_SMARTCARD_MspInit() API. + (#) If required, program SMARTCARD advanced features (TX/RX pins swap, TimeOut, auto-retry counter,...) + in the hsmartcard handle AdvancedInit structure. + + (#) Initialize the SMARTCARD registers by calling the HAL_SMARTCARD_Init() API: + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_SMARTCARD_MspInit() API. + [..] + (@) The specific SMARTCARD interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process. + + [..] + [..] Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_SMARTCARD_Transmit() + (+) Receive an amount of data in blocking mode using HAL_SMARTCARD_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non-blocking mode using HAL_SMARTCARD_Transmit_IT() + (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode using HAL_SMARTCARD_Receive_IT() + (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback() + (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non-blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA() + (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SMARTCARD_Receive_DMA() + (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback() + (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback() + + *** SMARTCARD HAL driver macros list *** + ======================================== + [..] + Below the list of most used macros in SMARTCARD HAL driver. + + (+) __HAL_SMARTCARD_GET_FLAG : Check whether or not the specified SMARTCARD flag is set + (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag + (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt + (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt + (+) __HAL_SMARTCARD_GET_IT_SOURCE: Check whether or not the specified SMARTCARD interrupt is enabled + + [..] + (@) You can refer to the SMARTCARD HAL driver header file for more useful macros @endverbatim ****************************************************************************** @@ -84,8 +127,8 @@ * 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. * - ****************************************************************************** - */ + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal.h" @@ -94,432 +137,396 @@ * @{ */ -#ifdef HAL_SMARTCARD_MODULE_ENABLED - -/** @addtogroup SMARTCARD +/** @defgroup SMARTCARD SMARTCARD * @brief HAL SMARTCARD module driver * @{ */ -/** @addtogroup SMARTCARD_Private SMARTCARD Private - * @{ - */ +#ifdef HAL_SMARTCARD_MODULE_ENABLED + /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -#define TEACK_REACK_TIMEOUT 1000U -#define HAL_SMARTCARD_TXDMA_TIMEOUTVALUE 22000U +/** @defgroup SMARTCARD_Private_Constants SMARTCARD Private Constants + * @{ + */ +#define SMARTCARD_TEACK_REACK_TIMEOUT 1000U /*!< SMARTCARD TX or RX enable acknowledge time-out value */ + #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ - USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) -#define USART_CR2_CLK_FIELDS ((uint32_t)(USART_CR2_CLKEN|USART_CR2_CPOL|USART_CR2_CPHA|USART_CR2_LBCL)) -#define USART_CR2_FIELDS ((uint32_t)(USART_CR2_RTOEN|USART_CR2_CLK_FIELDS|USART_CR2_STOP)) -#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_ONEBIT|USART_CR3_NACK|USART_CR3_SCARCNT)) -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma); -static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma); -static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma); -static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc); -static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout); -static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsc); -static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc); -static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc); -static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsc); -/* Private functions ---------------------------------------------------------*/ + USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) /*!< USART CR1 fields of parameters set by SMARTCARD_SetConfig API */ +#define USART_CR2_CLK_FIELDS ((uint32_t)(USART_CR2_CLKEN|USART_CR2_CPOL|USART_CR2_CPHA|USART_CR2_LBCL)) /*!< SMARTCARD clock-related USART CR2 fields of parameters */ +#define USART_CR2_FIELDS ((uint32_t)(USART_CR2_RTOEN|USART_CR2_CLK_FIELDS|USART_CR2_STOP)) /*!< USART CR2 fields of parameters set by SMARTCARD_SetConfig API */ +#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_ONEBIT|USART_CR3_NACK|USART_CR3_SCARCNT)) /*!< USART CR3 fields of parameters set by SMARTCARD_SetConfig API */ /** * @} */ -/** @addtogroup SMARTCARD_Exported_Functions +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SMARTCARD_Private_Functions + * @{ + */ +static HAL_StatusTypeDef SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsmartcard); +static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsmartcard); +static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout); +static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsmartcard); +static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard); +static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsmartcard); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions * @{ */ -/** @addtogroup SMARTCARD_Exported_Functions_Group1 - * @brief Initialization and Configuration functions +/** @defgroup SMARTCARD_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions * -@verbatim -=============================================================================== - ##### Initialization and Configuration functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to initialize the USARTx - associated to the SmartCard. - (+) These parameters can be configured: - (++) Baud Rate - (++) Parity: parity should be enabled,frame Length is fixed to 8 bits plus parity. - (++) Receiver/transmitter modes - (++) Synchronous mode (and if enabled, phase, polarity and last bit parameters) - (++) Prescaler value - (++) Guard bit time - (++) NACK enabling or disabling on transmission error +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USARTx + associated to the SmartCard. + (+) These parameters can be configured: + (++) Baud Rate + (++) Parity: parity should be enabled, frame Length is fixed to 8 bits plus parity + (++) Receiver/transmitter modes + (++) Synchronous mode (and if enabled, phase, polarity and last bit parameters) + (++) Prescaler value + (++) Guard bit time + (++) NACK enabling or disabling on transmission error - (+) The following advanced features can be configured as well: - (++) TX and/or RX pin level inversion - (++) data logical level inversion - (++) RX and TX pins swap - (++) RX overrun detection disabling - (++) DMA disabling on RX error - (++) MSB first on communication line - (++) Time out enabling (and if activated, timeout value) - (++) Block length - (++) Auto-retry counter - - [..] - The HAL_SMARTCARD_Init() API follow respectively the USART (a)synchronous configuration procedures - (details for the procedures are available in reference manual). + (+) The following advanced features can be configured as well: + (++) TX and/or RX pin level inversion + (++) data logical level inversion + (++) RX and TX pins swap + (++) RX overrun detection disabling + (++) DMA disabling on RX error + (++) MSB first on communication line + (++) Time out enabling (and if activated, timeout value) + (++) Block length + (++) Auto-retry counter + [..] + The HAL_SMARTCARD_Init() API follows the USART synchronous configuration procedures + (details for the procedures are available in reference manual). @endverbatim The USART frame format is given in the following table: - Table 1. USART frame format. - +---------------------------------------------------------------+ - | M1M0 bits | PCE bit | USART frame | - |-----------------------|---------------------------------------| - | 01 | 1 | | SB | 8 bit data | PB | STB | | - +---------------------------------------------------------------+ + Table 1. USART frame format. + +---------------------------------------------------------------+ + | M1M0 bits | PCE bit | USART frame | + |-----------------------|---------------------------------------| + | 01 | 1 | | SB | 8 bit data | PB | STB | | + +---------------------------------------------------------------+ + + * @{ */ /** - * @brief Initializes the SMARTCARD mode according to the specified - * parameters in the SMARTCARD_InitTypeDef and creates the associated handle . - * @param hsc: SMARTCARD handle + * @brief Initialize the SMARTCARD mode according to the specified + * parameters in the SMARTCARD_HandleTypeDef and initialize the associated handle. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval HAL status */ -HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) +HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsmartcard) { /* Check the SMARTCARD handle allocation */ - if(hsc == NULL) + if(hsmartcard == NULL) + { + return HAL_ERROR; + } + + /* Check the USART associated to the SMARTCARD handle */ + assert_param(IS_SMARTCARD_INSTANCE(hsmartcard->Instance)); + + if(hsmartcard->gState == HAL_SMARTCARD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsmartcard->Lock = HAL_UNLOCKED; + + /* Init the low level hardware : GPIO, CLOCK */ + HAL_SMARTCARD_MspInit(hsmartcard); + } + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Disable the Peripheral to set smartcard mode */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* In SmartCard mode, the following bits must be kept cleared: + - LINEN in the USART_CR2 register, + - HDSEL and IREN bits in the USART_CR3 register.*/ + CLEAR_BIT(hsmartcard->Instance->CR2, USART_CR2_LINEN); + CLEAR_BIT(hsmartcard->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN)); + + /* set the USART in SMARTCARD mode */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_SCEN); + + /* Set the SMARTCARD Communication parameters */ + if (hsmartcard->AdvancedInit.AdvFeatureInit != SMARTCARD_ADVFEATURE_NO_INIT) + { + SMARTCARD_AdvFeatureConfig(hsmartcard); + } + + if (SMARTCARD_SetConfig(hsmartcard) == HAL_ERROR) { return HAL_ERROR; } - /* Check the USART associated to the SmartCard */ - assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); - - if(hsc->State == HAL_SMARTCARD_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - hsc->Lock = HAL_UNLOCKED; - - /* Init the low level hardware : GPIO, CLOCK, CORTEX */ - HAL_SMARTCARD_MspInit(hsc); - } - - hsc->State = HAL_SMARTCARD_STATE_BUSY; - - /* Disable the Peripheral */ - __HAL_SMARTCARD_DISABLE(hsc); - - /* Set the SMARTCARD Communication parameters */ - SMARTCARD_SetConfig(hsc); - - if(hsc->AdvancedInit.AdvFeatureInit != SMARTCARD_ADVFEATURE_NO_INIT) - { - SMARTCARD_AdvFeatureConfig(hsc); - } - - /* In SmartCard mode, the following bits must be kept cleared: - - LINEN in the USART_CR2 register, - - HDSEL and IREN bits in the USART_CR3 register.*/ - hsc->Instance->CR2 &= ~(USART_CR2_LINEN); - hsc->Instance->CR3 &= ~(USART_CR3_HDSEL | USART_CR3_IREN); - - /* set the USART in SMARTCARD mode */ - hsc->Instance->CR3 |= USART_CR3_SCEN; - /* Enable the Peripheral */ - __HAL_SMARTCARD_ENABLE(hsc); - - /* TEACK and/or REACK to check before moving hsc->State to Ready */ - return (SMARTCARD_CheckIdleState(hsc)); + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* TEACK and/or REACK to check before moving hsmartcard->gState and hsmartcard->RxState to Ready */ + return (SMARTCARD_CheckIdleState(hsmartcard)); } /** - * @brief DeInitializes the SMARTCARD peripheral - * @param hsc: SMARTCARD handle + * @brief DeInitialize the SMARTCARD peripheral. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval HAL status */ -HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc) +HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsmartcard) { /* Check the SMARTCARD handle allocation */ - if(hsc == NULL) + if(hsmartcard == NULL) { return HAL_ERROR; } - - /* Check the parameters */ - assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); - - hsc->State = HAL_SMARTCARD_STATE_BUSY; - + + /* Check the USART/UART associated to the SMARTCARD handle */ + assert_param(IS_SMARTCARD_INSTANCE(hsmartcard->Instance)); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Disable the Peripheral */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + WRITE_REG(hsmartcard->Instance->CR1, 0x0); + WRITE_REG(hsmartcard->Instance->CR2, 0x0); + WRITE_REG(hsmartcard->Instance->CR3, 0x0); + WRITE_REG(hsmartcard->Instance->RTOR, 0x0); + WRITE_REG(hsmartcard->Instance->GTPR, 0x0); + /* DeInit the low level hardware */ - HAL_SMARTCARD_MspDeInit(hsc); - - hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - hsc->State = HAL_SMARTCARD_STATE_RESET; - - /* Release Lock */ - __HAL_UNLOCK(hsc); - + HAL_SMARTCARD_MspDeInit(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->gState = HAL_SMARTCARD_STATE_RESET; + hsmartcard->RxState = HAL_SMARTCARD_STATE_RESET; + + /* Process Unlock */ + __HAL_UNLOCK(hsmartcard); + return HAL_OK; } /** - * @brief SMARTCARD MSP Init - * @param hsc: SMARTCARD handle + * @brief Initialize the SMARTCARD MSP. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval None */ - __weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc) +__weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsmartcard) { /* Prevent unused argument(s) compilation warning */ - UNUSED(hsc); + UNUSED(hsmartcard); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMARTCARD_MspInit could be implenetd in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_MspInit can be implemented in the user file + */ } /** - * @brief SMARTCARD MSP DeInit - * @param hsc: SMARTCARD handle + * @brief DeInitialize the SMARTCARD MSP. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval None */ - __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc) +__weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsmartcard) { /* Prevent unused argument(s) compilation warning */ - UNUSED(hsc); + UNUSED(hsmartcard); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMARTCARD_MspDeInit could be implenetd in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_MspDeInit can be implemented in the user file + */ } /** * @} */ -/** @addtogroup SMARTCARD_Exported_Functions_Group2 - * @brief SMARTCARD Transmit/Receive functions +/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions + * @brief SMARTCARD Transmit and Receive functions * -@verbatim - =============================================================================== - ##### IO operation functions ##### - =============================================================================== +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] This subsection provides a set of functions allowing to manage the SMARTCARD data transfers. - (#) There are two mode of transfer: - (+) Blocking mode: The communication is performed in polling mode. - The HAL status of all data processing is returned by the same function - after finishing transfer. - (+) No-Blocking mode: The communication is performed using Interrupts - or DMA, These API's return the HAL status. - The end of the data processing will be indicated through the - dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when - using DMA mode. - The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks - will be executed respectivelly at the end of the transmit or Receive process - The HAL_SMARTCARD_ErrorCallback()user callback will be executed when a communication error is detected + [..] + Smartcard is a single wire half duplex communication protocol. + The Smartcard interface is designed to support asynchronous protocol Smartcards as + defined in the ISO 7816-3 standard. The USART should be configured as: + (+) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register + (+) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register. - (#) Blocking mode API's are : - (+) HAL_SMARTCARD_Transmit() - (+) HAL_SMARTCARD_Receive() - - (#) Non-Blocking mode API's with Interrupt are : - (+) HAL_SMARTCARD_Transmit_IT() - (+) HAL_SMARTCARD_Receive_IT() - (+) HAL_SMARTCARD_IRQHandler() - (+) SMARTCARD_Transmit_IT() - (+) SMARTCARD_Receive_IT() + [..] + (+) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) Non-Blocking mode: The communication is performed using Interrupts + or DMA, the relevant API's return the HAL status. + The end of the data processing will be indicated through the + dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + (++) The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks + will be executed respectively at the end of the Transmit or Receive process + The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication + error is detected. - (#) No-Blocking mode functions with DMA are : - (+) HAL_SMARTCARD_Transmit_DMA() - (+) HAL_SMARTCARD_Receive_DMA() + (+) Blocking mode APIs are : + (++) HAL_SMARTCARD_Transmit() + (++) HAL_SMARTCARD_Receive() + + (+) Non Blocking mode APIs with Interrupt are : + (++) HAL_SMARTCARD_Transmit_IT() + (++) HAL_SMARTCARD_Receive_IT() + (++) HAL_SMARTCARD_IRQHandler() + + (+) Non Blocking mode functions with DMA are : + (++) HAL_SMARTCARD_Transmit_DMA() + (++) HAL_SMARTCARD_Receive_DMA() + + (+) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_SMARTCARD_TxCpltCallback() + (++) HAL_SMARTCARD_RxCpltCallback() + (++) HAL_SMARTCARD_ErrorCallback() + + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (+) HAL_SMARTCARD_Abort() + (+) HAL_SMARTCARD_AbortTransmit() + (+) HAL_SMARTCARD_AbortReceive() + (+) HAL_SMARTCARD_Abort_IT() + (+) HAL_SMARTCARD_AbortTransmit_IT() + (+) HAL_SMARTCARD_AbortReceive_IT() + + (#) For Abort services based on interrupts (HAL_SMARTCARD_Abortxxx_IT), a set of Abort Complete Callbacks are provided: + (+) HAL_SMARTCARD_AbortCpltCallback() + (+) HAL_SMARTCARD_AbortTransmitCpltCallback() + (+) HAL_SMARTCARD_AbortReceiveCpltCallback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, + and HAL_SMARTCARD_ErrorCallback() user callback is executed. Transfer is kept ongoing on SMARTCARD side. + If user wants to abort it, Abort services should be called by user. + (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Frame Error in Interrupt mode tranmission, Overrun Error in Interrupt mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, and HAL_SMARTCARD_ErrorCallback() user callback is executed. - (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: - (+) HAL_SMARTCARD_TxCpltCallback() - (+) HAL_SMARTCARD_RxCpltCallback() - (+) HAL_SMARTCARD_ErrorCallback() - @endverbatim * @{ */ /** - * @brief Send an amount of data in blocking mode - * @param hsc: SMARTCARD handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent - * @param Timeout : Timeout duration + * @brief Send an amount of data in blocking mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be sent. + * @param Timeout Timeout duration. * @retval HAL status */ -HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout) +HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size, uint32_t Timeout) { - if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)) + uint32_t tickstart = 0; + + /* Check that a Tx process is not already ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - + /* Process Locked */ - __HAL_LOCK(hsc); - hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - /* Check if a non-blocking receive process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; - } - else - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; - } + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY_TX; + + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); - hsc->TxXferSize = Size; - hsc->TxXferCount = Size; - while(hsc->TxXferCount > 0U) + /* Disable the Peripheral first to update mode for TX master */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Disable Rx, enable Tx */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + SET_BIT(hsmartcard->Instance->RQR, SMARTCARD_RXDATA_FLUSH_REQUEST); + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE); + + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->TxXferSize = Size; + hsmartcard->TxXferCount = Size; + while(hsmartcard->TxXferCount > 0U) { - hsc->TxXferCount--; - if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, Timeout) != HAL_OK) - { + hsmartcard->TxXferCount--; + if(SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } - hsc->Instance->TDR = (*pData++ & (uint8_t)0xFFU); + hsmartcard->Instance->TDR = (*pData++ & (uint8_t)0xFFU); } - if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, Timeout) != HAL_OK) - { + if(SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, SMARTCARD_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } - /* Check if a non-blocking receive Process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) + /* Re-enable Rx at end of transmission if initial mode is Rx/Tx */ + if(hsmartcard->Init.Mode == SMARTCARD_MODE_TX_RX) { - hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; - } - else - { - hsc->State = HAL_SMARTCARD_STATE_READY; + /* Disable the Peripheral first to update modes */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); } - /* Process Unlocked */ - __HAL_UNLOCK(hsc); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} + /* At end of Tx process, restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; -/** - * @brief Receive an amount of data in blocking mode - * @param hsc: SMARTCARD handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received - * @param Timeout : Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Process Locked */ - __HAL_LOCK(hsc); - - hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - /* Check if a non-blocking transmit process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; - } - else - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; - } - - hsc->RxXferSize = Size; - hsc->RxXferCount = Size; - /* Check the remain data to be received */ - while(hsc->RxXferCount > 0U) - { - hsc->RxXferCount--; - if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } - *pData++ = (uint8_t)(hsc->Instance->RDR & (uint8_t)0x00FFU); - } - - /* Check if a non-blocking transmit Process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; - } - else - { - hsc->State = HAL_SMARTCARD_STATE_READY; - } - /* Process Unlocked */ - __HAL_UNLOCK(hsc); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} + __HAL_UNLOCK(hsmartcard); -/** - * @brief Send an amount of data in interrupt mode - * @param hsc: SMARTCARD handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) -{ - if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Process Locked */ - __HAL_LOCK(hsc); - - hsc->pTxBuffPtr = pData; - hsc->TxXferSize = Size; - hsc->TxXferCount = Size; - - hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - /* Check if a receive process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; - } - else - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; - } - - /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR); - - /* Process Unlocked */ - __HAL_UNLOCK(hsc); - - /* Enable the SMARTCARD Transmit Complete Interrupt */ - __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC); - return HAL_OK; } else @@ -529,788 +536,1752 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_ } /** - * @brief Receive an amount of data in interrupt mode - * @param hsc: SMARTCARD handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received + * @brief Receive an amount of data in blocking mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be received. + * @param Timeout Timeout duration. * @retval HAL status */ -HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) +HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size, uint32_t Timeout) { - if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)) + uint32_t tickstart = 0; + + /* Check that a Rx process is not already ongoing */ + if(hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { - return HAL_ERROR; + return HAL_ERROR; } - + /* Process Locked */ - __HAL_LOCK(hsc); - - hsc->pRxBuffPtr = pData; - hsc->RxXferSize = Size; - hsc->RxXferCount = Size; - - hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - /* Check if a transmit process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) + __HAL_LOCK(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->RxState = HAL_SMARTCARD_STATE_BUSY_RX; + + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + + hsmartcard->RxXferSize = Size; + hsmartcard->RxXferCount = Size; + + /* Check the remain data to be received */ + while(hsmartcard->RxXferCount > 0U) { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; + hsmartcard->RxXferCount--; + + if(SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + *pData++ = (uint8_t)(hsmartcard->Instance->RDR & (uint8_t)0x00FFU); } - else - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; - } - - /* Enable the SMARTCARD Parity Error Interrupt */ - __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE); - - /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR); - + + /* At end of Rx process, restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + /* Process Unlocked */ - __HAL_UNLOCK(hsc); - - /* Enable the SMARTCARD Data Register not empty Interrupt */ - __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_RXNE); - + __HAL_UNLOCK(hsmartcard); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Send an amount of data in DMA mode - * @param hsc: SMARTCARD handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @brief Send an amount of data in interrupt mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be sent. * @retval HAL status */ -HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size) { - uint32_t *tmp; - - if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)) + /* Check that a Tx process is not already ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - - /* Process Locked */ - __HAL_LOCK(hsc); - - hsc->pTxBuffPtr = pData; - hsc->TxXferSize = Size; - hsc->TxXferCount = Size; - - hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - /* Check if a receive process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; - } - else - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; - } - - /* Set the SMARTCARD DMA transfert complete callback */ - hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt; - - /* Set the SMARTCARD error callback */ - hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError; - /* Enable the SMARTCARD transmit DMA Stream */ - tmp = (uint32_t*)&pData; - HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t*)tmp, (uint32_t)&hsc->Instance->TDR, Size); + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY_TX; + + hsmartcard->pTxBuffPtr = pData; + hsmartcard->TxXferSize = Size; + hsmartcard->TxXferCount = Size; + + /* Disable the Peripheral first to update mode for TX master */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Disable Rx, enable Tx */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + SET_BIT(hsmartcard->Instance->RQR, SMARTCARD_RXDATA_FLUSH_REQUEST); + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE); - /* Clear the TC flag in the SR register by writing 0 to it */ - __HAL_SMARTCARD_CLEAR_FLAG(hsc, SMARTCARD_FLAG_TC); + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the SMARTCARD Error Interrupt: (Frame error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Enable the SMARTCARD Transmit Data Register Empty Interrupt */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TXEIE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in interrupt mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size) +{ + /* Check that a Rx process is not already ongoing */ + if(hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->RxState = HAL_SMARTCARD_STATE_BUSY_RX; + + hsmartcard->pRxBuffPtr = pData; + hsmartcard->RxXferSize = Size; + hsmartcard->RxXferCount = Size; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the SMARTCARD Parity Error and Data Register not empty Interrupts */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE| USART_CR1_RXNEIE); + + /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send an amount of data in DMA mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size) +{ + /* Check that a Tx process is not already ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY_TX; + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->pTxBuffPtr = pData; + hsmartcard->TxXferSize = Size; + hsmartcard->TxXferCount = Size; + + /* Disable the Peripheral first to update mode for TX master */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Disable Rx, enable Tx */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + SET_BIT(hsmartcard->Instance->RQR, SMARTCARD_RXDATA_FLUSH_REQUEST); + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE); + + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Set the SMARTCARD DMA transfer complete callback */ + hsmartcard->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt; + + /* Set the SMARTCARD error callback */ + hsmartcard->hdmatx->XferErrorCallback = SMARTCARD_DMAError; + + /* Set the DMA abort callback */ + hsmartcard->hdmatx->XferAbortCallback = NULL; + + /* Enable the SMARTCARD transmit DMA channel */ + HAL_DMA_Start_IT(hsmartcard->hdmatx, (uint32_t)hsmartcard->pTxBuffPtr, (uint32_t)&hsmartcard->Instance->TDR, Size); + + /* Clear the TC flag in the ICR register */ + CLEAR_BIT(hsmartcard->Instance->ICR, USART_ICR_TCCF); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the UART Error Interrupt: (Frame error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); /* Enable the DMA transfer for transmit request by setting the DMAT bit in the SMARTCARD associated USART CR3 register */ - hsc->Instance->CR3 |= USART_CR3_DMAT; - - /* Process Unlocked */ - __HAL_UNLOCK(hsc); - + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Receive an amount of data in DMA mode - * @param hsc: SMARTCARD handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received - * @note The SMARTCARD-associated USART parity is enabled (PCE = 1), - * the received data contain the parity bit (MSB position) + * @brief Receive an amount of data in DMA mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be received. + * @note The SMARTCARD-associated USART parity is enabled (PCE = 1), + * the received data contain the parity bit (MSB position). * @retval HAL status */ -HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) +HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size) { - uint32_t *tmp; - - if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)) + /* Check that a Rx process is not already ongoing */ + if(hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } - + /* Process Locked */ - __HAL_LOCK(hsc); - - hsc->pRxBuffPtr = pData; - hsc->RxXferSize = Size; - - hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - /* Check if a transmit rocess is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; - } - else - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; - } - - /* Set the SMARTCARD DMA transfert complete callback */ - hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt; - + __HAL_LOCK(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->RxState = HAL_SMARTCARD_STATE_BUSY_RX; + + hsmartcard->pRxBuffPtr = pData; + hsmartcard->RxXferSize = Size; + + /* Set the SMARTCARD DMA transfer complete callback */ + hsmartcard->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt; + /* Set the SMARTCARD DMA error callback */ - hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError; - - /* Enable the DMA Stream */ - tmp = (uint32_t*)&pData; - HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->RDR, *(uint32_t*)tmp, Size); - - /* Enable the DMA transfer for the receiver request by setting the DMAR bit - in the SMARTCARD associated USART CR3 register */ - hsc->Instance->CR3 |= USART_CR3_DMAR; - + hsmartcard->hdmarx->XferErrorCallback = SMARTCARD_DMAError; + + /* Set the DMA abort callback */ + hsmartcard->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hsmartcard->hdmarx, (uint32_t)&hsmartcard->Instance->RDR, (uint32_t)hsmartcard->pRxBuffPtr, Size); + /* Process Unlocked */ - __HAL_UNLOCK(hsc); - + __HAL_UNLOCK(hsmartcard); + + /* Enable the UART Parity Error Interrupt */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE); + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the SMARTCARD associated USART CR3 register */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } - + /** - * @brief SMARTCARD interrupt requests handling. - * @param hsc: SMARTCARD handle + * @brief Abort ongoing transfers (blocking mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable RTOIE, EOBIE, TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RTOIE | USART_CR1_EOBIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(hsmartcard->hdmatx != NULL) + { + /* Set the SMARTCARD DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hsmartcard->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hsmartcard->hdmatx); + } + } + + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(hsmartcard->hdmarx != NULL) + { + /* Set the SMARTCARD DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hsmartcard->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hsmartcard->hdmarx); + } + } + + /* Reset Tx and Rx transfer counters */ + hsmartcard->TxXferCount = 0; + hsmartcard->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->gState and hsmartcard->RxState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Reset Handle ErrorCode to No Error */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (blocking mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* Check if a receive process is ongoing or not. If not disable ERR IT */ + if(hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(hsmartcard->hdmatx != NULL) + { + /* Set the SMARTCARD DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hsmartcard->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hsmartcard->hdmatx); + } + } + + /* Reset Tx transfer counter */ + hsmartcard->TxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_FEF); + + /* Restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (blocking mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable RTOIE, EOBIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_RTOIE | USART_CR1_EOBIE)); + + /* Check if a Transmit process is ongoing or not. If not disable ERR IT */ + if(hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(hsmartcard->hdmarx != NULL) + { + /* Set the SMARTCARD DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hsmartcard->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(hsmartcard->hdmarx); + } + } + + /* Reset Rx transfer counter */ + hsmartcard->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint32_t abortcplt = 1; + + /* Disable RTOIE, EOBIE, TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RTOIE | USART_CR1_EOBIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* If DMA Tx and/or DMA Rx Handles are associated to SMARTCARD Handle, DMA Abort complete callbacks should be initialised + before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if(hsmartcard->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if SMARTCARD DMA Tx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + hsmartcard->hdmatx->XferAbortCallback = SMARTCARD_DMATxAbortCallback; + } + else + { + hsmartcard->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if(hsmartcard->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if SMARTCARD DMA Rx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + hsmartcard->hdmarx->XferAbortCallback = SMARTCARD_DMARxAbortCallback; + } + else + { + hsmartcard->hdmarx->XferAbortCallback = NULL; + } + } + + /* Disable the SMARTCARD DMA Tx request if enabled */ + if(HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable DMA Tx at UART level */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel : use non blocking DMA Abort API (callback) */ + if(hsmartcard->hdmatx != NULL) + { + /* SMARTCARD Tx DMA Abort callback has already been initialised : + will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(hsmartcard->hdmatx) != HAL_OK) + { + hsmartcard->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0; + } + } + } + + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel : use non blocking DMA Abort API (callback) */ + if(hsmartcard->hdmarx != NULL) + { + /* SMARTCARD Rx DMA Abort callback has already been initialised : + will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(hsmartcard->hdmarx) != HAL_OK) + { + hsmartcard->hdmarx->XferAbortCallback = NULL; + abortcplt = 1; + } + else + { + abortcplt = 0; + } + } + } + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1) + { + /* Reset Tx and Rx transfer counters */ + hsmartcard->TxXferCount = 0; + hsmartcard->RxXferCount = 0; + + /* Reset errorCode */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->gState and hsmartcard->RxState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_SMARTCARD_AbortCpltCallback(hsmartcard); + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (Interrupt mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* Check if a receive process is ongoing or not. If not disable ERR IT */ + if(hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel : use non blocking DMA Abort API (callback) */ + if(hsmartcard->hdmatx != NULL) + { + /* Set the SMARTCARD DMA Abort callback : + will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ + hsmartcard->hdmatx->XferAbortCallback = SMARTCARD_DMATxOnlyAbortCallback; + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(hsmartcard->hdmatx) != HAL_OK) + { + /* Call Directly hsmartcard->hdmatx->XferAbortCallback function in case of error */ + hsmartcard->hdmatx->XferAbortCallback(hsmartcard->hdmatx); + } + } + else + { + /* Reset Tx transfer counter */ + hsmartcard->TxXferCount = 0; + + /* Restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_SMARTCARD_AbortTransmitCpltCallback(hsmartcard); + } + } + else + { + /* Reset Tx transfer counter */ + hsmartcard->TxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_FEF); + + /* Restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_SMARTCARD_AbortTransmitCpltCallback(hsmartcard); + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (Interrupt mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable RTOIE, EOBIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_RTOIE | USART_CR1_EOBIE)); + + /* Check if a Transmit process is ongoing or not. If not disable ERR IT */ + if(hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel : use non blocking DMA Abort API (callback) */ + if(hsmartcard->hdmarx != NULL) + { + /* Set the SMARTCARD DMA Abort callback : + will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ + hsmartcard->hdmarx->XferAbortCallback = SMARTCARD_DMARxOnlyAbortCallback; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(hsmartcard->hdmarx) != HAL_OK) + { + /* Call Directly hsmartcard->hdmarx->XferAbortCallback function in case of error */ + hsmartcard->hdmarx->XferAbortCallback(hsmartcard->hdmarx); + } + } + else + { + /* Reset Rx transfer counter */ + hsmartcard->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_SMARTCARD_AbortReceiveCpltCallback(hsmartcard); + } + } + else + { + /* Reset Rx transfer counter */ + hsmartcard->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_SMARTCARD_AbortReceiveCpltCallback(hsmartcard); + } + + return HAL_OK; +} + +/** + * @brief Handle SMARTCARD interrupt requests. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval None */ -void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) +void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsmartcard) { - /* SMARTCARD parity error interrupt occurred -------------------------------*/ - if((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_PE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_PE) != RESET)) - { - __HAL_SMARTCARD_CLEAR_PEFLAG(hsc); - hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE; - /* Set the SMARTCARD state ready to be able to start again the process */ - hsc->State = HAL_SMARTCARD_STATE_READY; - } - - /* SMARTCARD frame error interrupt occured ---------------------------------*/ - if((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_FE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR) != RESET)) - { - __HAL_SMARTCARD_CLEAR_FEFLAG(hsc); - hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE; - /* Set the SMARTCARD state ready to be able to start again the process */ - hsc->State = HAL_SMARTCARD_STATE_READY; - } - - /* SMARTCARD noise error interrupt occured ---------------------------------*/ - if((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_NE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR) != RESET)) - { - __HAL_SMARTCARD_CLEAR_NEFLAG(hsc); - hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE; - /* Set the SMARTCARD state ready to be able to start again the process */ - hsc->State = HAL_SMARTCARD_STATE_READY; - } - - /* SMARTCARD Over-Run interrupt occured ------------------------------------*/ - if((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_ORE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR) != RESET)) - { - __HAL_SMARTCARD_CLEAR_OREFLAG(hsc); - hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE; - /* Set the SMARTCARD state ready to be able to start again the process */ - hsc->State = HAL_SMARTCARD_STATE_READY; - } - - /* SMARTCARD receiver timeout interrupt occured ----------------------------*/ - if((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_RTO) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_RTO) != RESET)) - { - __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_CLEAR_RTOF); - hsc->ErrorCode |= HAL_SMARTCARD_ERROR_RTO; - /* Set the SMARTCARD state ready to be able to start again the process */ - hsc->State = HAL_SMARTCARD_STATE_READY; - } - - /* Call SMARTCARD Error Call back function if need be ----------------------*/ - if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE) + uint32_t isrflags = READ_REG(hsmartcard->Instance->ISR); + uint32_t cr1its = READ_REG(hsmartcard->Instance->CR1); + uint32_t cr3its; + uint32_t errorflags; + + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF)); + if (errorflags == RESET) { - HAL_SMARTCARD_ErrorCallback(hsc); - } - - /* SMARTCARD in mode Receiver ----------------------------------------------*/ - if((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_RXNE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_RXNE) != RESET)) - { - SMARTCARD_Receive_IT(hsc); - /* Clear RXNE interrupt flag */ - __HAL_SMARTCARD_SEND_REQ(hsc, SMARTCARD_RXDATA_FLUSH_REQUEST); - } - - /* SMARTCARD in mode Receiver, end of block interruption -------------------*/ - if((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_EOB) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_EOB) != RESET)) - { - hsc->State = HAL_SMARTCARD_STATE_READY; - HAL_SMARTCARD_RxCpltCallback(hsc); - /* Clear EOBF interrupt after HAL_SMARTCARD_RxCpltCallback() call for the End of Block information - * to be available during HAL_SMARTCARD_RxCpltCallback() processing */ - __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_CLEAR_EOBF); + /* SMARTCARD in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + SMARTCARD_Receive_IT(hsmartcard); + /* Clear RXNE interrupt flag done by reading RDR in SMARTCARD_Receive_IT() */ + return; + } } - - /* SMARTCARD in mode Transmitter -------------------------------------------*/ - if((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_TC) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_TC) != RESET)) + + /* If some errors occur */ + cr3its = READ_REG(hsmartcard->Instance->CR3); + if( (errorflags != RESET) + && ( ((cr3its & USART_CR3_EIE) != RESET) + || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != RESET)) ) { - SMARTCARD_Transmit_IT(hsc); - } -} + /* SMARTCARD parity error interrupt occurred -------------------------------------*/ + if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_PEF); -/** - * @brief Tx Transfer completed callbacks - * @param hsc: SMARTCARD handle - * @retval None - */ - __weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hsc); + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_PE; + } - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file - */ + /* SMARTCARD frame error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_FEF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_FE; + } + + /* SMARTCARD noise error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_NEF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_NE; + } + + /* SMARTCARD Over-Run interrupt occurred -----------------------------------------*/ + if(((isrflags & USART_ISR_ORE) != RESET) && + (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_OREF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_ORE; + } + + /* SMARTCARD receiver timeout interrupt occurred -----------------------------------------*/ + if(((isrflags & USART_ISR_RTOF) != RESET) && ((cr1its & USART_CR1_RTOIE) != RESET)) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_RTOF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_RTO; + } + + /* Call SMARTCARD Error Call back function if need be --------------------------*/ + if(hsmartcard->ErrorCode != HAL_SMARTCARD_ERROR_NONE) + { + /* SMARTCARD in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + SMARTCARD_Receive_IT(hsmartcard); + } + + /* If Error is to be considered as blocking : + - Receiver Timeout error in Reception + - Overrun error in Reception + - any error occurs in DMA mode reception + */ + if ( ((hsmartcard->ErrorCode & (HAL_SMARTCARD_ERROR_RTO | HAL_SMARTCARD_ERROR_ORE)) != RESET) + || (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR))) + { + /* Blocking error : transfer is aborted + Set the SMARTCARD state ready to be able to start again the process, + Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ + SMARTCARD_EndRxTransfer(hsmartcard); + + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel */ + if(hsmartcard->hdmarx != NULL) + { + /* Set the SMARTCARD DMA Abort callback : + will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */ + hsmartcard->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(hsmartcard->hdmarx) != HAL_OK) + { + /* Call Directly hsmartcard->hdmarx->XferAbortCallback function in case of error */ + hsmartcard->hdmarx->XferAbortCallback(hsmartcard->hdmarx); + } + } + else + { + /* Call user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); + } + } + else + { + /* Call user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); + } + } + /* other error type to be considered as blocking : + - Frame error in Transmission + */ + else if ((hsmartcard->gState == HAL_SMARTCARD_STATE_BUSY_TX) && ((hsmartcard->ErrorCode & HAL_SMARTCARD_ERROR_FE) != RESET)) + { + /* Blocking error : transfer is aborted + Set the SMARTCARD state ready to be able to start again the process, + Disable Tx Interrupts, and disable Tx DMA request, if ongoing */ + SMARTCARD_EndTxTransfer(hsmartcard); + + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel */ + if(hsmartcard->hdmatx != NULL) + { + /* Set the SMARTCARD DMA Abort callback : + will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */ + hsmartcard->hdmatx->XferAbortCallback = SMARTCARD_DMAAbortOnError; + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(hsmartcard->hdmatx) != HAL_OK) + { + /* Call Directly hsmartcard->hdmatx->XferAbortCallback function in case of error */ + hsmartcard->hdmatx->XferAbortCallback(hsmartcard->hdmatx); + } + } + else + { + /* Call user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); + } + } + else + { + /* Call user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ + + /* SMARTCARD in mode Receiver, end of block interruption ------------------------*/ + if(((isrflags & USART_ISR_EOBF) != RESET) && ((cr1its & USART_CR1_EOBIE) != RESET)) + { + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + __HAL_UNLOCK(hsmartcard); + HAL_SMARTCARD_RxCpltCallback(hsmartcard); + /* Clear EOBF interrupt after HAL_SMARTCARD_RxCpltCallback() call for the End of Block information + * to be available during HAL_SMARTCARD_RxCpltCallback() processing */ + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_EOBF); + return; + } + + /* SMARTCARD in mode Transmitter ------------------------------------------------*/ + if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) + { + SMARTCARD_Transmit_IT(hsmartcard); + return; + } + + /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/ + if((__HAL_SMARTCARD_GET_IT(hsmartcard, SMARTCARD_IT_TC) != RESET) &&(__HAL_SMARTCARD_GET_IT_SOURCE(hsmartcard, SMARTCARD_IT_TC) != RESET)) + { + SMARTCARD_EndTransmit_IT(hsmartcard); + return; + } } /** - * @brief Rx Transfer completed callbacks - * @param hsc: SMARTCARD handle + * @brief Tx Transfer completed callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval None */ -__weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc) +__weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard) { /* Prevent unused argument(s) compilation warning */ - UNUSED(hsc); + UNUSED(hsmartcard); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_TxCpltCallback can be implemented in the user file. */ } /** - * @brief SMARTCARD error callbacks - * @param hsc: SMARTCARD handle + * @brief Rx Transfer completed callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval None */ - __weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc) +__weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard) { /* Prevent unused argument(s) compilation warning */ - UNUSED(hsc); + UNUSED(hsmartcard); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMARTCARD_ErrorCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_RxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD error callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_ErrorCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD Abort Complete callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_AbortCpltCallback (SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD Abort Complete callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_AbortTransmitCpltCallback (SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_AbortTransmitCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD Abort Receive Complete callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_AbortReceiveCpltCallback (SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_AbortReceiveCpltCallback can be implemented in the user file. */ } /** * @} - */ + */ -/** @addtogroup SMARTCARD_Exported_Functions_Group3 - * @brief SMARTCARD State functions +/** @defgroup SMARTCARD_Exported_Functions_Group4 Peripheral State and Errors functions + * @brief SMARTCARD State and Errors functions * -@verbatim - =============================================================================== - ##### Peripheral State functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to initialize the SMARTCARD. - (+) HAL_SMARTCARD_GetState() API is helpful to check in run-time the state of the SMARTCARD peripheral - (+) SMARTCARD_SetConfig() API configures the SMARTCARD peripheral - (+) SMARTCARD_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of SmartCard + handle and also return Peripheral Errors occurred during communication process + (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state + of the SMARTCARD peripheral. + (+) HAL_SMARTCARD_GetError() checks in run-time errors that could occur during + communication. @endverbatim * @{ */ - /** - * @brief return the SMARTCARD state - * @param hsc: SMARTCARD handle - * @retval HAL state + * @brief Return the SMARTCARD handle state. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval SMARTCARD handle state */ -HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc) +HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsmartcard) { - return hsc->State; + /* Return SMARTCARD handle state */ + uint32_t temp1= 0x00, temp2 = 0x00; + temp1 = hsmartcard->gState; + temp2 = hsmartcard->RxState; + + return (HAL_SMARTCARD_StateTypeDef)(temp1 | temp2); } /** -* @brief Return the SMARTCARD error code -* @param hsc : pointer to a SMARTCARD_HandleTypeDef structure that contains - * the configuration information for the specified SMARTCARD. -* @retval SMARTCARD Error Code + * @brief Return the SMARTCARD handle error code. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval SMARTCARD handle Error Code */ -uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc) +uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsmartcard) { - return hsc->ErrorCode; + return hsmartcard->ErrorCode; } /** * @} */ - -/** - * @brief Send an amount of data in non blocking mode - * @param hsc: SMARTCARD handle. - * Function called under interruption only, once - * interruptions have been enabled by HAL_SMARTCARD_Transmit_IT() - * @retval HAL status - */ -static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc) -{ - if((hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)) - { - if(hsc->TxXferCount == 0U) - { - /* Disable the SMARTCARD Transmit Complete Interrupt */ - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TC); - - /* Check if a receive Process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; - } - else - { - /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR); - - hsc->State = HAL_SMARTCARD_STATE_READY; - } - - HAL_SMARTCARD_TxCpltCallback(hsc); - - return HAL_OK; - } - else - { - hsc->Instance->TDR = (*hsc->pTxBuffPtr++ & (uint8_t)0xFFU); - hsc->TxXferCount--; - - return HAL_OK; - } - } - else - { - return HAL_BUSY; - } -} /** - * @brief Receive an amount of data in non blocking mode - * @param hsc: SMARTCARD handle. - * Function called under interruption only, once - * interruptions have been enabled by HAL_SMARTCARD_Receive_IT() - * @retval HAL status + * @} + */ + +/** @defgroup SMARTCARD_Private_Functions SMARTCARD Private Functions + * @{ */ -static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc) -{ - if((hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)) - { - *hsc->pRxBuffPtr++ = (uint8_t)(hsc->Instance->RDR & (uint8_t)0xFFU); - - if(--hsc->RxXferCount == 0U) - { - while(HAL_IS_BIT_SET(hsc->Instance->ISR, SMARTCARD_FLAG_RXNE)) - { - } - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); - - /* Check if a transmit Process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; - } - else - { - /* Disable the SMARTCARD Parity Error Interrupt */ - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE); - - /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR); - - hsc->State = HAL_SMARTCARD_STATE_READY; - } - - HAL_SMARTCARD_RxCpltCallback(hsc); - - return HAL_OK; - } - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} /** - * @brief Configure the SMARTCARD associated USART peripheral - * @param hsc: SMARTCARD handle + * @brief Configure the SMARTCARD associated USART peripheral. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval None */ -static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) +static HAL_StatusTypeDef SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsmartcard) { - uint32_t tmpreg = 0x00000000U; - uint32_t clocksource = 0x00000000U; - - /* Check the parameters */ - assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); - assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate)); - assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength)); - assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits)); - assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity)); - assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode)); - assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity)); - assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase)); - assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit)); - assert_param(IS_SMARTCARD_ONE_BIT_SAMPLE(hsc->Init.OneBitSampling)); - assert_param(IS_SMARTCARD_NACK(hsc->Init.NACKState)); - assert_param(IS_SMARTCARD_TIMEOUT(hsc->Init.TimeOutEnable)); - assert_param(IS_SMARTCARD_AUTORETRY_COUNT(hsc->Init.AutoRetryCount)); + uint32_t tmpreg = 0x00000000U; + SMARTCARD_ClockSourceTypeDef clocksource = SMARTCARD_CLOCKSOURCE_UNDEFINED; + HAL_StatusTypeDef ret = HAL_OK; + + /* Check the parameters */ + assert_param(IS_SMARTCARD_INSTANCE(hsmartcard->Instance)); + assert_param(IS_SMARTCARD_BAUDRATE(hsmartcard->Init.BaudRate)); + assert_param(IS_SMARTCARD_WORD_LENGTH(hsmartcard->Init.WordLength)); + assert_param(IS_SMARTCARD_STOPBITS(hsmartcard->Init.StopBits)); + assert_param(IS_SMARTCARD_PARITY(hsmartcard->Init.Parity)); + assert_param(IS_SMARTCARD_MODE(hsmartcard->Init.Mode)); + assert_param(IS_SMARTCARD_POLARITY(hsmartcard->Init.CLKPolarity)); + assert_param(IS_SMARTCARD_PHASE(hsmartcard->Init.CLKPhase)); + assert_param(IS_SMARTCARD_LASTBIT(hsmartcard->Init.CLKLastBit)); + assert_param(IS_SMARTCARD_ONE_BIT_SAMPLE(hsmartcard->Init.OneBitSampling)); + assert_param(IS_SMARTCARD_NACK(hsmartcard->Init.NACKEnable)); + assert_param(IS_SMARTCARD_TIMEOUT(hsmartcard->Init.TimeOutEnable)); + assert_param(IS_SMARTCARD_AUTORETRY_COUNT(hsmartcard->Init.AutoRetryCount)); /*-------------------------- USART CR1 Configuration -----------------------*/ /* In SmartCard mode, M and PCE are forced to 1 (8 bits + parity). * Oversampling is forced to 16 (OVER8 = 0). - * Configure the Parity and Mode: - * set PS bit according to hsc->Init.Parity value - * set TE and RE bits according to hsc->Init.Mode value */ - tmpreg = (uint32_t) hsc->Init.Parity | hsc->Init.Mode; + * Configure the Parity and Mode: + * set PS bit according to hsmartcard->Init.Parity value + * set TE and RE bits according to hsmartcard->Init.Mode value */ + tmpreg = (uint32_t) hsmartcard->Init.Parity | hsmartcard->Init.Mode; /* in case of TX-only mode, if NACK is enabled, the USART must be able to monitor the bidirectional line to detect a NACK signal in case of parity error. Therefore, the receiver block must be enabled as well (RE bit must be set). */ - if((hsc->Init.Mode == SMARTCARD_MODE_TX) && (hsc->Init.NACKState == SMARTCARD_NACK_ENABLE)) + if((hsmartcard->Init.Mode == SMARTCARD_MODE_TX) && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE)) { tmpreg |= USART_CR1_RE; } - tmpreg |= (uint32_t) hsc->Init.WordLength; - MODIFY_REG(hsc->Instance->CR1, USART_CR1_FIELDS, tmpreg); + tmpreg |= (uint32_t) hsmartcard->Init.WordLength; + MODIFY_REG(hsmartcard->Instance->CR1, USART_CR1_FIELDS, tmpreg); /*-------------------------- USART CR2 Configuration -----------------------*/ - /* Stop bits allowed in smartcard mode are 0.5 (receiving mode only) and 1.5 */ - tmpreg = hsc->Init.StopBits; + tmpreg = hsmartcard->Init.StopBits; /* Synchronous mode is activated by default */ - tmpreg |= (uint32_t) USART_CR2_CLKEN | hsc->Init.CLKPolarity; - tmpreg |= (uint32_t) hsc->Init.CLKPhase | hsc->Init.CLKLastBit; - tmpreg |= (uint32_t) hsc->Init.TimeOutEnable; - MODIFY_REG(hsc->Instance->CR2, USART_CR2_FIELDS, tmpreg); - + tmpreg |= (uint32_t) USART_CR2_CLKEN | hsmartcard->Init.CLKPolarity; + tmpreg |= (uint32_t) hsmartcard->Init.CLKPhase | hsmartcard->Init.CLKLastBit; + tmpreg |= (uint32_t) hsmartcard->Init.TimeOutEnable; + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_FIELDS, tmpreg); + /*-------------------------- USART CR3 Configuration -----------------------*/ - /* Configure - * - one-bit sampling method versus three samples' majority rule - * according to hsc->Init.OneBitSampling - * - NACK transmission in case of parity error according - * to hsc->Init.NACKEnable - * - autoretry counter according to hsc->Init.AutoRetryCount */ - tmpreg = (uint32_t) hsc->Init.OneBitSampling | hsc->Init.NACKState; - tmpreg |= (uint32_t) (hsc->Init.AutoRetryCount << SMARTCARD_CR3_SCARCNT_LSB_POS); - MODIFY_REG(hsc->Instance-> CR3,USART_CR3_FIELDS, tmpreg); - + /* Configure + * - one-bit sampling method versus three samples' majority rule + * according to hsmartcard->Init.OneBitSampling + * - NACK transmission in case of parity error according + * to hsmartcard->Init.NACKEnable + * - autoretry counter according to hsmartcard->Init.AutoRetryCount */ + tmpreg = (uint32_t) hsmartcard->Init.OneBitSampling | hsmartcard->Init.NACKEnable; + tmpreg |= ((uint32_t)hsmartcard->Init.AutoRetryCount << SMARTCARD_CR3_SCARCNT_LSB_POS); + MODIFY_REG(hsmartcard->Instance-> CR3,USART_CR3_FIELDS, tmpreg); + /*-------------------------- USART GTPR Configuration ----------------------*/ - tmpreg = (uint32_t) (hsc->Init.Prescaler | (hsc->Init.GuardTime << SMARTCARD_GTPR_GT_LSB_POS)); - MODIFY_REG(hsc->Instance->GTPR, (uint32_t)(USART_GTPR_GT|USART_GTPR_PSC), tmpreg); - - /*-------------------------- USART RTOR Configuration ----------------------*/ - tmpreg = (uint32_t) (hsc->Init.BlockLength << SMARTCARD_RTOR_BLEN_LSB_POS); - if(hsc->Init.TimeOutEnable == SMARTCARD_TIMEOUT_ENABLE) + tmpreg = (hsmartcard->Init.Prescaler | ((uint32_t)hsmartcard->Init.GuardTime << SMARTCARD_GTPR_GT_LSB_POS)); + MODIFY_REG(hsmartcard->Instance->GTPR, (USART_GTPR_GT|USART_GTPR_PSC), tmpreg); + + /*-------------------------- USART RTOR Configuration ----------------------*/ + tmpreg = ((uint32_t)hsmartcard->Init.BlockLength << SMARTCARD_RTOR_BLEN_LSB_POS); + if (hsmartcard->Init.TimeOutEnable == SMARTCARD_TIMEOUT_ENABLE) { - assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsc->Init.TimeOutValue)); - tmpreg |= (uint32_t) hsc->Init.TimeOutValue; + assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsmartcard->Init.TimeOutValue)); + tmpreg |= (uint32_t) hsmartcard->Init.TimeOutValue; } - MODIFY_REG(hsc->Instance->RTOR, (USART_RTOR_RTO|USART_RTOR_BLEN), tmpreg); - + MODIFY_REG(hsmartcard->Instance->RTOR, (USART_RTOR_RTO|USART_RTOR_BLEN), tmpreg); + /*-------------------------- USART BRR Configuration -----------------------*/ - SMARTCARD_GETCLOCKSOURCE(hsc, clocksource); + SMARTCARD_GETCLOCKSOURCE(hsmartcard, clocksource); switch (clocksource) { - case SMARTCARD_CLOCKSOURCE_PCLK1: - hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hsc->Init.BaudRate/2U)) / hsc->Init.BaudRate); - break; - case SMARTCARD_CLOCKSOURCE_PCLK2: - hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hsc->Init.BaudRate/2U)) / hsc->Init.BaudRate); - break; - case SMARTCARD_CLOCKSOURCE_HSI: - hsc->Instance->BRR = (uint16_t)((HSI_VALUE + (hsc->Init.BaudRate/2U)) / hsc->Init.BaudRate); - break; - case SMARTCARD_CLOCKSOURCE_SYSCLK: - hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hsc->Init.BaudRate/2U)) / hsc->Init.BaudRate); - break; - case SMARTCARD_CLOCKSOURCE_LSE: - hsc->Instance->BRR = (uint16_t)((LSE_VALUE + (hsc->Init.BaudRate/2U)) / hsc->Init.BaudRate); - break; - default: - break; - } + case SMARTCARD_CLOCKSOURCE_PCLK1: + hsmartcard->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hsmartcard->Init.BaudRate/2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_PCLK2: + hsmartcard->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hsmartcard->Init.BaudRate/2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_HSI: + hsmartcard->Instance->BRR = (uint16_t)((HSI_VALUE + (hsmartcard->Init.BaudRate/2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_SYSCLK: + hsmartcard->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hsmartcard->Init.BaudRate/2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_LSE: + hsmartcard->Instance->BRR = (uint16_t)((LSE_VALUE + (hsmartcard->Init.BaudRate/2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_UNDEFINED: + default: + ret = HAL_ERROR; + break; + } + + return ret; } -/** - * @brief Check the SMARTCARD Idle State - * @param hsc: SMARTCARD handle - * @retval HAL status - */ -static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsc) -{ - - /* Initialize the SMARTCARD ErrorCode */ - hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - - /* Check if the Transmitter is enabled */ - if((hsc->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) - { - /* Wait until TEACK flag is set */ - if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) - { - return HAL_TIMEOUT; - } - } - /* Check if the Receiver is enabled */ - if((hsc->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) - { - /* Wait until REACK flag is set */ - if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) - { - return HAL_TIMEOUT; - } - } - - /* Process Unlocked */ - __HAL_UNLOCK(hsc); - - /* Initialize the SMARTCARD state*/ - hsc->State= HAL_SMARTCARD_STATE_READY; - - return HAL_OK; -} /** - * @brief Configure the SMARTCARD associated USART peripheral advanced feautures - * @param hsc: SMARTCARD handle + * @brief Configure the SMARTCARD associated USART peripheral advanced features. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval None */ -static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsc) -{ - /* Check whether the set of advanced features to configure is properly set */ - assert_param(IS_SMARTCARD_ADVFEATURE_INIT(hsc->AdvancedInit.AdvFeatureInit)); - +static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Check whether the set of advanced features to configure is properly set */ + assert_param(IS_SMARTCARD_ADVFEATURE_INIT(hsmartcard->AdvancedInit.AdvFeatureInit)); + /* if required, configure TX pin active level inversion */ - if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_TXINVERT_INIT)) + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_TXINVERT_INIT)) { - assert_param(IS_SMARTCARD_ADVFEATURE_TXINV(hsc->AdvancedInit.TxPinLevelInvert)); - MODIFY_REG(hsc->Instance->CR2, USART_CR2_TXINV, hsc->AdvancedInit.TxPinLevelInvert); + assert_param(IS_SMARTCARD_ADVFEATURE_TXINV(hsmartcard->AdvancedInit.TxPinLevelInvert)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_TXINV, hsmartcard->AdvancedInit.TxPinLevelInvert); } - + /* if required, configure RX pin active level inversion */ - if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXINVERT_INIT)) + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXINVERT_INIT)) { - assert_param(IS_SMARTCARD_ADVFEATURE_RXINV(hsc->AdvancedInit.RxPinLevelInvert)); - MODIFY_REG(hsc->Instance->CR2, USART_CR2_RXINV, hsc->AdvancedInit.RxPinLevelInvert); + assert_param(IS_SMARTCARD_ADVFEATURE_RXINV(hsmartcard->AdvancedInit.RxPinLevelInvert)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_RXINV, hsmartcard->AdvancedInit.RxPinLevelInvert); } - + /* if required, configure data inversion */ - if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DATAINVERT_INIT)) + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DATAINVERT_INIT)) { - assert_param(IS_SMARTCARD_ADVFEATURE_DATAINV(hsc->AdvancedInit.DataInvert)); - MODIFY_REG(hsc->Instance->CR2, USART_CR2_DATAINV, hsc->AdvancedInit.DataInvert); + assert_param(IS_SMARTCARD_ADVFEATURE_DATAINV(hsmartcard->AdvancedInit.DataInvert)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_DATAINV, hsmartcard->AdvancedInit.DataInvert); } - + /* if required, configure RX/TX pins swap */ - if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_SWAP_INIT)) + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_SWAP_INIT)) { - assert_param(IS_SMARTCARD_ADVFEATURE_SWAP(hsc->AdvancedInit.Swap)); - MODIFY_REG(hsc->Instance->CR2, USART_CR2_SWAP, hsc->AdvancedInit.Swap); + assert_param(IS_SMARTCARD_ADVFEATURE_SWAP(hsmartcard->AdvancedInit.Swap)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_SWAP, hsmartcard->AdvancedInit.Swap); } - + /* if required, configure RX overrun detection disabling */ - if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT)) + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT)) { - assert_param(IS_SMARTCARD_OVERRUN(hsc->AdvancedInit.OverrunDisable)); - MODIFY_REG(hsc->Instance->CR3, USART_CR3_OVRDIS, hsc->AdvancedInit.OverrunDisable); + assert_param(IS_SMARTCARD_OVERRUN(hsmartcard->AdvancedInit.OverrunDisable)); + MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_OVRDIS, hsmartcard->AdvancedInit.OverrunDisable); } - + /* if required, configure DMA disabling on reception error */ - if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT)) + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT)) { - assert_param(IS_SMARTCARD_ADVFEATURE_DMAONRXERROR(hsc->AdvancedInit.DMADisableonRxError)); - MODIFY_REG(hsc->Instance->CR3, USART_CR3_DDRE, hsc->AdvancedInit.DMADisableonRxError); + assert_param(IS_SMARTCARD_ADVFEATURE_DMAONRXERROR(hsmartcard->AdvancedInit.DMADisableonRxError)); + MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_DDRE, hsmartcard->AdvancedInit.DMADisableonRxError); } - - /* if required, configure MSB first on communication line */ - if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_MSBFIRST_INIT)) + + /* if required, configure MSB first on communication line */ + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_MSBFIRST_INIT)) { - assert_param(IS_SMARTCARD_ADVFEATURE_MSBFIRST(hsc->AdvancedInit.MSBFirst)); - MODIFY_REG(hsc->Instance->CR2, USART_CR2_MSBFIRST, hsc->AdvancedInit.MSBFirst); + assert_param(IS_SMARTCARD_ADVFEATURE_MSBFIRST(hsmartcard->AdvancedInit.MSBFirst)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_MSBFIRST, hsmartcard->AdvancedInit.MSBFirst); } + } - + /** - * @brief This function handles SMARTCARD Communication Timeout. - * @param hsc: SMARTCARD handle - * @param Flag: specifies the SMARTCARD flag to check. - * @param Status: The new Flag status (SET or RESET). - * @param Timeout: Timeout duration + * @brief Check the SMARTCARD Idle State. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval HAL status */ -static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsmartcard) { - uint32_t tickstart = 0x00U; + uint32_t tickstart = 0; + + /* Initialize the SMARTCARD ErrorCode */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Init tickstart for timeout managment*/ tickstart = HAL_GetTick(); - /* Wait until flag is set */ - if(Status == RESET) - { - while(__HAL_SMARTCARD_GET_FLAG(hsc, Flag) == RESET) + /* Check if the Transmitter is enabled */ + if((hsmartcard->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + { + /* Wait until TEACK flag is set */ + if(SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, USART_ISR_TEACK, RESET, tickstart, SMARTCARD_TEACK_REACK_TIMEOUT) != HAL_OK) { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE); - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE); - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR); - - hsc->State= HAL_SMARTCARD_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hsc); - - return HAL_TIMEOUT; - } - } + /* Timeout occurred */ + return HAL_TIMEOUT; } } - else + /* Check if the Receiver is enabled */ + if((hsmartcard->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) { - while(__HAL_SMARTCARD_GET_FLAG(hsc, Flag) != RESET) + /* Wait until REACK flag is set */ + if(SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, USART_ISR_REACK, RESET, tickstart, SMARTCARD_TEACK_REACK_TIMEOUT) != HAL_OK) { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + + /* Initialize the SMARTCARD states */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; +} + +/** + * @brief Handle SMARTCARD Communication Timeout. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param Flag Specifies the SMARTCARD flag to check. + * @param Status The new Flag status (SET or RESET). + * @param Tickstart Tick start value + * @param Timeout Timeout duration. + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is set */ + while((__HAL_SMARTCARD_GET_FLAG(hsmartcard, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout)) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE); - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE); - __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR); + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); - hsc->State= HAL_SMARTCARD_STATE_READY; + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; - /* Process Unlocked */ - __HAL_UNLOCK(hsc); - - return HAL_TIMEOUT; - } + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + return HAL_TIMEOUT; } } } return HAL_OK; } + /** - * @brief DMA SMARTCARD transmit process complete callback - * @param hdma: DMA handle + * @brief End ongoing Tx transfer on SMARTCARD peripheral (following error detection or Transmit completion). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval None */ -static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma) +static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsmartcard) { - SMARTCARD_HandleTypeDef* hsmartcard = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - hsmartcard->TxXferCount = 0U; + /* Disable TXEIE, TCIE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* At end of Tx process, restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; +} + + +/** + * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* At end of Rx process, restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; +} + + +/** + * @brief DMA SMARTCARD transmit process complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsmartcard = (SMARTCARD_HandleTypeDef*)(hdma->Parent); + hsmartcard->TxXferCount = 0; /* Disable the DMA transfer for transmit request by resetting the DMAT bit in the SMARTCARD associated USART CR3 register */ - hsmartcard->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAT); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); /* Enable the SMARTCARD Transmit Complete Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsmartcard, SMARTCARD_IT_TC); } /** - * @brief DMA SMARTCARD receive process complete callback - * @param hdma: DMA handle + * @brief DMA SMARTCARD receive process complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. * @retval None */ -static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - hsc->RxXferCount = 0U; - - /* Disable the DMA transfer for the receiver request by setting the DMAR bit + SMARTCARD_HandleTypeDef* hsmartcard = (SMARTCARD_HandleTypeDef*)(hdma->Parent); + hsmartcard->RxXferCount = 0; + + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit in the SMARTCARD associated USART CR3 register */ - hsc->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAR); - - /* Check if a transmit Process is ongoing or not */ - if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) - { - hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; - } - else - { - hsc->State = HAL_SMARTCARD_STATE_READY; - } - - HAL_SMARTCARD_RxCpltCallback(hsc); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* At end of Rx process, restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + HAL_SMARTCARD_RxCpltCallback(hsmartcard); } /** - * @brief DMA SMARTCARD communication error callback - * @param hdma: DMA handle + * @brief DMA SMARTCARD communication error callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. * @retval None */ static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - hsc->RxXferCount = 0U; - hsc->TxXferCount = 0U; - hsc->State= HAL_SMARTCARD_STATE_READY; - hsc->ErrorCode |= HAL_SMARTCARD_ERROR_DMA; - HAL_SMARTCARD_ErrorCallback(hsc); + SMARTCARD_HandleTypeDef* hsmartcard = (SMARTCARD_HandleTypeDef*)(hdma->Parent); + + /* Stop SMARTCARD DMA Tx request if ongoing */ + if ( (hsmartcard->gState == HAL_SMARTCARD_STATE_BUSY_TX) + &&(HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) ) + { + hsmartcard->TxXferCount = 0; + SMARTCARD_EndTxTransfer(hsmartcard); + } + + /* Stop SMARTCARD DMA Rx request if ongoing */ + if ( (hsmartcard->RxState == HAL_SMARTCARD_STATE_BUSY_RX) + &&(HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) ) + { + hsmartcard->RxXferCount = 0; + SMARTCARD_EndRxTransfer(hsmartcard); + } + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_DMA; + HAL_SMARTCARD_ErrorCallback(hsmartcard); } + /** - * @} + * @brief DMA SMARTCARD communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None */ +static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsmartcard = (SMARTCARD_HandleTypeDef*)(hdma->Parent); + hsmartcard->RxXferCount = 0; + hsmartcard->TxXferCount = 0; + + HAL_SMARTCARD_ErrorCallback(hsmartcard); +} + +/** + * @brief DMA SMARTCARD Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsmartcard = (SMARTCARD_HandleTypeDef* )(hdma->Parent); + + hsmartcard->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(hsmartcard->hdmarx != NULL) + { + if(hsmartcard->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hsmartcard->TxXferCount = 0; + hsmartcard->RxXferCount = 0; + + /* Reset errorCode */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->gState and hsmartcard->RxState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Call user Abort complete callback */ + HAL_SMARTCARD_AbortCpltCallback(hsmartcard); +} + + +/** + * @brief DMA SMARTCARD Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsmartcard = (SMARTCARD_HandleTypeDef* )(hdma->Parent); + + hsmartcard->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(hsmartcard->hdmatx != NULL) + { + if(hsmartcard->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hsmartcard->TxXferCount = 0; + hsmartcard->RxXferCount = 0; + + /* Reset errorCode */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->gState and hsmartcard->RxState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Call user Abort complete callback */ + HAL_SMARTCARD_AbortCpltCallback(hsmartcard); +} + + +/** + * @brief DMA SMARTCARD Tx communication abort callback, when initiated by user by a call to + * HAL_SMARTCARD_AbortTransmit_IT API (Abort only Tx transfer) + * (This callback is executed at end of DMA Tx Abort procedure following user abort request, + * and leads to user Tx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsmartcard = (SMARTCARD_HandleTypeDef*)(hdma->Parent); + + hsmartcard->TxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_FEF); + + /* Restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Call user Abort complete callback */ + HAL_SMARTCARD_AbortTransmitCpltCallback(hsmartcard); +} + +/** + * @brief DMA SMARTCARD Rx communication abort callback, when initiated by user by a call to + * HAL_SMARTCARD_AbortReceive_IT API (Abort only Rx transfer) + * (This callback is executed at end of DMA Rx Abort procedure following user abort request, + * and leads to user Rx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsmartcard = ( SMARTCARD_HandleTypeDef* )(hdma->Parent); + + hsmartcard->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Call user Abort complete callback */ + HAL_SMARTCARD_AbortReceiveCpltCallback(hsmartcard); +} + +/** + * @brief Send an amount of data in non-blocking mode. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * Function called under interruption only, once + * interruptions have been enabled by HAL_SMARTCARD_Transmit_IT() + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Check that a Tx process is ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_BUSY_TX) + { + if(hsmartcard->TxXferCount == 0U) + { + /* Disable the SMARTCARD Transmit Data Register Empty Interrupt */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_TXEIE); + + /* Enable the SMARTCARD Transmit Complete Interrupt */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TCIE); + + return HAL_OK; + } + else + { + hsmartcard->Instance->TDR = (*hsmartcard->pTxBuffPtr++ & (uint8_t)0xFFU); + hsmartcard->TxXferCount--; + + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Wrap up transmission in non-blocking mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable the SMARTCARD Transmit Complete Interrupt */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_TCIE); + + /* Check if a receive process is ongoing or not. If not disable ERR IT */ + if(hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Re-enable Rx at end of transmission if initial mode is Rx/Tx */ + if(hsmartcard->Init.Mode == SMARTCARD_MODE_TX_RX) + { + /* Disable the Peripheral first to update modes */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + } + + /* Tx process is ended, restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + HAL_SMARTCARD_TxCpltCallback(hsmartcard); + + return HAL_OK; +} + +/** + * @brief Receive an amount of data in non-blocking mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * Function called under interruption only, once + * interruptions have been enabled by HAL_SMARTCARD_Receive_IT(). + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Check that a Rx process is ongoing */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_BUSY_RX) + { + *hsmartcard->pRxBuffPtr++ = (uint8_t)(hsmartcard->Instance->RDR & (uint8_t)0xFFU); + + if(--hsmartcard->RxXferCount == 0U) + { + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RXNEIE); + + /* Check if a transmit process is ongoing or not. If not disable ERR IT */ + if(hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Disable the SMARTCARD Parity Error Interrupt */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE); + + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + HAL_SMARTCARD_RxCpltCallback(hsmartcard); + + return HAL_OK; + } + + return HAL_OK; + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_SMARTCARD_SEND_REQ(hsmartcard, SMARTCARD_RXDATA_FLUSH_REQUEST); + + return HAL_BUSY; + } +} /** * @} */ #endif /* HAL_SMARTCARD_MODULE_ENABLED */ +/** + * @} + */ /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard.h index d7b86640a6..6c02d079c7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_smartcard.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of SMARTCARD HAL module. ****************************************************************************** * @attention @@ -50,83 +48,85 @@ * @{ */ -/** @defgroup SMARTCARD SMARTCARD +/** @addtogroup SMARTCARD * @{ */ + +/* Exported types ------------------------------------------------------------*/ /** @defgroup SMARTCARD_Exported_Types SMARTCARD Exported Types * @{ */ -/* Exported types ------------------------------------------------------------*/ -/** + +/** * @brief SMARTCARD Init Structure definition */ typedef struct { uint32_t BaudRate; /*!< Configures the SmartCard communication baud rate. The baud rate register is computed using the following formula: - Baud Rate Register = ((PCLKx) / ((hsc->Init.BaudRate))) */ - + Baud Rate Register = ((PCLKx) / ((hsmartcard->Init.BaudRate))) */ + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. This parameter @ref SMARTCARD_Word_Length can only be set to 9 (8 data + 1 parity bits). */ - uint32_t StopBits; /*!< Specifies the number of stop bits @ref SMARTCARD_Stop_Bits. - Only 0.5 or 1.5 stop bits are authorized in SmartCard mode. */ + uint32_t StopBits; /*!< Specifies the number of stop bits. + This parameter can be a value of @ref SMARTCARD_Stop_Bits. */ - uint32_t Parity; /*!< Specifies the parity mode. + uint16_t Parity; /*!< Specifies the parity mode. This parameter can be a value of @ref SMARTCARD_Parity @note The parity is enabled by default (PCE is forced to 1). Since the WordLength is forced to 8 bits + parity, M is forced to 1 and the parity bit is the 9th bit. */ - - uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + + uint16_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. This parameter can be a value of @ref SMARTCARD_Mode */ - uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock. + uint16_t CLKPolarity; /*!< Specifies the steady state of the serial clock. This parameter can be a value of @ref SMARTCARD_Clock_Polarity */ - uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made. + uint16_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made. This parameter can be a value of @ref SMARTCARD_Clock_Phase */ - uint32_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted + uint16_t CLKLastBit; /*!< 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 SMARTCARD_Last_Bit */ - - uint32_t OneBitSampling; /*!< Specifies wether a single sample or three samples' majority vote is selected. - Selecting the single sample method increases the receiver tolerance to clock - deviations. This parameter can be a value of @ref SMARTCARD_OneBit_Sampling */ - uint32_t Prescaler; /*!< Specifies the SmartCard Prescaler */ - - uint32_t GuardTime; /*!< Specifies the SmartCard Guard Time */ - - uint32_t NACKState; /*!< Specifies whether the SmartCard NACK transmission is enabled - in case of parity error. - This parameter can be a value of @ref SMARTCARD_NACK_Enable */ - - uint32_t TimeOutEnable; /*!< Specifies whether the receiver timeout is enabled. + uint16_t OneBitSampling; /*!< Specifies whether a single sample or three samples' majority vote is selected. + Selecting the single sample method increases the receiver tolerance to clock + deviations. This parameter can be a value of @ref SMARTCARD_OneBit_Sampling. */ + + uint8_t Prescaler; /*!< Specifies the SmartCard Prescaler. */ + + uint8_t GuardTime; /*!< Specifies the SmartCard Guard Time applied after stop bits. */ + + uint16_t NACKEnable; /*!< Specifies whether the SmartCard NACK transmission is enabled + in case of parity error. + This parameter can be a value of @ref SMARTCARD_NACK_Enable */ + + uint32_t TimeOutEnable; /*!< Specifies whether the receiver timeout is enabled. This parameter can be a value of @ref SMARTCARD_Timeout_Enable*/ - - uint32_t TimeOutValue; /*!< Specifies the receiver time out value in number of baud blocks: - it is used to implement the Character Wait Time (CWT) and - Block Wait Time (BWT). It is coded over 24 bits. */ - - uint32_t BlockLength; /*!< Specifies the SmartCard Block Length in T=1 Reception mode. - This parameter can be any value from 0x0 to 0xFF */ - - uint32_t AutoRetryCount; /*!< Specifies the SmartCard auto-retry count (number of retries in - receive and transmit mode). When set to 0, retransmission is - disabled. Otherwise, its maximum value is 7 (before signalling - an error) */ + + uint32_t TimeOutValue; /*!< Specifies the receiver time out value in number of baud blocks: + it is used to implement the Character Wait Time (CWT) and + Block Wait Time (BWT). It is coded over 24 bits. */ + + uint8_t BlockLength; /*!< Specifies the SmartCard Block Length in T=1 Reception mode. + This parameter can be any value from 0x0 to 0xFF */ + + uint8_t AutoRetryCount; /*!< Specifies the SmartCard auto-retry count (number of retries in + receive and transmit mode). When set to 0, retransmission is + disabled. Otherwise, its maximum value is 7 (before signalling + an error) */ }SMARTCARD_InitTypeDef; -/** - * @brief SMARTCARD advanced features initalization structure definition +/** + * @brief SMARTCARD advanced features initalization structure definition */ typedef struct { uint32_t AdvFeatureInit; /*!< Specifies which advanced SMARTCARD features is initialized. Several - advanced features may be initialized at the same time. This parameter + advanced features may be initialized at the same time. This parameter can be a value of @ref SMARTCARD_Advanced_Features_Initialization_Type */ uint32_t TxPinLevelInvert; /*!< Specifies whether the TX pin active level is inverted. @@ -139,148 +139,187 @@ typedef struct vs negative/inverted logic). This parameter can be a value of @ref SMARTCARD_Data_Inv */ - uint32_t Swap; /*!< Specifies whether TX and RX pins are swapped. + uint32_t Swap; /*!< Specifies whether TX and RX pins are swapped. This parameter can be a value of @ref SMARTCARD_Rx_Tx_Swap */ - uint32_t OverrunDisable; /*!< Specifies whether the reception overrun detection is disabled. + uint32_t OverrunDisable; /*!< Specifies whether the reception overrun detection is disabled. This parameter can be a value of @ref SMARTCARD_Overrun_Disable */ - uint32_t DMADisableonRxError; /*!< Specifies whether the DMA is disabled in case of reception error. + uint32_t DMADisableonRxError; /*!< Specifies whether the DMA is disabled in case of reception error. This parameter can be a value of @ref SMARTCARD_DMA_Disable_on_Rx_Error */ - uint32_t MSBFirst; /*!< Specifies whether MSB is sent first on UART line. + uint32_t MSBFirst; /*!< Specifies whether MSB is sent first on UART line. This parameter can be a value of @ref SMARTCARD_MSB_First */ }SMARTCARD_AdvFeatureInitTypeDef; -/** - * @brief HAL State structures definition - */ -typedef enum -{ - HAL_SMARTCARD_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ - HAL_SMARTCARD_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ - HAL_SMARTCARD_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */ - HAL_SMARTCARD_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */ - HAL_SMARTCARD_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ - HAL_SMARTCARD_STATE_BUSY_TX_RX = 0x32U, /*!< Data Transmission and Reception process is ongoing */ - HAL_SMARTCARD_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ - HAL_SMARTCARD_STATE_ERROR = 0x04U /*!< Error */ -}HAL_SMARTCARD_StateTypeDef; - - - /** - * @brief SMARTCARD clock sources definition + * @brief HAL SMARTCARD State structures definition + * @note HAL SMARTCARD State value is a combination of 2 different substates: gState and RxState. + * - gState contains SMARTCARD state information related to global Handle management + * and also information related to Tx operations. + * gState value coding follow below described bitmap : + * b7-b6 Error information + * 00 : No Error + * 01 : (Not Used) + * 10 : Timeout + * 11 : Error + * b5 IP initilisation status + * 0 : Reset (IP not initialized) + * 1 : Init done (IP not initialized. HAL SMARTCARD Init function already called) + * b4-b3 (not used) + * xx : Should be set to 00 + * b2 Intrinsic process state + * 0 : Ready + * 1 : Busy (IP busy with some configuration or internal operations) + * b1 (not used) + * x : Should be set to 0 + * b0 Tx state + * 0 : Ready (no Tx operation ongoing) + * 1 : Busy (Tx operation ongoing) + * - RxState contains information related to Rx operations. + * RxState value coding follow below described bitmap : + * b7-b6 (not used) + * xx : Should be set to 00 + * b5 IP initilisation status + * 0 : Reset (IP not initialized) + * 1 : Init done (IP not initialized) + * b4-b2 (not used) + * xxx : Should be set to 000 + * b1 Rx state + * 0 : Ready (no Rx operation ongoing) + * 1 : Busy (Rx operation ongoing) + * b0 (not used) + * x : Should be set to 0. */ typedef enum { - SMARTCARD_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ - SMARTCARD_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ - SMARTCARD_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ - SMARTCARD_CLOCKSOURCE_SYSCLK = 0x04U, /*!< SYSCLK clock source */ - SMARTCARD_CLOCKSOURCE_LSE = 0x08U /*!< LSE clock source */ -}SMARTCARD_ClockSourceTypeDef; + HAL_SMARTCARD_STATE_RESET = 0x00U, /*!< Peripheral is not initialized + Value is allowed for gState and RxState */ + HAL_SMARTCARD_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use + Value is allowed for gState and RxState */ + HAL_SMARTCARD_STATE_BUSY = 0x24U, /*!< an internal process is ongoing + Value is allowed for gState only */ + HAL_SMARTCARD_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing + Value is allowed for gState only */ + HAL_SMARTCARD_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing + Value is allowed for RxState only */ + HAL_SMARTCARD_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing + Not to be used for neither gState nor RxState. + Value is result of combination (Or) between gState and RxState values */ + HAL_SMARTCARD_STATE_TIMEOUT = 0xA0U, /*!< Timeout state + Value is allowed for gState only */ + HAL_SMARTCARD_STATE_ERROR = 0xE0U /*!< Error + Value is allowed for gState only */ +}HAL_SMARTCARD_StateTypeDef; -/** +/** + * @brief HAL SMARTCARD Error Code structure definition + */ +typedef enum +{ + HAL_SMARTCARD_ERROR_NONE = 0x00, /*!< No error */ + HAL_SMARTCARD_ERROR_PE = 0x01, /*!< Parity error */ + HAL_SMARTCARD_ERROR_NE = 0x02, /*!< Noise error */ + HAL_SMARTCARD_ERROR_FE = 0x04, /*!< frame error */ + HAL_SMARTCARD_ERROR_ORE = 0x08, /*!< Overrun error */ + HAL_SMARTCARD_ERROR_DMA = 0x10, /*!< DMA transfer error */ + HAL_SMARTCARD_ERROR_RTO = 0x20 /*!< Receiver TimeOut error */ +}HAL_SMARTCARD_ErrorTypeDef; + +/** * @brief SMARTCARD handle Structure definition */ typedef struct { - USART_TypeDef *Instance; /* USART registers base address */ + USART_TypeDef *Instance; /*!< USART registers base address */ - SMARTCARD_InitTypeDef Init; /* SmartCard communication parameters */ + SMARTCARD_InitTypeDef Init; /*!< SmartCard communication parameters */ - SMARTCARD_AdvFeatureInitTypeDef AdvancedInit; /* SmartCard advanced features initialization parameters */ + SMARTCARD_AdvFeatureInitTypeDef AdvancedInit; /*!< SmartCard advanced features initialization parameters */ - uint8_t *pTxBuffPtr; /* Pointer to SmartCard Tx transfer Buffer */ + uint8_t *pTxBuffPtr; /*!< Pointer to SmartCard Tx transfer Buffer */ - uint16_t TxXferSize; /* SmartCard Tx Transfer size */ + uint16_t TxXferSize; /*!< SmartCard Tx Transfer size */ - uint16_t TxXferCount; /* SmartCard Tx Transfer Counter */ + __IO uint16_t TxXferCount; /*!< SmartCard Tx Transfer Counter */ - uint8_t *pRxBuffPtr; /* Pointer to SmartCard Rx transfer Buffer */ + uint8_t *pRxBuffPtr; /*!< Pointer to SmartCard Rx transfer Buffer */ - uint16_t RxXferSize; /* SmartCard Rx Transfer size */ + uint16_t RxXferSize; /*!< SmartCard Rx Transfer size */ - uint16_t RxXferCount; /* SmartCard Rx Transfer Counter */ + __IO uint16_t RxXferCount; /*!< SmartCard Rx Transfer Counter */ - DMA_HandleTypeDef *hdmatx; /* SmartCard Tx DMA Handle parameters */ + DMA_HandleTypeDef *hdmatx; /*!< SmartCard Tx DMA Handle parameters */ - DMA_HandleTypeDef *hdmarx; /* SmartCard Rx DMA Handle parameters */ + DMA_HandleTypeDef *hdmarx; /*!< SmartCard Rx DMA Handle parameters */ - HAL_LockTypeDef Lock; /* Locking object */ + HAL_LockTypeDef Lock; /*!< Locking object */ - __IO HAL_SMARTCARD_StateTypeDef State; /* SmartCard communication state */ + __IO HAL_SMARTCARD_StateTypeDef gState; /*!< SmartCard state information related to global Handle management + and also related to Tx operations. + This parameter can be a value of @ref HAL_SMARTCARD_StateTypeDef */ - __IO uint32_t ErrorCode; /* SmartCard Error code */ + __IO HAL_SMARTCARD_StateTypeDef RxState; /*!< SmartCard state information related to Rx operations. + This parameter can be a value of @ref HAL_SMARTCARD_StateTypeDef */ + + __IO uint32_t ErrorCode; /*!< SmartCard Error code */ }SMARTCARD_HandleTypeDef; +/** + * @brief SMARTCARD clock sources + */ +typedef enum +{ + SMARTCARD_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ + SMARTCARD_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ + SMARTCARD_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ + SMARTCARD_CLOCKSOURCE_SYSCLK = 0x04U, /*!< SYSCLK clock source */ + SMARTCARD_CLOCKSOURCE_LSE = 0x08U, /*!< LSE clock source */ + SMARTCARD_CLOCKSOURCE_UNDEFINED = 0x10U /*!< undefined clock source */ +}SMARTCARD_ClockSourceTypeDef; + /** * @} */ /* Exported constants --------------------------------------------------------*/ -/** @defgroup SMARTCARD_Exported_Constants SMARTCARD Exported Constants +/** @defgroup SMARTCARD_Exported_Constants SMARTCARD Exported Constants * @{ */ -/** - * @brief HAL SMARTCARD Error Code definition - */ -/** @defgroup SMARTCARD_Error_Code SMARTCARD Error Code - * @{ - */ -#define HAL_SMARTCARD_ERROR_NONE ((uint32_t)0x00U) /*!< No error */ -#define HAL_SMARTCARD_ERROR_PE ((uint32_t)0x01U) /*!< Parity error */ -#define HAL_SMARTCARD_ERROR_NE ((uint32_t)0x02U) /*!< Noise error */ -#define HAL_SMARTCARD_ERROR_FE ((uint32_t)0x04U) /*!< frame error */ -#define HAL_SMARTCARD_ERROR_ORE ((uint32_t)0x08U) /*!< Overrun error */ -#define HAL_SMARTCARD_ERROR_DMA ((uint32_t)0x10U) /*!< DMA transfer error */ -#define HAL_SMARTCARD_ERROR_RTO ((uint32_t)0x20U) /*!< Receiver TimeOut error */ - -/** - * @} - */ - /** @defgroup SMARTCARD_Word_Length SMARTCARD Word Length * @{ */ -#define SMARTCARD_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) -#define IS_SMARTCARD_WORD_LENGTH(LENGTH) ((LENGTH) == SMARTCARD_WORDLENGTH_9B) +#define SMARTCARD_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) /*!< SMARTCARD frame length */ /** * @} */ - -/** @defgroup SMARTCARD_Stop_Bits SMARTCARD Stop Bits + +/** @defgroup SMARTCARD_Stop_Bits SMARTCARD Number of Stop Bits * @{ */ -#define SMARTCARD_STOPBITS_0_5 ((uint32_t)(USART_CR2_STOP_0)) -#define SMARTCARD_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP)) -#define IS_SMARTCARD_STOPBITS(STOPBITS) (((STOPBITS) == SMARTCARD_STOPBITS_0_5) || \ - ((STOPBITS) == SMARTCARD_STOPBITS_1_5)) +#define SMARTCARD_STOPBITS_0_5 ((uint32_t)USART_CR2_STOP_0) /*!< SMARTCARD frame with 0.5 stop bit */ +#define SMARTCARD_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP_0 | USART_CR2_STOP_1)) /*!< SMARTCARD frame with 1.5 stop bits */ /** * @} - */ + */ /** @defgroup SMARTCARD_Parity SMARTCARD Parity * @{ - */ -#define SMARTCARD_PARITY_EVEN ((uint32_t)USART_CR1_PCE) -#define SMARTCARD_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) -#define IS_SMARTCARD_PARITY(PARITY) (((PARITY) == SMARTCARD_PARITY_EVEN) || \ - ((PARITY) == SMARTCARD_PARITY_ODD)) + */ +#define SMARTCARD_PARITY_EVEN ((uint32_t)USART_CR1_PCE) /*!< SMARTCARD frame even parity */ +#define SMARTCARD_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) /*!< SMARTCARD frame odd parity */ /** * @} - */ + */ -/** @defgroup SMARTCARD_Mode SMARTCARD Mode +/** @defgroup SMARTCARD_Mode SMARTCARD Transfer Mode * @{ - */ -#define SMARTCARD_MODE_RX ((uint32_t)USART_CR1_RE) -#define SMARTCARD_MODE_TX ((uint32_t)USART_CR1_TE) -#define SMARTCARD_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) -#define IS_SMARTCARD_MODE(MODE) ((((MODE) & (uint32_t)0xFFF3) == 0x00) && ((MODE) != (uint32_t)0x00)) + */ +#define SMARTCARD_MODE_RX ((uint32_t)USART_CR1_RE) /*!< SMARTCARD RX mode */ +#define SMARTCARD_MODE_TX ((uint32_t)USART_CR1_TE) /*!< SMARTCARD TX mode */ +#define SMARTCARD_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) /*!< SMARTCARD RX and TX mode */ /** * @} */ @@ -288,19 +327,17 @@ typedef struct /** @defgroup SMARTCARD_Clock_Polarity SMARTCARD Clock Polarity * @{ */ -#define SMARTCARD_POLARITY_LOW ((uint32_t)0x0000U) -#define SMARTCARD_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL) -#define IS_SMARTCARD_POLARITY(CPOL) (((CPOL) == SMARTCARD_POLARITY_LOW) || ((CPOL) == SMARTCARD_POLARITY_HIGH)) +#define SMARTCARD_POLARITY_LOW ((uint32_t)0x00000000) /*!< SMARTCARD frame low polarity */ +#define SMARTCARD_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL) /*!< SMARTCARD frame high polarity */ /** * @} - */ + */ /** @defgroup SMARTCARD_Clock_Phase SMARTCARD Clock Phase * @{ */ -#define SMARTCARD_PHASE_1EDGE ((uint32_t)0x0000U) -#define SMARTCARD_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA) -#define IS_SMARTCARD_PHASE(CPHA) (((CPHA) == SMARTCARD_PHASE_1EDGE) || ((CPHA) == SMARTCARD_PHASE_2EDGE)) +#define SMARTCARD_PHASE_1EDGE ((uint32_t)0x00000000) /*!< SMARTCARD frame phase on first clock transition */ +#define SMARTCARD_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA) /*!< SMARTCARD frame phase on second clock transition */ /** * @} */ @@ -308,33 +345,27 @@ typedef struct /** @defgroup SMARTCARD_Last_Bit SMARTCARD Last Bit * @{ */ -#define SMARTCARD_LASTBIT_DISABLE ((uint32_t)0x0000U) -#define SMARTCARD_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL) -#define IS_SMARTCARD_LASTBIT(LASTBIT) (((LASTBIT) == SMARTCARD_LASTBIT_DISABLE) || \ - ((LASTBIT) == SMARTCARD_LASTBIT_ENABLE)) +#define SMARTCARD_LASTBIT_DISABLE ((uint32_t)0x00000000) /*!< SMARTCARD frame last data bit clock pulse not output to SCLK pin */ +#define SMARTCARD_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL) /*!< SMARTCARD frame last data bit clock pulse output to SCLK pin */ /** * @} */ -/** @defgroup SMARTCARD_OneBit_Sampling SMARTCARD OneBit Sampling +/** @defgroup SMARTCARD_OneBit_Sampling SMARTCARD One Bit Sampling Method * @{ */ -#define SMARTCARD_ONE_BIT_SAMPLE_DISABLE ((uint32_t)0x0000U) -#define SMARTCARD_ONE_BIT_SAMPLE_ENABLE ((uint32_t)USART_CR3_ONEBIT) -#define IS_SMARTCARD_ONE_BIT_SAMPLE(ONEBIT) (((ONEBIT) == SMARTCARD_ONE_BIT_SAMPLE_DISABLE) || \ - ((ONEBIT) == SMARTCARD_ONE_BIT_SAMPLE_ENABLE)) +#define SMARTCARD_ONE_BIT_SAMPLE_DISABLE ((uint32_t)0x00000000) /*!< SMARTCARD frame one-bit sample disabled */ +#define SMARTCARD_ONE_BIT_SAMPLE_ENABLE ((uint32_t)USART_CR3_ONEBIT) /*!< SMARTCARD frame one-bit sample enabled */ /** * @} - */ + */ /** @defgroup SMARTCARD_NACK_Enable SMARTCARD NACK Enable * @{ */ -#define SMARTCARD_NACK_ENABLE ((uint32_t)USART_CR3_NACK) -#define SMARTCARD_NACK_DISABLE ((uint32_t)0x0000U) -#define IS_SMARTCARD_NACK(NACK) (((NACK) == SMARTCARD_NACK_ENABLE) || \ - ((NACK) == SMARTCARD_NACK_DISABLE)) +#define SMARTCARD_NACK_ENABLE ((uint32_t)USART_CR3_NACK) /*!< SMARTCARD NACK transmission disabled */ +#define SMARTCARD_NACK_DISABLE ((uint32_t)0x00000000) /*!< SMARTCARD NACK transmission enabled */ /** * @} */ @@ -342,21 +373,18 @@ typedef struct /** @defgroup SMARTCARD_Timeout_Enable SMARTCARD Timeout Enable * @{ */ -#define SMARTCARD_TIMEOUT_DISABLE ((uint32_t)0x00000000U) -#define SMARTCARD_TIMEOUT_ENABLE ((uint32_t)USART_CR2_RTOEN) -#define IS_SMARTCARD_TIMEOUT(TIMEOUT) (((TIMEOUT) == SMARTCARD_TIMEOUT_DISABLE) || \ - ((TIMEOUT) == SMARTCARD_TIMEOUT_ENABLE)) +#define SMARTCARD_TIMEOUT_DISABLE ((uint32_t)0x00000000) /*!< SMARTCARD receiver timeout disabled */ +#define SMARTCARD_TIMEOUT_ENABLE ((uint32_t)USART_CR2_RTOEN) /*!< SMARTCARD receiver timeout enabled */ /** * @} */ - + /** @defgroup SMARTCARD_DMA_Requests SMARTCARD DMA Requests * @{ */ #define SMARTCARD_DMAREQ_TX ((uint32_t)USART_CR3_DMAT) #define SMARTCARD_DMAREQ_RX ((uint32_t)USART_CR3_DMAR) - /** * @} */ @@ -372,94 +400,82 @@ typedef struct #define SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT ((uint32_t)0x00000010U) #define SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT ((uint32_t)0x00000020U) #define SMARTCARD_ADVFEATURE_MSBFIRST_INIT ((uint32_t)0x00000080U) -#define IS_SMARTCARD_ADVFEATURE_INIT(INIT) ((INIT) <= (SMARTCARD_ADVFEATURE_NO_INIT | \ - SMARTCARD_ADVFEATURE_TXINVERT_INIT | \ - SMARTCARD_ADVFEATURE_RXINVERT_INIT | \ - SMARTCARD_ADVFEATURE_DATAINVERT_INIT | \ - SMARTCARD_ADVFEATURE_SWAP_INIT | \ - SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ - SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT | \ - SMARTCARD_ADVFEATURE_MSBFIRST_INIT)) /** * @} */ -/** @defgroup SMARTCARD_Tx_Inv SMARTCARD Tx Inv +/** @defgroup SMARTCARD_Tx_Inv SMARTCARD advanced feature TX pin active level inversion * @{ */ -#define SMARTCARD_ADVFEATURE_TXINV_DISABLE ((uint32_t)0x00000000U) -#define SMARTCARD_ADVFEATURE_TXINV_ENABLE ((uint32_t)USART_CR2_TXINV) -#define IS_SMARTCARD_ADVFEATURE_TXINV(TXINV) (((TXINV) == SMARTCARD_ADVFEATURE_TXINV_DISABLE) || \ - ((TXINV) == SMARTCARD_ADVFEATURE_TXINV_ENABLE)) +#define SMARTCARD_ADVFEATURE_TXINV_DISABLE ((uint32_t)0x00000000U) /*!< TX pin active level inversion disable */ +#define SMARTCARD_ADVFEATURE_TXINV_ENABLE ((uint32_t)USART_CR2_TXINV) /*!< TX pin active level inversion enable */ /** * @} */ -/** @defgroup SMARTCARD_Rx_Inv SMARTCARD Rx Inv +/** @defgroup SMARTCARD_Rx_Inv SMARTCARD advanced feature RX pin active level inversion * @{ */ -#define SMARTCARD_ADVFEATURE_RXINV_DISABLE ((uint32_t)0x00000000U) -#define SMARTCARD_ADVFEATURE_RXINV_ENABLE ((uint32_t)USART_CR2_RXINV) -#define IS_SMARTCARD_ADVFEATURE_RXINV(RXINV) (((RXINV) == SMARTCARD_ADVFEATURE_RXINV_DISABLE) || \ - ((RXINV) == SMARTCARD_ADVFEATURE_RXINV_ENABLE)) +#define SMARTCARD_ADVFEATURE_RXINV_DISABLE ((uint32_t)0x00000000U) /*!< RX pin active level inversion disable */ +#define SMARTCARD_ADVFEATURE_RXINV_ENABLE ((uint32_t)USART_CR2_RXINV) /*!< RX pin active level inversion enable */ /** * @} */ -/** @defgroup SMARTCARD_Data_Inv SMARTCARD Data Inv +/** @defgroup SMARTCARD_Data_Inv SMARTCARD advanced feature Binary Data inversion * @{ */ -#define SMARTCARD_ADVFEATURE_DATAINV_DISABLE ((uint32_t)0x00000000U) -#define SMARTCARD_ADVFEATURE_DATAINV_ENABLE ((uint32_t)USART_CR2_DATAINV) -#define IS_SMARTCARD_ADVFEATURE_DATAINV(DATAINV) (((DATAINV) == SMARTCARD_ADVFEATURE_DATAINV_DISABLE) || \ - ((DATAINV) == SMARTCARD_ADVFEATURE_DATAINV_ENABLE)) +#define SMARTCARD_ADVFEATURE_DATAINV_DISABLE ((uint32_t)0x00000000U) /*!< Binary data inversion disable */ +#define SMARTCARD_ADVFEATURE_DATAINV_ENABLE ((uint32_t)USART_CR2_DATAINV) /*!< Binary data inversion enable */ /** * @} - */ - -/** @defgroup SMARTCARD_Rx_Tx_Swap SMARTCARD Rx Tx Swap - * @{ */ -#define SMARTCARD_ADVFEATURE_SWAP_DISABLE ((uint32_t)0x00000000U) -#define SMARTCARD_ADVFEATURE_SWAP_ENABLE ((uint32_t)USART_CR2_SWAP) -#define IS_SMARTCARD_ADVFEATURE_SWAP(SWAP) (((SWAP) == SMARTCARD_ADVFEATURE_SWAP_DISABLE) || \ - ((SWAP) == SMARTCARD_ADVFEATURE_SWAP_ENABLE)) -/** - * @} - */ -/** @defgroup SMARTCARD_Overrun_Disable SMARTCARD Overrun Enabling +/** @defgroup SMARTCARD_Rx_Tx_Swap SMARTCARD advanced feature RX TX pins swap * @{ */ -#define SMARTCARD_ADVFEATURE_OVERRUN_ENABLE ((uint32_t)0x00000000U) -#define SMARTCARD_ADVFEATURE_OVERRUN_DISABLE ((uint32_t)USART_CR3_OVRDIS) -#define IS_SMARTCARD_OVERRUN(OVERRUN) (((OVERRUN) == SMARTCARD_ADVFEATURE_OVERRUN_ENABLE) || \ - ((OVERRUN) == SMARTCARD_ADVFEATURE_OVERRUN_DISABLE)) +#define SMARTCARD_ADVFEATURE_SWAP_DISABLE ((uint32_t)0x00000000U) /*!< TX/RX pins swap disable */ +#define SMARTCARD_ADVFEATURE_SWAP_ENABLE ((uint32_t)USART_CR2_SWAP) /*!< TX/RX pins swap enable */ /** * @} - */ + */ -/** @defgroup SMARTCARD_DMA_Disable_on_Rx_Error SMARTCARD DMA on Rx Error +/** @defgroup SMARTCARD_Overrun_Disable SMARTCARD advanced feature Overrun Disable * @{ */ -#define SMARTCARD_ADVFEATURE_DMA_ENABLEONRXERROR ((uint32_t)0x00000000U) -#define SMARTCARD_ADVFEATURE_DMA_DISABLEONRXERROR ((uint32_t)USART_CR3_DDRE) -#define IS_SMARTCARD_ADVFEATURE_DMAONRXERROR(DMA) (((DMA) == SMARTCARD_ADVFEATURE_DMA_ENABLEONRXERROR) || \ - ((DMA) == SMARTCARD_ADVFEATURE_DMA_DISABLEONRXERROR)) +#define SMARTCARD_ADVFEATURE_OVERRUN_ENABLE ((uint32_t)0x00000000U) /*!< RX overrun enable */ +#define SMARTCARD_ADVFEATURE_OVERRUN_DISABLE ((uint32_t)USART_CR3_OVRDIS) /*!< RX overrun disable */ /** * @} - */ + */ -/** @defgroup SMARTCARD_MSB_First SMARTCARD MSB First +/** @defgroup SMARTCARD_DMA_Disable_on_Rx_Error SMARTCARD advanced feature DMA Disable on Rx Error * @{ */ -#define SMARTCARD_ADVFEATURE_MSBFIRST_DISABLE ((uint32_t)0x00000000U) -#define SMARTCARD_ADVFEATURE_MSBFIRST_ENABLE ((uint32_t)USART_CR2_MSBFIRST) -#define IS_SMARTCARD_ADVFEATURE_MSBFIRST(MSBFIRST) (((MSBFIRST) == SMARTCARD_ADVFEATURE_MSBFIRST_DISABLE) || \ - ((MSBFIRST) == SMARTCARD_ADVFEATURE_MSBFIRST_ENABLE)) +#define SMARTCARD_ADVFEATURE_DMA_ENABLEONRXERROR ((uint32_t)0x00000000U) /*!< DMA enable on Reception Error */ +#define SMARTCARD_ADVFEATURE_DMA_DISABLEONRXERROR ((uint32_t)USART_CR3_DDRE) /*!< DMA disable on Reception Error */ /** * @} - */ + */ + +/** @defgroup SMARTCARD_MSB_First SMARTCARD advanced feature MSB first + * @{ + */ +#define SMARTCARD_ADVFEATURE_MSBFIRST_DISABLE ((uint32_t)0x00000000U) /*!< Most significant bit sent/received first disable */ +#define SMARTCARD_ADVFEATURE_MSBFIRST_ENABLE ((uint32_t)USART_CR2_MSBFIRST) /*!< Most significant bit sent/received first enable */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Request_Parameters SMARTCARD Request Parameters + * @{ + */ +#define SMARTCARD_RXDATA_FLUSH_REQUEST ((uint16_t)USART_RQR_RXFRQ) /*!< Receive data flush request */ +#define SMARTCARD_TXDATA_FLUSH_REQUEST ((uint16_t)USART_RQR_TXFRQ) /*!< Transmit data flush request */ +/** + * @} + */ + /** @defgroup SMARTCARD_Flags SMARTCARD Flags * Elements values convention: 0xXXXX @@ -528,67 +544,57 @@ typedef struct * @} */ -/** @defgroup SMARTCARD_Request_Parameters SMARTCARD Request Parameters - * @{ - */ -#define SMARTCARD_RXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_RXFRQ) /*!< Receive Data flush Request */ -#define SMARTCARD_TXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_TXFRQ) /*!< Transmit data flush Request */ -#define IS_SMARTCARD_REQUEST_PARAMETER(PARAM) (((PARAM) == SMARTCARD_RXDATA_FLUSH_REQUEST) || \ - ((PARAM) == SMARTCARD_TXDATA_FLUSH_REQUEST)) -/** - * @} - */ - - -/** @defgroup SMARTCARD_CR3_SCAR_CNT_LSB_POS SMARTCARD CR3 LSB Position +/** @defgroup SMARTCARD_CR3_SCARCNT_LSB_POS SMARTCARD auto retry counter LSB position in CR3 register * @{ */ -#define SMARTCARD_CR3_SCARCNT_LSB_POS ((uint32_t) 17U) +#define SMARTCARD_CR3_SCARCNT_LSB_POS ((uint32_t) 17U) /*!< SMARTCARD auto retry counter LSB position in CR3 register */ /** * @} */ - -/** @defgroup SMARTCARD_GTPR_GT_LSBPOS SMARTCARD GTPR GT LSB Position + +/** @defgroup SMARTCARD_GTPR_GT_LSB_POS SMARTCARD guard time value LSB position in GTPR register * @{ */ -#define SMARTCARD_GTPR_GT_LSB_POS ((uint32_t) 8U) -/** - * @} - */ - -/** @defgroup SMARTCARD_RTOR_BLEN_LSBPOS SMARTCARD RTOR BLEN LSB Position - * @{ - */ -#define SMARTCARD_RTOR_BLEN_LSB_POS ((uint32_t) 24U) -/** - * @} - */ - -/** @defgroup SMARTCARD_Interruption_Mask SMARTCARD Interruption Mask - * @{ - */ -#define SMARTCARD_IT_MASK ((uint16_t)0x001FU) +#define SMARTCARD_GTPR_GT_LSB_POS ((uint32_t) 8U) /*!< SMARTCARD guard time value LSB position in GTPR register */ /** * @} */ - + +/** @defgroup SMARTCARD_RTOR_BLEN_LSB_POS SMARTCARD block length LSB position in RTOR register + * @{ + */ +#define SMARTCARD_RTOR_BLEN_LSB_POS ((uint32_t) 24U) /*!< SMARTCARD block length LSB position in RTOR register */ /** * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/** @defgroup SMARTCARD_Exported_Macros SMARTCARD Exported Macros + */ + +/** @defgroup SMARTCARD_Interruption_Mask SMARTCARD interruptions flags mask + * @{ + */ +#define SMARTCARD_IT_MASK ((uint16_t)0x001FU) /*!< SMARTCARD interruptions flags mask */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup SMARTCARD_Exported_Macros SMARTCARD Exported Macros * @{ */ -/** @brief Reset SMARTCARD handle state - * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2 +/** @brief Reset SMARTCARD handle states. + * @param __HANDLE__: SMARTCARD handle. * @retval None */ -#define __HAL_SMARTCARD_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SMARTCARD_STATE_RESET) +#define __HAL_SMARTCARD_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_SMARTCARD_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_SMARTCARD_STATE_RESET; \ + } while(0) -/** @brief Flushs the Smartcard DR register +/** @brief Flush the Smartcard Data registers. * @param __HANDLE__: specifies the SMARTCARD Handle. * @retval None */ @@ -598,18 +604,18 @@ typedef struct SET_BIT((__HANDLE__)->Instance->RQR, SMARTCARD_TXDATA_FLUSH_REQUEST); \ } while(0) -/** @brief Clears the specified SMARTCARD pending flag. +/** @brief Clear the specified SMARTCARD pending flag. * @param __HANDLE__: specifies the SMARTCARD Handle. * @param __FLAG__: specifies the flag to check. * This parameter can be any combination of the following values: - * @arg SMARTCARD_CLEAR_PEF - * @arg SMARTCARD_CLEAR_FEF - * @arg SMARTCARD_CLEAR_NEF - * @arg SMARTCARD_CLEAR_OREF - * @arg SMARTCARD_CLEAR_IDLEF - * @arg SMARTCARD_CLEAR_TCF - * @arg SMARTCARD_CLEAR_RTOF - * @arg SMARTCARD_CLEAR_EOBF + * @arg @ref SMARTCARD_CLEAR_PEF Parity error clear flag + * @arg @ref SMARTCARD_CLEAR_FEF Framing error clear flag + * @arg @ref SMARTCARD_CLEAR_NEF Noise detected clear flag + * @arg @ref SMARTCARD_CLEAR_OREF OverRun error clear flag + * @arg @ref SMARTCARD_CLEAR_IDLEF Idle line detected clear flag + * @arg @ref SMARTCARD_CLEAR_TCF Transmission complete clear flag + * @arg @ref SMARTCARD_CLEAR_RTOF Receiver timeout clear flag + * @arg @ref SMARTCARD_CLEAR_EOBF End of block clear flag * @retval None */ #define __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) @@ -618,189 +624,180 @@ typedef struct * @param __HANDLE__: specifies the SMARTCARD Handle. * @retval None */ -#define __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__,SMARTCARD_CLEAR_PEF) +#define __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_PEF) /** @brief Clear the SMARTCARD FE pending flag. * @param __HANDLE__: specifies the SMARTCARD Handle. * @retval None */ -#define __HAL_SMARTCARD_CLEAR_FEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__,SMARTCARD_CLEAR_FEF) +#define __HAL_SMARTCARD_CLEAR_FEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_FEF) /** @brief Clear the SMARTCARD NE pending flag. * @param __HANDLE__: specifies the SMARTCARD Handle. * @retval None */ -#define __HAL_SMARTCARD_CLEAR_NEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__,SMARTCARD_CLEAR_NEF) +#define __HAL_SMARTCARD_CLEAR_NEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_NEF) /** @brief Clear the SMARTCARD ORE pending flag. * @param __HANDLE__: specifies the SMARTCARD Handle. * @retval None */ -#define __HAL_SMARTCARD_CLEAR_OREFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__,SMARTCARD_CLEAR_OREF) +#define __HAL_SMARTCARD_CLEAR_OREFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_OREF) /** @brief Clear the SMARTCARD IDLE pending flag. * @param __HANDLE__: specifies the SMARTCARD Handle. * @retval None */ -#define __HAL_SMARTCARD_CLEAR_IDLEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__,SMARTCARD_CLEAR_IDLEF) +#define __HAL_SMARTCARD_CLEAR_IDLEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_IDLEF) -/** @brief Checks whether the specified Smartcard flag is set or not. +/** @brief Check whether the specified Smartcard flag is set or not. * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. * @param __FLAG__: specifies the flag to check. * This parameter can be one of the following values: - * @arg SMARTCARD_FLAG_REACK: Receive enable ackowledge flag - * @arg SMARTCARD_FLAG_TEACK: Transmit enable ackowledge flag - * @arg SMARTCARD_FLAG_BUSY: Busy flag - * @arg SMARTCARD_FLAG_EOBF: End of block flag - * @arg SMARTCARD_FLAG_RTOF: Receiver timeout flag - * @arg SMARTCARD_FLAG_TXE: Transmit data register empty flag - * @arg SMARTCARD_FLAG_TC: Transmission Complete flag - * @arg SMARTCARD_FLAG_RXNE: Receive data register not empty flag - * @arg SMARTCARD_FLAG_IDLE: Idle line detection flag - * @arg SMARTCARD_FLAG_ORE: OverRun Error flag - * @arg SMARTCARD_FLAG_NE: Noise Error flag - * @arg SMARTCARD_FLAG_FE: Framing Error flag - * @arg SMARTCARD_FLAG_PE: Parity Error flag + * @arg @ref SMARTCARD_FLAG_REACK Receive enable acknowledge flag + * @arg @ref SMARTCARD_FLAG_TEACK Transmit enable acknowledge flag + * @arg @ref SMARTCARD_FLAG_BUSY Busy flag + * @arg @ref SMARTCARD_FLAG_EOBF End of block flag + * @arg @ref SMARTCARD_FLAG_RTOF Receiver timeout flag + * @arg @ref SMARTCARD_FLAG_TXE Transmit data register empty flag + * @arg @ref SMARTCARD_FLAG_TC Transmission complete flag + * @arg @ref SMARTCARD_FLAG_RXNE Receive data register not empty flag + * @arg @ref SMARTCARD_FLAG_IDLE Idle line detection flag + * @arg @ref SMARTCARD_FLAG_ORE Overrun error flag + * @arg @ref SMARTCARD_FLAG_NE Noise error flag + * @arg @ref SMARTCARD_FLAG_FE Framing error flag + * @arg @ref SMARTCARD_FLAG_PE Parity error flag * @retval The new state of __FLAG__ (TRUE or FALSE). */ #define __HAL_SMARTCARD_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) -/** @brief Enables the specified SmartCard interrupt. + +/** @brief Enable the specified SmartCard interrupt. * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. * @param __INTERRUPT__: specifies the SMARTCARD interrupt to enable. * This parameter can be one of the following values: - * @arg SMARTCARD_IT_EOB: End Of Block interrupt - * @arg SMARTCARD_IT_RTO: Receive TimeOut interrupt - * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt - * @arg SMARTCARD_IT_TC: Transmission complete interrupt - * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt - * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt - * @arg SMARTCARD_IT_PE: Parity Error interrupt - * @arg SMARTCARD_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @arg @ref SMARTCARD_IT_EOB End of block interrupt + * @arg @ref SMARTCARD_IT_RTO Receive timeout interrupt + * @arg @ref SMARTCARD_IT_TXE Transmit data register empty interrupt + * @arg @ref SMARTCARD_IT_TC Transmission complete interrupt + * @arg @ref SMARTCARD_IT_RXNE Receive data register not empty interrupt + * @arg @ref SMARTCARD_IT_IDLE Idle line detection interrupt + * @arg @ref SMARTCARD_IT_PE Parity error interrupt + * @arg @ref SMARTCARD_IT_ERR Error interrupt(frame error, noise error, overrun error) * @retval None */ #define __HAL_SMARTCARD_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 |= (1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK)))) -/** @brief Disables the specified SmartCard interrupt. + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK)))) + +/** @brief Disable the specified SmartCard interrupt. * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. - * @param __INTERRUPT__: specifies the SMARTCARD interrupt to enable. + * @param __INTERRUPT__: specifies the SMARTCARD interrupt to disable. * This parameter can be one of the following values: - * @arg SMARTCARD_IT_EOB: End Of Block interrupt - * @arg SMARTCARD_IT_RTO: Receive TimeOut interrupt - * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt - * @arg SMARTCARD_IT_TC: Transmission complete interrupt - * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt - * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt - * @arg SMARTCARD_IT_PE: Parity Error interrupt - * @arg SMARTCARD_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @arg @ref SMARTCARD_IT_EOB End of block interrupt + * @arg @ref SMARTCARD_IT_RTO Receive timeout interrupt + * @arg @ref SMARTCARD_IT_TXE Transmit data register empty interrupt + * @arg @ref SMARTCARD_IT_TC Transmission complete interrupt + * @arg @ref SMARTCARD_IT_RXNE Receive data register not empty interrupt + * @arg @ref SMARTCARD_IT_IDLE Idle line detection interrupt + * @arg @ref SMARTCARD_IT_PE Parity error interrupt + * @arg @ref SMARTCARD_IT_ERR Error interrupt(frame error, noise error, overrun error) * @retval None */ -#define __HAL_SMARTCARD_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 &= ~ ((uint32_t)1 << ((__INTERRUPT__) & SMARTCARD_IT_MASK)))) +#define __HAL_SMARTCARD_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 &= ~ (1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 &= ~ (1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 &= ~ (1U << ((__INTERRUPT__) & SMARTCARD_IT_MASK)))) -/** @brief Checks whether the specified SmartCard interrupt has occurred or not. + +/** @brief Check whether the specified SmartCard interrupt has occurred or not. * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. * @param __IT__: specifies the SMARTCARD interrupt to check. * This parameter can be one of the following values: - * @arg SMARTCARD_IT_EOB: End Of Block interrupt - * @arg SMARTCARD_IT_RTO: Receive TimeOut interrupt - * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt - * @arg SMARTCARD_IT_TC: Transmission complete interrupt - * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt - * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt - * @arg SMARTCARD_IT_ORE: OverRun Error interrupt - * @arg SMARTCARD_IT_NE: Noise Error interrupt - * @arg SMARTCARD_IT_FE: Framing Error interrupt - * @arg SMARTCARD_IT_PE: Parity Error interrupt + * @arg @ref SMARTCARD_IT_EOB End of block interrupt + * @arg @ref SMARTCARD_IT_RTO Receive timeout interrupt + * @arg @ref SMARTCARD_IT_TXE Transmit data register empty interrupt + * @arg @ref SMARTCARD_IT_TC Transmission complete interrupt + * @arg @ref SMARTCARD_IT_RXNE Receive data register not empty interrupt + * @arg @ref SMARTCARD_IT_IDLE Idle line detection interrupt + * @arg @ref SMARTCARD_IT_ORE Overrun error interrupt + * @arg @ref SMARTCARD_IT_NE Noise error interrupt + * @arg @ref SMARTCARD_IT_FE Framing error interrupt + * @arg @ref SMARTCARD_IT_PE Parity error interrupt * @retval The new state of __IT__ (TRUE or FALSE). */ #define __HAL_SMARTCARD_GET_IT(__HANDLE__, __IT__) ((__HANDLE__)->Instance->ISR & ((uint32_t)1U << ((__IT__)>> 0x08U))) -/** @brief Checks whether the specified SmartCard interrupt interrupt source is enabled. +/** @brief Check whether the specified SmartCard interrupt source is enabled or not. * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. * @param __IT__: specifies the SMARTCARD interrupt source to check. * This parameter can be one of the following values: - * @arg SMARTCARD_IT_EOB: End Of Block interrupt - * @arg SMARTCARD_IT_RTO: Receive TimeOut interrupt - * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt - * @arg SMARTCARD_IT_TC: Transmission complete interrupt - * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt - * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt - * @arg SMARTCARD_IT_ORE: OverRun Error interrupt - * @arg SMARTCARD_IT_NE: Noise Error interrupt - * @arg SMARTCARD_IT_FE: Framing Error interrupt - * @arg SMARTCARD_IT_PE: Parity Error interrupt + * @arg @ref SMARTCARD_IT_EOB End of block interrupt + * @arg @ref SMARTCARD_IT_RTO Receive timeout interrupt + * @arg @ref SMARTCARD_IT_TXE Transmit data register empty interrupt + * @arg @ref SMARTCARD_IT_TC Transmission complete interrupt + * @arg @ref SMARTCARD_IT_RXNE Receive data register not empty interrupt + * @arg @ref SMARTCARD_IT_IDLE Idle line detection interrupt + * @arg @ref SMARTCARD_IT_ERR Framing, overrun or noise error interrupt + * @arg @ref SMARTCARD_IT_PE Parity error interrupt * @retval The new state of __IT__ (TRUE or FALSE). */ -#define __HAL_SMARTCARD_GET_IT_SOURCE(__HANDLE__, __IT__) ((((((uint8_t)(__IT__)) >> 5U) == 1U)? (__HANDLE__)->Instance->CR1:(((((uint8_t)(__IT__)) >> 5U) == 2U)? \ - (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & ((uint32_t)1U << \ - (((uint16_t)(__IT__)) & SMARTCARD_IT_MASK))) +#define __HAL_SMARTCARD_GET_IT_SOURCE(__HANDLE__, __IT__) ((((((uint8_t)(__IT__)) >> 5U) == 1U)? (__HANDLE__)->Instance->CR1 : \ + (((((uint8_t)(__IT__)) >> 5U) == 2U)? (__HANDLE__)->Instance->CR2 : \ + (__HANDLE__)->Instance->CR3)) & ((uint32_t)1U << (((uint16_t)(__IT__)) & SMARTCARD_IT_MASK))) -/** @brief Clears the specified SMARTCARD ISR flag, in setting the proper ICR register flag. +/** @brief Clear the specified SMARTCARD ISR flag, in setting the proper ICR register flag. * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. * @param __IT_CLEAR__: specifies the interrupt clear register flag that needs to be set - * to clear the corresponding interrupt + * to clear the corresponding interrupt. * This parameter can be one of the following values: - * @arg SMARTCARD_CLEAR_PEF: Parity error clear flag - * @arg SMARTCARD_CLEAR_FEF: Framing error clear flag - * @arg SMARTCARD_CLEAR_NEF: Noise detected clear flag - * @arg SMARTCARD_CLEAR_OREF: OverRun error clear flag - * @arg SMARTCARD_CLEAR_IDLEF: Idle line detection clear flag - * @arg SMARTCARD_CLEAR_TCF: Transmission complete clear flag - * @arg SMARTCARD_CLEAR_RTOF: Receiver timeout clear flag - * @arg SMARTCARD_CLEAR_EOBF: End of block clear flag + * @arg @ref SMARTCARD_CLEAR_PEF Parity error clear flag + * @arg @ref SMARTCARD_CLEAR_FEF Framing error clear flag + * @arg @ref SMARTCARD_CLEAR_NEF Noise detected clear flag + * @arg @ref SMARTCARD_CLEAR_OREF OverRun error clear flag + * @arg @ref SMARTCARD_CLEAR_IDLEF Idle line detection clear flag + * @arg @ref SMARTCARD_CLEAR_TCF Transmission complete clear flag + * @arg @ref SMARTCARD_CLEAR_RTOF Receiver timeout clear flag + * @arg @ref SMARTCARD_CLEAR_EOBF End of block clear flag * @retval None */ -#define __HAL_SMARTCARD_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) +#define __HAL_SMARTCARD_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) /** @brief Set a specific SMARTCARD request flag. * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. * @param __REQ__: specifies the request flag to set - * This parameter can be one of the following values: - * @arg SMARTCARD_RXDATA_FLUSH_REQUEST: Receive Data flush Request - * @arg SMARTCARD_TXDATA_FLUSH_REQUEST: Transmit data flush Request + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_RXDATA_FLUSH_REQUEST Receive data flush Request + * @arg @ref SMARTCARD_TXDATA_FLUSH_REQUEST Transmit data flush Request * * @retval None - */ -#define __HAL_SMARTCARD_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint32_t)(__REQ__)) + */ +#define __HAL_SMARTCARD_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__)) -/** @brief Enables the SMARTCARD one bit sample method - * @param __HANDLE__: specifies the SMARTCARD Handle. +/** @brief Enable the SMARTCARD one bit sample method. + * @param __HANDLE__: specifies the SMARTCARD Handle. * @retval None */ #define __HAL_SMARTCARD_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) -/** @brief Disables the SMARTCARD one bit sample method - * @param __HANDLE__: specifies the SMARTCARD Handle. +/** @brief Disable the SMARTCARD one bit sample method. + * @param __HANDLE__: specifies the SMARTCARD Handle. * @retval None */ #define __HAL_SMARTCARD_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT)) -/** @brief Enable the USART associated to the SMARTCARD Handle +/** @brief Enable the USART associated to the SMARTCARD Handle. * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. * @retval None - */ - -#define __HAL_SMARTCARD_ENABLE(__HANDLE__) ( (__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + */ +#define __HAL_SMARTCARD_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) /** @brief Disable the USART associated to the SMARTCARD Handle * @param __HANDLE__: specifies the SMARTCARD Handle. - * The Handle Instance which can be USART1 or USART2. * @retval None */ -#define __HAL_SMARTCARD_DISABLE(__HANDLE__) ( (__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) +#define __HAL_SMARTCARD_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) /** @brief Macros to enable or disable the SmartCard DMA request. * @param __HANDLE__: specifies the SMARTCARD Handle. @@ -813,106 +810,281 @@ typedef struct #define __HAL_SMARTCARD_DMA_REQUEST_ENABLE(__HANDLE__, __REQUEST__) ((__HANDLE__)->Instance->CR3 |= (__REQUEST__)) #define __HAL_SMARTCARD_DMA_REQUEST_DISABLE(__HANDLE__, __REQUEST__) ((__HANDLE__)->Instance->CR3 &= ~(__REQUEST__)) -/** @brief Check the Baud rate range. The maximum Baud Rate is derived from the - * maximum clock on F3 (i.e. 72 MHz) divided by the oversampling used - * on the SMARTCARD (i.e. 16) - * @param __BAUDRATE__: Baud rate set by the configuration function. - * @retval Test result (TRUE or FALSE) - */ -#define IS_SMARTCARD_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 4500001U) +/** + * @} + */ -/** @brief Check the block length range. The maximum SMARTCARD block length is 0xFF. +/* Private macros -------------------------------------------------------------*/ +/** @defgroup SMARTCARD_Private_Macros SMARTCARD Private Macros + * @{ + */ + +/** @brief Check the Baud rate range. + * @note The maximum Baud Rate is derived from the maximum clock on L0 (i.e. 32 MHz) + * divided by the oversampling used on the SMARTCARD (i.e. 16). + * @param __BAUDRATE__: Baud rate set by the configuration function. + * @retval Test result (TRUE or FALSE) + */ +#define IS_SMARTCARD_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 2000001U) + +/** @brief Check the block length range. + * @note The maximum SMARTCARD block length is 0xFF. * @param __LENGTH__: block length. - * @retval Test result (TRUE or FALSE) + * @retval Test result (TRUE or FALSE) */ #define IS_SMARTCARD_BLOCKLENGTH(__LENGTH__) ((__LENGTH__) <= 0xFFU) -/** @brief Check the receiver timeout value. The maximum SMARTCARD receiver timeout - * value is 0xFFFFFF. +/** @brief Check the receiver timeout value. + * @note The maximum SMARTCARD receiver timeout value is 0xFFFFFF. * @param __TIMEOUTVALUE__: receiver timeout value. - * @retval Test result (TRUE or FALSE) + * @retval Test result (TRUE or FALSE) */ #define IS_SMARTCARD_TIMEOUT_VALUE(__TIMEOUTVALUE__) ((__TIMEOUTVALUE__) <= 0xFFFFFFU) -/** @brief Check the SMARTCARD autoretry counter value. The maximum number of - * retransmissions is 0x7. - * @param __COUNT__: number of retransmissions - * @retval Test result (TRUE or FALSE) +/** @brief Check the SMARTCARD autoretry counter value. + * @note The maximum number of retransmissions is 0x7. + * @param __COUNT__: number of retransmissions. + * @retval Test result (TRUE or FALSE) */ #define IS_SMARTCARD_AUTORETRY_COUNT(__COUNT__) ((__COUNT__) <= 0x7U) /** - * @} + * @brief Ensure that SMARTCARD frame length is valid. + * @param __LENGTH__: SMARTCARD frame length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) */ +#define IS_SMARTCARD_WORD_LENGTH(__LENGTH__) ((__LENGTH__) == SMARTCARD_WORDLENGTH_9B) -/* Include SMARTCARD HAL Extension module */ +/** + * @brief Ensure that SMARTCARD frame number of stop bits is valid. + * @param __STOPBITS__: SMARTCARD frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_SMARTCARD_STOPBITS(__STOPBITS__) (((__STOPBITS__) == SMARTCARD_STOPBITS_0_5) ||\ + ((__STOPBITS__) == SMARTCARD_STOPBITS_1_5)) + +/** + * @brief Ensure that SMARTCARD frame parity is valid. + * @param __PARITY__: SMARTCARD frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_SMARTCARD_PARITY(__PARITY__) (((__PARITY__) == SMARTCARD_PARITY_EVEN) || \ + ((__PARITY__) == SMARTCARD_PARITY_ODD)) + +/** + * @brief Ensure that SMARTCARD communication mode is valid. + * @param __MODE__: SMARTCARD communication mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_SMARTCARD_MODE(__MODE__) ((((__MODE__) & (uint16_t)0xFFF3) == 0x00) && ((__MODE__) != (uint16_t)0x00)) + +/** + * @brief Ensure that SMARTCARD frame polarity is valid. + * @param __CPOL__: SMARTCARD frame polarity. + * @retval SET (__CPOL__ is valid) or RESET (__CPOL__ is invalid) + */ +#define IS_SMARTCARD_POLARITY(__CPOL__) (((__CPOL__) == SMARTCARD_POLARITY_LOW) || ((__CPOL__) == SMARTCARD_POLARITY_HIGH)) + +/** + * @brief Ensure that SMARTCARD frame phase is valid. + * @param __CPHA__: SMARTCARD frame phase. + * @retval SET (__CPHA__ is valid) or RESET (__CPHA__ is invalid) + */ +#define IS_SMARTCARD_PHASE(__CPHA__) (((__CPHA__) == SMARTCARD_PHASE_1EDGE) || ((__CPHA__) == SMARTCARD_PHASE_2EDGE)) + +/** + * @brief Ensure that SMARTCARD frame last bit clock pulse setting is valid. + * @param __LASTBIT__: SMARTCARD frame last bit clock pulse setting. + * @retval SET (__LASTBIT__ is valid) or RESET (__LASTBIT__ is invalid) + */ +#define IS_SMARTCARD_LASTBIT(__LASTBIT__) (((__LASTBIT__) == SMARTCARD_LASTBIT_DISABLE) || \ + ((__LASTBIT__) == SMARTCARD_LASTBIT_ENABLE)) + +/** + * @brief Ensure that SMARTCARD frame sampling is valid. + * @param __ONEBIT__: SMARTCARD frame sampling. + * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid) + */ +#define IS_SMARTCARD_ONE_BIT_SAMPLE(__ONEBIT__) (((__ONEBIT__) == SMARTCARD_ONE_BIT_SAMPLE_DISABLE) || \ + ((__ONEBIT__) == SMARTCARD_ONE_BIT_SAMPLE_ENABLE)) + +/** + * @brief Ensure that SMARTCARD NACK transmission setting is valid. + * @param __NACK__: SMARTCARD NACK transmission setting. + * @retval SET (__NACK__ is valid) or RESET (__NACK__ is invalid) + */ +#define IS_SMARTCARD_NACK(__NACK__) (((__NACK__) == SMARTCARD_NACK_ENABLE) || \ + ((__NACK__) == SMARTCARD_NACK_DISABLE)) + +/** + * @brief Ensure that SMARTCARD receiver timeout setting is valid. + * @param __TIMEOUT__: SMARTCARD receiver timeout setting. + * @retval SET (__TIMEOUT__ is valid) or RESET (__TIMEOUT__ is invalid) + */ +#define IS_SMARTCARD_TIMEOUT(__TIMEOUT__) (((__TIMEOUT__) == SMARTCARD_TIMEOUT_DISABLE) || \ + ((__TIMEOUT__) == SMARTCARD_TIMEOUT_ENABLE)) + +/** + * @brief Ensure that SMARTCARD advanced features initialization is valid. + * @param __INIT__: SMARTCARD advanced features initialization. + * @retval SET (__INIT__ is valid) or RESET (__INIT__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_INIT(__INIT__) ((__INIT__) <= (SMARTCARD_ADVFEATURE_NO_INIT | \ + SMARTCARD_ADVFEATURE_TXINVERT_INIT | \ + SMARTCARD_ADVFEATURE_RXINVERT_INIT | \ + SMARTCARD_ADVFEATURE_DATAINVERT_INIT | \ + SMARTCARD_ADVFEATURE_SWAP_INIT | \ + SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ + SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT | \ + SMARTCARD_ADVFEATURE_MSBFIRST_INIT)) + +/** + * @brief Ensure that SMARTCARD frame TX inversion setting is valid. + * @param __TXINV__: SMARTCARD frame TX inversion setting. + * @retval SET (__TXINV__ is valid) or RESET (__TXINV__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_TXINV(__TXINV__) (((__TXINV__) == SMARTCARD_ADVFEATURE_TXINV_DISABLE) || \ + ((__TXINV__) == SMARTCARD_ADVFEATURE_TXINV_ENABLE)) + +/** + * @brief Ensure that SMARTCARD frame RX inversion setting is valid. + * @param __RXINV__: SMARTCARD frame RX inversion setting. + * @retval SET (__RXINV__ is valid) or RESET (__RXINV__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_RXINV(__RXINV__) (((__RXINV__) == SMARTCARD_ADVFEATURE_RXINV_DISABLE) || \ + ((__RXINV__) == SMARTCARD_ADVFEATURE_RXINV_ENABLE)) + +/** + * @brief Ensure that SMARTCARD frame data inversion setting is valid. + * @param __DATAINV__: SMARTCARD frame data inversion setting. + * @retval SET (__DATAINV__ is valid) or RESET (__DATAINV__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_DATAINV(__DATAINV__) (((__DATAINV__) == SMARTCARD_ADVFEATURE_DATAINV_DISABLE) || \ + ((__DATAINV__) == SMARTCARD_ADVFEATURE_DATAINV_ENABLE)) + +/** + * @brief Ensure that SMARTCARD frame RX/TX pins swap setting is valid. + * @param __SWAP__: SMARTCARD frame RX/TX pins swap setting. + * @retval SET (__SWAP__ is valid) or RESET (__SWAP__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_SWAP(__SWAP__) (((__SWAP__) == SMARTCARD_ADVFEATURE_SWAP_DISABLE) || \ + ((__SWAP__) == SMARTCARD_ADVFEATURE_SWAP_ENABLE)) + +/** + * @brief Ensure that SMARTCARD frame overrun setting is valid. + * @param __OVERRUN__: SMARTCARD frame overrun setting. + * @retval SET (__OVERRUN__ is valid) or RESET (__OVERRUN__ is invalid) + */ +#define IS_SMARTCARD_OVERRUN(__OVERRUN__) (((__OVERRUN__) == SMARTCARD_ADVFEATURE_OVERRUN_ENABLE) || \ + ((__OVERRUN__) == SMARTCARD_ADVFEATURE_OVERRUN_DISABLE)) + +/** + * @brief Ensure that SMARTCARD DMA enabling or disabling on error setting is valid. + * @param __DMA__: SMARTCARD DMA enabling or disabling on error setting. + * @retval SET (__DMA__ is valid) or RESET (__DMA__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_DMAONRXERROR(__DMA__) (((__DMA__) == SMARTCARD_ADVFEATURE_DMA_ENABLEONRXERROR) || \ + ((__DMA__) == SMARTCARD_ADVFEATURE_DMA_DISABLEONRXERROR)) + +/** + * @brief Ensure that SMARTCARD frame MSB first setting is valid. + * @param __MSBFIRST__: SMARTCARD frame MSB first setting. + * @retval SET (__MSBFIRST__ is valid) or RESET (__MSBFIRST__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_MSBFIRST(__MSBFIRST__) (((__MSBFIRST__) == SMARTCARD_ADVFEATURE_MSBFIRST_DISABLE) || \ + ((__MSBFIRST__) == SMARTCARD_ADVFEATURE_MSBFIRST_ENABLE)) + +/** + * @brief Ensure that SMARTCARD request parameter is valid. + * @param __PARAM__: SMARTCARD request parameter. + * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) + */ +#define IS_SMARTCARD_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == SMARTCARD_RXDATA_FLUSH_REQUEST) || \ + ((__PARAM__) == SMARTCARD_TXDATA_FLUSH_REQUEST)) + +/** + * @} + */ + +/* Include SMARTCARD HAL Extended module */ #include "stm32l0xx_hal_smartcard_ex.h" + + /* Exported functions --------------------------------------------------------*/ -/** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions +/** @addtogroup SMARTCARD_Exported_Functions * @{ */ -/* Initialization/de-initialization functions **********************************/ -/** @defgroup SMARTCARD_Exported_Functions_Group1 Initialization/de-initialization functions - * @{ - */ -HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc); -HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc); -void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc); -void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc); -/** - * @} - */ -/* IO operation functions *******************************************************/ -/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions - * @{ - */ -HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size); -void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc); -void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc); -void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc); -void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc); -/** - * @} - */ -/* IO operation functions *******************************************************/ -/** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State functions - * @{ - */ -/* Peripheral State functions **************************************************/ -HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc); -uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc); -/** - * @} - */ - -/** - * @} - */ - -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup SMARTCARD_Private SMARTCARD Private +/* Initialization and de-initialization functions ****************************/ +/** @addtogroup SMARTCARD_Exported_Functions_Group1 * @{ */ -/** - * @} - */ -/**************************************************************/ -/** - * @} - */ +HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsmartcard); /** * @} */ - + +/* IO operation functions *****************************************************/ +/** @addtogroup SMARTCARD_Exported_Functions_Group2 + * @{ + */ + +HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size); +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsmartcard); + +void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_AbortCpltCallback (SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_AbortTransmitCpltCallback (SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_AbortReceiveCpltCallback (SMARTCARD_HandleTypeDef *hsmartcard); + +/** + * @} + */ + +/* Peripheral Control functions ***********************************************/ +/* Peripheral State and Error functions ***************************************/ +/** @addtogroup SMARTCARD_Exported_Functions_Group4 + * @{ + */ + +HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsmartcard); +uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsmartcard); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard_ex.c index c77bb8d615..14b99f3ce6 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard_ex.c @@ -2,24 +2,25 @@ ****************************************************************************** * @file stm32l0xx_hal_smartcard_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief SMARTCARD HAL module driver. - * - * This file provides extended firmware functions to manage the following + * This file provides extended firmware functions to manage the following * functionalities of the SmartCard. * + Initialization and de-initialization functions * + Peripheral Control functions + * + * @verbatim - =============================================================================== - ##### How to use this driver ##### - =============================================================================== - [..] - The Extended SMARTCARD HAL driver can be used as follow: + ============================================================================= + ##### SMARTCARD peripheral extended features ##### + ============================================================================= + [..] + The Extended SMARTCARD HAL driver can be used as follows: + + (#) After having configured the SMARTCARD basic features with HAL_SMARTCARD_Init(), + then program SMARTCARD advanced features if required (TX/RX pins swap, TimeOut, + auto-retry counter,...) in the hsmartcard AdvancedInit structure. + - (#) After having configured the SMARTCARD basic features with HAL_SMARTCARD_Init(), - then if required, program SMARTCARD advanced features (TX/RX pins swap, TimeOut, - auto-retry counter,...) in the hsc AdvancedInit structure. @endverbatim ****************************************************************************** @@ -59,36 +60,34 @@ * @{ */ -#ifdef HAL_SMARTCARD_MODULE_ENABLED - - -/** @addtogroup SMARTCARDEx +/** @defgroup SMARTCARDEx SMARTCARDEx * @brief SMARTCARD Extended HAL module driver * @{ */ +#ifdef HAL_SMARTCARD_MODULE_ENABLED /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ -/** @addtogroup SMARTCARDEx_Exported_Functions +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SMARTCARDEx_Exported_Functions SMARTCARD Extended Exported Functions * @{ */ -/** @addtogroup SMARTCARDEx_Exported_Functions_Group1 +/** @defgroup SMARTCARDEx_Exported_Functions_Group1 Extended Peripheral Control functions * @brief Extended control functions * -@verbatim - =============================================================================== +@verbatim + =============================================================================== ##### Peripheral Control functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to initialize the SMARTCARD. - (+) HAL_SMARTCARDEx_BlockLength_Config() API allows to configure the Block Length on the fly - (+) HAL_SMARTCARDEx_TimeOut_Config() API allows to configure the receiver timeout value on the fly + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the SMARTCARD. + (+) HAL_SMARTCARDEx_BlockLength_Config() API allows to configure the Block Length on the fly + (+) HAL_SMARTCARDEx_TimeOut_Config() API allows to configure the receiver timeout value on the fly (+) HAL_SMARTCARDEx_EnableReceiverTimeOut() API enables the receiver timeout feature (+) HAL_SMARTCARDEx_DisableReceiverTimeOut() API disables the receiver timeout feature @@ -97,73 +96,93 @@ */ /** - * @brief Update on the fly the SMARTCARD block length in RTOR register - * @param hsc: SMARTCARD handle - * @param BlockLength: SMARTCARD block length (8-bit long at most) + * @brief Update on the fly the SMARTCARD block length in RTOR register. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param BlockLength: SMARTCARD block length (8-bit long at most) * @retval None */ -void HAL_SMARTCARDEx_BlockLength_Config(SMARTCARD_HandleTypeDef *hsc, uint8_t BlockLength) +void HAL_SMARTCARDEx_BlockLength_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t BlockLength) { - MODIFY_REG(hsc->Instance->RTOR, USART_RTOR_BLEN, ((uint32_t)BlockLength << SMARTCARD_RTOR_BLEN_LSB_POS)); + MODIFY_REG(hsmartcard->Instance->RTOR, USART_RTOR_BLEN, ((uint32_t)BlockLength << SMARTCARD_RTOR_BLEN_LSB_POS)); } /** - * @brief Update on the fly the receiver timeout value in RTOR register - * @param hsc: SMARTCARD handle + * @brief Update on the fly the receiver timeout value in RTOR register. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @param TimeOutValue: receiver timeout value in number of baud blocks. The timeout - * value must be less or equal to 0x0FFFFFFFF. + * value must be less or equal to 0x0FFFFFFFF. * @retval None */ -void HAL_SMARTCARDEx_TimeOut_Config(SMARTCARD_HandleTypeDef *hsc, uint32_t TimeOutValue) +void HAL_SMARTCARDEx_TimeOut_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t TimeOutValue) { - assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsc->Init.TimeOutValue)); - MODIFY_REG(hsc->Instance->RTOR, USART_RTOR_RTO, TimeOutValue); + assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsmartcard->Init.TimeOutValue)); + MODIFY_REG(hsmartcard->Instance->RTOR, USART_RTOR_RTO, TimeOutValue); } /** - * @brief Enable the SMARTCARD receiver timeout feature - * @param hsc: SMARTCARD handle + * @brief Enable the SMARTCARD receiver timeout feature. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval HAL status */ -HAL_StatusTypeDef HAL_SMARTCARDEx_EnableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsc) +HAL_StatusTypeDef HAL_SMARTCARDEx_EnableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard) { - /* Process Locked */ - __HAL_LOCK(hsc); - hsc->State = HAL_SMARTCARD_STATE_BUSY; + if(hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmartcard); - /* Set the USART RTOEN bit */ - hsc->Instance->CR2 |= USART_CR2_RTOEN; + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; - hsc->State = HAL_SMARTCARD_STATE_READY; + /* Set the USART RTOEN bit */ + SET_BIT(hsmartcard->Instance->CR2, USART_CR2_RTOEN); - /* Process Unlocked */ - __HAL_UNLOCK(hsc); + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; - return HAL_OK; + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } } /** - * @brief Disable the SMARTCARD receiver timeout feature - * @param hsc: SMARTCARD handle + * @brief Disable the SMARTCARD receiver timeout feature. + * @param hsmartcard: Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. * @retval HAL status */ -HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsc) +HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard) { - /* Process Locked */ - __HAL_LOCK(hsc); - hsc->State = HAL_SMARTCARD_STATE_BUSY; + if(hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmartcard); - /* Clear the USART RTOEN bit */ - hsc->Instance->CR2 &= ~(USART_CR2_RTOEN); + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; - hsc->State = HAL_SMARTCARD_STATE_READY; + /* Clear the USART RTOEN bit */ + CLEAR_BIT(hsmartcard->Instance->CR2, USART_CR2_RTOEN); - /* Process Unlocked */ - __HAL_UNLOCK(hsc); + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; - return HAL_OK; + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } } /** @@ -174,10 +193,12 @@ HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef * @} */ -/** - * @} - */ #endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +/** + * @} + */ + /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard_ex.h index 291cb3c102..2f84a9d22f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smartcard_ex.h @@ -2,9 +2,7 @@ ****************************************************************************** * @file stm32l0xx_hal_smartcard_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief Header file of SMARTCARD HAL module. + * @brief Header file of SMARTCARD HAL Extended module. ****************************************************************************** * @attention * @@ -50,91 +48,95 @@ * @{ */ -/** @defgroup SMARTCARDEx SMARTCARDEx - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ -/** @defgroup SMARTCARDEx_Exported_Macros SMARTCARDEx Exported Macros +/** @addtogroup SMARTCARDEx * @{ */ -/** @brief Reports the SMARTCARD clock source. - * @param __HANDLE__: specifies the USART Handle - * @param __CLOCKSOURCE__ : output variable - * @retval the USART clocking source, written in __CLOCKSOURCE__. + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SMARTCARDEx_Private_Macros SMARTCARD Extended Private Macros + * @{ + */ + +/** @brief Report the SMARTCARD clock source. + * @param __HANDLE__: specifies the SMARTCARD Handle. + * @param __CLOCKSOURCE__: output variable. + * @retval the SMARTCARD clocking source, written in __CLOCKSOURCE__. */ #if defined (STM32L031xx) || defined (STM32L041xx) || defined (STM32L011xx) || defined (STM32L021xx) -#define SMARTCARD_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ - do { \ - if((__HANDLE__)->Instance == USART2) \ - { \ - switch(__HAL_RCC_GET_USART2_SOURCE()) \ - { \ - case RCC_USART2CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART2CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART2CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART2CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ - break; \ - default: \ - break; \ - } \ - } \ +#define SMARTCARD_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ } while(0) #else /* (STM32L031xx) || defined (STM32L041xx) || (STM32L011xx) || defined (STM32L021xx) */ -#define SMARTCARD_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ - do { \ - if((__HANDLE__)->Instance == USART1) \ - { \ - switch(__HAL_RCC_GET_USART1_SOURCE()) \ - { \ - case RCC_USART1CLKSOURCE_PCLK2: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK2; \ - break; \ - case RCC_USART1CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART1CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART1CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ - break; \ - default: \ - break; \ - } \ - } \ - else if((__HANDLE__)->Instance == USART2) \ - { \ - switch(__HAL_RCC_GET_USART2_SOURCE()) \ - { \ - case RCC_USART2CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART2CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART2CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART2CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ - break; \ - default: \ - break; \ - } \ - } \ +#define SMARTCARD_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ } while(0) #endif /* (STM32L031xx) || (STM32L041xx) || (STM32L011xx) || defined (STM32L021xx) */ @@ -143,27 +145,22 @@ */ /* Exported functions --------------------------------------------------------*/ -/** @defgroup SMARTCARDEx_Exported_Functions SMARTCARDEx Exported Functions +/** @addtogroup SMARTCARDEx_Exported_Functions * @{ */ -/* Initialization/de-initialization functions ********************************/ -/** @defgroup SMARTCARDEx_Exported_Functions_Group1 Extended Peripheral Control functions - * @{ - */ /* Initialization and de-initialization functions ****************************/ -/* IO operation functions *****************************************************/ +/* IO operation methods *******************************************************/ + +/** @addtogroup SMARTCARDEx_Exported_Functions_Group1 + * @{ + */ + /* Peripheral Control functions ***********************************************/ -void HAL_SMARTCARDEx_BlockLength_Config(SMARTCARD_HandleTypeDef *hsc, uint8_t BlockLength); -void HAL_SMARTCARDEx_TimeOut_Config(SMARTCARD_HandleTypeDef *hsc, uint32_t TimeOutValue); -HAL_StatusTypeDef HAL_SMARTCARDEx_EnableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsc); -HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsc); - -/* Peripheral State and Error functions ***************************************/ - -/** - * @} - */ +void HAL_SMARTCARDEx_BlockLength_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t BlockLength); +void HAL_SMARTCARDEx_TimeOut_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t TimeOutValue); +HAL_StatusTypeDef HAL_SMARTCARDEx_EnableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard); /** * @} @@ -176,6 +173,11 @@ HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef /** * @} */ + +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smbus.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smbus.c index afbf8e9346..0ad8200b12 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smbus.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smbus.c @@ -2,80 +2,77 @@ ****************************************************************************** * @file stm32l0xx_hal_smbus.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief SMBUS HAL module driver. - * - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the System Management Bus (SMBus) peripheral, - * based on I2C principales of operation : - * + Initialization/de-initialization functions - * + I/O operation functions - * + Peripheral Control functions - * + Peripheral State functions - * + * based on I2C principles of operation : + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + * @verbatim ============================================================================== ##### How to use this driver ##### ============================================================================== [..] The SMBUS HAL driver can be used as follows: - - (#) Declare a SMBUS_HandleTypeDef handle structure, for example: - SMBUS_HandleTypeDef hsmbus; - (#)Initialize the SMBUS low level resources by implement the HAL_SMBUS_MspInit ()API: + (#) Declare a SMBUS_HandleTypeDef handle structure, for example: + SMBUS_HandleTypeDef hsmbus; + + (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API: (##) Enable the SMBUSx interface clock (##) SMBUS pins configuration - (+) Enable the clock for the SMBUS GPIOs - (+) Configure SMBUS pins as alternate function open-drain + (+++) Enable the clock for the SMBUS GPIOs + (+++) Configure SMBUS pins as alternate function open-drain (##) NVIC configuration if you need to use interrupt process - (+) Configure the SMBUSx interrupt priority - (+) Enable the NVIC SMBUS IRQ Channel + (+++) Configure the SMBUSx interrupt priority + (+++) Enable the NVIC SMBUS IRQ Channel - (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Adressing Mode, + (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode, Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode, Peripheral mode and Packet Error Check mode in the hsmbus Init structure. (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API: - (+) These API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) - by calling the customed HAL_SMBUS_MspInit(&hsmbus) API. + (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_SMBUS_MspInit(&hsmbus) API. (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady() - (#) For SMBUS IO operations, only one mode of operations is available within this driver : - + (#) For SMBUS IO operations, only one mode of operations is available within this driver + *** Interrupt mode IO operation *** =================================== [..] - (+) Transmit in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Transmit_IT() - (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback - (+) Receive in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Receive_IT() - (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback - (+) Abort a master/host SMBUS process commnunication with Interrupt using HAL_SMBUS_Master_Abort_IT() + (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Master_Transmit_IT() + (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback() + (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Master_Receive_IT() + (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback() + (+) Abort a master/host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT() (++) The associated previous transfer callback is called at the end of abort process - (++) mean HAL_SMBUS_MasterTxCpltCallback in case of previous state was master transmit - (++) mean HAL_SMBUS_MasterRxCpltCallback in case of previous state was master receive - (+) Enable the Address listen mode in slave/device SMBUS mode using HAL_SMBUS_EnableListen_IT() - (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback is executed and user can + (++) mean HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit + (++) mean HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive + (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode + using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT() + (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and user can add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read). - (++) At Listen mode end HAL_SMBUS_ListenCpltCallback is executed and user can - add his own code by customization of function pointer HAL_SMBUS_ListenCpltCallback - (+) Transmit in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Transmit_IT() - (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback - (+) Receive in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Receive_IT() - (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback + (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMBUS_ListenCpltCallback() + (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Slave_Transmit_IT() + (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback() + (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Slave_Receive_IT() + (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback() (+) Enable/Disable the SMBUS alert mode using HAL_SMBUS_EnableAlert_IT() HAL_SMBUS_DisableAlert_IT() (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and user can - add his own code by customization of function pointer HAL_SMBUS_ErrorCallback + add his own code by customization of function pointer HAL_SMBUS_ErrorCallback() to check the Alert Error Code using function HAL_SMBUS_GetError() (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError() (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_SMBUS_ErrorCallback + add his own code by customization of function pointer HAL_SMBUS_ErrorCallback() to check the Error Code using function HAL_SMBUS_GetError() *** SMBUS HAL driver macros list *** @@ -83,17 +80,17 @@ [..] Below the list of most used macros in SMBUS HAL driver. - (+) __HAL_SMBUS_ENABLE: Enable the SMBUS peripheral - (+) __HAL_SMBUS_DISABLE: Disable the SMBUS peripheral - (+) __HAL_SMBUS_GET_FLAG : Checks whether the specified SMBUS flag is set or not - (+) __HAL_SMBUS_CLEAR_FLAG : Clears the specified SMBUS pending flag - (+) __HAL_SMBUS_ENABLE_IT: Enables the specified SMBUS interrupt - (+) __HAL_SMBUS_DISABLE_IT: Disables the specified SMBUS interrupt + (+) __HAL_SMBUS_ENABLE: Enable the SMBUS peripheral + (+) __HAL_SMBUS_DISABLE: Disable the SMBUS peripheral + (+) __HAL_SMBUS_GET_FLAG: Check whether the specified SMBUS flag is set or not + (+) __HAL_SMBUS_CLEAR_FLAG: Clear the specified SMBUS pending flag + (+) __HAL_SMBUS_ENABLE_IT: Enable the specified SMBUS interrupt + (+) __HAL_SMBUS_DISABLE_IT: Disable the specified SMBUS interrupt [..] (@) You can refer to the SMBUS HAL driver header file for more useful macros - + @endverbatim ****************************************************************************** * @attention @@ -122,8 +119,8 @@ * 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. * - ****************************************************************************** - */ + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal.h" @@ -132,36 +129,38 @@ * @{ */ - -#ifdef HAL_SMBUS_MODULE_ENABLED - -/** @addtogroup SMBUS +/** @defgroup SMBUS SMBUS * @brief SMBUS HAL module driver * @{ */ +#ifdef HAL_SMBUS_MODULE_ENABLED + /* Private typedef -----------------------------------------------------------*/ -/** @addtogroup SMBUS_Private +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SMBUS_Private_Define SMBUS Private Constants * @{ */ -/* Private define ------------------------------------------------------------*/ -#define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFFU) /*Instance->ISR) -#define __SMBUS_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & ((__FLAG__) & SMBUS_FLAG_MASK)) == ((__FLAG__) & SMBUS_FLAG_MASK))) - /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SMBUS_Private_Functions SMBUS Private Functions + * @{ + */ static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout); static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest); @@ -169,31 +168,35 @@ static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus); static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus); +static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus); + +static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus); + static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request); /** * @} */ -/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ -/** @addtogroup SMBUS_Exported_Functions SMBUS Exported Functions +/** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions * @{ */ -/** @addtogroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions - * -@verbatim +/** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim =============================================================================== ##### Initialization and de-initialization functions ##### =============================================================================== - [..] This subsection provides a set of functions allowing to initialize and - de-initialiaze the SMBUSx peripheral: + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the SMBUSx peripheral: - (+) User must Implement HAL_SMBUS_MspInit() function in which he configures + (+) User must Implement HAL_SMBUS_MspInit() function in which he configures all related peripherals resources (CLOCK, GPIO, IT and NVIC ). - (+) Call the function HAL_SMBUS_Init() to configure the selected device with + (+) Call the function HAL_SMBUS_Init() to configure the selected device with the selected configuration: (++) Clock Timing (++) Bus Timeout @@ -208,28 +211,32 @@ static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddre (++) Packet Error Check mode (++) Peripheral mode - (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration - of the selected SMBUSx periperal. + + (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration + of the selected SMBUSx peripheral. + + (+) Enable/Disable Analog/Digital filters with HAL_SMBUS_ConfigAnalogFilter() and + HAL_SMBUS_ConfigDigitalFilter(). @endverbatim * @{ */ /** - * @brief Initializes the SMBUS according to the specified parameters - * in the SMBUS_InitTypeDef and create the associated handle. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Initialize the SMBUS according to the specified parameters + * in the SMBUS_InitTypeDef and initialize the associated handle. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval HAL status */ HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus) -{ +{ /* Check the SMBUS handle allocation */ - if(hsmbus == NULL) + if (hsmbus == NULL) { return HAL_ERROR; } - + /* Check the parameters */ assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance)); assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter)); @@ -243,7 +250,7 @@ HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus) assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode)); assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode)); - if(hsmbus->State == HAL_SMBUS_STATE_RESET) + if (hsmbus->State == HAL_SMBUS_STATE_RESET) { /* Allocate lock resource and initialize it */ hsmbus->Lock = HAL_UNLOCKED; @@ -251,26 +258,29 @@ HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus) /* Init the low level hardware : GPIO, CLOCK, NVIC */ HAL_SMBUS_MspInit(hsmbus); } - + hsmbus->State = HAL_SMBUS_STATE_BUSY; - + /* Disable the selected SMBUS peripheral */ __HAL_SMBUS_DISABLE(hsmbus); - - /*---------------------------- SMBUSx TIMINGR Configuration ----------------*/ + + /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/ /* Configure SMBUSx: Frequency range */ hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK; - - /*---------------------------- SMBUSx TIMEOUTR Configuration ---------------*/ + + /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/ /* Configure SMBUSx: Bus Timeout */ + hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN; + hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN; hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout; - /*---------------------------- SMBUSx OAR1 Configuration -------------------*/ + /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/ /* Configure SMBUSx: Own Address1 and ack own address1 mode */ hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN; - if(hsmbus->Init.OwnAddress1 != 0U) + + if (hsmbus->Init.OwnAddress1 != 0U) { - if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT) + if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT) { hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1); } @@ -280,142 +290,241 @@ HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus) } } - /*---------------------------- SMBUSx CR2 Configuration --------------------*/ + /*---------------------------- SMBUSx CR2 Configuration ------------------------*/ /* Configure SMBUSx: Addressing Master mode */ - if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT) + if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT) { hsmbus->Instance->CR2 = (I2C_CR2_ADD10); } /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */ /* AUTOEND and NACK bit will be manage during Transfer process */ hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK); - - /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/ + + /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/ /* Configure SMBUSx: Dual mode and Own Address2 */ - hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | (hsmbus->Init.OwnAddress2Masks << 8)); + hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | (hsmbus->Init.OwnAddress2Masks << 8U)); /*---------------------------- SMBUSx CR1 Configuration ------------------------*/ /* Configure SMBUSx: Generalcall and NoStretch mode */ hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | hsmbus->Init.AnalogFilter); - + /* Enable Slave Byte Control only in case of Packet Error Check is enabled and SMBUS Peripheral is set in Slave mode */ - if( (hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE) - && ( (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP) ) ) + if ((hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE) + && ((hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP))) { hsmbus->Instance->CR1 |= I2C_CR1_SBC; } /* Enable the selected SMBUS peripheral */ __HAL_SMBUS_ENABLE(hsmbus); - + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; hsmbus->PreviousState = HAL_SMBUS_STATE_READY; hsmbus->State = HAL_SMBUS_STATE_READY; - + return HAL_OK; } /** - * @brief DeInitializes the SMBUS peripheral. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief DeInitialize the SMBUS peripheral. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval HAL status */ HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus) { /* Check the SMBUS handle allocation */ - if(hsmbus == NULL) + if (hsmbus == NULL) { return HAL_ERROR; } - + /* Check the parameters */ assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance)); - + hsmbus->State = HAL_SMBUS_STATE_BUSY; - + /* Disable the SMBUS Peripheral Clock */ __HAL_SMBUS_DISABLE(hsmbus); - + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ HAL_SMBUS_MspDeInit(hsmbus); - + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; hsmbus->PreviousState = HAL_SMBUS_STATE_RESET; hsmbus->State = HAL_SMBUS_STATE_RESET; - - /* Release Lock */ + + /* Release Lock */ __HAL_UNLOCK(hsmbus); - + return HAL_OK; } /** - * @brief SMBUS MSP Init. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Initialize the SMBUS MSP. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ - __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus) +__weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus) { /* Prevent unused argument(s) compilation warning */ UNUSED(hsmbus); - /* NOTE : This function Should not be modified, when the callback is needed, + /* NOTE : This function should not be modified, when the callback is needed, the HAL_SMBUS_MspInit could be implemented in the user file - */ + */ } /** - * @brief SMBUS MSP DeInit - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief DeInitialize the SMBUS MSP. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ - __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus) +__weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus) { /* Prevent unused argument(s) compilation warning */ UNUSED(hsmbus); - /* NOTE : This function Should not be modified, when the callback is needed, + /* NOTE : This function should not be modified, when the callback is needed, the HAL_SMBUS_MspDeInit could be implemented in the user file - */ + */ +} + +/** + * @brief Configure Analog noise filter. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param AnalogFilter This parameter can be one of the following values: + * @arg @ref SMBUS_ANALOGFILTER_ENABLE + * @arg @ref SMBUS_ANALOGFILTER_DISABLE + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter) +{ + /* Check the parameters */ + assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance)); + assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + /* Reset ANOFF bit */ + hsmbus->Instance->CR1 &= ~(I2C_CR1_ANFOFF); + + /* Set analog filter bit*/ + hsmbus->Instance->CR1 |= AnalogFilter; + + __HAL_SMBUS_ENABLE(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configure Digital noise filter. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter) +{ + uint32_t tmpreg = 0U; + + /* Check the parameters */ + assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance)); + assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + /* Get the old register value */ + tmpreg = hsmbus->Instance->CR1; + + /* Reset I2C DNF bits [11:8] */ + tmpreg &= ~(I2C_CR1_DNF); + + /* Set I2Cx DNF coefficient */ + tmpreg |= DigitalFilter << I2C_CR1_DNF_Pos; + + /* Store the new register value */ + hsmbus->Instance->CR1 = tmpreg; + + __HAL_SMBUS_ENABLE(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } } /** * @} */ -/** @addtogroup SMBUS_Exported_Functions_Group2 - * @brief Data transfers functions +/** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions * -@verbatim +@verbatim =============================================================================== ##### IO operation functions ##### - =============================================================================== + =============================================================================== [..] - This subsection provides a set of functions allowing to manage the SMBUS data + This subsection provides a set of functions allowing to manage the SMBUS data transfers. (#) Blocking mode function to check if device is ready for usage is : (++) HAL_SMBUS_IsDeviceReady() (#) There is only one mode of transfer: - (++) No-Blocking mode : The communication is performed using Interrupts. + (++) Non-Blocking mode : The communication is performed using Interrupts. These functions return the status of the transfer startup. - The end of the data processing will be indicated through the + The end of the data processing will be indicated through the dedicated SMBUS IRQ when using Interrupt mode. - (#) No-Blocking mode functions with Interrupt are : + (#) Non-Blocking mode functions with Interrupt are : (++) HAL_SMBUS_Master_Transmit_IT() (++) HAL_SMBUS_Master_Receive_IT() (++) HAL_SMBUS_Slave_Transmit_IT() (++) HAL_SMBUS_Slave_Receive_IT() - (++) HAL_SMBUS_EnableListen_IT() + (++) HAL_SMBUS_EnableListen_IT() or alias HAL_SMBUS_EnableListen_IT() + (++) HAL_SMBUS_DisableListen_IT() (++) HAL_SMBUS_EnableAlert_IT() (++) HAL_SMBUS_DisableAlert_IT() - (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: + (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode: (++) HAL_SMBUS_MasterTxCpltCallback() (++) HAL_SMBUS_MasterRxCpltCallback() (++) HAL_SMBUS_SlaveTxCpltCallback() @@ -429,25 +538,26 @@ HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus) */ /** - * @brief Transmit in master/host SMBUS mode an amount of data in no-blocking mode with Interrupt - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. - * @param DevAddress: Target device address - * @param pData: Pointer to data buffer - * @param Size: Amount of data to be sent - * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition * @retval HAL status */ HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -{ +{ /* Check the parameters */ assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); - if(hsmbus->State == HAL_SMBUS_STATE_READY) + if (hsmbus->State == HAL_SMBUS_STATE_READY) { /* Process Locked */ __HAL_LOCK(hsmbus); - + hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX; hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; /* Prepare transfer parameters */ @@ -457,12 +567,12 @@ HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint /* In case of Quick command, remove autoend mode */ /* Manage the stop generation by software */ - if(hsmbus->pBuffPtr == NULL) + if (hsmbus->pBuffPtr == NULL) { hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE; } - if(Size > MAX_NBYTE_SIZE) + if (Size > MAX_NBYTE_SIZE) { hsmbus->XferSize = MAX_NBYTE_SIZE; } @@ -470,60 +580,65 @@ HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint { hsmbus->XferSize = Size; } - + /* Send Slave Address */ /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ - if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) ) + if ((hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount)) { - SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE, SMBUS_GENERATE_START_WRITE); + SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_WRITE); } else { /* If transfer direction not change, do not generate Restart Condition */ /* Mean Previous state is same as current state */ - if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) + if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(hsmbus->XferOptions) == 0)) { - SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); + SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); } /* Else transfer direction change, so generate Restart with new transfer direction */ else { - SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE); + /* Convert OTHER_xxx XferOptions if any */ + SMBUS_ConvertOtherXferOptions(hsmbus); + + /* Handle Transfer */ + SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE); } /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */ /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ - if(__SMBUS_GET_PEC_MODE(hsmbus) != RESET) + if (SMBUS_GET_PEC_MODE(hsmbus) != RESET) { hsmbus->XferSize--; hsmbus->XferCount--; } } - - /* Process Unlocked */ - __HAL_UNLOCK(hsmbus); - /* Note : The SMBUS interrupts must be enabled after unlocking current process + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process to avoid the risk of SMBUS interrupt handle execution before current process unlock */ SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX); - + return HAL_OK; } else { return HAL_BUSY; - } + } } /** - * @brief Receive in master/host SMBUS mode an amount of data in no-blocking mode with Interrupt - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. - * @param DevAddress: Target device address - * @param pData: Pointer to data buffer - * @param Size: Amount of data to be sent - * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition * @retval HAL status */ HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) @@ -531,7 +646,7 @@ HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint1 /* Check the parameters */ assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); - if(hsmbus->State == HAL_SMBUS_STATE_READY) + if (hsmbus->State == HAL_SMBUS_STATE_READY) { /* Process Locked */ __HAL_LOCK(hsmbus); @@ -546,12 +661,12 @@ HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint1 /* In case of Quick command, remove autoend mode */ /* Manage the stop generation by software */ - if(hsmbus->pBuffPtr == NULL) + if (hsmbus->pBuffPtr == NULL) { hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE; } - if(Size > MAX_NBYTE_SIZE) + if (Size > MAX_NBYTE_SIZE) { hsmbus->XferSize = MAX_NBYTE_SIZE; } @@ -562,63 +677,68 @@ HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint1 /* Send Slave Address */ /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ - if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) ) + if ((hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount)) { - SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE, SMBUS_GENERATE_START_READ); + SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_READ); } else { /* If transfer direction not change, do not generate Restart Condition */ /* Mean Previous state is same as current state */ - if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) + if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(hsmbus->XferOptions) == 0)) { - SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); + SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); } /* Else transfer direction change, so generate Restart with new transfer direction */ else { - SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ); + /* Convert OTHER_xxx XferOptions if any */ + SMBUS_ConvertOtherXferOptions(hsmbus); + + /* Handle Transfer */ + SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ); } } - - /* Process Unlocked */ - __HAL_UNLOCK(hsmbus); - /* Note : The SMBUS interrupts must be enabled after unlocking current process + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process to avoid the risk of SMBUS interrupt handle execution before current process unlock */ SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX); - + return HAL_OK; } else { - return HAL_BUSY; - } + return HAL_BUSY; + } } /** - * @brief Abort a master/host SMBUS process commnunication with Interrupt - * @note : This abort can be called only if state is ready - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Abort a master/host SMBUS process communication with Interrupt. + * @note This abort can be called only if state is ready + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. - * @param DevAddress: Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface * @retval HAL status */ HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress) { - if(hsmbus->State == HAL_SMBUS_STATE_READY) + if (hsmbus->State == HAL_SMBUS_STATE_READY) { /* Process Locked */ __HAL_LOCK(hsmbus); - + /* Keep the same state as previous */ /* to perform as well the call of the corresponding end of transfer callback */ - if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) + if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) { hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX; } - else if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) + else if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) { hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX; } @@ -629,210 +749,26 @@ HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_ return HAL_ERROR; } hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; - + /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */ /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */ SMBUS_TransferConfig(hsmbus, DevAddress, 1U, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP); - - /* Process Unlocked */ - __HAL_UNLOCK(hsmbus); - /* Note : The SMBUS interrupts must be enabled after unlocking current process + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process to avoid the risk of SMBUS interrupt handle execution before current process unlock */ - if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) + if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) { SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX); } - else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) + else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) { SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX); } - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} -/** - * @brief Transmit in slave/device SMBUS mode an amount of data in no-blocking mode with Interrupt - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains - * the configuration information for the specified SMBUS. - * @param pData: Pointer to data buffer - * @param Size: Amount of data to be sent - * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -{ - /* Check the parameters */ - assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); - - if(hsmbus->State == HAL_SMBUS_STATE_LISTEN) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ - SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX); - - /* Process Locked */ - __HAL_LOCK(hsmbus); - - hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_TX; - hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; - - /* Enable Address Acknowledge */ - hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; - - /* Prepare transfer parameters */ - hsmbus->pBuffPtr = pData; - hsmbus->XferSize = Size; - hsmbus->XferCount = Size; - hsmbus->XferOptions = XferOptions; - - /* Set NBYTE to transmit */ - SMBUS_TransferConfig(hsmbus,0U,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); - - /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ - /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ - if(__SMBUS_GET_PEC_MODE(hsmbus) != RESET) - { - hsmbus->XferSize--; - hsmbus->XferCount--; - } - - /* Clear ADDR flag after prepare the transfer parameters */ - /* This action will generate an acknowledge to the HOST */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR); - - /* Process Unlocked */ - __HAL_UNLOCK(hsmbus); - - /* Note : The SMBUS interrupts must be enabled after unlocking current process - to avoid the risk of SMBUS interrupt handle execution before current - process unlock */ - /* REnable ADDR interrupt */ - SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Receive in slave/device SMBUS mode an amount of data in no-blocking mode with Interrupt - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains - * the configuration information for the specified SMBUS. - * @param pData: Pointer to data buffer - * @param Size: Amount of data to be sent - * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -{ - /* Check the parameters */ - assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); - - if(hsmbus->State == HAL_SMBUS_STATE_LISTEN) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ - SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX); - - /* Process Locked */ - __HAL_LOCK(hsmbus); - - hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_RX; - hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; - - /* Enable Address Acknowledge */ - hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; - - /* Prepare transfer parameters */ - hsmbus->pBuffPtr = pData; - hsmbus->XferSize = Size; - hsmbus->XferCount = Size; - hsmbus->XferOptions = XferOptions; - - /* Set NBYTE to receive */ - /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */ - /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */ - /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */ - /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */ - if((hsmbus->XferSize == 1U) || ((hsmbus->XferSize == 2U) && (__SMBUS_GET_PEC_MODE(hsmbus) != RESET))) - { - SMBUS_TransferConfig(hsmbus,0U,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); - } - else - { - SMBUS_TransferConfig(hsmbus,0U,/*hsmbus->XferSize*/1U, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP); - } - - /* Clear ADDR flag after prepare the transfer parameters */ - /* This action will generate an acknowledge to the HOST */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR); - - /* Process Unlocked */ - __HAL_UNLOCK(hsmbus); - - /* Note : The SMBUS interrupts must be enabled after unlocking current process - to avoid the risk of SMBUS interrupt handle execution before current - process unlock */ - /* REnable ADDR interrupt */ - SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} -/** - * @brief This function enable the Address listen mode in Slave mode - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains - * the configuration information for the specified SMBUS. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus) -{ - hsmbus->State = HAL_SMBUS_STATE_LISTEN; - - /* Enable the Address Match interrupt */ - SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR); - - return HAL_OK; -} - -/** - * @brief This function disable the Address listen mode - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains - * the configuration information for the specified SMBUS. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus) -{ - /* Disable Address listen mode only if a transfer is not ongoing */ - if(hsmbus->State == HAL_SMBUS_STATE_LISTEN) - { - hsmbus->State = HAL_SMBUS_STATE_READY; - - /* Disable the Address Match interrupt */ - SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR); - return HAL_OK; } else @@ -842,15 +778,228 @@ HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus) } /** - * @brief Enable SMBUS alert. - * @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hsmbus->State == HAL_SMBUS_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX); + + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_TX; + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + + /* Set SBC bit to manage Acknowledge at each bit */ + hsmbus->Instance->CR1 |= I2C_CR1_SBC; + + /* Enable Address Acknowledge */ + hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hsmbus->pBuffPtr = pData; + hsmbus->XferCount = Size; + hsmbus->XferOptions = XferOptions; + + /* Convert OTHER_xxx XferOptions if any */ + SMBUS_ConvertOtherXferOptions(hsmbus); + + if (Size > MAX_NBYTE_SIZE) + { + hsmbus->XferSize = MAX_NBYTE_SIZE; + } + else + { + hsmbus->XferSize = Size; + } + + /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ + if ((hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount)) + { + SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP); + } + else + { + /* Set NBYTE to transmit */ + SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); + + /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ + /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ + if (SMBUS_GET_PEC_MODE(hsmbus) != RESET) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the HOST */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process + to avoid the risk of SMBUS interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hsmbus->State == HAL_SMBUS_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX); + + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_RX; + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + + /* Set SBC bit to manage Acknowledge at each bit */ + hsmbus->Instance->CR1 |= I2C_CR1_SBC; + + /* Enable Address Acknowledge */ + hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hsmbus->pBuffPtr = pData; + hsmbus->XferSize = Size; + hsmbus->XferCount = Size; + hsmbus->XferOptions = XferOptions; + + /* Convert OTHER_xxx XferOptions if any */ + SMBUS_ConvertOtherXferOptions(hsmbus); + + /* Set NBYTE to receive */ + /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */ + /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */ + /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */ + /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */ + if ((hsmbus->XferSize == 1U) || ((hsmbus->XferSize == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) != RESET))) + { + SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); + } + else + { + SMBUS_TransferConfig(hsmbus, 0U, 1U, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP); + } + + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the HOST */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process + to avoid the risk of SMBUS interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Enable the Address listen mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus) +{ + hsmbus->State = HAL_SMBUS_STATE_LISTEN; + + /* Enable the Address Match interrupt */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR); + + return HAL_OK; +} + +/** + * @brief Disable the Address listen mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus) +{ + /* Disable Address listen mode only if a transfer is not ongoing */ + if (hsmbus->State == HAL_SMBUS_STATE_LISTEN) + { + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Disable the Address Match interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Enable the SMBUS alert mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUSx peripheral. * @retval HAL status */ HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus) { /* Enable SMBus alert */ - hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN; + hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN; /* Clear ALERT flag */ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT); @@ -858,92 +1007,102 @@ HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus) /* Enable Alert Interrupt */ SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT); - return HAL_OK; + return HAL_OK; } /** - * @brief Disable SMBUS alert. - * @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Disable the SMBUS alert mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUSx peripheral. * @retval HAL status */ HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus) { /* Enable SMBus alert */ - hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN; - + hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN; + /* Disable Alert Interrupt */ SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT); - return HAL_OK; + return HAL_OK; } + /** - * @brief Checks if target device is ready for communication. - * @note This function is used with Memory devices - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Check if target device is ready for communication. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. - * @param DevAddress: Target device address - * @param Trials: Number of trials - * @param Timeout: Timeout duration + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * @param Trials Number of trials + * @param Timeout Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) { - uint32_t tickstart = 0x00U; - __IO uint32_t SMBUS_Trials = 0x00U; + uint32_t tickstart = 0U; - if(hsmbus->State == HAL_SMBUS_STATE_READY) + __IO uint32_t SMBUS_Trials = 0U; + + if (hsmbus->State == HAL_SMBUS_STATE_READY) { - if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET) + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET) { return HAL_BUSY; } /* Process Locked */ __HAL_LOCK(hsmbus); - + hsmbus->State = HAL_SMBUS_STATE_BUSY; hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; - + do { /* Generate Start */ - hsmbus->Instance->CR2 = __SMBUS_GENERATE_START(hsmbus->Init.AddressingMode,DevAddress); - + hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode, DevAddress); + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ /* Wait until STOPF flag is set or a NACK flag is set*/ tickstart = HAL_GetTick(); - while((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) == RESET) && (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET) && (hsmbus->State != HAL_SMBUS_STATE_TIMEOUT)) + while ((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) == RESET) && (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET) && (hsmbus->State != HAL_SMBUS_STATE_TIMEOUT)) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + if (Timeout != HAL_MAX_DELAY) { - hsmbus->State = HAL_SMBUS_STATE_TIMEOUT; - } + if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + { + /* Device is ready */ + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + return HAL_TIMEOUT; + } + } } - + /* Check if the NACKF flag has not been set */ if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET) { - /* Wait until STOPF flag is reset */ - if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) + /* Wait until STOPF flag is reset */ + if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } - + /* Clear STOP Flag */ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); /* Device is ready */ hsmbus->State = HAL_SMBUS_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + return HAL_OK; } else { - /* Wait until STOPF flag is reset */ - if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) + /* Wait until STOPF flag is reset */ + if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } @@ -954,23 +1113,24 @@ HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t /* Clear STOP Flag, auto generated with autoend*/ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); } - - /* Check if the maximum allowed numbe of trials has bee reached */ + + /* Check if the maximum allowed number of trials has been reached */ if (SMBUS_Trials++ == Trials) { /* Generate Stop */ hsmbus->Instance->CR2 |= I2C_CR2_STOP; - - /* Wait until STOPF flag is reset */ - if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) + + /* Wait until STOPF flag is reset */ + if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } - + /* Clear STOP Flag */ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); - } - }while(SMBUS_Trials++ < Trials); + } + } + while (SMBUS_Trials < Trials); hsmbus->State = HAL_SMBUS_STATE_READY; @@ -978,44 +1138,51 @@ HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t __HAL_UNLOCK(hsmbus); return HAL_TIMEOUT; - } + } else { return HAL_BUSY; } } +/** + * @} + */ + +/** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ /** - * @brief This function handles SMBUS event interrupt request. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Handle SMBUS event interrupt request. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus) { uint32_t tmpisrvalue = 0U; - + /* Use a local variable to store the current ISR flags */ /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */ - tmpisrvalue = __SMBUS_GET_ISR_REG(hsmbus); - + tmpisrvalue = SMBUS_GET_ISR_REG(hsmbus); + /* SMBUS in mode Transmitter ---------------------------------------------------*/ - if (((__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI| SMBUS_IT_STOPI| SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET)) - { + if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET)) + { /* Slave mode selected */ if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) { SMBUS_Slave_ISR(hsmbus); } /* Master mode selected */ - else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX) + else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX) { SMBUS_Master_ISR(hsmbus); } } - + /* SMBUS in mode Receiver ----------------------------------------------------*/ - if (((__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI| SMBUS_IT_STOPI| SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET)) + if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET)) { /* Slave mode selected */ if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX) @@ -1023,16 +1190,15 @@ void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus) SMBUS_Slave_ISR(hsmbus); } /* Master mode selected */ - else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX) + else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX) { SMBUS_Master_ISR(hsmbus); } - } - - /* SMBUS in mode Listener Only --------------------------------------------------*/ - /* Slave mode selected */ - if (((__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (__SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) - && ((__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ADDRI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_STOPI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_NACKI) != RESET))) + } + + /* SMBUS in mode Listener Only --------------------------------------------------*/ + if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) + && ((__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ADDRI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_STOPI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_NACKI) != RESET))) { if (hsmbus->State == HAL_SMBUS_STATE_LISTEN) { @@ -1042,102 +1208,35 @@ void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus) } /** - * @brief This function handles SMBUS error interrupt request. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Handle SMBUS error interrupt request. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus) { - /* SMBUS Bus error interrupt occurred ------------------------------------*/ - if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BERR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET)) - { - hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR; - - /* Clear BERR flag */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR); - } - - /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/ - if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_OVR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET)) - { - hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR; - - /* Clear OVR flag */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR); - } - - /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/ - if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ARLO) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET)) - { - hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO; - - /* Clear ARLO flag */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO); - } - - /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/ - if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET)) - { - hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT; - - /* Clear TIMEOUT flag */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT); - } - - /* SMBUS Alert error interrupt occurred -----------------------------------------------*/ - if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ALERT) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET)) - { - hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT; - - /* Clear ALERT flag */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT); - } - - /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/ - if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_PECERR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET)) - { - hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR; - - /* Clear PEC error flag */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR); - } - - /* Call the Error Callback in case of Error detected */ - if((hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)&&(hsmbus->ErrorCode != HAL_SMBUS_ERROR_ACKF)) - { - /* Do not Reset the the HAL state in case of ALERT error */ - if((hsmbus->ErrorCode & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT) - { - /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX and HAL_SMBUS_STATE_MASTER_BUSY_XX */ - /* keep HAL_SMBUS_STATE_LISTEN if set */ - hsmbus->State &= (uint32_t)~((uint32_t)HAL_SMBUS_STATE_MASTER_BUSY_RX | HAL_SMBUS_STATE_MASTER_BUSY_TX | HAL_SMBUS_STATE_SLAVE_BUSY_RX | HAL_SMBUS_STATE_SLAVE_BUSY_TX); - } - - /* Call the Error callback to prevent upper layer */ - HAL_SMBUS_ErrorCallback(hsmbus); - } + SMBUS_ITErrorHandler(hsmbus); } /** - * @brief Master Tx Transfer completed callbacks. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Master Tx Transfer completed callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ - __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus) +__weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus) { /* Prevent unused argument(s) compilation warning */ UNUSED(hsmbus); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMBUS_TxCpltCallback could be implemented in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file + */ } /** - * @brief Master Rx Transfer completed callbacks. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Master Rx Transfer completed callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ @@ -1146,48 +1245,48 @@ __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus) /* Prevent unused argument(s) compilation warning */ UNUSED(hsmbus); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMBUS_TxCpltCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file */ } -/** @brief Slave Tx Transfer completed callbacks. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains +/** @brief Slave Tx Transfer completed callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ - __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus) +__weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus) { /* Prevent unused argument(s) compilation warning */ UNUSED(hsmbus); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMBUS_TxCpltCallback could be implemented in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file + */ } /** - * @brief Slave Rx Transfer completed callbacks. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Slave Rx Transfer completed callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus) { - /* Prevent unused argument(s) compilation warning */ - UNUSED(hsmbus); + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMBUS_TxCpltCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file */ } /** - * @brief Slave Address Match callbacks. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Slave Address Match callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. - * @param TransferDirection: Master request Transfer Direction (Write/Read) - * @param AddrMatchCode: Address Match Code + * @param TransferDirection Master request Transfer Direction (Write/Read) + * @param AddrMatchCode Address Match Code * @retval None */ __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode) @@ -1197,14 +1296,14 @@ __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t Transfer UNUSED(TransferDirection); UNUSED(AddrMatchCode); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMBUS_AddrCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_AddrCallback() could be implemented in the user file */ } /** - * @brief Slave Listen Complete callbacks. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Listen Complete callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ @@ -1213,40 +1312,40 @@ __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus) /* Prevent unused argument(s) compilation warning */ UNUSED(hsmbus); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMBUS_ListenCpltCallback could be implemented in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file + */ } /** - * @brief SMBUS error callbacks. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief SMBUS error callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval None */ - __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus) +__weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus) { /* Prevent unused argument(s) compilation warning */ UNUSED(hsmbus); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_SMBUS_ErrorCallback could be implemented in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_ErrorCallback() could be implemented in the user file + */ } /** * @} */ -/** @addtogroup SMBUS_Exported_Functions_Group3 - * @brief Peripheral State and Errors functions +/** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral State and Errors functions * -@verbatim +@verbatim =============================================================================== ##### Peripheral State and Errors functions ##### - =============================================================================== + =============================================================================== [..] - This subsection permit to get in run-time the status of the peripheral + This subsection permits to get in run-time the status of the peripheral and the data flow. @endverbatim @@ -1254,18 +1353,20 @@ __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus) */ /** - * @brief Returns the SMBUS state. - * @param hsmbus : SMBUS handle + * @brief Return the SMBUS handle state. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. * @retval HAL state */ uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus) { + /* Return SMBUS handle state */ return hsmbus->State; } /** -* @brief Return the SMBUS error code -* @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains +* @brief Return the SMBUS error code. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval SMBUS Error Code */ @@ -1276,59 +1377,61 @@ uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus) /** * @} - */ + */ /** * @} */ -/** @addtogroup SMBUS_Private +/** @addtogroup SMBUS_Private_Functions SMBUS Private Functions + * @brief Data transfers Private functions * @{ */ /** - * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval HAL status */ -static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) +static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) { uint16_t DevAddress; /* Process Locked */ __HAL_LOCK(hsmbus); - - if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET) + + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET) { /* Clear NACK Flag */ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); - + /* Set corresponding Error Code */ /* No need to generate STOP, it is automatically done */ hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF; /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - - /* Call the Error callback to prevent upper layer */ + + /* Call the Error callback to inform upper layer */ HAL_SMBUS_ErrorCallback(hsmbus); } - else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET) + else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET) { - + /* Check and treat errors if errors occurs during STOP process */ + SMBUS_ITErrorHandler(hsmbus); + /* Call the corresponding callback to inform upper layer of End of Transfer */ - if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) + if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) { /* Disable Interrupt */ SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); /* Clear STOP Flag */ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); - + /* Clear Configuration Register 2 */ - __SMBUS_RESET_CR2(hsmbus); - + SMBUS_RESET_CR2(hsmbus); /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */ /* Disable the selected SMBUS peripheral */ @@ -1339,77 +1442,90 @@ static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + /* REenable the selected SMBUS peripheral */ __HAL_SMBUS_ENABLE(hsmbus); HAL_SMBUS_MasterTxCpltCallback(hsmbus); } - else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) + else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) { + /* Store Last receive data if any */ + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) + { + /* Read data from RXDR */ + (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR; + + if ((hsmbus->XferSize > 0U)) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + /* Disable Interrupt */ SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); /* Clear STOP Flag */ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); - + /* Clear Configuration Register 2 */ - __SMBUS_RESET_CR2(hsmbus); - + SMBUS_RESET_CR2(hsmbus); + hsmbus->PreviousState = HAL_SMBUS_STATE_READY; hsmbus->State = HAL_SMBUS_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + HAL_SMBUS_MasterRxCpltCallback(hsmbus); } } - else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) - { + else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) + { /* Read data from RXDR */ (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR; hsmbus->XferSize--; hsmbus->XferCount--; } - else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET) + else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET) { /* Write data to TXDR */ hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++); hsmbus->XferSize--; - hsmbus->XferCount--; + hsmbus->XferCount--; } - else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET) + else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET) { - if((hsmbus->XferSize == 0U)&&(hsmbus->XferCount!=0U)) + if ((hsmbus->XferSize == 0U) && (hsmbus->XferCount != 0U)) { DevAddress = (hsmbus->Instance->CR2 & I2C_CR2_SADD); - - if(hsmbus->XferCount > MAX_NBYTE_SIZE) - { - SMBUS_TransferConfig(hsmbus,DevAddress,MAX_NBYTE_SIZE, SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP); + + if (hsmbus->XferCount > MAX_NBYTE_SIZE) + { + SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP); hsmbus->XferSize = MAX_NBYTE_SIZE; } else { - SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_AUTOEND_MODE, SMBUS_GENERATE_START_WRITE); + hsmbus->XferSize = hsmbus->XferCount; + SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ - if(__SMBUS_GET_PEC_MODE(hsmbus) != RESET) + if (SMBUS_GET_PEC_MODE(hsmbus) != RESET) { hsmbus->XferSize--; hsmbus->XferCount--; } - hsmbus->XferSize = hsmbus->XferCount; } } - else if((hsmbus->XferSize == 0U)&&(hsmbus->XferCount==0U)) + else if ((hsmbus->XferSize == 0U) && (hsmbus->XferCount == 0U)) { - /* Call TxCpltCallback if no stop mode is set */ - if(__SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE) + /* Call TxCpltCallback() if no stop mode is set */ + if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE) { /* Call the corresponding callback to inform upper layer of End of Transfer */ - if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) + if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) { /* Disable Interrupt */ SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); @@ -1418,10 +1534,10 @@ static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + HAL_SMBUS_MasterTxCpltCallback(hsmbus); } - else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) + else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) { SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); hsmbus->PreviousState = hsmbus->State; @@ -1429,30 +1545,30 @@ static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + HAL_SMBUS_MasterRxCpltCallback(hsmbus); } } } } - else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TC) != RESET) + else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TC) != RESET) { - if(hsmbus->XferCount == 0U) + if (hsmbus->XferCount == 0U) { /* Specific use case for Quick command */ - if(hsmbus->pBuffPtr == NULL) + if (hsmbus->pBuffPtr == NULL) { /* Generate a Stop command */ hsmbus->Instance->CR2 |= I2C_CR2_STOP; } - /* Call TxCpltCallback if no stop mode is set */ - else if(__SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE) + /* Call TxCpltCallback() if no stop mode is set */ + else if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE) { /* No Generate Stop, to permit restart mode */ /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */ - + /* Call the corresponding callback to inform upper layer of End of Transfer */ - if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) + if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) { /* Disable Interrupt */ SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); @@ -1461,10 +1577,10 @@ static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + HAL_SMBUS_MasterTxCpltCallback(hsmbus); } - else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) + else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) { SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); hsmbus->PreviousState = hsmbus->State; @@ -1472,40 +1588,39 @@ static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + HAL_SMBUS_MasterRxCpltCallback(hsmbus); } } } } - - /* Process Unlocked */ - __HAL_UNLOCK(hsmbus); - - return HAL_OK; -} + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; +} /** - * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. * @retval HAL status */ -static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) +static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) { uint8_t TransferDirection = 0U; uint16_t SlaveAddrCode = 0U; /* Process Locked */ __HAL_LOCK(hsmbus); - - if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET) + + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET) { /* Check that SMBUS transfer finished */ /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */ /* Mean XferCount == 0*/ /* So clear Flag NACKF only */ - if(hsmbus->XferCount == 0U) + if (hsmbus->XferCount == 0U) { /* Clear NACK Flag */ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); @@ -1522,8 +1637,8 @@ static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) /* Set HAL State to "Idle" State, mean to LISTEN state */ /* So reset Slave Busy state */ hsmbus->PreviousState = hsmbus->State; - hsmbus->State &= (uint32_t)~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX); - hsmbus->State &= (uint32_t)~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX); + hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX); + hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX); /* Disable RX/TX Interrupts, keep only ADDR Interrupt */ SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX); @@ -1534,72 +1649,97 @@ static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - /* Call the Error callback to prevent upper layer */ + /* Call the Error callback to inform upper layer */ HAL_SMBUS_ErrorCallback(hsmbus); } } - else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) != RESET) + else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) != RESET) { - TransferDirection = __SMBUS_GET_DIR(hsmbus); - SlaveAddrCode = __SMBUS_GET_ADDR_MATCH(hsmbus); - + TransferDirection = SMBUS_GET_DIR(hsmbus); + SlaveAddrCode = SMBUS_GET_ADDR_MATCH(hsmbus); + /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/ /* Other ADDRInterrupt will be treat in next Listen usecase */ __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI); - + /* Process Unlocked */ __HAL_UNLOCK(hsmbus); /* Call Slave Addr callback */ HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode); } - else if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) || (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET)) + else if ((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) || (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET)) { - /* Read data from RXDR */ - (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR; - hsmbus->XferSize--; - hsmbus->XferCount--; - - if(hsmbus->XferCount == 1U) + if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX) { - /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */ - /* or only the last Byte of Transfer */ - /* So reset the RELOAD bit mode */ - hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE; - SMBUS_TransferConfig(hsmbus,0U ,1U , hsmbus->XferOptions, SMBUS_NO_STARTSTOP); + /* Read data from RXDR */ + (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR; + hsmbus->XferSize--; + hsmbus->XferCount--; + + if (hsmbus->XferCount == 1U) + { + /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */ + /* or only the last Byte of Transfer */ + /* So reset the RELOAD bit mode */ + hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE; + SMBUS_TransferConfig(hsmbus, 0U, 1U, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); + } + else if (hsmbus->XferCount == 0U) + { + /* Last Byte is received, disable Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); + + /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */ + hsmbus->PreviousState = hsmbus->State; + hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the Rx complete callback to inform upper layer of the end of receive process */ + HAL_SMBUS_SlaveRxCpltCallback(hsmbus); + } + else + { + /* Set Reload for next Bytes */ + SMBUS_TransferConfig(hsmbus, 0U, 1U, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP); + + /* Ack last Byte Read */ + hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; + } } - else if(hsmbus->XferCount == 0U) + else if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) { - /* Last Byte is received, disable Interrupt */ - SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); - - /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */ - hsmbus->PreviousState = hsmbus->State; - hsmbus->State &= (uint32_t)~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX); - - /* Process Unlocked */ - __HAL_UNLOCK(hsmbus); - - /* Call the Rx complete callback to inform upper layer of the end of receive process */ - HAL_SMBUS_SlaveRxCpltCallback(hsmbus); - } - else - { - /* Set Reload for next Bytes */ - SMBUS_TransferConfig(hsmbus,0U, 1U, SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP); - - /* Ack last Byte Read */ - hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; + if ((hsmbus->XferSize == 0U) && (hsmbus->XferCount != 0U)) + { + if (hsmbus->XferCount > MAX_NBYTE_SIZE) + { + SMBUS_TransferConfig(hsmbus, 0U, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP); + hsmbus->XferSize = MAX_NBYTE_SIZE; + } + else + { + hsmbus->XferSize = hsmbus->XferCount; + SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); + /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ + /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ + if (SMBUS_GET_PEC_MODE(hsmbus) != RESET) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + } } } - else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET) + else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET) { /* Write data to TXDR only if XferCount not reach "0" */ /* A TXIS flag can be set, during STOP treatment */ - - /* Check if all Datas have already been sent */ + /* Check if all Data have already been sent */ /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ - if(hsmbus->XferCount > 0U) + if (hsmbus->XferCount > 0U) { /* Write data to TXDR */ hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++); @@ -1607,13 +1747,13 @@ static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) hsmbus->XferSize--; } - if(hsmbus->XferSize == 0U) + if (hsmbus->XferCount == 0U) { /* Last Byte is Transmitted */ /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */ SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); hsmbus->PreviousState = hsmbus->State; - hsmbus->State &= (uint32_t)~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX); + hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX); /* Process Unlocked */ __HAL_UNLOCK(hsmbus); @@ -1624,10 +1764,23 @@ static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) } /* Check if STOPF is set */ - if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET) + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET) { - if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) + if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) { + /* Store Last receive data if any */ + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) + { + /* Read data from RXDR */ + (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR; + + if ((hsmbus->XferSize > 0U)) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + /* Disable RX and TX Interrupts */ SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX); @@ -1638,13 +1791,13 @@ static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) hsmbus->Instance->CR2 |= I2C_CR2_NACK; /* Clear Configuration Register 2 */ - __SMBUS_RESET_CR2(hsmbus); + SMBUS_RESET_CR2(hsmbus); /* Clear STOP Flag */ __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); - /* Clear ADDR flag */ - __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR); + /* Clear ADDR flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); hsmbus->XferOptions = 0U; hsmbus->PreviousState = hsmbus->State; @@ -1653,120 +1806,119 @@ static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - /* Call the Slave Complete callback, to prevent upper layer of the end of slave usecase */ + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ HAL_SMBUS_ListenCpltCallback(hsmbus); } } /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + return HAL_OK; } - /** - * @brief Manage the enabling of Interrupts - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Manage the enabling of Interrupts. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. - * @param InterruptRequest : Value of @ref SMBUS_Interrupt_configuration_definition. + * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition. * @retval HAL status */ -static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest) +static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest) { uint32_t tmpisr = 0U; - if((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) + if ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) { /* Enable ERR interrupt */ tmpisr |= SMBUS_IT_ERRI; } - - if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR) + + if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR) { /* Enable ADDR, STOP interrupt */ tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI; } - - if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX) + + if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX) { /* Enable ERR, TC, STOP, NACK, RXI interrupt */ tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI; } - - if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX) + + if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX) { /* Enable ERR, TC, STOP, NACK, TXI interrupt */ tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI; } - + /* Enable interrupts only at the end */ /* to avoid the risk of SMBUS interrupt handle execution before */ /* all interrupts requested done */ __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr); - return HAL_OK; + return HAL_OK; } /** - * @brief Manage the disabling of Interrupts - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief Manage the disabling of Interrupts. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. - * @param InterruptRequest : Value of @ref SMBUS_Interrupt_configuration_definition. + * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition. * @retval HAL status */ -static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest) +static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest) { uint32_t tmpisr = 0U; - if( ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) && (hsmbus->State == HAL_SMBUS_STATE_READY) ) + if (((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) && (hsmbus->State == HAL_SMBUS_STATE_READY)) { /* Disable ERR interrupt */ tmpisr |= SMBUS_IT_ERRI; } - - if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX) + + if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX) { /* Disable TC, STOP, NACK, TXI interrupt */ tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI; - - if((__SMBUS_GET_ALERT_ENABLE(hsmbus) == RESET) - && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)) - { - /* Disable ERR interrupt */ - tmpisr |= SMBUS_IT_ERRI; - } - - if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN) - { - /* Disable STOPI, NACKI */ - tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI; - } - } - - if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX) - { - /* Disable TC, STOP, NACK, RXI interrupt */ - tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI; - - if((__SMBUS_GET_ALERT_ENABLE(hsmbus) == RESET) - && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)) + + if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET) + && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)) { /* Disable ERR interrupt */ tmpisr |= SMBUS_IT_ERRI; } - if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN) + if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN) { /* Disable STOPI, NACKI */ tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI; } } - - if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR) + + if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX) + { + /* Disable TC, STOP, NACK, RXI interrupt */ + tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI; + + if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET) + && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)) + { + /* Disable ERR interrupt */ + tmpisr |= SMBUS_IT_ERRI; + } + + if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN) + { + /* Disable STOPI, NACKI */ + tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI; + } + } + + if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR) { /* Enable ADDR, STOP interrupt */ tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI; - if(__SMBUS_GET_ALERT_ENABLE(hsmbus) == RESET) + if (SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET) { /* Disable ERR interrupt */ tmpisr |= SMBUS_IT_ERRI; @@ -1777,39 +1929,124 @@ static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t /* to avoid a breaking situation like at "t" time */ /* all disable interrupts request are not done */ __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr); - + return HAL_OK; } + /** - * @brief This function handles SMBUS Communication Timeout. - * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains + * @brief SMBUS interrupts error handler. + * @param hsmbus SMBUS handle. + * @retval None + */ +static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus) +{ + uint32_t itflags = READ_REG(hsmbus->Instance->ISR); + uint32_t itsources = READ_REG(hsmbus->Instance->CR1); + + /* SMBUS Bus error interrupt occurred ------------------------------------*/ + if (((itflags & SMBUS_FLAG_BERR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR); + } + + /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/ + if (((itflags & SMBUS_FLAG_OVR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR; + + /* Clear OVR flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR); + } + + /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/ + if (((itflags & SMBUS_FLAG_ARLO) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO); + } + + /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/ + if (((itflags & SMBUS_FLAG_TIMEOUT) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT; + + /* Clear TIMEOUT flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT); + } + + /* SMBUS Alert error interrupt occurred -----------------------------------------------*/ + if (((itflags & SMBUS_FLAG_ALERT) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT; + + /* Clear ALERT flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT); + } + + /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/ + if (((itflags & SMBUS_FLAG_PECERR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR; + + /* Clear PEC error flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR); + } + + /* Call the Error Callback in case of Error detected */ + if ((hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE) && (hsmbus->ErrorCode != HAL_SMBUS_ERROR_ACKF)) + { + /* Do not Reset the HAL state in case of ALERT error */ + if ((hsmbus->ErrorCode & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT) + { + if (((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) + || ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)) + { + /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */ + /* keep HAL_SMBUS_STATE_LISTEN if set */ + hsmbus->PreviousState = HAL_SMBUS_STATE_READY; + hsmbus->State = HAL_SMBUS_STATE_LISTEN; + } + } + + /* Call the Error callback to inform upper layer */ + HAL_SMBUS_ErrorCallback(hsmbus); + } +} + +/** + * @brief Handle SMBUS Communication Timeout. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains * the configuration information for the specified SMBUS. - * @param Flag: specifies the SMBUS flag to check. - * @param Status: The new Flag status (SET or RESET). - * @param Timeout: Timeout duration + * @param Flag Specifies the SMBUS flag to check. + * @param Status The new Flag status (SET or RESET). + * @param Timeout Timeout duration * @retval HAL status */ -static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout) -{ - uint32_t tickstart = 0x00U; - tickstart = HAL_GetTick(); - +static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + /* Wait until flag is set */ - if(Status == RESET) - { - while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET) + if (Status == RESET) + { + while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET) { /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + if (Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) { hsmbus->PreviousState = hsmbus->State; - hsmbus->State= HAL_SMBUS_STATE_READY; - + hsmbus->State = HAL_SMBUS_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + return HAL_TIMEOUT; } } @@ -1817,19 +2054,19 @@ static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbu } else { - while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) != RESET) + while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) != RESET) { /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + if (Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) { hsmbus->PreviousState = hsmbus->State; - hsmbus->State= HAL_SMBUS_STATE_READY; - + hsmbus->State = HAL_SMBUS_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(hsmbus); - + return HAL_TIMEOUT; } } @@ -1839,62 +2076,86 @@ static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbu } /** - * @brief Handles SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set). - * @param hsmbus: SMBUS handle. - * @param DevAddress: specifies the slave address to be programmed. - * @param Size: specifies the number of bytes to be programmed. + * @brief Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set). + * @param hsmbus SMBUS handle. + * @param DevAddress specifies the slave address to be programmed. + * @param Size specifies the number of bytes to be programmed. * This parameter must be a value between 0 and 255. - * @param Mode: new state of the SMBUS START condition generation. + * @param Mode New state of the SMBUS START condition generation. * This parameter can be one or a combination of the following values: - * @arg SMBUS_NO_MODE: No specific mode enabled. - * @arg SMBUS_RELOAD_MODE: Enable Reload mode. - * @arg SMBUS_AUTOEND_MODE: Enable Automatic end mode. - * @arg SMBUS_SOFTEND_MODE: Enable Software end mode and Reload mode. - * @param Request: new state of the SMBUS START condition generation. + * @arg @ref SMBUS_RELOAD_MODE Enable Reload mode. + * @arg @ref SMBUS_AUTOEND_MODE Enable Automatic end mode. + * @arg @ref SMBUS_SOFTEND_MODE Enable Software end mode and Reload mode. + * @arg @ref SMBUS_SENDPEC_MODE Enable Packet Error Calculation mode. + * @param Request New state of the SMBUS START condition generation. * This parameter can be one of the following values: - * @arg SMBUS_NO_STARTSTOP: Do not Generate stop and start condition. - * @arg SMBUS_GENERATE_STOP: Generate stop condition (Size should be set to 0). - * @arg SMBUS_GENERATE_START_READ: Generate Restart for read request. - * @arg SMBUS_GENERATE_START_WRITE: Generate Restart for write request. + * @arg @ref SMBUS_NO_STARTSTOP Don't Generate stop and start condition. + * @arg @ref SMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0). + * @arg @ref SMBUS_GENERATE_START_READ Generate Restart for read request. + * @arg @ref SMBUS_GENERATE_START_WRITE Generate Restart for write request. * @retval None */ static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request) { - uint32_t tmpreg = 0U; - /* Check the parameters */ assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance)); assert_param(IS_SMBUS_TRANSFER_MODE(Mode)); assert_param(IS_SMBUS_TRANSFER_REQUEST(Request)); - - /* Get the CR2 register value */ - tmpreg = hsmbus->Instance->CR2; - - /* clear tmpreg specific bits */ - tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE)); - - /* update tmpreg */ - tmpreg |= (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << 16U ) & I2C_CR2_NBYTES) | \ - (uint32_t)Mode | (uint32_t)Request); - - /* update CR2 register */ - hsmbus->Instance->CR2 = tmpreg; -} + /* update CR2 register */ + MODIFY_REG(hsmbus->Instance->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE)), \ + (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request)); +} /** - * @} + * @brief Convert SMBUSx OTHER_xxx XferOptions to functionnal XferOptions. + * @param hsmbus SMBUS handle. + * @retval None */ - +static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus) +{ + /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC */ + /* it request implicitly to generate a restart condition */ + /* set XferOptions to SMBUS_FIRST_FRAME */ + if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC) + { + hsmbus->XferOptions = SMBUS_FIRST_FRAME; + } + /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */ + /* it request implicitly to generate a restart condition */ + /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE */ + else if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC) + { + hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE; + } + /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */ + /* it request implicitly to generate a restart condition */ + /* then generate a stop condition at the end of transfer */ + /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC */ + else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC) + { + hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC; + } + /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */ + /* it request implicitly to generate a restart condition */ + /* then generate a stop condition at the end of transfer */ + /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC */ + else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC) + { + hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC; + } +} /** * @} */ #endif /* HAL_SMBUS_MODULE_ENABLED */ +/** + * @} + */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smbus.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smbus.h index 97adc81684..c46525e585 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smbus.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_smbus.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_smbus.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of SMBUS HAL module. ****************************************************************************** * @attention @@ -33,43 +31,43 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32L0xx_HAL_SMBUS_H #define __STM32L0xx_HAL_SMBUS_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ -#include "stm32l0xx_hal_def.h" +#include "stm32l0xx_hal_def.h" /** @addtogroup STM32L0xx_HAL_Driver * @{ */ -/** @defgroup SMBUS SMBUS +/** @addtogroup SMBUS * @{ - */ + */ /* Exported types ------------------------------------------------------------*/ /** @defgroup SMBUS_Exported_Types SMBUS Exported Types * @{ */ -/** - * @brief SMBUS Configuration Structure definition +/** @defgroup SMBUS_Configuration_Structure_definition SMBUS Configuration Structure definition + * @brief SMBUS Configuration Structure definition + * @{ */ typedef struct { uint32_t Timing; /*!< Specifies the SMBUS_TIMINGR_register value. - This parameter calculated by referring to SMBUS initialization - section in Reference manual */ - + This parameter calculated by referring to SMBUS initialization + section in Reference manual */ uint32_t AnalogFilter; /*!< Specifies if Analog Filter is enable or not. - This parameter can be a a value of @ref SMBUS_Analog_Filter */ + This parameter can be a value of @ref SMBUS_Analog_Filter */ uint32_t OwnAddress1; /*!< Specifies the first device own address. This parameter can be a 7-bit or 10-bit address. */ @@ -84,10 +82,10 @@ typedef struct This parameter can be a 7-bit address. */ uint32_t OwnAddress2Masks; /*!< Specifies the acknoledge mask address second device own address if dual addressing mode is selected - This parameter can be a value of @ref SMBUS_own_address2_masks */ + This parameter can be a value of @ref SMBUS_own_address2_masks. */ uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. - This parameter can be a value of @ref SMBUS_general_call_addressing_mode */ + This parameter can be a value of @ref SMBUS_general_call_addressing_mode. */ uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. This parameter can be a value of @ref SMBUS_nostretch_mode */ @@ -99,77 +97,83 @@ typedef struct This parameter can be a value of @ref SMBUS_peripheral_mode */ uint32_t SMBusTimeout; /*!< Specifies the content of the 32 Bits SMBUS_TIMEOUT_register value. - (Enable bits and different timeout values) - This parameter calculated by referring to SMBUS initialization + (Enable bits and different timeout values) + This parameter calculated by referring to SMBUS initialization section in Reference manual */ } SMBUS_InitTypeDef; - -/** @defgroup SMBUS_State SMBUS State - * @brief HAL States definition - * @{ - */ -#define HAL_SMBUS_STATE_RESET 0x00U /*!< SMBUS not yet initialized or disabled */ -#define HAL_SMBUS_STATE_READY 0x01U /*!< SMBUS initialized and ready for use */ -#define HAL_SMBUS_STATE_BUSY 0x02U /*!< SMBUS internal process is ongoing */ -#define HAL_SMBUS_STATE_MASTER_BUSY_TX 0x12U /*!< Master Data Transmission process is ongoing */ -#define HAL_SMBUS_STATE_MASTER_BUSY_RX 0x22U /*!< Master Data Reception process is ongoing */ -#define HAL_SMBUS_STATE_SLAVE_BUSY_TX 0x32U /*!< Slave Data Transmission process is ongoing */ -#define HAL_SMBUS_STATE_SLAVE_BUSY_RX 0x42U /*!< Slave Data Reception process is ongoing */ -#define HAL_SMBUS_STATE_TIMEOUT 0x03U /*!< Timeout state */ -#define HAL_SMBUS_STATE_ERROR 0x04U /*!< Reception process is ongoing */ -#define HAL_SMBUS_STATE_LISTEN 0x08U /*!< Address Listen Mode is ongoing */ -/** - * @} - */ - -/** @defgroup SMBUS_Error_Code SMBUS Error Code - * @brief SMBUS Error Code - * @{ - */ -#define HAL_SMBUS_ERROR_NONE 0x00U /*!< No error */ -#define HAL_SMBUS_ERROR_BERR 0x01U /*!< BERR error */ -#define HAL_SMBUS_ERROR_ARLO 0x02U /*!< ARLO error */ -#define HAL_SMBUS_ERROR_ACKF 0x04U /*!< ACKF error */ -#define HAL_SMBUS_ERROR_OVR 0x08U /*!< OVR error */ -#define HAL_SMBUS_ERROR_HALTIMEOUT 0x10U /*!< Timeout error */ -#define HAL_SMBUS_ERROR_BUSTIMEOUT 0x20U /*!< Bus Timeout error */ -#define HAL_SMBUS_ERROR_ALERT 0x40U /*!< Alert error */ -#define HAL_SMBUS_ERROR_PECERR 0x80U /*!< PEC error */ -/** +/** * @} */ -/** - * @brief SMBUS handle Structure definition +/** @defgroup HAL_state_definition HAL state definition + * @brief HAL State definition + * @{ + */ +#define HAL_SMBUS_STATE_RESET (0x00000000U) /*!< SMBUS not yet initialized or disabled */ +#define HAL_SMBUS_STATE_READY (0x00000001U) /*!< SMBUS initialized and ready for use */ +#define HAL_SMBUS_STATE_BUSY (0x00000002U) /*!< SMBUS internal process is ongoing */ +#define HAL_SMBUS_STATE_MASTER_BUSY_TX (0x00000012U) /*!< Master Data Transmission process is ongoing */ +#define HAL_SMBUS_STATE_MASTER_BUSY_RX (0x00000022U) /*!< Master Data Reception process is ongoing */ +#define HAL_SMBUS_STATE_SLAVE_BUSY_TX (0x00000032U) /*!< Slave Data Transmission process is ongoing */ +#define HAL_SMBUS_STATE_SLAVE_BUSY_RX (0x00000042U) /*!< Slave Data Reception process is ongoing */ +#define HAL_SMBUS_STATE_TIMEOUT (0x00000003U) /*!< Timeout state */ +#define HAL_SMBUS_STATE_ERROR (0x00000004U) /*!< Reception process is ongoing */ +#define HAL_SMBUS_STATE_LISTEN (0x00000008U) /*!< Address Listen Mode is ongoing */ +/** + * @} + */ + +/** @defgroup SMBUS_Error_Code_definition SMBUS Error Code definition + * @brief SMBUS Error Code definition + * @{ + */ +#define HAL_SMBUS_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_SMBUS_ERROR_BERR (0x00000001U) /*!< BERR error */ +#define HAL_SMBUS_ERROR_ARLO (0x00000002U) /*!< ARLO error */ +#define HAL_SMBUS_ERROR_ACKF (0x00000004U) /*!< ACKF error */ +#define HAL_SMBUS_ERROR_OVR (0x00000008U) /*!< OVR error */ +#define HAL_SMBUS_ERROR_HALTIMEOUT (0x00000010U) /*!< Timeout error */ +#define HAL_SMBUS_ERROR_BUSTIMEOUT (0x00000020U) /*!< Bus Timeout error */ +#define HAL_SMBUS_ERROR_ALERT (0x00000040U) /*!< Alert error */ +#define HAL_SMBUS_ERROR_PECERR (0x00000080U) /*!< PEC error */ +/** + * @} + */ + +/** @defgroup SMBUS_handle_Structure_definition SMBUS handle Structure definition + * @brief SMBUS handle Structure definition + * @{ */ typedef struct { - I2C_TypeDef *Instance; /*!< SMBUS registers base address */ - - SMBUS_InitTypeDef Init; /*!< SMBUS communication parameters */ - - uint8_t *pBuffPtr; /*!< Pointer to SMBUS transfer buffer */ - - uint16_t XferSize; /*!< SMBUS transfer size */ - - __IO uint16_t XferCount; /*!< SMBUS transfer counter */ - - __IO uint32_t XferOptions; /*!< SMBUS transfer options */ - - __IO uint32_t PreviousState; /*!< SMBUS communication Previous tate */ - - HAL_LockTypeDef Lock; /*!< SMBUS locking object */ - - __IO uint32_t State; /*!< SMBUS communication state */ + I2C_TypeDef *Instance; /*!< SMBUS registers base address */ - __IO uint32_t ErrorCode; /*!< SMBUS Error code , see SMBUS_Error_Code */ + SMBUS_InitTypeDef Init; /*!< SMBUS communication parameters */ -}SMBUS_HandleTypeDef; + uint8_t *pBuffPtr; /*!< Pointer to SMBUS transfer buffer */ -/** - * @} - */ + uint16_t XferSize; /*!< SMBUS transfer size */ + __IO uint16_t XferCount; /*!< SMBUS transfer counter */ + + __IO uint32_t XferOptions; /*!< SMBUS transfer options */ + + __IO uint32_t PreviousState; /*!< SMBUS communication Previous state */ + + HAL_LockTypeDef Lock; /*!< SMBUS locking object */ + + __IO uint32_t State; /*!< SMBUS communication state */ + + __IO uint32_t ErrorCode; /*!< SMBUS Error code */ + +} SMBUS_HandleTypeDef; +/** + * @} + */ + +/** + * @} + */ /* Exported constants --------------------------------------------------------*/ /** @defgroup SMBUS_Exported_Constants SMBUS Exported Constants @@ -179,41 +183,32 @@ typedef struct /** @defgroup SMBUS_Analog_Filter SMBUS Analog Filter * @{ */ -#define SMBUS_ANALOGFILTER_ENABLE ((uint32_t)0x00000000U) -#define SMBUS_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF - -#define IS_SMBUS_ANALOG_FILTER(FILTER) (((FILTER) == SMBUS_ANALOGFILTER_ENABLE) || \ - ((FILTER) == SMBUS_ANALOGFILTER_DISABLE)) +#define SMBUS_ANALOGFILTER_ENABLE (0x00000000U) +#define SMBUS_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF /** * @} */ -/** @defgroup SMBUS_addressing_mode SMBUS Addressing Mode +/** @defgroup SMBUS_addressing_mode SMBUS addressing mode * @{ */ -#define SMBUS_ADDRESSINGMODE_7BIT ((uint32_t)0x00000001U) -#define SMBUS_ADDRESSINGMODE_10BIT ((uint32_t)0x00000002U) - -#define IS_SMBUS_ADDRESSING_MODE(MODE) (((MODE) == SMBUS_ADDRESSINGMODE_7BIT) || \ - ((MODE) == SMBUS_ADDRESSINGMODE_10BIT)) +#define SMBUS_ADDRESSINGMODE_7BIT (0x00000001U) +#define SMBUS_ADDRESSINGMODE_10BIT (0x00000002U) /** * @} */ -/** @defgroup SMBUS_dual_addressing_mode SMBUS Dual Addressing Mode +/** @defgroup SMBUS_dual_addressing_mode SMBUS dual addressing mode * @{ */ -#define SMBUS_DUALADDRESS_DISABLE ((uint32_t)0x00000000U) -#define SMBUS_DUALADDRESS_ENABLE I2C_OAR2_OA2EN - -#define IS_SMBUS_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == SMBUS_DUALADDRESS_DISABLE) || \ - ((ADDRESS) == SMBUS_DUALADDRESS_ENABLE)) +#define SMBUS_DUALADDRESS_DISABLE (0x00000000U) +#define SMBUS_DUALADDRESS_ENABLE I2C_OAR2_OA2EN /** * @} */ -/** @defgroup SMBUS_own_address2_masks SMBUS Own Address2 Masks +/** @defgroup SMBUS_own_address2_masks SMBUS ownaddress2 masks * @{ */ @@ -225,173 +220,142 @@ typedef struct #define SMBUS_OA2_MASK05 ((uint8_t)0x05U) #define SMBUS_OA2_MASK06 ((uint8_t)0x06U) #define SMBUS_OA2_MASK07 ((uint8_t)0x07U) - -#define IS_SMBUS_OWN_ADDRESS2_MASK(MASK) (((MASK) == SMBUS_OA2_NOMASK) || \ - ((MASK) == SMBUS_OA2_MASK01) || \ - ((MASK) == SMBUS_OA2_MASK02) || \ - ((MASK) == SMBUS_OA2_MASK03) || \ - ((MASK) == SMBUS_OA2_MASK04) || \ - ((MASK) == SMBUS_OA2_MASK05) || \ - ((MASK) == SMBUS_OA2_MASK06) || \ - ((MASK) == SMBUS_OA2_MASK07)) /** * @} */ -/** @defgroup SMBUS_general_call_addressing_mode SMBUS General Call Enabling +/** @defgroup SMBUS_general_call_addressing_mode SMBUS general call addressing mode * @{ */ -#define SMBUS_GENERALCALL_DISABLE ((uint32_t)0x00000000U) -#define SMBUS_GENERALCALL_ENABLE I2C_CR1_GCEN - -#define IS_SMBUS_GENERAL_CALL(CALL) (((CALL) == SMBUS_GENERALCALL_DISABLE) || \ - ((CALL) == SMBUS_GENERALCALL_ENABLE)) +#define SMBUS_GENERALCALL_DISABLE (0x00000000U) +#define SMBUS_GENERALCALL_ENABLE I2C_CR1_GCEN /** * @} */ -/** @defgroup SMBUS_nostretch_mode SMBUS Nostretch Enabling +/** @defgroup SMBUS_nostretch_mode SMBUS nostretch mode * @{ */ -#define SMBUS_NOSTRETCH_DISABLE ((uint32_t)0x00000000U) -#define SMBUS_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH - -#define IS_SMBUS_NO_STRETCH(STRETCH) (((STRETCH) == SMBUS_NOSTRETCH_DISABLE) || \ - ((STRETCH) == SMBUS_NOSTRETCH_ENABLE)) +#define SMBUS_NOSTRETCH_DISABLE (0x00000000U) +#define SMBUS_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH /** * @} */ -/** @defgroup SMBUS_packet_error_check_mode SMBUS Packet Error Check Enabling +/** @defgroup SMBUS_packet_error_check_mode SMBUS packet error check mode * @{ */ -#define SMBUS_PEC_DISABLE ((uint32_t)0x00000000U) +#define SMBUS_PEC_DISABLE (0x00000000U) #define SMBUS_PEC_ENABLE I2C_CR1_PECEN - -#define IS_SMBUS_PEC(PEC) (((PEC) == SMBUS_PEC_DISABLE) || \ - ((PEC) == SMBUS_PEC_ENABLE)) /** * @} */ -/** @defgroup SMBUS_peripheral_mode SMBUS Peripheral Mode +/** @defgroup SMBUS_peripheral_mode SMBUS peripheral mode * @{ */ -#define SMBUS_PERIPHERAL_MODE_SMBUS_HOST (uint32_t)(I2C_CR1_SMBHEN) -#define SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE (uint32_t)(0x00000000U) -#define SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP (uint32_t)(I2C_CR1_SMBDEN) - -#define IS_SMBUS_PERIPHERAL_MODE(MODE) (((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_HOST) || \ - ((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || \ - ((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP)) +#define SMBUS_PERIPHERAL_MODE_SMBUS_HOST I2C_CR1_SMBHEN +#define SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE (0x00000000U) +#define SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP I2C_CR1_SMBDEN /** * @} */ -/** @defgroup SMBUS_ReloadEndMode_definition SMBUS Mode Definition +/** @defgroup SMBUS_ReloadEndMode_definition SMBUS ReloadEndMode definition * @{ */ -#define SMBUS_SOFTEND_MODE ((uint32_t)0x00000000U) +#define SMBUS_SOFTEND_MODE (0x00000000U) #define SMBUS_RELOAD_MODE I2C_CR2_RELOAD #define SMBUS_AUTOEND_MODE I2C_CR2_AUTOEND #define SMBUS_SENDPEC_MODE I2C_CR2_PECBYTE - -#define IS_SMBUS_TRANSFER_MODE(MODE) (((MODE) == SMBUS_RELOAD_MODE) || \ - ((MODE) == SMBUS_AUTOEND_MODE) || \ - ((MODE) == SMBUS_SOFTEND_MODE) || \ - ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE)) || \ - ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_RELOAD_MODE)) || \ - ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE | SMBUS_RELOAD_MODE ))) - /** * @} */ -/** @defgroup SMBUS_StartStopMode_definition SMBUS StartStop Mode Definition +/** @defgroup SMBUS_StartStopMode_definition SMBUS StartStopMode definition * @{ */ -#define SMBUS_NO_STARTSTOP ((uint32_t)0x00000000U) -#define SMBUS_GENERATE_STOP I2C_CR2_STOP -#define SMBUS_GENERATE_START_READ (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN) -#define SMBUS_GENERATE_START_WRITE I2C_CR2_START - -#define IS_SMBUS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == SMBUS_GENERATE_STOP) || \ - ((REQUEST) == SMBUS_GENERATE_START_READ) || \ - ((REQUEST) == SMBUS_GENERATE_START_WRITE) || \ - ((REQUEST) == SMBUS_NO_STARTSTOP)) +#define SMBUS_NO_STARTSTOP (0x00000000U) +#define SMBUS_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP) +#define SMBUS_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) +#define SMBUS_GENERATE_START_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) /** * @} */ -/** @defgroup SMBUS_XferOptions_definition SMBUS Transfer Request Definition +/** @defgroup SMBUS_XferOptions_definition SMBUS XferOptions definition * @{ */ -#define SMBUS_FIRST_FRAME ((uint32_t)(SMBUS_SOFTEND_MODE)) +/* List of XferOptions in usage of : + * 1- Restart condition when direction change + * 2- No Restart condition in other use cases + */ +#define SMBUS_FIRST_FRAME SMBUS_SOFTEND_MODE #define SMBUS_NEXT_FRAME ((uint32_t)(SMBUS_RELOAD_MODE | SMBUS_SOFTEND_MODE)) -#define SMBUS_FIRST_AND_LAST_FRAME_NO_PEC SMBUS_AUTOEND_MODE +#define SMBUS_FIRST_AND_LAST_FRAME_NO_PEC SMBUS_AUTOEND_MODE #define SMBUS_LAST_FRAME_NO_PEC SMBUS_AUTOEND_MODE #define SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC ((uint32_t)(SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE)) #define SMBUS_LAST_FRAME_WITH_PEC ((uint32_t)(SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE)) -#define IS_SMBUS_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == SMBUS_FIRST_FRAME) || \ - ((REQUEST) == SMBUS_NEXT_FRAME) || \ - ((REQUEST) == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || \ - ((REQUEST) == SMBUS_LAST_FRAME_NO_PEC) || \ - ((REQUEST) == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || \ - ((REQUEST) == SMBUS_LAST_FRAME_WITH_PEC)) - +/* List of XferOptions in usage of : + * 1- Restart condition in all use cases (direction change or not) + */ +#define SMBUS_OTHER_FRAME_NO_PEC (0x000000AAU) +#define SMBUS_OTHER_FRAME_WITH_PEC (0x0000AA00U) +#define SMBUS_OTHER_AND_LAST_FRAME_NO_PEC (0x00AA0000U) +#define SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC (0xAA000000U) /** * @} */ -/** @defgroup SMBUS_Interrupt_configuration_definition SMBUS Interrupt Configuration Definition +/** @defgroup SMBUS_Interrupt_configuration_definition SMBUS Interrupt configuration definition * @brief SMBUS Interrupt definition * Elements values convention: 0xXXXXXXXX * - XXXXXXXX : Interrupt control mask * @{ */ -#define SMBUS_IT_ERRI I2C_CR1_ERRIE -#define SMBUS_IT_TCI I2C_CR1_TCIE -#define SMBUS_IT_STOPI I2C_CR1_STOPIE -#define SMBUS_IT_NACKI I2C_CR1_NACKIE -#define SMBUS_IT_ADDRI I2C_CR1_ADDRIE -#define SMBUS_IT_RXI I2C_CR1_RXIE -#define SMBUS_IT_TXI I2C_CR1_TXIE -#define SMBUS_IT_TX (SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI) -#define SMBUS_IT_RX (SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_NACKI | SMBUS_IT_RXI) -#define SMBUS_IT_ALERT (SMBUS_IT_ERRI) -#define SMBUS_IT_ADDR (SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI) +#define SMBUS_IT_ERRI I2C_CR1_ERRIE +#define SMBUS_IT_TCI I2C_CR1_TCIE +#define SMBUS_IT_STOPI I2C_CR1_STOPIE +#define SMBUS_IT_NACKI I2C_CR1_NACKIE +#define SMBUS_IT_ADDRI I2C_CR1_ADDRIE +#define SMBUS_IT_RXI I2C_CR1_RXIE +#define SMBUS_IT_TXI I2C_CR1_TXIE +#define SMBUS_IT_TX (SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI) +#define SMBUS_IT_RX (SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_NACKI | SMBUS_IT_RXI) +#define SMBUS_IT_ALERT (SMBUS_IT_ERRI) +#define SMBUS_IT_ADDR (SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI) /** * @} */ -/** @defgroup SMBUS_Flag_definition SMBUS Flag Definition +/** @defgroup SMBUS_Flag_definition SMBUS Flag definition * @brief Flag definition * Elements values convention: 0xXXXXYYYY * - XXXXXXXX : Flag mask * @{ - */ + */ -#define SMBUS_FLAG_TXE I2C_ISR_TXE -#define SMBUS_FLAG_TXIS I2C_ISR_TXIS -#define SMBUS_FLAG_RXNE I2C_ISR_RXNE -#define SMBUS_FLAG_ADDR I2C_ISR_ADDR -#define SMBUS_FLAG_AF I2C_ISR_NACKF -#define SMBUS_FLAG_STOPF I2C_ISR_STOPF -#define SMBUS_FLAG_TC I2C_ISR_TC -#define SMBUS_FLAG_TCR I2C_ISR_TCR -#define SMBUS_FLAG_BERR I2C_ISR_BERR -#define SMBUS_FLAG_ARLO I2C_ISR_ARLO -#define SMBUS_FLAG_OVR I2C_ISR_OVR -#define SMBUS_FLAG_PECERR I2C_ISR_PECERR -#define SMBUS_FLAG_TIMEOUT I2C_ISR_TIMEOUT -#define SMBUS_FLAG_ALERT I2C_ISR_ALERT -#define SMBUS_FLAG_BUSY I2C_ISR_BUSY -#define SMBUS_FLAG_DIR I2C_ISR_DIR +#define SMBUS_FLAG_TXE I2C_ISR_TXE +#define SMBUS_FLAG_TXIS I2C_ISR_TXIS +#define SMBUS_FLAG_RXNE I2C_ISR_RXNE +#define SMBUS_FLAG_ADDR I2C_ISR_ADDR +#define SMBUS_FLAG_AF I2C_ISR_NACKF +#define SMBUS_FLAG_STOPF I2C_ISR_STOPF +#define SMBUS_FLAG_TC I2C_ISR_TC +#define SMBUS_FLAG_TCR I2C_ISR_TCR +#define SMBUS_FLAG_BERR I2C_ISR_BERR +#define SMBUS_FLAG_ARLO I2C_ISR_ARLO +#define SMBUS_FLAG_OVR I2C_ISR_OVR +#define SMBUS_FLAG_PECERR I2C_ISR_PECERR +#define SMBUS_FLAG_TIMEOUT I2C_ISR_TIMEOUT +#define SMBUS_FLAG_ALERT I2C_ISR_ALERT +#define SMBUS_FLAG_BUSY I2C_ISR_BUSY +#define SMBUS_FLAG_DIR I2C_ISR_DIR /** * @} */ @@ -400,154 +364,261 @@ typedef struct * @} */ -/* Exported macro ------------------------------------------------------------*/ +/* Exported macros ------------------------------------------------------------*/ /** @defgroup SMBUS_Exported_Macros SMBUS Exported Macros * @{ */ -/** @brief Reset SMBUS handle state - * @param __HANDLE__: specifies the SMBUS Handle. - * This parameter can be SMBUSx where x: 1 or 2 to select the SMBUS peripheral. +/** @brief Reset SMBUS handle state. + * @param __HANDLE__ specifies the SMBUS Handle. * @retval None */ #define __HAL_SMBUS_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SMBUS_STATE_RESET) -/** @brief Enable or disable the specified SMBUS interrupts. - * @param __HANDLE__: specifies the SMBUS Handle. - * This parameter can be SMBUSx where x: 1 or 2 to select the SMBUS peripheral. - * @param __INTERRUPT__: specifies the interrupt source to enable or disable. +/** @brief Enable the specified SMBUS interrupts. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __INTERRUPT__ specifies the interrupt source to enable. * This parameter can be one of the following values: - * @arg SMBUS_IT_ERRI: Errors interrupt enable - * @arg SMBUS_IT_TCI: Transfer complete interrupt enable - * @arg SMBUS_IT_STOPI: STOP detection interrupt enable - * @arg SMBUS_IT_NACKI: NACK received interrupt enable - * @arg SMBUS_IT_ADDRI: Address match interrupt enable - * @arg SMBUS_IT_RXI: RX interrupt enable - * @arg SMBUS_IT_TXI: TX interrupt enable - * + * @arg @ref SMBUS_IT_ERRI Errors interrupt enable + * @arg @ref SMBUS_IT_TCI Transfer complete interrupt enable + * @arg @ref SMBUS_IT_STOPI STOP detection interrupt enable + * @arg @ref SMBUS_IT_NACKI NACK received interrupt enable + * @arg @ref SMBUS_IT_ADDRI Address match interrupt enable + * @arg @ref SMBUS_IT_RXI RX interrupt enable + * @arg @ref SMBUS_IT_TXI TX interrupt enable + * * @retval None */ - #define __HAL_SMBUS_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 |= (__INTERRUPT__)) + +/** @brief Disable the specified SMBUS interrupts. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __INTERRUPT__ specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref SMBUS_IT_ERRI Errors interrupt enable + * @arg @ref SMBUS_IT_TCI Transfer complete interrupt enable + * @arg @ref SMBUS_IT_STOPI STOP detection interrupt enable + * @arg @ref SMBUS_IT_NACKI NACK received interrupt enable + * @arg @ref SMBUS_IT_ADDRI Address match interrupt enable + * @arg @ref SMBUS_IT_RXI RX interrupt enable + * @arg @ref SMBUS_IT_TXI TX interrupt enable + * + * @retval None + */ #define __HAL_SMBUS_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__))) - -/** @brief Checks if the specified SMBUS interrupt source is enabled or disabled. - * @param __HANDLE__: specifies the SMBUS Handle. - * This parameter can be SMBUSx where x: 1 or 2 to select the SMBUS peripheral. - * @param __INTERRUPT__: specifies the SMBUS interrupt source to check. + +/** @brief Check whether the specified SMBUS interrupt source is enabled or not. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __INTERRUPT__ specifies the SMBUS interrupt source to check. * This parameter can be one of the following values: - * @arg SMBUS_IT_ERRI: Errors interrupt enable - * @arg SMBUS_IT_TCI: Transfer complete interrupt enable - * @arg SMBUS_IT_STOPI: STOP detection interrupt enable - * @arg SMBUS_IT_NACKI: NACK received interrupt enable - * @arg SMBUS_IT_ADDRI: Address match interrupt enable - * @arg SMBUS_IT_RXI: RX interrupt enable - * @arg SMBUS_IT_TXI: TX interrupt enable - * + * @arg @ref SMBUS_IT_ERRI Errors interrupt enable + * @arg @ref SMBUS_IT_TCI Transfer complete interrupt enable + * @arg @ref SMBUS_IT_STOPI STOP detection interrupt enable + * @arg @ref SMBUS_IT_NACKI NACK received interrupt enable + * @arg @ref SMBUS_IT_ADDRI Address match interrupt enable + * @arg @ref SMBUS_IT_RXI RX interrupt enable + * @arg @ref SMBUS_IT_TXI TX interrupt enable + * * @retval The new state of __IT__ (TRUE or FALSE). */ #define __HAL_SMBUS_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) -/** @brief Checks whether the specified SMBUS flag is set or not. - * @param __HANDLE__: specifies the SMBUS Handle. - * This parameter can be SMBUSx where x: 1 or 2 to select the SMBUS peripheral. - * @param __FLAG__: specifies the flag to check. +/** @brief Check whether the specified SMBUS flag is set or not. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __FLAG__ specifies the flag to check. * This parameter can be one of the following values: - * @arg SMBUS_FLAG_TXE: Transmit data register empty - * @arg SMBUS_FLAG_TXIS: Transmit interrupt status - * @arg SMBUS_FLAG_RXNE: Receive data register not empty - * @arg SMBUS_FLAG_ADDR: Address matched (slave mode) - * @arg SMBUS_FLAG_AF NACK received flag - * @arg SMBUS_FLAG_STOPF: STOP detection flag - * @arg SMBUS_FLAG_TC: Transfer complete (master mode) - * @arg SMBUS_FLAG_TCR: Transfer complete reload - * @arg SMBUS_FLAG_BERR: Bus error - * @arg SMBUS_FLAG_ARLO: Arbitration lost - * @arg SMBUS_FLAG_OVR: Overrun/Underrun - * @arg SMBUS_FLAG_PECERR: PEC error in reception - * @arg SMBUS_FLAG_TIMEOUT: Timeout or Tlow detection flag - * @arg SMBUS_FLAG_ALERT: SMBus alert - * @arg SMBUS_FLAG_BUSY: Bus busy - * @arg SMBUS_FLAG_DIR: Transfer direction (slave mode) + * @arg @ref SMBUS_FLAG_TXE Transmit data register empty + * @arg @ref SMBUS_FLAG_TXIS Transmit interrupt status + * @arg @ref SMBUS_FLAG_RXNE Receive data register not empty + * @arg @ref SMBUS_FLAG_ADDR Address matched (slave mode) + * @arg @ref SMBUS_FLAG_AF NACK received flag + * @arg @ref SMBUS_FLAG_STOPF STOP detection flag + * @arg @ref SMBUS_FLAG_TC Transfer complete (master mode) + * @arg @ref SMBUS_FLAG_TCR Transfer complete reload + * @arg @ref SMBUS_FLAG_BERR Bus error + * @arg @ref SMBUS_FLAG_ARLO Arbitration lost + * @arg @ref SMBUS_FLAG_OVR Overrun/Underrun + * @arg @ref SMBUS_FLAG_PECERR PEC error in reception + * @arg @ref SMBUS_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref SMBUS_FLAG_ALERT SMBus alert + * @arg @ref SMBUS_FLAG_BUSY Bus busy + * @arg @ref SMBUS_FLAG_DIR Transfer direction (slave mode) + * * @retval The new state of __FLAG__ (TRUE or FALSE). */ -#define SMBUS_FLAG_MASK ((uint32_t)0x0001FFFFU) +#define SMBUS_FLAG_MASK (0x0001FFFFU) #define __HAL_SMBUS_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & ((__FLAG__) & SMBUS_FLAG_MASK)) == ((__FLAG__) & SMBUS_FLAG_MASK))) - -/** @brief Clears the SMBUS pending flags which are cleared by writing 1 in a specific bit. - * @param __HANDLE__: specifies the SMBUS Handle. - * This parameter can be SMBUSx where x: 1 or 2 to select the SMBUS peripheral. - * @param __FLAG__: specifies the flag to clear. + +/** @brief Clear the SMBUS pending flags which are cleared by writing 1 in a specific bit. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __FLAG__ specifies the flag to clear. * This parameter can be any combination of the following values: - * @arg SMBUS_FLAG_ADDR: Address matched (slave mode) - * @arg SMBUS_FLAG_AF: NACK received flag - * @arg SMBUS_FLAG_STOPF: STOP detection flag - * @arg SMBUS_FLAG_BERR: Bus error - * @arg SMBUS_FLAG_ARLO: Arbitration lost - * @arg SMBUS_FLAG_OVR: Overrun/Underrun - * @arg SMBUS_FLAG_PECERR: PEC error in reception - * @arg SMBUS_FLAG_TIMEOUT: Timeout or Tlow detection flag - * @arg SMBUS_FLAG_ALERT: SMBus alert + * @arg @ref SMBUS_FLAG_ADDR Address matched (slave mode) + * @arg @ref SMBUS_FLAG_AF NACK received flag + * @arg @ref SMBUS_FLAG_STOPF STOP detection flag + * @arg @ref SMBUS_FLAG_BERR Bus error + * @arg @ref SMBUS_FLAG_ARLO Arbitration lost + * @arg @ref SMBUS_FLAG_OVR Overrun/Underrun + * @arg @ref SMBUS_FLAG_PECERR PEC error in reception + * @arg @ref SMBUS_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref SMBUS_FLAG_ALERT SMBus alert + * * @retval None */ -#define __HAL_SMBUS_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = ((__FLAG__) & SMBUS_FLAG_MASK)) - +#define __HAL_SMBUS_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) -#define __HAL_SMBUS_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) -#define __HAL_SMBUS_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE) +/** @brief Enable the specified SMBUS peripheral. + * @param __HANDLE__ specifies the SMBUS Handle. + * @retval None + */ +#define __HAL_SMBUS_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) -#define __SMBUS_RESET_CR1(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= (uint32_t)~((uint32_t)(I2C_CR1_SMBHEN | I2C_CR1_SMBDEN | I2C_CR1_PECEN))) -#define __SMBUS_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN))) +/** @brief Disable the specified SMBUS peripheral. + * @param __HANDLE__ specifies the SMBUS Handle. + * @retval None + */ +#define __HAL_SMBUS_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) -#define __SMBUS_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == SMBUS_ADDRESSINGMODE_7BIT) ? (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & (~I2C_CR2_RD_WRN)) : \ +/** @brief Generate a Non-Acknowledge SMBUS peripheral in Slave mode. + * @param __HANDLE__ specifies the SMBUS Handle. + * @retval None + */ +#define __HAL_SMBUS_GENERATE_NACK(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR2, I2C_CR2_NACK)) + +/** + * @} + */ + + +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SMBUS_Private_Macro SMBUS Private Macros + * @{ + */ + +#define IS_SMBUS_ANALOG_FILTER(FILTER) (((FILTER) == SMBUS_ANALOGFILTER_ENABLE) || \ + ((FILTER) == SMBUS_ANALOGFILTER_DISABLE)) + +#define IS_SMBUS_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) + +#define IS_SMBUS_ADDRESSING_MODE(MODE) (((MODE) == SMBUS_ADDRESSINGMODE_7BIT) || \ + ((MODE) == SMBUS_ADDRESSINGMODE_10BIT)) + +#define IS_SMBUS_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == SMBUS_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == SMBUS_DUALADDRESS_ENABLE)) + +#define IS_SMBUS_OWN_ADDRESS2_MASK(MASK) (((MASK) == SMBUS_OA2_NOMASK) || \ + ((MASK) == SMBUS_OA2_MASK01) || \ + ((MASK) == SMBUS_OA2_MASK02) || \ + ((MASK) == SMBUS_OA2_MASK03) || \ + ((MASK) == SMBUS_OA2_MASK04) || \ + ((MASK) == SMBUS_OA2_MASK05) || \ + ((MASK) == SMBUS_OA2_MASK06) || \ + ((MASK) == SMBUS_OA2_MASK07)) + +#define IS_SMBUS_GENERAL_CALL(CALL) (((CALL) == SMBUS_GENERALCALL_DISABLE) || \ + ((CALL) == SMBUS_GENERALCALL_ENABLE)) + +#define IS_SMBUS_NO_STRETCH(STRETCH) (((STRETCH) == SMBUS_NOSTRETCH_DISABLE) || \ + ((STRETCH) == SMBUS_NOSTRETCH_ENABLE)) + +#define IS_SMBUS_PEC(PEC) (((PEC) == SMBUS_PEC_DISABLE) || \ + ((PEC) == SMBUS_PEC_ENABLE)) + +#define IS_SMBUS_PERIPHERAL_MODE(MODE) (((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_HOST) || \ + ((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || \ + ((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP)) + +#define IS_SMBUS_TRANSFER_MODE(MODE) (((MODE) == SMBUS_RELOAD_MODE) || \ + ((MODE) == SMBUS_AUTOEND_MODE) || \ + ((MODE) == SMBUS_SOFTEND_MODE) || \ + ((MODE) == SMBUS_SENDPEC_MODE) || \ + ((MODE) == (SMBUS_RELOAD_MODE | SMBUS_SENDPEC_MODE)) || \ + ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE)) || \ + ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_RELOAD_MODE)) || \ + ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE | SMBUS_RELOAD_MODE ))) + + +#define IS_SMBUS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == SMBUS_GENERATE_STOP) || \ + ((REQUEST) == SMBUS_GENERATE_START_READ) || \ + ((REQUEST) == SMBUS_GENERATE_START_WRITE) || \ + ((REQUEST) == SMBUS_NO_STARTSTOP)) + + +#define IS_SMBUS_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == SMBUS_FIRST_FRAME) || \ + ((REQUEST) == SMBUS_NEXT_FRAME) || \ + ((REQUEST) == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || \ + ((REQUEST) == SMBUS_LAST_FRAME_NO_PEC) || \ + ((REQUEST) == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || \ + ((REQUEST) == SMBUS_LAST_FRAME_WITH_PEC) || \ + IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST)) + +#define IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == SMBUS_OTHER_FRAME_NO_PEC) || \ + ((REQUEST) == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC) || \ + ((REQUEST) == SMBUS_OTHER_FRAME_WITH_PEC) || \ + ((REQUEST) == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)) + +#define SMBUS_RESET_CR1(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= (uint32_t)~((uint32_t)(I2C_CR1_SMBHEN | I2C_CR1_SMBDEN | I2C_CR1_PECEN))) +#define SMBUS_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN))) + +#define SMBUS_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == SMBUS_ADDRESSINGMODE_7BIT) ? (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & (~I2C_CR2_RD_WRN)) : \ (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_ADD10) | (I2C_CR2_START)) & (~I2C_CR2_RD_WRN))) -#define __SMBUS_GET_ADDR_MATCH(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) >> 17U) -#define __SMBUS_GET_DIR(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) >> 16U) -#define __SMBUS_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND) -#define __SMBUS_GET_PEC_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_PECBYTE) -#define __SMBUS_GET_ALERT_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 & I2C_CR1_ALERTEN) -#define __HAL_SMBUS_GENERATE_NACK(__HANDLE__) ((__HANDLE__)->Instance->CR2 |= I2C_CR2_NACK) +#define SMBUS_GET_ADDR_MATCH(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) >> 17U) +#define SMBUS_GET_DIR(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) >> 16U) +#define SMBUS_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND) +#define SMBUS_GET_PEC_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_PECBYTE) +#define SMBUS_GET_ALERT_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR1 & I2C_CR1_ALERTEN) -#define IS_SMBUS_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= (uint32_t)0x000003FFU) +#define SMBUS_GET_ISR_REG(__HANDLE__) ((__HANDLE__)->Instance->ISR) +#define SMBUS_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & ((__FLAG__) & SMBUS_FLAG_MASK)) == ((__FLAG__) & SMBUS_FLAG_MASK))) + +#define IS_SMBUS_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x000003FFU) #define IS_SMBUS_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU) + /** * @} - */ - + */ /* Exported functions --------------------------------------------------------*/ -/** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions +/** @addtogroup SMBUS_Exported_Functions SMBUS Exported Functions * @{ */ -/* Initialization and de-initialization functions ****************************/ -/* IO operation functions ****************************************************/ -/** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions - * @{ - */ +/** @addtogroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions **********************************/ HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus); -HAL_StatusTypeDef HAL_SMBUS_DeInit (SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus); void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus); void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter); +HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter); + /** * @} - */ - -/* IO operation functions ****************************************************/ -/** @defgroup SMBUS_Exported_Functions_Group2 IO operation functions - * @{ */ -HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus); -HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus); -HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus); -HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus); -/* Aliases for inter STM32 series compatibility */ -#define HAL_SMBUS_EnableListen_IT HAL_SMBUS_EnableListen_IT +/** @addtogroup SMBUS_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ + +/* IO operation functions *****************************************************/ +/** @addtogroup Blocking_mode_Polling Blocking mode Polling + * @{ + */ /******* Blocking mode: Polling */ HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); +/** + * @} + */ +/** @addtogroup Non-Blocking_mode_Interrupt Non-Blocking mode Interrupt + * @{ + */ /******* Non-Blocking mode: Interrupt */ HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); @@ -555,6 +626,17 @@ HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_ HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions); HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus); +/** + * @} + */ + +/** @addtogroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ /******* SMBUS IRQHandler and Callbacks used in non blocking modes (Interrupt) */ void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus); void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus); @@ -564,39 +646,40 @@ void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus); void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus); void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode); void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus); -/* Aliases for inter STM32 series compatibility */ -#define HAL_SMBUS_AddrCallback HAL_SMBUS_AddrCallback -#define HAL_SMBUS_ListenCpltCallback HAL_SMBUS_ListenCpltCallback - void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus); + /** * @} */ -/* Peripheral State and Errors functions *************************************/ -/** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions - * @{ - */ +/** @addtogroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions + * @{ + */ + +/* Peripheral State and Errors functions **************************************************/ uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus); uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus); /** * @} - */ + */ /** * @} - */ + */ -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup SMBUS_Private SMBUS_Private +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup SMBUS_Private_Functions SMBUS Private Functions * @{ */ +/* Private functions are defined in stm32l0xx_hal_smbus.c file */ +/** + * @} + */ + /** * @} */ -/**************************************************************/ /** * @} @@ -605,6 +688,7 @@ uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus); /** * @} */ + #ifdef __cplusplus } #endif @@ -613,5 +697,3 @@ uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus); #endif /* __STM32L0xx_HAL_SMBUS_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c index a98f2ee6d3..9ef6dcd9f1 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_spi.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief SPI HAL module driver. * * This file provides firmware functions to manage the following @@ -53,7 +51,45 @@ (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks - [..] + @note + (#) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA() + (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA() + (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA() + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2016 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + */ + +/* + Additional Table: + Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes, the following table resume the max SPI frequency reached with data size 8bits/16bits, according to frequency used on APBx Peripheral Clock (fPCLK) used by the SPI instance : @@ -109,41 +145,7 @@ +----------------------------------------------------------------------------------------------+ @note The max SPI frequency depend on SPI data size (8bits, 16bits), SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA). - @note - (#) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA() - (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA() - (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA() - - @endverbatim - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2016 STMicroelectronics

- * - * 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. - * - ****************************************************************************** - */ +*/ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal.h" diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.h index 42dfde9b1b..a0270e4475 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_spi.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of SPI HAL module. ****************************************************************************** * @attention @@ -131,13 +129,13 @@ typedef struct __SPI_HandleTypeDef uint16_t TxXferSize; /*!< SPI Tx transfer size */ - uint16_t TxXferCount; /*!< SPI Tx Transfer Counter */ + __IO uint16_t TxXferCount; /*!< SPI Tx Transfer Counter */ uint8_t *pRxBuffPtr; /*!< Pointer to SPI Rx transfer Buffer */ uint16_t RxXferSize; /*!< SPI Rx transfer size */ - uint16_t RxXferCount; /*!< SPI Rx Transfer Counter */ + __IO uint16_t RxXferCount; /*!< SPI Rx Transfer Counter */ DMA_HandleTypeDef *hdmatx; /*!< SPI Tx DMA handle parameters */ @@ -396,10 +394,10 @@ typedef struct __SPI_HandleTypeDef */ #define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__) \ do{ \ - __IO uint32_t tmpreg; \ - tmpreg = (__HANDLE__)->Instance->SR; \ + __IO uint32_t tmpreg_modf; \ + tmpreg_modf = (__HANDLE__)->Instance->SR; \ (__HANDLE__)->Instance->CR1 &= (~SPI_CR1_SPE); \ - UNUSED(tmpreg); \ + UNUSED(tmpreg_modf); \ } while(0) /** @brief Clear the SPI OVR pending flag. @@ -409,10 +407,10 @@ typedef struct __SPI_HandleTypeDef */ #define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) \ do{ \ - __IO uint32_t tmpreg; \ - tmpreg = (__HANDLE__)->Instance->DR; \ - tmpreg = (__HANDLE__)->Instance->SR; \ - UNUSED(tmpreg); \ + __IO uint32_t tmpreg_ovr; \ + tmpreg_ovr = (__HANDLE__)->Instance->DR; \ + tmpreg_ovr = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg_ovr); \ } while(0) /** @brief Clear the SPI FRE pending flag. @@ -422,9 +420,9 @@ typedef struct __SPI_HandleTypeDef */ #define __HAL_SPI_CLEAR_FREFLAG(__HANDLE__) \ do{ \ - __IO uint32_t tmpreg; \ - tmpreg = (__HANDLE__)->Instance->SR; \ - UNUSED(tmpreg); \ + __IO uint32_t tmpreg_fre; \ + tmpreg_fre = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg_fre); \ } while(0) /** @brief Enables the SPI. diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim.c index 1708b3964a..a431331ded 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_tim.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief TIM HAL module driver. * @brief This file provides firmware functions to manage the following * functionalities of the Timer (TIM) peripheral: @@ -1109,7 +1107,7 @@ HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) /** * @brief Starts the PWM signal generation in interrupt mode. * @param htim : TIM handle - * @param Channel: TIM Channel to be disabled. + * @param Channel: TIM Channel to be enabled. * This parameter can be one of the following values: * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim.h index e9e47f720f..6f0a885f32 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_tim.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of TIM HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim_ex.c index bac0a17d13..10a2b332fd 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_tim_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief TIM HAL module driver. * @brief This file provides firmware functions to manage the following * functionalities of the Timer (TIM) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim_ex.h index ca1579be49..fcb5c1cf5e 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tim_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_tim_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of TIM HAL module. ****************************************************************************** * @attention @@ -155,10 +153,10 @@ typedef struct { #define TIM21_TI2_COMP2_OUT TIM21_OR_TI2_RMP #if !defined(STM32L011xx) && !defined(STM32L021xx) -#define TIM22_ETR_LSE ((uint32_t)0x0U) +#define TIM22_ETR_GPIO ((uint32_t)0x0U) #define TIM22_ETR_COMP2_OUT TIM22_OR_ETR_RMP_0 #define TIM22_ETR_COMP1_OUT TIM22_OR_ETR_RMP_1 -#define TIM22_ETR_GPIO TIM22_OR_ETR_RMP +#define TIM22_ETR_LSE TIM22_OR_ETR_RMP #define TIM22_TI1_GPIO1 ((uint32_t)0x0U) #define TIM22_TI1_COMP2_OUT TIM22_OR_TI1_RMP_0 #define TIM22_TI1_COMP1_OUT TIM22_OR_TI1_RMP_1 @@ -185,54 +183,54 @@ typedef struct { #define IS_TIM_REMAP(__INSTANCE__, __TIM_REMAP__) \ - (((__INSTANCE__ == TIM2) && ((__TIM_REMAP__) <= (TIM2_OR_TI4_RMP | TIM2_OR_ETR_RMP))) || \ - ((__INSTANCE__ == TIM22) && ((__TIM_REMAP__) <= (TIM22_OR_TI1_RMP | TIM22_OR_ETR_RMP))) || \ - ((__INSTANCE__ == TIM21) && ((__TIM_REMAP__) <= (TIM21_OR_ETR_RMP | TIM21_OR_TI1_RMP | TIM21_OR_TI2_RMP))) || \ - ((__INSTANCE__ == TIM3) && ((__TIM_REMAP__) <= (TIM3_OR_ETR_RMP | TIM3_OR_TI1_RMP | TIM3_OR_TI2_RMP | TIM3_OR_TI4_RMP)))) + ((((__INSTANCE__) == TIM2) && ((__TIM_REMAP__) <= (TIM2_OR_TI4_RMP | TIM2_OR_ETR_RMP))) || \ + (((__INSTANCE__) == TIM22) && ((__TIM_REMAP__) <= (TIM22_OR_TI1_RMP | TIM22_OR_ETR_RMP))) || \ + (((__INSTANCE__) == TIM21) && ((__TIM_REMAP__) <= (TIM21_OR_ETR_RMP | TIM21_OR_TI1_RMP | TIM21_OR_TI2_RMP))) || \ + (((__INSTANCE__) == TIM3) && ((__TIM_REMAP__) <= (TIM3_OR_ETR_RMP | TIM3_OR_TI1_RMP | TIM3_OR_TI2_RMP | TIM3_OR_TI4_RMP)))) #define IS_CHANNEL_AVAILABLE(__INSTANCE__, __CHANNEL__) \ - (((__INSTANCE__ == TIM2) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((((__INSTANCE__) == TIM2) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2) || \ ((__CHANNEL__) == TIM_CHANNEL_3) || \ ((__CHANNEL__) == TIM_CHANNEL_4))) || \ - ((__INSTANCE__ == TIM3) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + (((__INSTANCE__) == TIM3) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2) || \ ((__CHANNEL__) == TIM_CHANNEL_3) || \ ((__CHANNEL__) == TIM_CHANNEL_4))) || \ - ((__INSTANCE__ == TIM21) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + (((__INSTANCE__) == TIM21) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2))) || \ - ((__INSTANCE__ == TIM22) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + (((__INSTANCE__) == TIM22) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2)))) #elif defined (STM32L011xx) || defined (STM32L021xx) #define IS_TIM_REMAP(__INSTANCE__, __TIM_REMAP__) \ - (((__INSTANCE__ == TIM2) && ((__TIM_REMAP__) <= (TIM2_OR_TI4_RMP | TIM2_OR_ETR_RMP))) || \ - ((__INSTANCE__ == TIM21) && ((__TIM_REMAP__) <= (TIM21_OR_ETR_RMP | TIM21_OR_TI1_RMP | TIM21_OR_TI2_RMP)))) + ((((__INSTANCE__) == TIM2) && ((__TIM_REMAP__) <= (TIM2_OR_TI4_RMP | TIM2_OR_ETR_RMP))) || \ + (((__INSTANCE__) == TIM21) && ((__TIM_REMAP__) <= (TIM21_OR_ETR_RMP | TIM21_OR_TI1_RMP | TIM21_OR_TI2_RMP)))) #define IS_CHANNEL_AVAILABLE(__INSTANCE__, __CHANNEL__) \ - (((__INSTANCE__ == TIM2) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((((__INSTANCE__) == TIM2) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2) || \ ((__CHANNEL__) == TIM_CHANNEL_3) || \ ((__CHANNEL__) == TIM_CHANNEL_4))) || \ - ((__INSTANCE__ == TIM21) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + (((__INSTANCE__) == TIM21) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2)))) #else #define IS_TIM_REMAP(__INSTANCE__, __TIM_REMAP__) \ - (((__INSTANCE__ == TIM2) && ((__TIM_REMAP__) <= (TIM2_OR_TI4_RMP | TIM2_OR_ETR_RMP))) || \ - ((__INSTANCE__ == TIM22) && ((__TIM_REMAP__) <= (TIM22_OR_TI1_RMP | TIM22_OR_ETR_RMP))) || \ - ((__INSTANCE__ == TIM21) && ((__TIM_REMAP__) <= (TIM21_OR_ETR_RMP | TIM21_OR_TI1_RMP | TIM21_OR_TI2_RMP)))) + ((((__INSTANCE__) == TIM2) && ((__TIM_REMAP__) <= (TIM2_OR_TI4_RMP | TIM2_OR_ETR_RMP))) || \ + (((__INSTANCE__) == TIM22) && ((__TIM_REMAP__) <= (TIM22_OR_TI1_RMP | TIM22_OR_ETR_RMP))) || \ + (((__INSTANCE__) == TIM21) && ((__TIM_REMAP__) <= (TIM21_OR_ETR_RMP | TIM21_OR_TI1_RMP | TIM21_OR_TI2_RMP)))) #define IS_CHANNEL_AVAILABLE(__INSTANCE__, __CHANNEL__) \ - (((__INSTANCE__ == TIM2) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((((__INSTANCE__) == TIM2) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2) || \ ((__CHANNEL__) == TIM_CHANNEL_3) || \ ((__CHANNEL__) == TIM_CHANNEL_4))) || \ - ((__INSTANCE__ == TIM21) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + (((__INSTANCE__) == TIM21) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2))) || \ - ((__INSTANCE__ == TIM22) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ + (((__INSTANCE__) == TIM22) && (((__CHANNEL__) == TIM_CHANNEL_1) || \ ((__CHANNEL__) == TIM_CHANNEL_2)))) #endif /*defined (STM32L07Xxx) or defined (STM32L08Xxx) */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tsc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tsc.c index daf265ddd3..3487ad06e7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tsc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tsc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_tsc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief This file provides firmware functions to manage the following * functionalities of the Touch Sensing Controller (TSC) peripheral: * + Initialization and DeInitialization diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tsc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tsc.h index 5c7808b41f..cacef337c7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tsc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_tsc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_tsc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief This file contains all the functions prototypes for the TSC firmware * library. ****************************************************************************** @@ -36,7 +34,6 @@ ****************************************************************************** */ -#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined (STM32L051xx) && !defined (STM32L061xx) && !defined (STM32L071xx) && !defined (STM32L081xx) /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32L0xx_TSC_H #define __STM32L0xx_TSC_H @@ -45,6 +42,8 @@ extern "C" { #endif +#if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined (STM32L051xx) && !defined (STM32L061xx) && !defined (STM32L071xx) && !defined (STM32L081xx) + /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal_def.h" diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart.c index 98470850f3..964fc4c44e 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart.c @@ -2,15 +2,13 @@ ****************************************************************************** * @file stm32l0xx_hal_uart.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief UART HAL module driver. - * - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). - * + Initialization and de-initialization methods - * + IO operation methods - * + Peripheral Control methods + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * * @verbatim =============================================================================== @@ -18,110 +16,56 @@ =============================================================================== [..] The UART HAL driver can be used as follows: - - (#) Declare a UART_HandleTypeDef handle structure. - + + (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart). (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: - (##) Enable the USARTx interface clock. - (##) UART pins configuration: + (++) Enable the USARTx interface clock. + (++) UART pins configuration: (+++) Enable the clock for the UART GPIOs. (+++) Configure these UART pins as alternate function pull-up. - (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() + (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() and HAL_UART_Receive_IT() APIs): (+++) Configure the USARTx interrupt priority. (+++) Enable the NVIC USART IRQ handle. - - (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() + (++) UART interrupts handling: + -@@- The specific UART interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) are managed using the macros + __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit and receive processes. + (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() and HAL_UART_Receive_DMA() APIs): - (+++) Declare a DMA handle structure for the Tx/Rx stream. + (+++) Declare a DMA handle structure for the Tx/Rx channel. (+++) Enable the DMAx interface clock. - (+++) Configure the declared DMA handle structure with the required - Tx/Rx parameters. - (+++) Configure the DMA Tx/Rx Stream. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx channel. (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. - (+++) Configure the priority and enable the NVIC for the transfer complete - interrupt on the DMA Tx/Rx Stream. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. - (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware - flow control and Mode(Receiver/Transmitter) in the Init structure. + (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware + flow control and Mode (Receiver/Transmitter) in the huart handle Init structure. + + (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...) + in the huart handle AdvancedInit structure. (#) For the UART asynchronous mode, initialize the UART registers by calling the HAL_UART_Init() API. - (#) For the UART Half duplex mode, initialize the UART registers by calling + (#) For the UART Half duplex mode, initialize the UART registers by calling the HAL_HalfDuplex_Init() API. - (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API. + (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers + by calling the HAL_LIN_Init() API. - (#) For the Multi-Processor mode, initialize the UART registers by calling - the HAL_MultiProcessor_Init() API. + (#) For the UART Multiprocessor mode, initialize the UART registers + by calling the HAL_MultiProcessor_Init() API. - [..] - (@) The specific UART interrupts (Transmission complete interrupt, - RXNE interrupt and Error Interrupts) will be managed using the macros - __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit - and receive process. + (#) For the UART RS485 Driver Enabled mode, initialize the UART registers + by calling the HAL_RS485Ex_Init() API. - [..] - (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the - low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customed - HAL_UART_MspInit() API. + [..] + (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(), + also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by + calling the customized HAL_UART_MspInit() API. - [..] - Three operation modes are available within this driver : - - *** Polling mode IO operation *** - ================================= - [..] - (+) Send an amount of data in blocking mode using HAL_UART_Transmit() - (+) Receive an amount of data in blocking mode using HAL_UART_Receive() - - -*** Interrupt mode IO operation *** - =================================== - [..] - (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT() - (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_UART_TxCpltCallback - (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT() - (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_UART_RxCpltCallback - (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_UART_ErrorCallback - - *** DMA mode IO operation *** - ============================== - [..] - (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA() - (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can - add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback - (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_UART_TxCpltCallback - (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA() - (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can - add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback - (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_UART_RxCpltCallback - (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_UART_ErrorCallback - (+) Pause the DMA Transfer using HAL_UART_DMAPause() - (+) Resume the DMA Transfer using HAL_UART_DMAResume() - (+) Stop the DMA Transfer using HAL_UART_DMAStop() - - *** UART HAL driver macros list *** - ============================================= - [..] - Below the list of most used macros in UART HAL driver. - - (+) __HAL_UART_ENABLE: Enable the UART peripheral - (+) __HAL_UART_DISABLE: Disable the UART peripheral - (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not - (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag - (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt - (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt - - [..] - (@) You can refer to the UART HAL driver header file for more useful macros @endverbatim ****************************************************************************** * @attention @@ -150,7 +94,7 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -160,57 +104,71 @@ * @{ */ +/** @defgroup UART UART + * @brief HAL UART module driver + * @{ + */ + #ifdef HAL_UART_MODULE_ENABLED - -/** @addtogroup UART - * @brief UART module driver - * @{ - */ - -/** @addtogroup UART_Private - * @{ - */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -#define UART_TIMEOUT_VALUE ((uint32_t) 22000U) +/** @defgroup UART_Private_Constants UART Private Constants + * @{ + */ #define UART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ - USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); -static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); -static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); -static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); -static void UART_DMAError(DMA_HandleTypeDef *hdma); -static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart); -static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart); -static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart); + USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ +#define UART_LPUART_BRR_MIN ((uint32_t)0x00000300) /* LPUART BRR minimum authorized value */ +#define UART_LPUART_BRR_MAX ((uint32_t)0x000FFFFF) /* LPUART BRR maximum authorized value */ /** * @} */ -/* Private functions ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup UART_Private_Functions + * @{ + */ +static void UART_EndTxTransfer(UART_HandleTypeDef *huart); +static void UART_EndRxTransfer(UART_HandleTypeDef *huart); +static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +static void UART_DMAError(DMA_HandleTypeDef *hdma); +static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart); +static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart); +static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart); +/** + * @} + */ -/** @addtogroup UART_Exported_Functions UART Exported Functions +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup UART_Exported_Functions UART Exported Functions * @{ */ -/** @addtogroup UART_Exported_Functions_Group1 - * @brief Initialization and Configuration functions +/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions * -@verbatim +@verbatim =============================================================================== ##### Initialization and Configuration functions ##### =============================================================================== [..] - This subsection provides a set of functions allowing to initialize the USARTx or the UARTy + This subsection provides a set of functions allowing to initialize the USARTx or the UARTy in asynchronous mode. - (+) For the asynchronous mode only these parameters can be configured: + (+) For the asynchronous mode the parameters below can be configured: (++) Baud Rate - (++) Word Length + (++) 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. @@ -227,41 +185,41 @@ static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart); (++) MSB first on communication line (++) auto Baud rate detection [..] - The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessorEx_Init()API + The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API follow respectively the UART asynchronous, UART Half duplex, UART LIN mode - and UART multiprocessor mode mode configuration procedures (details for the procedures + and UART multiprocessor mode configuration procedures (details for the procedures are available in reference manual). @endverbatim - Depending on the frame length defined by the M1 and M0 bits (7-bit, - 8-bit or 9-bit), the possible UART formats are listed in the + Depending on the frame length defined by the M1 and M0 bits (7-bit, + 8-bit or 9-bit), the possible UART formats are listed in the following table. - + Table 1. UART frame format. - +-----------------------------------------------------------------------+ - | M1 bit | M0 bit | PCE bit | USART frame | - |---------|---------|-----------|---------------------------------------| - | 0 | 0 | 0 | | SB | 8 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 1 | 0 | | SB | 9 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | - |---------|---------|-----------|---------------------------------------| - | 1 | 0 | 0 | | SB | 7 bit data | STB | | - |---------|---------|-----------|---------------------------------------| - | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | - +-----------------------------------------------------------------------+ + +-----------------------------------------------------------------------+ + | M1 bit | M0 bit | PCE bit | UART frame | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 0 | | SB | 8 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 0 | | SB | 9 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 0 | | SB | 7 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + +-----------------------------------------------------------------------+ * @{ */ /** - * @brief Initializes the UART mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle . - * @param huart: uart handle + * @brief Initialize the UART mode according to the specified + * parameters in the UART_InitTypeDef and initialize the associated handle. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) @@ -271,7 +229,7 @@ HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) { return HAL_ERROR; } - + if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) { /* Check the parameters */ @@ -282,46 +240,49 @@ HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) /* Check the parameters */ assert_param(IS_UART_INSTANCE(huart->Instance)); } - + if(huart->gState == HAL_UART_STATE_RESET) { /* Allocate lock resource and initialize it */ huart->Lock = HAL_UNLOCKED; - /* Init the low level hardware : GPIO, CLOCK, CORTEX */ + /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); } - + huart->gState = HAL_UART_STATE_BUSY; /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + /* Set the UART Communication parameters */ - UART_SetConfig(huart); - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { UART_AdvFeatureConfig(huart); } - - /* In asynchronous mode, the following bits must be kept cleared: + + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In asynchronous mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ - huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); - huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); - + CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); + /* Enable the Peripheral */ __HAL_UART_ENABLE(huart); - + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ return (UART_CheckIdleState(huart)); } /** - * @brief Initializes the half-duplex mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle . - * @param huart: uart handle + * @brief Initialize the half-duplex mode according to the specified + * parameters in the UART_InitTypeDef and creates the associated handle. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) @@ -331,54 +292,60 @@ HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) { return HAL_ERROR; } - + /* Check UART instance */ assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance)); - if(huart->gState == HAL_UART_STATE_RESET) - { - /* Init the low level hardware : GPIO, CLOCK, CORTEX */ + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + + /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); } - + huart->gState = HAL_UART_STATE_BUSY; /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + /* Set the UART Communication parameters */ - UART_SetConfig(huart); - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { UART_AdvFeatureConfig(huart); } - - /* In half-duplex mode, the following bits must be kept cleared: + + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* 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.*/ - huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); - huart->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_SCEN); - + CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN)); + /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ - huart->Instance->CR3 |= USART_CR3_HDSEL; - + SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL); + /* Enable the Peripheral */ __HAL_UART_ENABLE(huart); - + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ return (UART_CheckIdleState(huart)); } + /** - * @brief Initializes the LIN mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle . - * @param huart: uart handle + * @brief Initialize the LIN mode according to the specified + * parameters in the UART_InitTypeDef and creates the associated handle . + * @param huart: UART handle. * @param BreakDetectLength: specifies the LIN break detection length. * This parameter can be one of the following values: - * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection - * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection + * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection + * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection * @retval HAL status */ HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength) @@ -388,78 +355,84 @@ HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLe { return HAL_ERROR; } + /* Check the LIN UART instance */ assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); - /* Check the Break detection length parameter */ assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength)); - + /* LIN mode limited to 16-bit oversampling only */ if(huart->Init.OverSampling == UART_OVERSAMPLING_8) { return HAL_ERROR; } - - /* in LIN mode limited, data length limited to 8-bit only */ - if(huart->Init.WordLength!= UART_WORDLENGTH_8B) + /* LIN mode limited to 8-bit data length */ + if(huart->Init.WordLength != UART_WORDLENGTH_8B) { return HAL_ERROR; } if(huart->gState == HAL_UART_STATE_RESET) - { - /* Init the low level hardware : GPIO, CLOCK, CORTEX */ + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + + /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); } - + huart->gState = HAL_UART_STATE_BUSY; /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + /* Set the UART Communication parameters */ - UART_SetConfig(huart); - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { UART_AdvFeatureConfig(huart); } - - /* In LIN mode, the following bits must be kept cleared: + + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In LIN 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.*/ - huart->Instance->CR2 &= ~(USART_CR2_CLKEN); - huart->Instance->CR3 &= ~(USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN); - + CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN); + CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN)); + /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ - huart->Instance->CR2 |= USART_CR2_LINEN; - + SET_BIT(huart->Instance->CR2, USART_CR2_LINEN); + /* Set the USART LIN Break detection length. */ MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength); - - /* Enable the Peripheral */ + + /* Enable the Peripheral */ __HAL_UART_ENABLE(huart); - + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ return (UART_CheckIdleState(huart)); } + /** - * @brief Initializes the multiprocessor mode according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle. - * @param huart: UART handle - * @param Address: UART node address (4-, 6-, 7- or 8-bit long) + * @brief Initialize the multiprocessor mode according to the specified + * parameters in the UART_InitTypeDef and initialize the associated handle. + * @param huart: UART handle. + * @param Address: UART node address (4-, 6-, 7- or 8-bit long). * @param WakeUpMethod: specifies the UART wakeup method. * This parameter can be one of the following values: - * @arg UART_WAKEUPMETHOD_IDLELINE: WakeUp by an idle line detection - * @arg UART_WAKEUPMETHOD_ADDRESSMARK: WakeUp by an address mark + * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection + * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark * @note If the user resorts to idle line detection wake up, the Address parameter - * is useless and ignored by the initialization function. - * @note If the user resorts to address mark wake up, the address length detection - * is configured by default to 4 bits only. For the UART to be able to + * is useless and ignored by the initialization function. + * @note If the user resorts to address mark wake up, the address length detection + * is configured by default to 4 bits only. For the UART to be able to * manage 6-, 7- or 8-bit long addresses detection, the API - * HAL_MultiProcessorEx_AddressLength_Set() must be called after - * HAL_MultiProcessor_Init(). + * HAL_MultiProcessorEx_AddressLength_Set() must be called after + * HAL_MultiProcessor_Init(). * @retval HAL status */ HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) @@ -472,51 +445,58 @@ HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Add /* Check the wake up method parameter */ assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); - + if(huart->gState == HAL_UART_STATE_RESET) - { + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); } - + huart->gState = HAL_UART_STATE_BUSY; - + /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + /* Set the UART Communication parameters */ - UART_SetConfig(huart); - if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { UART_AdvFeatureConfig(huart); } - - /* In multiprocessor mode, the following bits must be kept cleared: + + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In multiprocessor mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register. */ - huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); - huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); - + CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); + if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK) { /* If address mark wake up method is chosen, set the USART address node */ MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS)); } - + /* Set the wake up method by setting the WAKE bit in the CR1 register */ MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod); - + /* Enable the Peripheral */ - __HAL_UART_ENABLE(huart); - + __HAL_UART_ENABLE(huart); + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ return (UART_CheckIdleState(huart)); } + /** - * @brief DeInitializes the UART peripheral - * @param huart: uart handle + * @brief DeInitialize the UART peripheral. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) @@ -526,70 +506,70 @@ HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) { return HAL_ERROR; } - + /* Check the parameters */ assert_param(IS_UART_INSTANCE(huart->Instance)); huart->gState = HAL_UART_STATE_BUSY; - + /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + huart->Instance->CR1 = 0x0U; huart->Instance->CR2 = 0x0U; huart->Instance->CR3 = 0x0U; - + /* DeInit the low level hardware */ HAL_UART_MspDeInit(huart); huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->gState = HAL_UART_STATE_RESET; - huart->RxState = HAL_UART_STATE_RESET; - - /* Release Lock */ + huart->gState = HAL_UART_STATE_RESET; + huart->RxState = HAL_UART_STATE_RESET; + + /* Process Unlock */ __HAL_UNLOCK(huart); - + return HAL_OK; } /** - * @brief UART MSP Init - * @param huart: uart handle + * @brief Initialize the UART MSP. + * @param huart: UART handle. * @retval None */ - __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) +__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); /* NOTE : This function should not be modified, when the callback is needed, the HAL_UART_MspInit can be implemented in the user file - */ + */ } /** - * @brief UART MSP DeInit - * @param huart: uart handle + * @brief DeInitialize the UART MSP. + * @param huart: UART handle. * @retval None */ - __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) +__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); /* NOTE : This function should not be modified, when the callback is needed, the HAL_UART_MspDeInit can be implemented in the user file - */ + */ } /** * @} */ -/** @addtogroup UART_Exported_Functions_Group2 - * @brief UART Transmit/Receive functions +/** @defgroup UART_Exported_Functions_Group2 IO operation functions + * @brief UART Transmit/Receive functions * -@verbatim +@verbatim =============================================================================== ##### IO operation functions ##### =============================================================================== @@ -597,44 +577,66 @@ HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) and Half duplex data transfers. (#) There are two mode of transfer: - (+) Blocking mode: The communication is performed in polling mode. - The HAL status of all data processing is returned by the same function - after finishing transfer. - (+) No-Blocking mode: The communication is performed using Interrupts + (+) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (+) Non-Blocking mode: The communication is performed using Interrupts or DMA, These API's return the HAL status. - The end of the data processing will be indicated through the - dedicated UART IRQ when using Interrupt mode or the DMA IRQ when + The end of the data processing will be indicated through the + dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. - The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks - will be executed respectivelly at the end of the transmit or Receive process + The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected (#) Blocking mode API's are : (+) HAL_UART_Transmit() - (+) HAL_UART_Receive() - + (+) HAL_UART_Receive() + (#) Non-Blocking mode API's with Interrupt are : (+) HAL_UART_Transmit_IT() (+) HAL_UART_Receive_IT() (+) HAL_UART_IRQHandler() - (+) UART_Transmit_IT() - (+) UART_Receive_IT() - (#) No-Blocking mode API's with DMA are : + (#) Non-Blocking mode API's with DMA are : (+) HAL_UART_Transmit_DMA() (+) HAL_UART_Receive_DMA() (+) HAL_UART_DMAPause() (+) HAL_UART_DMAResume() (+) HAL_UART_DMAStop() - (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: + (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: (+) HAL_UART_TxHalfCpltCallback() (+) HAL_UART_TxCpltCallback() (+) HAL_UART_RxHalfCpltCallback() (+) HAL_UART_RxCpltCallback() (+) HAL_UART_ErrorCallback() - -@- In the Half duplex communication, it is forbidden to run the transmit + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (+) HAL_UART_Abort() + (+) HAL_UART_AbortTransmit() + (+) HAL_UART_AbortReceive() + (+) HAL_UART_Abort_IT() + (+) HAL_UART_AbortTransmit_IT() + (+) HAL_UART_AbortReceive_IT() + + (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided: + (+) HAL_UART_AbortCpltCallback() + (+) HAL_UART_AbortTransmitCpltCallback() + (+) HAL_UART_AbortReceiveCpltCallback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, + and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side. + If user wants to abort it, Abort services should be called by user. + (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed. + + -@- In the Half duplex communication, it is forbidden to run the transmit and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful. @endverbatim @@ -642,17 +644,21 @@ HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) */ /** - * @brief Send an amount of data in blocking mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent - * @param Timeout : Timeout duration + * @brief Send an amount of data in blocking mode. + * @param huart: UART handle. + * @param pData: Pointer to data buffer. + * @param Size: Amount of data to be sent. + * @param Timeout: Timeout duration. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) { - uint16_t* tmp; - + uint16_t* tmp; + uint32_t tickstart = 0; /* Check that a Tx process is not already ongoing */ if(huart->gState == HAL_UART_STATE_READY) @@ -662,22 +668,35 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u return HAL_ERROR; } + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(huart); huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_BUSY_TX; + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); huart->TxXferSize = Size; huart->TxXferCount = Size; while(huart->TxXferCount > 0U) { huart->TxXferCount--; - if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) { tmp = (uint16_t*) pData; @@ -689,12 +708,13 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u huart->Instance->TDR = (*pData++ & (uint8_t)0xFFU); } } - if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, Timeout) != HAL_OK) - { + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } + /* At end of Tx process, restore huart->gState to Ready */ - huart->gState = HAL_UART_STATE_READY; + huart->gState = HAL_UART_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(huart); @@ -708,17 +728,22 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u } /** - * @brief Receive an amount of data in blocking mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received - * @param Timeout : Timeout duration + * @brief Receive an amount of data in blocking mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be received. + * @param Timeout: Timeout duration. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer for storing data to be received, should be aligned on a half word frontier (16 bits) + * (as received data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint16_t uhMask; + uint32_t tickstart = 0; /* Check that a Rx process is not already ongoing */ if(huart->RxState == HAL_UART_STATE_READY) @@ -728,13 +753,27 @@ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, ui return HAL_ERROR; } + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be received from RDR will be + handled through a u16 cast. */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(huart); huart->ErrorCode = HAL_UART_ERROR_NONE; huart->RxState = HAL_UART_STATE_BUSY_RX; - huart->RxXferSize = Size; + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + + huart->RxXferSize = Size; huart->RxXferCount = Size; /* Computation of UART mask to apply to RDR register */ @@ -745,19 +784,19 @@ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, ui while(huart->RxXferCount > 0U) { huart->RxXferCount--; - if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) { tmp = (uint16_t*) pData ; *tmp = (uint16_t)(huart->Instance->RDR & uhMask); - pData +=2U; + pData +=2U; } else { - *pData++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); + *pData++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); } } @@ -776,54 +815,70 @@ HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, ui } /** - * @brief Send an amount of data in interrupt mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @brief Send an amount of data in interrupt mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be sent. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) -{ +{ /* Check that a Tx process is not already ongoing */ if(huart->gState == HAL_UART_STATE_READY) { - if((pData == NULL ) || (Size == 0U)) + if((pData == NULL ) || (Size == 0U)) { return HAL_ERROR; } - + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(huart); - + huart->pTxBuffPtr = pData; huart->TxXferSize = Size; huart->TxXferCount = Size; - + huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_BUSY_TX; - - /* Enable the UART Parity Error Interrupt */ - __HAL_UART_ENABLE_IT(huart, UART_IT_PE); - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - /* Enable the UART Transmit data register empty Interrupt */ - __HAL_UART_ENABLE_IT(huart, UART_IT_TXE); - + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + /* Enable the UART Transmit Data Register Empty Interrupt */ + SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Receive an amount of data in interrupt mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received + * @brief Receive an amount of data in interrupt mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be received. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) @@ -831,11 +886,22 @@ HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, /* Check that a Rx process is not already ongoing */ if(huart->RxState == HAL_UART_STATE_READY) { - if((pData == NULL ) || (Size == 0U)) + if((pData == NULL ) || (Size == 0U)) { return HAL_ERROR; } + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be received from RDR will be + handled through a u16 cast. */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(huart); @@ -849,37 +915,36 @@ HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, huart->ErrorCode = HAL_UART_ERROR_NONE; huart->RxState = HAL_UART_STATE_BUSY_RX; - /* Enable the UART Parity Error Interrupt */ - __HAL_UART_ENABLE_IT(huart, UART_IT_PE); - - /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_UART_ENABLE_IT(huart, UART_IT_ERR); - /* Process Unlocked */ __HAL_UNLOCK(huart); - /* Enable the UART Data Register not empty Interrupt */ - __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Enable the UART Parity Error and Data Register not empty Interrupts */ + SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Send an amount of data in DMA mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @brief Send an amount of data in DMA mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be sent. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { - uint32_t *tmp; - /* Check that a Tx process is not already ongoing */ if(huart->gState == HAL_UART_STATE_READY) { @@ -887,135 +952,176 @@ HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pDat { return HAL_ERROR; } - + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data copy into TDR will be + handled by DMA from a u16 frontier. */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(huart); - + huart->pTxBuffPtr = pData; huart->TxXferSize = Size; - huart->TxXferCount = Size; - + huart->TxXferCount = Size; + huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_BUSY_TX; - - /* Set the UART DMA transfert complete callback */ + + /* Set the UART DMA transfer complete callback */ huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; - + /* Set the UART DMA Half transfer complete callback */ huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; - + /* Set the DMA error callback */ huart->hdmatx->XferErrorCallback = UART_DMAError; - /* Enable the UART transmit DMA Stream */ - tmp = (uint32_t*)&pData; - HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->TDR, Size); - - /* Clear the TC flag in the SR register by writing 0 to it */ - __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC); + /* Set the DMA abort callback */ + huart->hdmatx->XferAbortCallback = NULL; + + /* Enable the UART transmit DMA channel */ + HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size); + + /* Clear the TC flag in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); + + /* Process Unlocked */ + __HAL_UNLOCK(huart); /* Enable the DMA transfer for transmit request by setting the DMAT bit in the UART CR3 register */ - huart->Instance->CR3 |= USART_CR3_DMAT; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - + SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Receive an amount of data in DMA mode - * @param huart: uart handle - * @param pData: pointer to data buffer - * @param Size: amount of data to be received + * @brief Receive an amount of data in DMA mode. + * @param huart: UART handle. + * @param pData: pointer to data buffer. + * @param Size: amount of data to be received. * @note When the UART parity is enabled (PCE = 1) the data received contain the parity bit. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pData. * @retval HAL status */ HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { - uint32_t *tmp; - /* Check that a Rx process is not already ongoing */ if(huart->RxState == HAL_UART_STATE_READY) { - if((pData == NULL ) || (Size == 0U)) + if((pData == NULL ) || (Size == 0U)) { return HAL_ERROR; } - + + /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter + should be aligned on a u16 frontier, as data copy from RDR will be + handled by DMA from a u16 frontier. */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + if((((uint32_t)pData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(huart); - + huart->pRxBuffPtr = pData; huart->RxXferSize = Size; - + huart->ErrorCode = HAL_UART_ERROR_NONE; huart->RxState = HAL_UART_STATE_BUSY_RX; - - /* Set the UART DMA transfert complete callback */ + + /* Set the UART DMA transfer complete callback */ huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; - + /* Set the UART DMA Half transfer complete callback */ huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; - + /* Set the DMA error callback */ huart->hdmarx->XferErrorCallback = UART_DMAError; - /* Enable the DMA Stream */ - tmp = (uint32_t*)&pData; - HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, *(uint32_t*)tmp, Size); + /* Set the DMA abort callback */ + huart->hdmarx->XferAbortCallback = NULL; - /* Enable the DMA transfer for the receiver request by setting the DMAR bit + /* Enable the DMA channel */ + HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size); + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + /* Enable the UART Parity Error Interrupt */ + SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit in the UART CR3 register */ - huart->Instance->CR3 |= USART_CR3_DMAR; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - + SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); + return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Pauses the DMA Transfer. - * @param huart: UART handle - * @retval None + * @brief Pause the DMA Transfer. + * @param huart: UART handle. + * @retval HAL status */ HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) { /* Process Locked */ __HAL_LOCK(huart); - - if(huart->gState == HAL_UART_STATE_BUSY_TX) + + if ((huart->gState == HAL_UART_STATE_BUSY_TX) && + (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))) { /* Disable the UART DMA Tx request */ - huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); } - if(huart->RxState == HAL_UART_STATE_BUSY_RX) + if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && + (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))) { + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + /* Disable the UART DMA Rx request */ - huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); } + /* Process Unlocked */ __HAL_UNLOCK(huart); - return HAL_OK; + return HAL_OK; } /** - * @brief Resumes the DMA Transfer. - * @param huart: UART handle - * @retval None + * @brief Resume the DMA Transfer. + * @param huart: UART handle. + * @retval HAL status */ HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) { @@ -1025,15 +1131,19 @@ HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) if(huart->gState == HAL_UART_STATE_BUSY_TX) { /* Enable the UART DMA Tx request */ - huart->Instance->CR3 |= USART_CR3_DMAT; + SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); } - else if(huart->RxState == HAL_UART_STATE_BUSY_RX) + if(huart->RxState == HAL_UART_STATE_BUSY_RX) { - /* Clear the Overrun flag before resumming the Rx transfer*/ - __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF); - + /* Clear the Overrun flag before resuming the Rx transfer */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + + /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */ + SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + /* Enable the UART DMA Rx request */ - huart->Instance->CR3 |= USART_CR3_DMAR; + SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); } /* Process Unlocked */ @@ -1043,165 +1153,654 @@ HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) } /** - * @brief Stops the DMA Transfer. - * @param huart: UART handle - * @retval None + * @brief Stop the DMA Transfer. + * @param huart: UART handle. + * @retval HAL status */ HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) { /* The Lock is not implemented on this API to allow the user application - to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback(): - when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated - and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() - */ - - /* Disable the UART Tx/Rx DMA requests */ - huart->Instance->CR3 &= ~USART_CR3_DMAT; - huart->Instance->CR3 &= ~USART_CR3_DMAR; - - /* Abort the UART DMA tx channel */ - if(huart->hdmatx != NULL) + to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() / + HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback: + indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete + interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of + the stream and the corresponding call back is executed. */ + + /* Stop UART DMA Tx request if ongoing */ + if ((huart->gState == HAL_UART_STATE_BUSY_TX) && + (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))) { - HAL_DMA_Abort(huart->hdmatx); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel */ + if(huart->hdmatx != NULL) + { + HAL_DMA_Abort(huart->hdmatx); + } + + UART_EndTxTransfer(huart); } - /* Abort the UART DMA rx channel */ - if(huart->hdmarx != NULL) + + /* Stop UART DMA Rx request if ongoing */ + if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && + (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))) { - HAL_DMA_Abort(huart->hdmarx); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel */ + if(huart->hdmarx != NULL) + { + HAL_DMA_Abort(huart->hdmarx); + } + + UART_EndRxTransfer(huart); } - - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - + return HAL_OK; } /** - * @brief This function handles UART interrupt request. - * @param huart: uart handle + * @brief Abort ongoing transfers (blocking mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) +{ + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Disable the UART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(huart->hdmatx); + } + } + + /* Disable the UART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(huart->hdmarx); + } + } + + /* Reset Tx and Rx transfer counters */ + huart->TxXferCount = 0; + huart->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->gState and huart->RxState to Ready */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + + /* Reset Handle ErrorCode to No Error */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (blocking mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* Disable the UART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(huart->hdmatx); + } + } + + /* Reset Tx transfer counter */ + huart->TxXferCount = 0; + + /* Restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (blocking mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Disable the UART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(huart->hdmarx); + } + } + + /* Reset Rx transfer counter */ + huart->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) +{ + uint32_t abortcplt = 1; + + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised + before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if(huart->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback; + } + else + { + huart->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if(huart->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback; + } + else + { + huart->hdmarx->XferAbortCallback = NULL; + } + } + + /* Disable the UART DMA Tx request if enabled */ + if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable DMA Tx at UART level */ + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ + if(huart->hdmatx != NULL) + { + /* UART Tx DMA Abort callback has already been initialised : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) + { + huart->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0; + } + } + } + + /* Disable the UART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ + if(huart->hdmarx != NULL) + { + /* UART Rx DMA Abort callback has already been initialised : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + huart->hdmarx->XferAbortCallback = NULL; + abortcplt = 1; + } + else + { + abortcplt = 0; + } + } + } + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1) + { + /* Reset Tx and Rx transfer counters */ + huart->TxXferCount = 0; + huart->RxXferCount = 0; + + /* Reset errorCode */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->gState and huart->RxState to Ready */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_UART_AbortCpltCallback(huart); + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (Interrupt mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* Disable the UART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ + if(huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback; + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) + { + /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */ + huart->hdmatx->XferAbortCallback(huart->hdmatx); + } + } + else + { + /* Reset Tx transfer counter */ + huart->TxXferCount = 0; + + /* Restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_UART_AbortTransmitCpltCallback(huart); + } + } + else + { + /* Reset Tx transfer counter */ + huart->TxXferCount = 0; + + /* Restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_UART_AbortTransmitCpltCallback(huart); + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (Interrupt mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Disable the UART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ + if(huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ + huart->hdmarx->XferAbortCallback(huart->hdmarx); + } + } + else + { + /* Reset Rx transfer counter */ + huart->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_UART_AbortReceiveCpltCallback(huart); + } + } + else + { + /* Reset Rx transfer counter */ + huart->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_UART_AbortReceiveCpltCallback(huart); + } + + return HAL_OK; +} + +/** + * @brief Handle UART interrupt request. + * @param huart: UART handle. * @retval None */ void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) { - /* UART parity error interrupt occurred ------------------------------------*/ + uint32_t isrflags = READ_REG(huart->Instance->ISR); + uint32_t cr1its = READ_REG(huart->Instance->CR1); + uint32_t cr3its; + uint32_t errorflags; - if((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE) != RESET)) - { - __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF); - - huart->ErrorCode |= HAL_UART_ERROR_PE; - /* Set the UART state ready to be able to start again the process */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - } - - /* UART frame error interrupt occured --------------------------------------*/ - if((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET)) - { - __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF); - - huart->ErrorCode |= HAL_UART_ERROR_FE; - /* Set the UART state ready to be able to start again the process */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - } - - /* UART noise error interrupt occured --------------------------------------*/ - if((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET)) - { - __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF); - - huart->ErrorCode |= HAL_UART_ERROR_NE; - /* Set the UART state ready to be able to start again the process */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - } - - /* UART Over-Run interrupt occurred -----------------------------------------*/ - if((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET)) - { - __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF); - - huart->ErrorCode |= HAL_UART_ERROR_ORE; - /* Set the UART state ready to be able to start again the process */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; - } - - /* Call UART Error Call back function if need be --------------------------*/ - if(huart->ErrorCode != HAL_UART_ERROR_NONE) + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); + if (errorflags == RESET) { - /* Set the UART state ready to be able to start again the process */ - huart->gState = HAL_UART_STATE_READY; - huart->RxState = HAL_UART_STATE_READY; + /* UART in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + UART_Receive_IT(huart); + return; + } + } - HAL_UART_ErrorCallback(huart); - } + /* If some errors occur */ + cr3its = READ_REG(huart->Instance->CR3); + if( (errorflags != RESET) + && ( ((cr3its & USART_CR3_EIE) != RESET) + || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)) ) + { + /* UART parity error interrupt occurred -------------------------------------*/ + if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF); - /* UART Wake Up interrupt occured ------------------------------------------*/ - if((__HAL_UART_GET_IT(huart, UART_IT_WUF) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_WUF) != RESET)) - { + huart->ErrorCode |= HAL_UART_ERROR_PE; + } + + /* UART frame error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF); + + huart->ErrorCode |= HAL_UART_ERROR_FE; + } + + /* UART noise error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF); + + huart->ErrorCode |= HAL_UART_ERROR_NE; + } + + /* UART Over-Run interrupt occurred -----------------------------------------*/ + if(((isrflags & USART_ISR_ORE) != RESET) && + (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF); + + huart->ErrorCode |= HAL_UART_ERROR_ORE; + } + + /* Call UART Error Call back function if need be --------------------------*/ + if(huart->ErrorCode != HAL_UART_ERROR_NONE) + { + /* UART in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + UART_Receive_IT(huart); + } + + /* If Overrun error occurs, or if any error occurs in DMA mode reception, + consider error as blocking */ + if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || + (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))) + { + /* Blocking error : transfer is aborted + Set the UART state ready to be able to start again the process, + Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ + UART_EndRxTransfer(huart); + + /* Disable the UART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel */ + if(huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ + huart->hdmarx->XferAbortCallback(huart->hdmarx); + } + } + else + { + /* Call user error callback */ + HAL_UART_ErrorCallback(huart); + } + } + else + { + /* Call user error callback */ + HAL_UART_ErrorCallback(huart); + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ + HAL_UART_ErrorCallback(huart); + huart->ErrorCode = HAL_UART_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ + + /* UART wakeup from Stop mode interrupt occurred ---------------------------*/ + if(((isrflags & USART_ISR_WUF) != RESET) && ((cr3its & USART_CR3_WUFIE) != RESET)) + { __HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF); - /* Set the UART state ready to be able to start again the process */ - huart->gState = HAL_UART_STATE_READY; + huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; - HAL_UARTEx_WakeupCallback(huart); + return; } - - /* UART in mode Receiver ---------------------------------------------------*/ - if((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET)) - { - UART_Receive_IT(huart); - } - + /* UART in mode Transmitter ------------------------------------------------*/ - if((__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE) != RESET)) + if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) { UART_Transmit_IT(huart); + return; } - /* UART in mode Transmitter -- TC ------------------------------------------*/ - if((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET)) + /* UART in mode Transmitter (transmission end) -----------------------------*/ + if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { UART_EndTransmit_IT(huart); + return; } + } /** - * @brief Tx Transfer completed callbacks - * @param huart: uart handle + * @brief Tx Transfer completed callback. + * @param huart: UART handle. * @retval None */ - __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) +__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_UART_TxCpltCallback could be implemented in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_TxCpltCallback can be implemented in the user file. + */ } /** - * @brief Tx Half Transfer completed callbacks. - * @param huart: UART handle + * @brief Tx Half Transfer completed callback. + * @param huart: UART handle. * @retval None */ - __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) +__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_UART_TxCpltCallback could be implemented in the user file - */ + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_UART_TxHalfCpltCallback can be implemented in the user file. + */ } /** - * @brief Rx Transfer completed callbacks - * @param huart: uart handle + * @brief Rx Transfer completed callback. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) @@ -1209,14 +1808,14 @@ __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) /* Prevent unused argument(s) compilation warning */ UNUSED(huart); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_UART_TxCpltCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_RxCpltCallback can be implemented in the user file. */ } /** - * @brief Rx Half Transfer completed callbacks. - * @param huart: UART handle + * @brief Rx Half Transfer completed callback. + * @param huart: UART handle. * @retval None */ __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) @@ -1224,109 +1823,154 @@ __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) /* Prevent unused argument(s) compilation warning */ UNUSED(huart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_UART_TxCpltCallback could be implemented in the user file + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_UART_RxHalfCpltCallback can be implemented in the user file. */ } /** - * @brief UART error callbacks - * @param huart: uart handle + * @brief UART error callback. + * @param huart: UART handle. * @retval None */ - __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) +__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_ErrorCallback can be implemented in the user file - */ + the HAL_UART_ErrorCallback can be implemented in the user file. + */ } +/** + * @brief UART Abort Complete callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_AbortCpltCallback (UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief UART Abort Complete callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_AbortTransmitCpltCallback (UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief UART Abort Receive Complete callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file. + */ +} /** * @} */ -/** @addtogroup UART_Exported_Functions_Group3 - * @brief UART control functions +/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions + * @brief UART control functions * -@verbatim +@verbatim =============================================================================== ##### Peripheral Control functions ##### - =============================================================================== + =============================================================================== [..] This subsection provides a set of functions allowing to control the UART. (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode - (+) HAL_HalfDuplex_EnableTransmitter() API enables the transmitter - (+) HAL_HalfDuplex_EnableReceiver() API enables the receiver - (+) HAL_UART_GetState() API is helpful to check in run-time the state of the UART peripheral - (+) HAL_UART_GetError()API is helpful to check in run-time the error state of the UART peripheral + (+) UART_SetConfig() API configures the UART peripheral + (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features + (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization + (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter + (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver + (+) HAL_LIN_SendBreak() API transmits the break characters @endverbatim * @{ */ /** - * @brief Enable UART in mute mode (doesn't mean UART enters mute mode; - * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called) - * @param huart: uart handle + * @brief Enable UART in mute mode (does not mean UART enters mute mode; + * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called). + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart) -{ +{ /* Process Locked */ __HAL_LOCK(huart); - + huart->gState = HAL_UART_STATE_BUSY; - + /* Enable USART mute mode by setting the MME bit in the CR1 register */ - huart->Instance->CR1 |= USART_CR1_MME; - + SET_BIT(huart->Instance->CR1, USART_CR1_MME); + huart->gState = HAL_UART_STATE_READY; - + return (UART_CheckIdleState(huart)); } /** - * @brief Disable UART mute mode (doesn't mean it actually wakes up the software, - * as it may not have been in mute mode at this very moment). - * @param huart: uart handle + * @brief Disable UART mute mode (does not mean the UART actually exits mute mode + * as it may not have been in mute mode at this very moment). + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart) -{ +{ /* Process Locked */ __HAL_LOCK(huart); - + huart->gState = HAL_UART_STATE_BUSY; - + /* Disable USART mute mode by clearing the MME bit in the CR1 register */ - huart->Instance->CR1 &= ~(USART_CR1_MME); - + CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME); + huart->gState = HAL_UART_STATE_READY; - + return (UART_CheckIdleState(huart)); } /** * @brief Enter UART mute mode (means UART actually enters mute mode). - * To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called. - * @param huart: uart handle - * @retval HAL status + * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called. + * @param huart: UART handle. + * @retval None */ void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) -{ +{ __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST); } /** - * @brief Enables the UART transmitter and disables the UART receiver. - * @param huart: UART handle + * @brief Enable the UART transmitter and disable the UART receiver. + * @param huart: UART handle. * @retval HAL status - * @retval None */ HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) { @@ -1340,6 +1984,7 @@ HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) SET_BIT(huart->Instance->CR1, USART_CR1_TE); huart->gState = HAL_UART_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(huart); @@ -1347,9 +1992,9 @@ HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) } /** - * @brief Enables the UART receiver and disables the UART transmitter. - * @param huart: UART handle - * @retval HAL status + * @brief Enable the UART receiver and disable the UART transmitter. + * @param huart: UART handle. + * @retval HAL status. */ HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) { @@ -1369,36 +2014,58 @@ HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) return HAL_OK; } + /** - * @brief Transmits break characters. - * @param huart: pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART module. + * @brief Transmit break characters. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) { /* Check the parameters */ assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); - + /* Process Locked */ __HAL_LOCK(huart); - + huart->gState = HAL_UART_STATE_BUSY; - + /* Send break characters */ - huart->Instance->RQR |= USART_RQR_SBKRQ; - + huart->Instance->RQR |= UART_SENDBREAK_REQUEST; + huart->gState = HAL_UART_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(huart); - - return HAL_OK; + + return HAL_OK; } + /** - * @brief return the UART state - * @param huart: uart handle + * @} + */ + +/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions + * @brief UART Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the UART handle state. + (+) Return the UART handle error code + +@endverbatim + * @{ + */ + +/** + * @brief Return the UART handle state. + * @param huart Pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART. * @retval HAL state */ HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) @@ -1411,16 +2078,15 @@ HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) } /** -* @brief Return the UART error code -* @param huart : pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART. -* @retval UART Error Code + * @brief Return the UART handle error code. + * @param huart Pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART. + * @retval UART Error Code */ uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart) { return huart->ErrorCode; } - /** * @} */ @@ -1429,244 +2095,24 @@ uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart) * @} */ -/*************************************************************** - * Private functions... - * - ***************************************************************/ -/** @addtogroup UART_Private +/** @defgroup UART_Private_Functions UART Private Functions * @{ */ -/** - * @brief DMA UART transmit process complete callback - * @param hdma: DMA handle - * @retval None - */ -static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - /* DMA Normal mode */ - if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) - { - huart->TxXferCount = 0U; - - /* Disable the DMA transfer for transmit request by resetting the DMAT bit - in the UART CR3 register */ - huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); - - /* Enable the UART Transmit Complete Interrupt */ - __HAL_UART_ENABLE_IT(huart, UART_IT_TC); - } - /* DMA Circular mode */ - else - { - HAL_UART_TxCpltCallback(huart); - } - -} /** - * @brief DMA UART transmit process half complete callback - * @param hdma : DMA handle - * @retval None - */ -static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; - - HAL_UART_TxHalfCpltCallback(huart); -} - -/** - * @brief DMA UART receive process complete callback - * @param hdma: DMA handle - * @retval None - */ -static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - /* DMA Normal mode*/ - if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) - { - huart->RxXferCount = 0U; - - /* Disable the DMA transfer for the receiver request by setting the DMAR bit - in the UART CR3 register */ - huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); - - /* At end of Rx process, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - } - HAL_UART_RxCpltCallback(huart); -} - -/** - * @brief DMA UART receive process half complete callback - * @param hdma : DMA handle - * @retval None - */ -static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; - - HAL_UART_RxHalfCpltCallback(huart); -} - -/** - * @brief DMA UART communication error callback - * @param hdma: DMA handle - * @retval None - */ -static void UART_DMAError(DMA_HandleTypeDef *hdma) -{ - UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - huart->RxXferCount = 0U; - huart->TxXferCount = 0U; - huart->gState= HAL_UART_STATE_READY; - huart->RxState= HAL_UART_STATE_READY; - huart->ErrorCode |= HAL_UART_ERROR_DMA; - HAL_UART_ErrorCallback(huart); -} - -/** - * @brief Send an amount of data in interrupt mode - * Function called under interruption only, once - * interruptions have been enabled by HAL_UART_Transmit_IT() - * @param huart: UART handle + * @brief Configure the UART peripheral. + * @param huart: UART handle. * @retval HAL status */ -static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) +HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) { - uint16_t* tmp; + uint32_t tmpreg = 0x00000000U; + UART_ClockSourceTypeDef clocksource = UART_CLOCKSOURCE_UNDEFINED; + uint16_t brrtemp = 0x0000U; + uint16_t usartdiv = 0x0000U; + HAL_StatusTypeDef ret = HAL_OK; - if (huart->gState == HAL_UART_STATE_BUSY_TX) - { - if(huart->TxXferCount == 0U) - { - /* Disable the UART TXE Interrupt */ - __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); - - /* Enable the UART Transmit Complete Interrupt */ - __HAL_UART_ENABLE_IT(huart, UART_IT_TC); - - return HAL_OK; - - } - else - { - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - tmp = (uint16_t*) huart->pTxBuffPtr; - huart->Instance->TDR = (*tmp & (uint16_t)0x01FFU); - huart->pTxBuffPtr += 2U; - } - else - { - huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFFU); - } - - huart->TxXferCount--; - - return HAL_OK; - } - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Wraps up transmission in non blocking mode. - * @param huart: pointer to a UART_HandleTypeDef structure that contains - * the configuration information for the specified UART module. - * @retval HAL status - */ -static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) -{ - /* Disable the UART Transmit Complete Interrupt */ - __HAL_UART_DISABLE_IT(huart, UART_IT_TC); - - huart->gState = HAL_UART_STATE_READY; - - HAL_UART_TxCpltCallback(huart); - - return HAL_OK; -} - - -/** - * @brief Receive an amount of data in interrupt mode - * Function called under interruption only, once - * interruptions have been enabled by HAL_UART_Receive_IT() - * @param huart: UART handle - * @retval HAL status - */ -static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) -{ - uint16_t* tmp; - uint16_t uhMask = huart->Mask; - - /* Check that a Rx process is ongoing */ - if(huart->RxState == HAL_UART_STATE_BUSY_RX) - { - if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) - { - tmp = (uint16_t*) huart->pRxBuffPtr ; - *tmp = (uint16_t)(huart->Instance->RDR & uhMask); - huart->pRxBuffPtr +=2U; - } - else - { - *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); - } - - if(--huart->RxXferCount == 0U) - { - while(HAL_IS_BIT_SET(huart->Instance->ISR, UART_FLAG_RXNE)) - { - } - __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); - - /* Disable the UART Parity Error Interrupt */ - __HAL_UART_DISABLE_IT(huart, UART_IT_PE); - - /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); - - /* Rx process is completed, restore huart->RxState to Ready */ - huart->RxState = HAL_UART_STATE_READY; - - HAL_UART_RxCpltCallback(huart); - - return HAL_OK; - } - return HAL_OK; - } - else - { - /* Clear RXNE interrupt flag */ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); - - return HAL_BUSY; - } -} - -/** - * @brief Configure the UART peripheral - * @param huart: uart handle - * @retval None - */ -void UART_SetConfig(UART_HandleTypeDef *huart) -{ - uint32_t tmpreg = 0x00000000U; - uint32_t clocksource = 0x00000000U; - uint16_t brrtemp = 0x0000U; - uint16_t usartdiv = 0x0000U; - - /* Check the parameters */ + /* Check the parameters */ assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); if(UART_INSTANCE_LOWPOWER(huart)) @@ -1684,10 +2130,11 @@ void UART_SetConfig(UART_HandleTypeDef *huart) assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); + /*-------------------------- USART CR1 Configuration -----------------------*/ - /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure - * the UART Word Length, Parity, Mode and oversampling: - * set the M bits according to huart->Init.WordLength value + /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure + * the UART Word Length, Parity, Mode and oversampling: + * set the M bits according to huart->Init.WordLength value * set PCE and PS bits according to huart->Init.Parity value * set TE and RE bits according to huart->Init.Mode value * set OVER8 bit according to huart->Init.OverSampling value */ @@ -1695,16 +2142,16 @@ void UART_SetConfig(UART_HandleTypeDef *huart) MODIFY_REG(huart->Instance->CR1, UART_CR1_FIELDS, tmpreg); /*-------------------------- USART CR2 Configuration -----------------------*/ - /* Configure the UART Stop Bits: Set STOP[13:12] bits according + /* Configure the UART Stop Bits: Set STOP[13:12] bits according * to huart->Init.StopBits value */ MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); - + /*-------------------------- USART CR3 Configuration -----------------------*/ - /* Configure - * - UART HardWare Flow Control: set CTSE and RTSE bits according - * to huart->Init.HwFlowCtl value + /* Configure + * - UART HardWare Flow Control: set CTSE and RTSE bits according + * to huart->Init.HwFlowCtl value * - one-bit sampling method versus three samples' majority rule according - * to huart->Init.OneBitSampling */ + * to huart->Init.OneBitSampling (not applicable to LPUART) */ tmpreg = (uint32_t)huart->Init.HwFlowCtl; if (!(UART_INSTANCE_LOWPOWER(huart))) { @@ -1714,66 +2161,98 @@ void UART_SetConfig(UART_HandleTypeDef *huart) /*-------------------------- USART BRR Configuration -----------------------*/ UART_GETCLOCKSOURCE(huart, clocksource); - - /* Check LPUART instace */ + uint32_t frequency = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_USART2); + + /* Check LPUART instance */ if(UART_INSTANCE_LOWPOWER(huart)) { - switch (clocksource) - { - case UART_CLOCKSOURCE_PCLK1: - huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_HSI: - if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) - { - huart->Instance->BRR = (uint32_t)(__DIV_LPUART((HSI_VALUE >> 2U), huart->Init.BaudRate)); - } - else - { - huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HSI_VALUE, huart->Init.BaudRate)); - } - break; - case UART_CLOCKSOURCE_SYSCLK: - huart->Instance->BRR = (uint32_t)(__DIV_LPUART(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_LSE: - huart->Instance->BRR = (uint32_t)(__DIV_LPUART(LSE_VALUE, huart->Init.BaudRate)); - break; - default: - break; - } - } - /* Check the UART Over Sampling 8 to set Baud Rate Register */ - else if (huart->Init.OverSampling == UART_OVERSAMPLING_8) - { + /* Retrieve frequency clock */ + tmpreg = 0; + switch (clocksource) { case UART_CLOCKSOURCE_PCLK1: - usartdiv = (uint32_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); - break; - case UART_CLOCKSOURCE_PCLK2: - usartdiv = (uint32_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate)); + tmpreg = HAL_RCC_GetPCLK1Freq(); break; case UART_CLOCKSOURCE_HSI: if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) - { - usartdiv = (uint32_t)(UART_DIV_SAMPLING8((HSI_VALUE >> 2U), huart->Init.BaudRate)); - } - else { - usartdiv = (uint32_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate)); + tmpreg = (uint32_t) (HSI_VALUE >> 2U); + } + else + { + tmpreg = (uint32_t) HSI_VALUE; } break; case UART_CLOCKSOURCE_SYSCLK: - usartdiv = (uint32_t)(UART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); + tmpreg = HAL_RCC_GetSysClockFreq(); break; case UART_CLOCKSOURCE_LSE: - usartdiv = (uint32_t)(UART_DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate)); + tmpreg = (uint32_t) LSE_VALUE; break; + case UART_CLOCKSOURCE_UNDEFINED: default: + ret = HAL_ERROR; break; } - + + /* if proper clock source reported */ + if (tmpreg != 0) + { + /* ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ + if ( (tmpreg < (3 * huart->Init.BaudRate) ) || + (tmpreg > (4096 * huart->Init.BaudRate) )) + { + ret = HAL_ERROR; + } + else + { + tmpreg = (uint32_t)(UART_DIV_LPUART(tmpreg, huart->Init.BaudRate)); + + if ((tmpreg >= UART_LPUART_BRR_MIN) && (tmpreg <= UART_LPUART_BRR_MAX)) + { + huart->Instance->BRR = tmpreg; + } + else + { + ret = HAL_ERROR; + } + } /* if ( (tmpreg < (3 * huart->Init.BaudRate) ) || (tmpreg > (4096 * huart->Init.BaudRate) )) */ + } /* if (tmpreg != 0) */ + } + /* Check UART Over Sampling to set Baud Rate Register */ + else if (huart->Init.OverSampling == UART_OVERSAMPLING_8) + { + switch (clocksource) + { + case UART_CLOCKSOURCE_PCLK1: + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(frequency, huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_PCLK2: + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_HSI: + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) + { + usartdiv = (uint16_t)(UART_DIV_SAMPLING8((HSI_VALUE >> 2U), huart->Init.BaudRate)); + } + else + { + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate)); + } + break; + case UART_CLOCKSOURCE_SYSCLK: + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_LSE: + usartdiv = (uint16_t)(UART_DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate)); + break; + case UART_CLOCKSOURCE_UNDEFINED: + default: + ret = HAL_ERROR; + break; + } + brrtemp = usartdiv & 0xFFF0U; brrtemp |= (uint16_t)((uint16_t)(usartdiv & (uint16_t)0x000FU) >> (uint16_t)1U); huart->Instance->BRR = brrtemp; @@ -1782,124 +2261,92 @@ void UART_SetConfig(UART_HandleTypeDef *huart) { switch (clocksource) { - case UART_CLOCKSOURCE_PCLK1: - huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); + case UART_CLOCKSOURCE_PCLK1: + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate)); break; - case UART_CLOCKSOURCE_PCLK2: - huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate)); + case UART_CLOCKSOURCE_PCLK2: + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate)); break; - case UART_CLOCKSOURCE_HSI: + case UART_CLOCKSOURCE_HSI: if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) - { - huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16((HSI_VALUE >> 2U), huart->Init.BaudRate)); - } - else { - huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate)); + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16((HSI_VALUE >> 2U), huart->Init.BaudRate)); } - break; - case UART_CLOCKSOURCE_SYSCLK: - huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); - break; + else + { + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate)); + } + break; + case UART_CLOCKSOURCE_SYSCLK: + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate)); + break; case UART_CLOCKSOURCE_LSE: - huart->Instance->BRR = (uint32_t)(UART_DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate)); + huart->Instance->BRR = (uint16_t)(UART_DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate)); break; + case UART_CLOCKSOURCE_UNDEFINED: default: + ret = HAL_ERROR; break; } } + + return ret; + } /** - * @brief Check the UART Idle State - * @param huart: uart handle - * @retval HAL status - */ -HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) -{ - /* Check if the Transmitter is enabled */ - if((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) - { - /* Wait until TEACK flag is set */ - if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, UART_TIMEOUT_VALUE) != HAL_OK) - { - return HAL_TIMEOUT; - } - } - /* Check if the Receiver is enabled */ - if((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) - { - /* Wait until REACK flag is set */ - if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, UART_TIMEOUT_VALUE) != HAL_OK) - { - return HAL_TIMEOUT; - } - } - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - /* Initialize the UART state*/ - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->gState= HAL_UART_STATE_READY; - huart->RxState= HAL_UART_STATE_READY; - - return HAL_OK; -} - -/** - * @brief Configure the UART peripheral advanced feautures - * @param huart: uart handle + * @brief Configure the UART peripheral advanced features. + * @param huart: UART handle. * @retval None */ void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) { - /* Check whether the set of advanced features to configure is properly set */ + /* Check whether the set of advanced features to configure is properly set */ assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit)); - + /* if required, configure TX pin active level inversion */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT)) { assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert)); MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert); } - + /* if required, configure RX pin active level inversion */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT)) { assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert)); MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert); } - + /* if required, configure data inversion */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT)) { assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert)); MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert); } - + /* if required, configure RX/TX pins swap */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT)) { assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap)); MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap); } - + /* if required, configure RX overrun detection disabling */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT)) { - assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable)); + assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable)); MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable); } - + /* if required, configure DMA disabling on reception error */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT)) { - assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError)); + assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError)); MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError); } - - /* if required, configure auto Baud rate detection scheme */ + + /* if required, configure auto Baud rate detection scheme */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) { assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance)); @@ -1912,93 +2359,512 @@ void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); } } - - /* if required, configure MSB first on communication line */ + + /* if required, configure MSB first on communication line */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT)) { - assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst)); + assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst)); MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst); } } /** - * @brief This function handles UART Communication Timeout. - * @param huart: UART handle - * @param Flag: specifies the UART flag to check. - * @param Status: The new Flag status (SET or RESET). - * @param Timeout: Timeout duration + * @brief Check the UART Idle State. + * @param huart UART handle. * @retval HAL status */ -HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) { - uint32_t tickstart = 0x00U; + uint32_t tickstart = 0; + + /* Initialize the UART ErrorCode */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + /* Init tickstart for timeout managment*/ tickstart = HAL_GetTick(); - - /* Wait until flag is set */ - if(Status == RESET) + + /* Check if the Transmitter is enabled */ + if((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) { - while(__HAL_UART_GET_FLAG(huart, Flag) == RESET) + /* Wait until TEACK flag is set */ + if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + /* Check if the Receiver is enabled */ + if((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) + { + /* Wait until REACK flag is set */ + if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + + /* Initialize the UART State */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Handle UART Communication Timeout. + * @param huart UART handle. + * @param Flag Specifies the UART flag to check + * @param Status Flag status (SET or RESET) + * @param Tickstart Tick start value + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is set */ + while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout)) { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); - __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); - __HAL_UART_DISABLE_IT(huart, UART_IT_PE); - __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); - - huart->gState= HAL_UART_STATE_READY; - huart->RxState= HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_TIMEOUT; - } + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + return HAL_TIMEOUT; } } } + return HAL_OK; +} + + +/** + * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion). + * @param huart UART handle. + * @retval None + */ +static void UART_EndTxTransfer(UART_HandleTypeDef *huart) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); + + /* At end of Tx process, restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; +} + + +/** + * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). + * @param huart UART handle. + * @retval None + */ +static void UART_EndRxTransfer(UART_HandleTypeDef *huart) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; +} + + +/** + * @brief DMA UART transmit process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)(hdma->Parent); + + /* DMA Normal mode */ + if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) + { + huart->TxXferCount = 0U; + + /* Disable the DMA transfer for transmit request by resetting the DMAT bit + in the UART CR3 register */ + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Enable the UART Transmit Complete Interrupt */ + SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + } + /* DMA Circular mode */ + else + { + HAL_UART_TxCpltCallback(huart); + } + +} + +/** + * @brief DMA UART transmit process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)(hdma->Parent); + + HAL_UART_TxHalfCpltCallback(huart); +} + +/** + * @brief DMA UART receive process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)(hdma->Parent); + + /* DMA Normal mode */ + if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) + { + huart->RxXferCount = 0U; + + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit + in the UART CR3 register */ + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + } + + HAL_UART_RxCpltCallback(huart); +} + +/** + * @brief DMA UART receive process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)(hdma->Parent); + + HAL_UART_RxHalfCpltCallback(huart); +} + +/** + * @brief DMA UART communication error callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMAError(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)(hdma->Parent); + + /* Stop UART DMA Tx request if ongoing */ + if ( (huart->gState == HAL_UART_STATE_BUSY_TX) + &&(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) ) + { + huart->TxXferCount = 0; + UART_EndTxTransfer(huart); + } + + /* Stop UART DMA Rx request if ongoing */ + if ( (huart->RxState == HAL_UART_STATE_BUSY_RX) + &&(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ) + { + huart->RxXferCount = 0; + UART_EndRxTransfer(huart); + } + + huart->ErrorCode |= HAL_UART_ERROR_DMA; + HAL_UART_ErrorCallback(huart); +} + +/** + * @brief DMA UART communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)(hdma->Parent); + huart->RxXferCount = 0; + huart->TxXferCount = 0; + + HAL_UART_ErrorCallback(huart); +} + +/** + * @brief DMA UART Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef* )(hdma->Parent); + + huart->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(huart->hdmarx != NULL) + { + if(huart->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + huart->TxXferCount = 0; + huart->RxXferCount = 0; + + /* Reset errorCode */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->gState and huart->RxState to Ready */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + + /* Call user Abort complete callback */ + HAL_UART_AbortCpltCallback(huart); +} + + +/** + * @brief DMA UART Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef* )(hdma->Parent); + + huart->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(huart->hdmatx != NULL) + { + if(huart->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + huart->TxXferCount = 0; + huart->RxXferCount = 0; + + /* Reset errorCode */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->gState and huart->RxState to Ready */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + + /* Call user Abort complete callback */ + HAL_UART_AbortCpltCallback(huart); +} + + +/** + * @brief DMA UART Tx communication abort callback, when initiated by user by a call to + * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer) + * (This callback is executed at end of DMA Tx Abort procedure following user abort request, + * and leads to user Tx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)(hdma->Parent); + + huart->TxXferCount = 0; + + /* Restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + /* Call user Abort complete callback */ + HAL_UART_AbortTransmitCpltCallback(huart); +} + +/** + * @brief DMA UART Rx communication abort callback, when initiated by user by a call to + * HAL_UART_AbortReceive_IT API (Abort only Rx transfer) + * (This callback is executed at end of DMA Rx Abort procedure following user abort request, + * and leads to user Rx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + huart->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* Call user Abort complete callback */ + HAL_UART_AbortReceiveCpltCallback(huart); +} + +/** + * @brief Send an amount of data in interrupt mode. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Transmit_IT(). + * @param huart UART handle. + * @retval HAL status + */ +static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) +{ + uint16_t* tmp; + + /* Check that a Tx process is ongoing */ + if (huart->gState == HAL_UART_STATE_BUSY_TX) + { + if(huart->TxXferCount == 0U) + { + /* Disable the UART Transmit Data Register Empty Interrupt */ + CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE); + + /* Enable the UART Transmit Complete Interrupt */ + SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + + return HAL_OK; + } + else + { + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + tmp = (uint16_t*) huart->pTxBuffPtr; + huart->Instance->TDR = (*tmp & (uint16_t)0x01FFU); + huart->pTxBuffPtr += 2U; + } + else + { + huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFFU); + } + huart->TxXferCount--; + + return HAL_OK; + } + } else { - while(__HAL_UART_GET_FLAG(huart, Flag) != RESET) - { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); - __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); - __HAL_UART_DISABLE_IT(huart, UART_IT_PE); - __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); - - huart->gState= HAL_UART_STATE_READY; - huart->RxState= HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_TIMEOUT; - } - } - } + return HAL_BUSY; } - return HAL_OK; } /** - * @} + * @brief Wrap up transmission in non-blocking mode. + * @param huart pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status */ +static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) +{ + /* Disable the UART Transmit Complete Interrupt */ + CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE); + + /* Tx process is ended, restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + HAL_UART_TxCpltCallback(huart); + + return HAL_OK; +} + +/** + * @brief Receive an amount of data in interrupt mode. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Receive_IT() + * @param huart UART handle. + * @retval HAL status + */ +static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) +{ + uint16_t* tmp; + uint16_t uhMask = huart->Mask; + uint16_t uhdata; + + /* Check that a Rx process is ongoing */ + if(huart->RxState == HAL_UART_STATE_BUSY_RX) + { + uhdata = (uint16_t) READ_REG(huart->Instance->RDR); + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + tmp = (uint16_t*) huart->pRxBuffPtr ; + *tmp = (uint16_t)(uhdata & uhMask); + huart->pRxBuffPtr +=2; + } + else + { + *huart->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)uhMask); + } + + if(--huart->RxXferCount == 0U) + { + /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + HAL_UART_RxCpltCallback(huart); + + return HAL_OK; + } + + return HAL_OK; + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + + return HAL_BUSY; + } +} /** * @} */ #endif /* HAL_UART_MODULE_ENABLED */ +/** + * @} + */ /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart.h index 11d6261f58..4ae7f175b3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_uart.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of UART HAL module. ****************************************************************************** * @attention @@ -32,7 +30,7 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ @@ -50,24 +48,18 @@ * @{ */ -/** @defgroup UART UART +/** @addtogroup UART * @{ - */ + */ -/******************************************************************************/ /* Exported types ------------------------------------------------------------*/ -/******************************************************************************/ - - /** @defgroup UART_Exported_Types UART Exported Types +/** @defgroup UART_Exported_Types UART Exported Types * @{ */ -/** @defgroup UART_Init_Configuration UART initialization configuration structure - * @{ +/** + * @brief UART Init Structure definition */ -/** - * @brief UART Init Structure definition - */ typedef struct { uint32_t BaudRate; /*!< This member configures the UART communication baud rate. @@ -75,15 +67,15 @@ typedef struct - If oversampling is 16 or in LIN mode, Baud Rate Register = ((PCLKx) / ((huart->Init.BaudRate))) - If oversampling is 8, - Baud Rate Register[15:4] = ((2 * PCLKx) / ((huart->Init.BaudRate)))[15:4] + Baud Rate Register[15:4] = ((2 * PCLKx) / ((huart->Init.BaudRate)))[15:4] Baud Rate Register[3] = 0 Baud Rate Register[2:0] = (((2 * PCLKx) / ((huart->Init.BaudRate)))[3:0]) >> 1 */ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref UARTEx_Word_Length */ + This parameter can be a value of @ref UARTEx_Word_Length. */ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. - This parameter can be a value of @ref UART_Stop_Bits */ + This parameter can be a value of @ref UART_Stop_Bits. */ uint32_t Parity; /*!< Specifies the parity mode. This parameter can be a value of @ref UART_Parity @@ -91,80 +83,70 @@ typedef struct 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). */ - - uint32_t Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. - This parameter can be a value of @ref UART_Mode */ - uint32_t HwFlowCtl; /*!< Specifies wether the hardware flow control mode is enabled + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref UART_Mode. */ + + uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled or disabled. - This parameter can be a value of @ref UART_Hardware_Flow_Control */ - - uint32_t OverSampling; /*!< Specifies wether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8). - This parameter can be a value of @ref UART_Over_Sampling */ - - uint32_t OneBitSampling; /*!< Specifies wether a single sample or three samples' majority vote is selected. + This parameter can be a value of @ref UART_Hardware_Flow_Control. */ + + uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to f_PCLK/8). + This parameter can be a value of @ref UART_Over_Sampling. */ + + uint32_t OneBitSampling; /*!< Specifies whether a single sample or three samples' majority vote is selected. Selecting the single sample method increases the receiver tolerance to clock - deviations. This parameter can be a value of @ref UART_One_Bit */ + deviations. This parameter can be a value of @ref UART_OneBit_Sampling. */ }UART_InitTypeDef; + /** - * @} + * @brief UART Advanced Features initalization structure definition */ -/** @defgroup UART_Advanced_Feature UART advanced feature structure - * @{ - */ -/** - * @brief UART Advanced Features initalization structure definition - */ -typedef struct +typedef struct { uint32_t AdvFeatureInit; /*!< Specifies which advanced UART features is initialized. Several Advanced Features may be initialized at the same time . - This parameter can be a value of @ref UART_Advanced_Features_Initialization_Type */ - + This parameter can be a value of @ref UART_Advanced_Features_Initialization_Type. */ + uint32_t TxPinLevelInvert; /*!< Specifies whether the TX pin active level is inverted. - This parameter can be a value of @ref UART_Tx_Inv */ - + This parameter can be a value of @ref UART_Tx_Inv. */ + uint32_t RxPinLevelInvert; /*!< Specifies whether the RX pin active level is inverted. - This parameter can be a value of @ref UART_Rx_Inv */ + This parameter can be a value of @ref UART_Rx_Inv. */ uint32_t DataInvert; /*!< Specifies whether data are inverted (positive/direct logic vs negative/inverted logic). - This parameter can be a value of @ref UART_Data_Inv */ - - uint32_t Swap; /*!< Specifies whether TX and RX pins are swapped. - This parameter can be a value of @ref UART_Rx_Tx_Swap */ - - uint32_t OverrunDisable; /*!< Specifies whether the reception overrun detection is disabled. - This parameter can be a value of @ref UART_Overrun_Disable */ - - uint32_t DMADisableonRxError; /*!< Specifies whether the DMA is disabled in case of reception error. - This parameter can be a value of @ref UART_DMA_Disable_on_Rx_Error */ - - uint32_t AutoBaudRateEnable; /*!< Specifies whether auto Baud rate detection is enabled. - This parameter can be a value of @ref UART_AutoBaudRate_Enable */ - - uint32_t AutoBaudRateMode; /*!< If auto Baud rate detection is enabled, specifies how the rate - detection is carried out. - This parameter can be a value of @ref UARTEx_AutoBaud_Rate_Mode */ - - uint32_t MSBFirst; /*!< Specifies whether MSB is sent first on UART line. - This parameter can be a value of @ref UART_MSB_First */ + This parameter can be a value of @ref UART_Data_Inv. */ + + uint32_t Swap; /*!< Specifies whether TX and RX pins are swapped. + This parameter can be a value of @ref UART_Rx_Tx_Swap. */ + + uint32_t OverrunDisable; /*!< Specifies whether the reception overrun detection is disabled. + This parameter can be a value of @ref UART_Overrun_Disable. */ + + uint32_t DMADisableonRxError; /*!< Specifies whether the DMA is disabled in case of reception error. + This parameter can be a value of @ref UART_DMA_Disable_on_Rx_Error. */ + + uint32_t AutoBaudRateEnable; /*!< Specifies whether auto Baud rate detection is enabled. + This parameter can be a value of @ref UART_AutoBaudRate_Enable */ + + uint32_t AutoBaudRateMode; /*!< If auto Baud rate detection is enabled, specifies how the rate + detection is carried out. + This parameter can be a value of @ref UART_AutoBaud_Rate_Mode. */ + + uint32_t MSBFirst; /*!< Specifies whether MSB is sent first on UART line. + This parameter can be a value of @ref UART_MSB_First. */ } UART_AdvFeatureInitTypeDef; + + + /** - * @} - */ - -/** @defgroup UART_State_Definition UART state definition - * @{ - */ - -/** - * @brief HAL UART State structures definition + * @brief HAL UART State structures definition * @note HAL UART State value is a combination of 2 different substates: gState and RxState. - * - gState contains UART state information related to global Handle management + * - gState contains UART state information related to global Handle management * and also information related to Tx operations. * gState value coding follow below described bitmap : - * b7-b6 Error information + * b7-b6 Error information * 00 : No Error * 01 : (Not Used) * 10 : Timeout @@ -196,114 +178,97 @@ typedef struct * 1 : Busy (Rx operation ongoing) * b0 (not used) * x : Should be set to 0. - */ + */ typedef enum { - HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized + HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not initialized Value is allowed for gState and RxState */ - HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use + HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use Value is allowed for gState and RxState */ - HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing + HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing Value is allowed for gState only */ - HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing + HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing Value is allowed for gState only */ - HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing + HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing Value is allowed for RxState only */ - HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing + HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing Not to be used for neither gState nor RxState. Value is result of combination (Or) between gState and RxState values */ - HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state + HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state Value is allowed for gState only */ - HAL_UART_STATE_ERROR = 0xE0U /*!< Error + HAL_UART_STATE_ERROR = 0xE0U /*!< Error Value is allowed for gState only */ }HAL_UART_StateTypeDef; /** - * @} + * @brief HAL UART Error Code structure definition */ -/** @defgroup UART_Error_Definition UART error definition - * @{ - */ -/** - * @brief HAL UART Error Code definition - */ +typedef enum +{ + HAL_UART_ERROR_NONE = 0x00, /*!< No error */ + HAL_UART_ERROR_PE = 0x01, /*!< Parity error */ + HAL_UART_ERROR_NE = 0x02, /*!< Noise error */ + HAL_UART_ERROR_FE = 0x04, /*!< frame error */ + HAL_UART_ERROR_ORE = 0x08, /*!< Overrun error */ + HAL_UART_ERROR_DMA = 0x10, /*!< DMA transfer error */ + HAL_UART_ERROR_BUSY = 0x20 /*!< Busy Error */ +}HAL_UART_ErrorTypeDef; -#define HAL_UART_ERROR_NONE ((uint32_t)0x00U) /*!< No error */ -#define HAL_UART_ERROR_PE ((uint32_t)0x01U) /*!< Parity error */ -#define HAL_UART_ERROR_NE ((uint32_t)0x02U) /*!< Noise error */ -#define HAL_UART_ERROR_FE ((uint32_t)0x04U) /*!< frame error */ -#define HAL_UART_ERROR_ORE ((uint32_t)0x08U) /*!< Overrun error */ -#define HAL_UART_ERROR_DMA ((uint32_t)0x10U) /*!< DMA transfer error */ - -/** - * @} - */ -/** @defgroup UART_Clock_SourceDefinition UART clock source definition - * @{ - */ /** * @brief UART clock sources definition */ typedef enum { - UART_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ - UART_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ - UART_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ - UART_CLOCKSOURCE_SYSCLK = 0x04U, /*!< SYSCLK clock source */ - UART_CLOCKSOURCE_LSE = 0x08U /*!< LSE clock source */ + UART_CLOCKSOURCE_PCLK1 = 0x00, /*!< PCLK1 clock source */ + UART_CLOCKSOURCE_PCLK2 = 0x01, /*!< PCLK2 clock source */ + UART_CLOCKSOURCE_HSI = 0x02, /*!< HSI clock source */ + UART_CLOCKSOURCE_SYSCLK = 0x04, /*!< SYSCLK clock source */ + UART_CLOCKSOURCE_LSE = 0x08, /*!< LSE clock source */ + UART_CLOCKSOURCE_UNDEFINED = 0x10 /*!< Undefined clock source */ }UART_ClockSourceTypeDef; -/** - * @} - */ -/** @defgroup UART_handle_Definition Handle structure definition - * @{ - */ -/** - * @brief UART handle Structure definition +/** + * @brief UART handle Structure definition */ typedef struct { - USART_TypeDef *Instance; /*!< UART registers base address */ + USART_TypeDef *Instance; /*!< UART registers base address */ - UART_InitTypeDef Init; /*!< UART communication parameters */ + UART_InitTypeDef Init; /*!< UART communication parameters */ - UART_AdvFeatureInitTypeDef AdvancedInit; /*!< UART Advanced Features initialization parameters */ + UART_AdvFeatureInitTypeDef AdvancedInit; /*!< UART Advanced Features initialization parameters */ - uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */ + uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */ - uint16_t TxXferSize; /*!< UART Tx Transfer size */ + uint16_t TxXferSize; /*!< UART Tx Transfer size */ - uint16_t TxXferCount; /*!< UART Tx Transfer Counter */ + __IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */ - uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */ + uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */ - uint16_t RxXferSize; /*!< UART Rx Transfer size */ + uint16_t RxXferSize; /*!< UART Rx Transfer size */ - uint16_t RxXferCount; /*!< UART Rx Transfer Counter */ + __IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */ - uint16_t Mask; /*!< UART Rx RDR register mask */ + uint16_t Mask; /*!< UART Rx RDR register mask */ - DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */ + DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */ - DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */ + DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */ - HAL_LockTypeDef Lock; /*!< Locking object */ + HAL_LockTypeDef Lock; /*!< Locking object */ - __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management - and also related to Tx operations. - This parameter can be a value of @ref HAL_UART_StateTypeDef */ + __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management + and also related to Tx operations. + This parameter can be a value of @ref HAL_UART_StateTypeDef */ - __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations. - This parameter can be a value of @ref HAL_UART_StateTypeDef */ + __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations. + This parameter can be a value of @ref HAL_UART_StateTypeDef */ - __IO uint32_t ErrorCode; /*!< UART Error code */ + __IO uint32_t ErrorCode; /*!< UART Error code */ }UART_HandleTypeDef; -/** - * @} - */ /** * @} */ @@ -313,197 +278,357 @@ typedef struct * @{ */ -/** @defgroup UART_Stop_Bits UART stop bit definition +/** @defgroup UART_Stop_Bits UART Number of Stop Bits * @{ */ -#define UART_STOPBITS_1 ((uint32_t)0x0000U) /*!< USART frame with 1 stop bit */ -#define UART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< USART frame with 1.5 stop bits */ -#define UART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1) /*!< USART frame with 2 stop bits */ -#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_STOPBITS_1) || \ - ((STOPBITS) == UART_STOPBITS_1_5) || \ - ((STOPBITS) == UART_STOPBITS_2)) - -#define IS_LPUART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_1) || \ - ((__STOPBITS__) == UART_STOPBITS_2)) - -/** - * @} - */ - -/** @defgroup UART_Parity UART parity definition - * @{ - */ -#define UART_PARITY_NONE ((uint32_t)0x0000U) -#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE) -#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) -#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NONE) || \ - ((PARITY) == UART_PARITY_EVEN) || \ - ((PARITY) == UART_PARITY_ODD)) -/** - * @} - */ - -/** @defgroup UART_Hardware_Flow_Control UART hardware flow control definition - * @{ - */ -#define UART_HWCONTROL_NONE ((uint32_t)0x0000U) -#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE) -#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE) -#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)) -#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\ - (((CONTROL) == UART_HWCONTROL_NONE) || \ - ((CONTROL) == UART_HWCONTROL_RTS) || \ - ((CONTROL) == UART_HWCONTROL_CTS) || \ - ((CONTROL) == UART_HWCONTROL_RTS_CTS)) +#define UART_STOPBITS_1 ((uint32_t)0x00000000U) /*!< UART frame with 1 stop bit */ +#define UART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< UART frame with 1.5 stop bits */ +#define UART_STOPBITS_2 USART_CR2_STOP_1 /*!< UART frame with 2 stop bits */ /** * @} */ -/** @defgroup UART_Mode UART mode definition +/** @defgroup UART_Parity UART Parity * @{ - */ -#define UART_MODE_RX ((uint32_t)USART_CR1_RE) -#define UART_MODE_TX ((uint32_t)USART_CR1_TE) -#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) -#define IS_UART_MODE(MODE) ((((MODE) & (~((uint32_t)(UART_MODE_TX_RX)))) == (uint32_t)0x00U) && ((MODE) != (uint32_t)0x00U)) -/** - * @} */ - - /** @defgroup UART_State UART state enable and disable definition - * @{ - */ -#define UART_STATE_DISABLE ((uint32_t)0x0000U) -#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE) -#define IS_UART_STATE(STATE) (((STATE) == UART_STATE_DISABLE) || \ - ((STATE) == UART_STATE_ENABLE)) +#define UART_PARITY_NONE ((uint32_t)0x00000000U) /*!< No parity */ +#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE) /*!< Even parity */ +#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) /*!< Odd parity */ /** * @} */ -/** @defgroup UART_Over_Sampling UART over sampling definition +/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control * @{ */ -#define UART_OVERSAMPLING_16 ((uint32_t)0x0000U) -#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8) -#define IS_UART_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16) || \ - ((SAMPLING) == UART_OVERSAMPLING_8)) -/** - * @} - */ - - -/** @defgroup UART_Receiver_TimeOut UART receiver timeOut definition - * @{ - */ -#define UART_RECEIVER_TIMEOUT_DISABLE ((uint32_t)0x00000000U) -#define UART_RECEIVER_TIMEOUT_ENABLE ((uint32_t)USART_CR2_RTOEN) -#define IS_UART_RECEIVER_TIMEOUT(TIMEOUT) (((TIMEOUT) == UART_RECEIVER_TIMEOUT_DISABLE) || \ - ((TIMEOUT) == UART_RECEIVER_TIMEOUT_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_LIN UART LIN enable and disable definition - * @{ - */ -#define UART_LIN_DISABLE ((uint32_t)0x00000000U) -#define UART_LIN_ENABLE ((uint32_t)USART_CR2_LINEN) -#define IS_UART_LIN(LIN) (((LIN) == UART_LIN_DISABLE) || \ - ((LIN) == UART_LIN_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_LIN_Break_Detection UART LIN break detection definition - * @{ - */ -#define UART_LINBREAKDETECTLENGTH_10B ((uint32_t)0x00000000U) -#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)USART_CR2_LBDL) -#define IS_UART_LIN_BREAK_DETECT_LENGTH(LENGTH) (((LENGTH) == UART_LINBREAKDETECTLENGTH_10B) || \ - ((LENGTH) == UART_LINBREAKDETECTLENGTH_11B)) -/** - * @} - */ - - - -/** @defgroup UART_One_Bit UART one bit definition - * @{ - */ -#define UART_ONE_BIT_SAMPLE_DISABLE ((uint32_t)0x00000000U) -#define UART_ONE_BIT_SAMPLE_ENABLE ((uint32_t)USART_CR3_ONEBIT) -#define IS_UART_ONE_BIT_SAMPLE(ONEBIT) (((ONEBIT) == UART_ONE_BIT_SAMPLE_DISABLE) || \ - ((ONEBIT) == UART_ONE_BIT_SAMPLE_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_DMA_Tx UART DMA Tx definition - * @{ - */ -#define UART_DMA_TX_DISABLE ((uint32_t)0x00000000U) -#define UART_DMA_TX_ENABLE ((uint32_t)USART_CR3_DMAT) -#define IS_UART_DMA_TX(DMATX) (((DMATX) == UART_DMA_TX_DISABLE) || \ - ((DMATX) == UART_DMA_TX_ENABLE)) +#define UART_HWCONTROL_NONE ((uint32_t)0x00000000U) /*!< No hardware control */ +#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE) /*!< Request To Send */ +#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE) /*!< Clear To Send */ +#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)) /*!< Request and Clear To Send */ /** * @} */ -/** @defgroup UART_DMA_Rx UART DMA Rx definition +/** @defgroup UART_Mode UART Transfer Mode * @{ */ -#define UART_DMA_RX_DISABLE ((uint32_t)0x0000U) -#define UART_DMA_RX_ENABLE ((uint32_t)USART_CR3_DMAR) -#define IS_UART_DMA_RX(DMARX) (((DMARX) == UART_DMA_RX_DISABLE) || \ - ((DMARX) == UART_DMA_RX_ENABLE)) +#define UART_MODE_RX ((uint32_t)USART_CR1_RE) /*!< RX mode */ +#define UART_MODE_TX ((uint32_t)USART_CR1_TE) /*!< TX mode */ +#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) /*!< RX and TX mode */ /** * @} */ -/** @defgroup UART_Half_Duplex_Selection UART half duplex selection definition +/** @defgroup UART_State UART State * @{ */ -#define UART_HALF_DUPLEX_DISABLE ((uint32_t)0x0000U) -#define UART_HALF_DUPLEX_ENABLE ((uint32_t)USART_CR3_HDSEL) -#define IS_UART_HALF_DUPLEX(HDSEL) (((HDSEL) == UART_HALF_DUPLEX_DISABLE) || \ - ((HDSEL) == UART_HALF_DUPLEX_ENABLE)) +#define UART_STATE_DISABLE ((uint32_t)0x00000000U) /*!< UART disabled */ +#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE) /*!< UART enabled */ /** * @} */ -/** @defgroup UART_Flags UART flags definition +/** @defgroup UART_Over_Sampling UART Over Sampling + * @{ + */ +#define UART_OVERSAMPLING_16 ((uint32_t)0x00000000U) /*!< Oversampling by 16 */ +#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8) /*!< Oversampling by 8 */ +/** + * @} + */ + +/** @defgroup UART_OneBit_Sampling UART One Bit Sampling Method + * @{ + */ +#define UART_ONE_BIT_SAMPLE_DISABLE ((uint32_t)0x00000000U) /*!< One-bit sampling disable */ +#define UART_ONE_BIT_SAMPLE_ENABLE ((uint32_t)USART_CR3_ONEBIT) /*!< One-bit sampling enable */ +/** + * @} + */ + +/** @defgroup UART_AutoBaud_Rate_Mode UART Advanced Feature AutoBaud Rate Mode + * @{ + */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT ((uint32_t)0x00000000) /*!< Auto Baud rate detection on start bit */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE ((uint32_t)USART_CR2_ABRMODE_0) /*!< Auto Baud rate detection on falling edge */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME ((uint32_t)USART_CR2_ABRMODE_1) /*!< Auto Baud rate detection on 0x7F frame detection */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME ((uint32_t)USART_CR2_ABRMODE) /*!< Auto Baud rate detection on 0x55 frame detection */ +/** + * @} + */ + +/** @defgroup UART_Receiver_TimeOut UART Receiver TimeOut + * @{ + */ +#define UART_RECEIVER_TIMEOUT_DISABLE ((uint32_t)0x00000000U) /*!< UART receiver timeout disable */ +#define UART_RECEIVER_TIMEOUT_ENABLE ((uint32_t)USART_CR2_RTOEN) /*!< UART receiver timeout enable */ +/** + * @} + */ + +/** @defgroup UART_LIN UART Local Interconnection Network mode + * @{ + */ +#define UART_LIN_DISABLE ((uint32_t)0x00000000U) /*!< Local Interconnect Network disable */ +#define UART_LIN_ENABLE ((uint32_t)USART_CR2_LINEN) /*!< Local Interconnect Network enable */ +/** + * @} + */ + +/** @defgroup UART_LIN_Break_Detection UART LIN Break Detection + * @{ + */ +#define UART_LINBREAKDETECTLENGTH_10B ((uint32_t)0x00000000U) /*!< LIN 10-bit break detection length */ +#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)USART_CR2_LBDL) /*!< LIN 11-bit break detection length */ +/** + * @} + */ + +/** @defgroup UART_DMA_Tx UART DMA Tx + * @{ + */ +#define UART_DMA_TX_DISABLE ((uint32_t)0x00000000U) /*!< UART DMA TX disabled */ +#define UART_DMA_TX_ENABLE ((uint32_t)USART_CR3_DMAT) /*!< UART DMA TX enabled */ +/** + * @} + */ + +/** @defgroup UART_DMA_Rx UART DMA Rx + * @{ + */ +#define UART_DMA_RX_DISABLE ((uint32_t)0x00000000U) /*!< UART DMA RX disabled */ +#define UART_DMA_RX_ENABLE ((uint32_t)USART_CR3_DMAR) /*!< UART DMA RX enabled */ +/** + * @} + */ + +/** @defgroup UART_Half_Duplex_Selection UART Half Duplex Selection + * @{ + */ +#define UART_HALF_DUPLEX_DISABLE ((uint32_t)0x00000000U) /*!< UART half-duplex disabled */ +#define UART_HALF_DUPLEX_ENABLE ((uint32_t)USART_CR3_HDSEL) /*!< UART half-duplex enabled */ +/** + * @} + */ + +/** @defgroup UART_WakeUp_Methods UART WakeUp Methods + * @{ + */ +#define UART_WAKEUPMETHOD_IDLELINE ((uint32_t)0x00000000U) /*!< UART wake-up on idle line */ +#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)USART_CR1_WAKE) /*!< UART wake-up on address mark */ +/** + * @} + */ + +/** @defgroup UART_Request_Parameters UART Request Parameters + * @{ + */ +#define UART_AUTOBAUD_REQUEST ((uint32_t)USART_RQR_ABRRQ) /*!< Auto-Baud Rate Request */ +#define UART_SENDBREAK_REQUEST ((uint32_t)USART_RQR_SBKRQ) /*!< Send Break Request */ +#define UART_MUTE_MODE_REQUEST ((uint32_t)USART_RQR_MMRQ) /*!< Mute Mode Request */ +#define UART_RXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_RXFRQ) /*!< Receive Data flush Request */ +#define UART_TXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_TXFRQ) /*!< Transmit data flush Request */ +/** + * @} + */ + +/** @defgroup UART_Advanced_Features_Initialization_Type UART Advanced Feature Initialization Type + * @{ + */ +#define UART_ADVFEATURE_NO_INIT ((uint32_t)0x00000000U) /*!< No advanced feature initialization */ +#define UART_ADVFEATURE_TXINVERT_INIT ((uint32_t)0x00000001U) /*!< TX pin active level inversion */ +#define UART_ADVFEATURE_RXINVERT_INIT ((uint32_t)0x00000002U) /*!< RX pin active level inversion */ +#define UART_ADVFEATURE_DATAINVERT_INIT ((uint32_t)0x00000004U) /*!< Binary data inversion */ +#define UART_ADVFEATURE_SWAP_INIT ((uint32_t)0x00000008U) /*!< TX/RX pins swap */ +#define UART_ADVFEATURE_RXOVERRUNDISABLE_INIT ((uint32_t)0x00000010U) /*!< RX overrun disable */ +#define UART_ADVFEATURE_DMADISABLEONERROR_INIT ((uint32_t)0x00000020U) /*!< DMA disable on Reception Error */ +#define UART_ADVFEATURE_AUTOBAUDRATE_INIT ((uint32_t)0x00000040U) /*!< Auto Baud rate detection initialization */ +#define UART_ADVFEATURE_MSBFIRST_INIT ((uint32_t)0x00000080U) /*!< Most significant bit sent/received first */ +/** + * @} + */ + +/** @defgroup UART_Tx_Inv UART Advanced Feature TX Pin Active Level Inversion + * @{ + */ +#define UART_ADVFEATURE_TXINV_DISABLE ((uint32_t)0x00000000U) /*!< TX pin active level inversion disable */ +#define UART_ADVFEATURE_TXINV_ENABLE ((uint32_t)USART_CR2_TXINV) /*!< TX pin active level inversion enable */ +/** + * @} + */ + +/** @defgroup UART_Rx_Inv UART Advanced Feature RX Pin Active Level Inversion + * @{ + */ +#define UART_ADVFEATURE_RXINV_DISABLE ((uint32_t)0x00000000U) /*!< RX pin active level inversion disable */ +#define UART_ADVFEATURE_RXINV_ENABLE ((uint32_t)USART_CR2_RXINV) /*!< RX pin active level inversion enable */ +/** + * @} + */ + +/** @defgroup UART_Data_Inv UART Advanced Feature Binary Data Inversion + * @{ + */ +#define UART_ADVFEATURE_DATAINV_DISABLE ((uint32_t)0x00000000U) /*!< Binary data inversion disable */ +#define UART_ADVFEATURE_DATAINV_ENABLE ((uint32_t)USART_CR2_DATAINV) /*!< Binary data inversion enable */ +/** + * @} + */ + +/** @defgroup UART_Rx_Tx_Swap UART Advanced Feature RX TX Pins Swap + * @{ + */ +#define UART_ADVFEATURE_SWAP_DISABLE ((uint32_t)0x00000000U) /*!< TX/RX pins swap disable */ +#define UART_ADVFEATURE_SWAP_ENABLE ((uint32_t)USART_CR2_SWAP) /*!< TX/RX pins swap enable */ +/** + * @} + */ + +/** @defgroup UART_Overrun_Disable UART Advanced Feature Overrun Disable + * @{ + */ +#define UART_ADVFEATURE_OVERRUN_ENABLE ((uint32_t)0x00000000U) /*!< RX overrun enable */ +#define UART_ADVFEATURE_OVERRUN_DISABLE ((uint32_t)USART_CR3_OVRDIS) /*!< RX overrun disable */ +/** + * @} + */ + +/** @defgroup UART_AutoBaudRate_Enable UART Advanced Feature Auto BaudRate Enable + * @{ + */ +#define UART_ADVFEATURE_AUTOBAUDRATE_DISABLE ((uint32_t)0x00000000U) /*!< RX Auto Baud rate detection enable */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ENABLE ((uint32_t)USART_CR2_ABREN) /*!< RX Auto Baud rate detection disable */ +/** + * @} + */ + +/** @defgroup UART_DMA_Disable_on_Rx_Error UART Advanced Feature DMA Disable On Rx Error + * @{ + */ +#define UART_ADVFEATURE_DMA_ENABLEONRXERROR ((uint32_t)0x00000000U) /*!< DMA enable on Reception Error */ +#define UART_ADVFEATURE_DMA_DISABLEONRXERROR ((uint32_t)USART_CR3_DDRE) /*!< DMA disable on Reception Error */ +/** + * @} + */ + +/** @defgroup UART_MSB_First UART Advanced Feature MSB First + * @{ + */ +#define UART_ADVFEATURE_MSBFIRST_DISABLE ((uint32_t)0x00000000U) /*!< Most significant bit sent/received first disable */ +#define UART_ADVFEATURE_MSBFIRST_ENABLE ((uint32_t)USART_CR2_MSBFIRST) /*!< Most significant bit sent/received first enable */ +/** + * @} + */ + +/** @defgroup UART_Stop_Mode_Enable UART Advanced Feature Stop Mode Enable + * @{ + */ +#define UART_ADVFEATURE_STOPMODE_DISABLE ((uint32_t)0x00000000U) /*!< UART stop mode disable */ +#define UART_ADVFEATURE_STOPMODE_ENABLE ((uint32_t)USART_CR1_UESM) /*!< UART stop mode enable */ +/** + * @} + */ + +/** @defgroup UART_Mute_Mode UART Advanced Feature Mute Mode Enable + * @{ + */ +#define UART_ADVFEATURE_MUTEMODE_DISABLE ((uint32_t)0x00000000U) /*!< UART mute mode disable */ +#define UART_ADVFEATURE_MUTEMODE_ENABLE ((uint32_t)USART_CR1_MME) /*!< UART mute mode enable */ +/** + * @} + */ + +/** @defgroup UART_CR2_ADDRESS_LSB_POS UART Address-matching LSB Position In CR2 Register + * @{ + */ +#define UART_CR2_ADDRESS_LSB_POS ((uint32_t) 24U) /*!< UART address-matching LSB position in CR2 register */ +/** + * @} + */ + +/** @defgroup UART_WakeUp_from_Stop_Selection UART WakeUp From Stop Selection + * @{ + */ +#define UART_WAKEUP_ON_ADDRESS ((uint32_t)0x00000000U) /*!< UART wake-up on address */ +#define UART_WAKEUP_ON_STARTBIT ((uint32_t)USART_CR3_WUS_1) /*!< UART wake-up on start bit */ +#define UART_WAKEUP_ON_READDATA_NONEMPTY ((uint32_t)USART_CR3_WUS) /*!< UART wake-up on receive data register not empty */ +/** + * @} + */ + +/** @defgroup UART_DriverEnable_Polarity UART DriverEnable Polarity + * @{ + */ +#define UART_DE_POLARITY_HIGH ((uint32_t)0x00000000U) /*!< Driver enable signal is active high */ +#define UART_DE_POLARITY_LOW ((uint32_t)USART_CR3_DEP) /*!< Driver enable signal is active low */ +/** + * @} + */ + +/** @defgroup UART_CR1_DEAT_ADDRESS_LSB_POS UART Driver Enable Assertion Time LSB Position In CR1 Register + * @{ + */ +#define UART_CR1_DEAT_ADDRESS_LSB_POS ((uint32_t) 21U) /*!< UART Driver Enable assertion time LSB position in CR1 register */ +/** + * @} + */ + +/** @defgroup UART_CR1_DEDT_ADDRESS_LSB_POS UART Driver Enable DeAssertion Time LSB Position In CR1 Register + * @{ + */ +#define UART_CR1_DEDT_ADDRESS_LSB_POS ((uint32_t) 16U) /*!< UART Driver Enable de-assertion time LSB position in CR1 register */ +/** + * @} + */ + +/** @defgroup UART_Interruption_Mask UART Interruptions Flag Mask + * @{ + */ +#define UART_IT_MASK ((uint32_t)0x001FU) /*!< UART interruptions flags mask */ +/** + * @} + */ + +/** @defgroup UART_TimeOut_Value UART polling-based communications time-out value + * @{ + */ +#define HAL_UART_TIMEOUT_VALUE 0x1FFFFFF /*!< UART polling-based communications time-out value */ +/** + * @} + */ + +/** @defgroup UART_Flags UART Status Flags * Elements values convention: 0xXXXX * - 0xXXXX : Flag mask in the ISR register * @{ */ -#define UART_FLAG_REACK USART_ISR_REACK /*!< Receive Enable Acknowledge Flag */ -#define UART_FLAG_TEACK USART_ISR_TEACK /*!< Transmit Enable Acknowledge Flag */ -#define UART_FLAG_WUF USART_ISR_WUF /*!< Wake Up from stop mode Flag */ -#define UART_FLAG_RWU USART_ISR_RWU /*!< Receive Wake Up from mute mode Flag */ -#define UART_FLAG_SBKF USART_ISR_SBKF /*!< Send Break Flag */ -#define UART_FLAG_CMF USART_ISR_CMF /*!< Character Match Flag */ -#define UART_FLAG_BUSY USART_ISR_BUSY /*!< Busy Flag */ -#define UART_FLAG_ABRF USART_ISR_ABRF /*!< Auto-Baud Rate Flag */ -#define UART_FLAG_ABRE USART_ISR_ABRE /*!< Auto-Baud Rate Error */ -#define UART_FLAG_EOBF USART_ISR_EOBF /*!< End Of Block Flag */ -#define UART_FLAG_RTOF USART_ISR_RTOF /*!< Receiver Time Out */ -#define UART_FLAG_CTS USART_ISR_CTS /*!< CTS flag */ -#define UART_FLAG_CTSIF USART_ISR_CTSIF /*!< CTS interrupt flag */ -#define UART_FLAG_LBDF USART_ISR_LBDF /*!< LIN Break Detection Flag */ -#define UART_FLAG_TXE USART_ISR_TXE /*!< Transmit Data Register Empty */ -#define UART_FLAG_TC USART_ISR_TC /*!< Transmission Complete */ -#define UART_FLAG_RXNE USART_ISR_RXNE /*!< Read Data Register Not Empty */ -#define UART_FLAG_IDLE USART_ISR_IDLE /*!< IDLE line detected */ -#define UART_FLAG_ORE USART_ISR_ORE /*!< OverRun Error */ -#define UART_FLAG_NE USART_ISR_NE /*!< Noise detected Flag */ -#define UART_FLAG_FE USART_ISR_FE /*!< Framing Error */ -#define UART_FLAG_PE USART_ISR_PE /*!< Parity Error */ +#define UART_FLAG_REACK USART_ISR_REACK /*!< UART receive enable acknowledge flag */ +#define UART_FLAG_TEACK USART_ISR_TEACK /*!< UART transmit enable acknowledge flag */ +#define UART_FLAG_WUF USART_ISR_WUF /*!< UART wake-up from stop mode flag */ +#define UART_FLAG_RWU USART_ISR_RWU /*!< UART receiver wake-up from mute mode flag */ +#define UART_FLAG_SBKF USART_ISR_SBKF /*!< UART send break flag */ +#define UART_FLAG_CMF USART_ISR_CMF /*!< UART character match flag */ +#define UART_FLAG_BUSY USART_ISR_BUSY /*!< UART busy flag */ +#define UART_FLAG_ABRF USART_ISR_ABRF /*!< UART auto Baud rate flag */ +#define UART_FLAG_ABRE USART_ISR_ABRE /*!< UART auto Baud rate error */ +#define UART_FLAG_EOBF USART_ISR_EOBF /*!< UART end of block flag */ +#define UART_FLAG_RTOF USART_ISR_RTOF /*!< UART receiver timeout flag */ +#define UART_FLAG_CTS USART_ISR_CTS /*!< UART clear to send flag */ +#define UART_FLAG_CTSIF USART_ISR_CTSIF /*!< UART clear to send interrupt flag */ +#define UART_FLAG_LBDF USART_ISR_LBDF /*!< UART LIN break detection flag */ +#define UART_FLAG_TXE USART_ISR_TXE /*!< UART transmit data register empty */ +#define UART_FLAG_TC USART_ISR_TC /*!< UART transmission complete */ +#define UART_FLAG_RXNE USART_ISR_RXNE /*!< UART read data register not empty */ +#define UART_FLAG_IDLE USART_ISR_IDLE /*!< UART idle flag */ +#define UART_FLAG_ORE USART_ISR_ORE /*!< UART overrun error */ +#define UART_FLAG_NE USART_ISR_NE /*!< UART noise error */ +#define UART_FLAG_FE USART_ISR_FE /*!< UART frame error */ +#define UART_FLAG_PE USART_ISR_PE /*!< UART parity error */ /** * @} - */ + */ -/** @defgroup UART_Interrupt_definition UART interrupt definition +/** @defgroup UART_Interrupt_definition UART Interrupts Definition * Elements values convention: 000ZZZZZ0XXYYYYYb * - YYYYY : Interrupt source position in the XX register (5bits) * - XX : Interrupt source register (2bits) @@ -513,15 +638,15 @@ typedef struct * - ZZZZZ : Flag position in the ISR register(5bits) * @{ */ -#define UART_IT_PE ((uint32_t)0x0028U) -#define UART_IT_TXE ((uint32_t)0x0727U) -#define UART_IT_TC ((uint32_t)0x0626U) -#define UART_IT_RXNE ((uint32_t)0x0525U) -#define UART_IT_IDLE ((uint32_t)0x0424U) -#define UART_IT_LBD ((uint32_t)0x0846U) -#define UART_IT_CTS ((uint32_t)0x096AU) -#define UART_IT_CM ((uint32_t)0x112EU) -#define UART_IT_WUF ((uint32_t)0x1476U) +#define UART_IT_PE ((uint32_t)0x0028) /*!< UART parity error interruption */ +#define UART_IT_TXE ((uint32_t)0x0727) /*!< UART transmit data register empty interruption */ +#define UART_IT_TC ((uint32_t)0x0626) /*!< UART transmission complete interruption */ +#define UART_IT_RXNE ((uint32_t)0x0525) /*!< UART read data register not empty interruption */ +#define UART_IT_IDLE ((uint32_t)0x0424) /*!< UART idle interruption */ +#define UART_IT_LBD ((uint32_t)0x0846) /*!< UART LIN break detection interruption */ +#define UART_IT_CTS ((uint32_t)0x096A) /*!< UART CTS interruption */ +#define UART_IT_CM ((uint32_t)0x112E) /*!< UART character match interruption */ +#define UART_IT_WUF ((uint32_t)0x1476) /*!< UART wake-up from stop mode interruption */ /** Elements values convention: 000000000XXYYYYYb * - YYYYY : Interrupt source position in the XX register (5bits) @@ -530,508 +655,292 @@ typedef struct * - 10: CR2 register * - 11: CR3 register */ -#define UART_IT_ERR ((uint32_t)0x0060U) +#define UART_IT_ERR ((uint32_t)0x0060) /*!< UART error interruption */ /** Elements values convention: 0000ZZZZ00000000b * - ZZZZ : Flag position in the ISR register(4bits) */ -#define UART_IT_ORE ((uint32_t)0x0300U) -#define UART_IT_NE ((uint32_t)0x0200U) -#define UART_IT_FE ((uint32_t)0x0100U) +#define UART_IT_ORE ((uint32_t)0x0300) /*!< UART overrun error interruption */ +#define UART_IT_NE ((uint32_t)0x0200) /*!< UART noise error interruption */ +#define UART_IT_FE ((uint32_t)0x0100) /*!< UART frame error interruption */ /** * @} */ -/** @defgroup UART_IT_CLEAR_Flags UART interrupt clear flags definition +/** @defgroup UART_IT_CLEAR_Flags UART Interruption Clear Flags * @{ */ -#define UART_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ -#define UART_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ -#define UART_CLEAR_NEF USART_ICR_NCF /*!< Noise detected Clear Flag */ -#define UART_CLEAR_OREF USART_ICR_ORECF /*!< OverRun Error Clear Flag */ -#define UART_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ -#define UART_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ -#define UART_CLEAR_LBDF USART_ICR_LBDCF /*!< LIN Break Detection Clear Flag */ -#define UART_CLEAR_CTSF USART_ICR_CTSCF /*!< CTS Interrupt Clear Flag */ -#define UART_CLEAR_RTOF USART_ICR_RTOCF /*!< Receiver Time Out Clear Flag */ -#define UART_CLEAR_EOBF USART_ICR_EOBCF /*!< End Of Block Clear Flag */ -#define UART_CLEAR_CMF USART_ICR_CMCF /*!< Character Match Clear Flag */ +#define UART_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ +#define UART_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ +#define UART_CLEAR_NEF USART_ICR_NCF /*!< Noise detected Clear Flag */ +#define UART_CLEAR_OREF USART_ICR_ORECF /*!< Overrun Error Clear Flag */ +#define UART_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ +#define UART_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ +#define UART_CLEAR_LBDF USART_ICR_LBDCF /*!< LIN Break Detection Clear Flag */ +#define UART_CLEAR_CTSF USART_ICR_CTSCF /*!< CTS Interrupt Clear Flag */ +#define UART_CLEAR_RTOF USART_ICR_RTOCF /*!< Receiver Time Out Clear Flag */ +#define UART_CLEAR_EOBF USART_ICR_EOBCF /*!< End Of Block Clear Flag */ +#define UART_CLEAR_CMF USART_ICR_CMCF /*!< Character Match Clear Flag */ #define UART_CLEAR_WUF USART_ICR_WUCF /*!< Wake Up from stop mode Clear Flag */ /** * @} */ -/** @defgroup UART_Request_Parameters UART request parameter definition - * @{ - */ -#define UART_AUTOBAUD_REQUEST ((uint32_t)USART_RQR_ABRRQ) /*!< Auto-Baud Rate Request */ -#define UART_SENDBREAK_REQUEST ((uint32_t)USART_RQR_SBKRQ) /*!< Send Break Request */ -#define UART_MUTE_MODE_REQUEST ((uint32_t)USART_RQR_MMRQ) /*!< Mute Mode Request */ -#define UART_RXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_RXFRQ) /*!< Receive Data flush Request */ -#define UART_TXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_TXFRQ) /*!< Transmit data flush Request */ -#define IS_UART_REQUEST_PARAMETER(PARAM) (((PARAM) == UART_AUTOBAUD_REQUEST) || \ - ((PARAM) == UART_SENDBREAK_REQUEST) || \ - ((PARAM) == UART_MUTE_MODE_REQUEST) || \ - ((PARAM) == UART_RXDATA_FLUSH_REQUEST) || \ - ((PARAM) == UART_TXDATA_FLUSH_REQUEST)) -/** - * @} - */ - -/** @defgroup UART_Advanced_Features_Initialization_Type UART advanced features initialization type definition - * @{ - */ -#define UART_ADVFEATURE_NO_INIT ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_TXINVERT_INIT ((uint32_t)0x00000001U) -#define UART_ADVFEATURE_RXINVERT_INIT ((uint32_t)0x00000002U) -#define UART_ADVFEATURE_DATAINVERT_INIT ((uint32_t)0x00000004U) -#define UART_ADVFEATURE_SWAP_INIT ((uint32_t)0x00000008U) -#define UART_ADVFEATURE_RXOVERRUNDISABLE_INIT ((uint32_t)0x00000010U) -#define UART_ADVFEATURE_DMADISABLEONERROR_INIT ((uint32_t)0x00000020U) -#define UART_ADVFEATURE_AUTOBAUDRATE_INIT ((uint32_t)0x00000040U) -#define UART_ADVFEATURE_MSBFIRST_INIT ((uint32_t)0x00000080U) -#define IS_UART_ADVFEATURE_INIT(INIT) ((INIT) <= (UART_ADVFEATURE_NO_INIT | \ - UART_ADVFEATURE_TXINVERT_INIT | \ - UART_ADVFEATURE_RXINVERT_INIT | \ - UART_ADVFEATURE_DATAINVERT_INIT | \ - UART_ADVFEATURE_SWAP_INIT | \ - UART_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ - UART_ADVFEATURE_DMADISABLEONERROR_INIT | \ - UART_ADVFEATURE_AUTOBAUDRATE_INIT | \ - UART_ADVFEATURE_MSBFIRST_INIT)) -/** - * @} - */ - -/** @defgroup UART_Tx_Inv UART advanced Tx inv activation definition - * @{ - */ -#define UART_ADVFEATURE_TXINV_DISABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_TXINV_ENABLE ((uint32_t)USART_CR2_TXINV) -#define IS_UART_ADVFEATURE_TXINV(TXINV) (((TXINV) == UART_ADVFEATURE_TXINV_DISABLE) || \ - ((TXINV) == UART_ADVFEATURE_TXINV_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_Rx_Inv UART advanced Rx inv activation definition - * @{ - */ -#define UART_ADVFEATURE_RXINV_DISABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_RXINV_ENABLE ((uint32_t)USART_CR2_RXINV) -#define IS_UART_ADVFEATURE_RXINV(RXINV) (((RXINV) == UART_ADVFEATURE_RXINV_DISABLE) || \ - ((RXINV) == UART_ADVFEATURE_RXINV_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_Data_Inv UART advanced data inv activation definition - * @{ - */ -#define UART_ADVFEATURE_DATAINV_DISABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_DATAINV_ENABLE ((uint32_t)USART_CR2_DATAINV) -#define IS_UART_ADVFEATURE_DATAINV(DATAINV) (((DATAINV) == UART_ADVFEATURE_DATAINV_DISABLE) || \ - ((DATAINV) == UART_ADVFEATURE_DATAINV_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_Rx_Tx_Swap UART advanced swap activation definition - * @{ - */ -#define UART_ADVFEATURE_SWAP_DISABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_SWAP_ENABLE ((uint32_t)USART_CR2_SWAP) -#define IS_UART_ADVFEATURE_SWAP(SWAP) (((SWAP) == UART_ADVFEATURE_SWAP_DISABLE) || \ - ((SWAP) == UART_ADVFEATURE_SWAP_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_Overrun_Disable UART advanced overrun activation definition - * @{ - */ -#define UART_ADVFEATURE_OVERRUN_ENABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_OVERRUN_DISABLE ((uint32_t)USART_CR3_OVRDIS) -#define IS_UART_OVERRUN(OVERRUN) (((OVERRUN) == UART_ADVFEATURE_OVERRUN_ENABLE) || \ - ((OVERRUN) == UART_ADVFEATURE_OVERRUN_DISABLE)) -/** - * @} - */ - -/** @defgroup UART_AutoBaudRate_Enable UART advanced auto baud rate activation definition - * @{ - */ -#define UART_ADVFEATURE_AUTOBAUDRATE_DISABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_AUTOBAUDRATE_ENABLE ((uint32_t)USART_CR2_ABREN) -#define IS_UART_ADVFEATURE_AUTOBAUDRATE(AUTOBAUDRATE) (((AUTOBAUDRATE) == UART_ADVFEATURE_AUTOBAUDRATE_DISABLE) || \ - ((AUTOBAUDRATE) == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_DMA_Disable_on_Rx_Error UART advanced DMA on Rx error activation definition - * @{ - */ -#define UART_ADVFEATURE_DMA_ENABLEONRXERROR ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_DMA_DISABLEONRXERROR ((uint32_t)USART_CR3_DDRE) -#define IS_UART_ADVFEATURE_DMAONRXERROR(DMA) (((DMA) == UART_ADVFEATURE_DMA_ENABLEONRXERROR) || \ - ((DMA) == UART_ADVFEATURE_DMA_DISABLEONRXERROR)) -/** - * @} - */ - -/** @defgroup UART_MSB_First UART advanced MSB first activation definition - * @{ - */ -#define UART_ADVFEATURE_MSBFIRST_DISABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_MSBFIRST_ENABLE ((uint32_t)USART_CR2_MSBFIRST) -#define IS_UART_ADVFEATURE_MSBFIRST(MSBFIRST) (((MSBFIRST) == UART_ADVFEATURE_MSBFIRST_DISABLE) || \ - ((MSBFIRST) == UART_ADVFEATURE_MSBFIRST_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_Stop_Mode_Enable UART advanced stop mode activation definition - * @{ - */ -#define UART_ADVFEATURE_STOPMODE_DISABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_STOPMODE_ENABLE ((uint32_t)USART_CR1_UESM) -#define IS_UART_ADVFEATURE_STOPMODE(STOPMODE) (((STOPMODE) == UART_ADVFEATURE_STOPMODE_DISABLE) || \ - ((STOPMODE) == UART_ADVFEATURE_STOPMODE_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_Mute_Mode UART advanced mute mode activation definition - * @{ - */ -#define UART_ADVFEATURE_MUTEMODE_DISABLE ((uint32_t)0x00000000U) -#define UART_ADVFEATURE_MUTEMODE_ENABLE ((uint32_t)USART_CR1_MME) -#define IS_UART_MUTE_MODE(MUTE) (((MUTE) == UART_ADVFEATURE_MUTEMODE_DISABLE) || \ - ((MUTE) == UART_ADVFEATURE_MUTEMODE_ENABLE)) -/** - * @} - */ - -/** @defgroup UART_CR2_ADDRESS_LSBPOS UART CR2 address lsb position definition - * @{ - */ -#define UART_CR2_ADDRESS_LSB_POS ((uint32_t) 24U) -/** - * @} - */ - -/** @defgroup UART_WakeUp_from_Stop_Selection UART wake up mode selection definition - * @{ - */ -#define UART_WAKEUP_ON_ADDRESS ((uint32_t)0x0000U) -#define UART_WAKEUP_ON_STARTBIT ((uint32_t)USART_CR3_WUS_1) -#define UART_WAKEUP_ON_READDATA_NONEMPTY ((uint32_t)USART_CR3_WUS) -#define IS_UART_WAKEUP_SELECTION(WAKE) (((WAKE) == UART_WAKEUP_ON_ADDRESS) || \ - ((WAKE) == UART_WAKEUP_ON_STARTBIT) || \ - ((WAKE) == UART_WAKEUP_ON_READDATA_NONEMPTY)) -/** - * @} - */ - -/** @defgroup UART_DriverEnable_Polarity UART driver polarity level definition - * @{ - */ -#define UART_DE_POLARITY_HIGH ((uint32_t)0x00000000U) -#define UART_DE_POLARITY_LOW ((uint32_t)USART_CR3_DEP) -#define IS_UART_DE_POLARITY(POLARITY) (((POLARITY) == UART_DE_POLARITY_HIGH) || \ - ((POLARITY) == UART_DE_POLARITY_LOW)) -/** - * @} - */ - -/** @defgroup UART_CR1_DEAT_ADDRESS_LSBPOS UART CR1 DEAT address lsb position definition - * @{ - */ -#define UART_CR1_DEAT_ADDRESS_LSB_POS ((uint32_t) 21U) -/** - * @} - */ - -/** @defgroup UART_CR1_DEDT_ADDRESS_LSBPOS UART CR1 DEDT address lsb position definition - * @{ - */ -#define UART_CR1_DEDT_ADDRESS_LSB_POS ((uint32_t) 16U) -/** - * @} - */ - -/** @defgroup UART_Interruption_Mask UART interruption mask definition - * @{ - */ -#define UART_IT_MASK ((uint32_t)0x001FU) -/** - * @} - */ /** * @} */ -/* Exported macro ------------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ /** @defgroup UART_Exported_Macros UART Exported Macros * @{ */ -/** @brief Reset UART handle state - * @param __HANDLE__: specifies the UART Handle. - * The Handle Instance which can be USART1, USART2 or LPUART. +/** @brief Reset UART handle states. + * @param __HANDLE__: UART handle. * @retval None */ -#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_UART_STATE_RESET) - -/** @brief Flush the UART Data registers +#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_UART_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \ + } while(0) +/** @brief Flush the UART Data registers. * @param __HANDLE__: specifies the UART Handle. + * @retval None */ #define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) \ do{ \ SET_BIT((__HANDLE__)->Instance->RQR, UART_RXDATA_FLUSH_REQUEST); \ SET_BIT((__HANDLE__)->Instance->RQR, UART_TXDATA_FLUSH_REQUEST); \ - } while(0) + } while(0) - -/** @brief Clears the specified UART pending flag. +/** @brief Clear the specified UART pending flag. * @param __HANDLE__: specifies the UART Handle. * @param __FLAG__: specifies the flag to check. * This parameter can be any combination of the following values: - * @arg UART_CLEAR_PEF - * @arg UART_CLEAR_FEF - * @arg UART_CLEAR_NEF - * @arg UART_CLEAR_OREF - * @arg UART_CLEAR_IDLEF - * @arg UART_CLEAR_TCF - * @arg UART_CLEAR_LBDF - * @arg UART_CLEAR_CTSF - * @arg UART_CLEAR_RTOF - * @arg UART_CLEAR_EOBF - * @arg UART_CLEAR_CMF - * @arg UART_CLEAR_WUF + * @arg @ref UART_CLEAR_PEF Parity Error Clear Flag + * @arg @ref UART_CLEAR_FEF Framing Error Clear Flag + * @arg @ref UART_CLEAR_NEF Noise detected Clear Flag + * @arg @ref UART_CLEAR_OREF Overrun Error Clear Flag + * @arg @ref UART_CLEAR_IDLEF IDLE line detected Clear Flag + * @arg @ref UART_CLEAR_TCF Transmission Complete Clear Flag + * @arg @ref UART_CLEAR_LBDF LIN Break Detection Clear Flag + * @arg @ref UART_CLEAR_CTSF CTS Interrupt Clear Flag + * @arg @ref UART_CLEAR_RTOF Receiver Time Out Clear Flag + * @arg @ref UART_CLEAR_EOBF End Of Block Clear Flag + * @arg @ref UART_CLEAR_CMF Character Match Clear Flag + * @arg @ref UART_CLEAR_WUF Wake Up from stop mode Clear Flag * @retval None */ #define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) - /** @brief Clear the UART PE pending flag. * @param __HANDLE__: specifies the UART Handle. * @retval None */ -#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG(__HANDLE__,UART_CLEAR_PEF) +#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_PEF) /** @brief Clear the UART FE pending flag. * @param __HANDLE__: specifies the UART Handle. * @retval None */ -#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG(__HANDLE__,UART_CLEAR_FEF) +#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_FEF) /** @brief Clear the UART NE pending flag. * @param __HANDLE__: specifies the UART Handle. * @retval None */ -#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG(__HANDLE__,UART_CLEAR_NEF) +#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_NEF) /** @brief Clear the UART ORE pending flag. * @param __HANDLE__: specifies the UART Handle. * @retval None */ -#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG(__HANDLE__,UART_CLEAR_OREF) +#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_OREF) /** @brief Clear the UART IDLE pending flag. * @param __HANDLE__: specifies the UART Handle. * @retval None */ -#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG(__HANDLE__,UART_CLEAR_IDLEF) +#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_IDLEF) -/** @brief Checks whether the specified UART flag is set or not. +/** @brief Check whether the specified UART flag is set or not. * @param __HANDLE__: specifies the UART Handle. - * This parameter can be USART1, USART2 or LPUART. * @param __FLAG__: specifies the flag to check. * This parameter can be one of the following values: - * @arg UART_FLAG_REACK: Receive enable ackowledge flag - * @arg UART_FLAG_TEACK: Transmit enable ackowledge flag - * @arg UART_FLAG_WUF: Wake up from stop mode flag - * @arg UART_FLAG_RWU: Receiver wake up flag (is the UART in mute mode) - * @arg UART_FLAG_SBKF: Send Break flag - * @arg UART_FLAG_CMF: Character match flag - * @arg UART_FLAG_BUSY: Busy flag - * @arg UART_FLAG_ABRF: Auto Baud rate detection flag - * @arg UART_FLAG_ABRE: Auto Baud rate detection error flag - * @arg UART_FLAG_EOBF: End of block flag - * @arg UART_FLAG_RTOF: Receiver timeout flag - * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) - * @arg UART_FLAG_LBD: LIN Break detection flag - * @arg UART_FLAG_TXE: Transmit data register empty flag - * @arg UART_FLAG_TC: Transmission Complete flag - * @arg UART_FLAG_RXNE: Receive data register not empty flag - * @arg UART_FLAG_IDLE: Idle Line detection flag - * @arg UART_FLAG_ORE: OverRun Error flag - * @arg UART_FLAG_NE: Noise Error flag - * @arg UART_FLAG_FE: Framing Error flag - * @arg UART_FLAG_PE: Parity Error flag + * @arg @ref UART_FLAG_REACK Receive enable acknowledge flag + * @arg @ref UART_FLAG_TEACK Transmit enable acknowledge flag + * @arg @ref UART_FLAG_WUF Wake up from stop mode flag + * @arg @ref UART_FLAG_RWU Receiver wake up flag (if the UART in mute mode) + * @arg @ref UART_FLAG_SBKF Send Break flag + * @arg @ref UART_FLAG_CMF Character match flag + * @arg @ref UART_FLAG_BUSY Busy flag + * @arg @ref UART_FLAG_ABRF Auto Baud rate detection flag + * @arg @ref UART_FLAG_ABRE Auto Baud rate detection error flag + * @arg @ref UART_FLAG_EOBF End of block flag + * @arg @ref UART_FLAG_RTOF Receiver timeout flag + * @arg @ref UART_FLAG_CTS CTS Change flag + * @arg @ref UART_FLAG_LBDF LIN Break detection flag + * @arg @ref UART_FLAG_TXE Transmit data register empty flag + * @arg @ref UART_FLAG_TC Transmission Complete flag + * @arg @ref UART_FLAG_RXNE Receive data register not empty flag + * @arg @ref UART_FLAG_IDLE Idle Line detection flag + * @arg @ref UART_FLAG_ORE Overrun Error flag + * @arg @ref UART_FLAG_NE Noise Error flag + * @arg @ref UART_FLAG_FE Framing Error flag + * @arg @ref UART_FLAG_PE Parity Error flag * @retval The new state of __FLAG__ (TRUE or FALSE). */ #define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) -/** @brief Enables the specified UART interrupt. +/** @brief Enable the specified UART interrupt. * @param __HANDLE__: specifies the UART Handle. - * This parameter can be USART1, USART2 or LPUART. * @param __INTERRUPT__: specifies the UART interrupt source to enable. * This parameter can be one of the following values: - * @arg UART_IT_WUF: Wakeup from stop mode interrupt - * @arg UART_IT_CM: Character match interrupt - * @arg UART_IT_CTS: CTS change interrupt - * @arg UART_IT_LBD: LIN Break detection interrupt - * @arg UART_IT_TXE: Transmit Data Register empty interrupt - * @arg UART_IT_TC: Transmission complete interrupt - * @arg UART_IT_RXNE: Receive Data register not empty interrupt - * @arg UART_IT_IDLE: Idle line detection interrupt - * @arg UART_IT_PE: Parity Error interrupt - * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt + * @arg @ref UART_IT_CM Character match interrupt + * @arg @ref UART_IT_CTS CTS change interrupt + * @arg @ref UART_IT_LBD LIN Break detection interrupt + * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref UART_IT_TC Transmission complete interrupt + * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref UART_IT_IDLE Idle line detection interrupt + * @arg @ref UART_IT_PE Parity Error interrupt + * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) * @retval None */ #define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 |= (1U << ((__INTERRUPT__) & UART_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & UART_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & UART_IT_MASK)))) + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & UART_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & UART_IT_MASK)))) -/** @brief Disables the specified UART interrupt. + +/** @brief Disable the specified UART interrupt. * @param __HANDLE__: specifies the UART Handle. - * This parameter can be USART1, USART2 or LPUART. * @param __INTERRUPT__: specifies the UART interrupt source to disable. * This parameter can be one of the following values: - * @arg UART_IT_WUF: Wakeup from stop mode interrupt - * @arg UART_IT_CM: Character match interrupt - * @arg UART_IT_CTS: CTS change interrupt - * @arg UART_IT_LBD: LIN Break detection interrupt - * @arg UART_IT_TXE: Transmit Data Register empty interrupt - * @arg UART_IT_TC: Transmission complete interrupt - * @arg UART_IT_RXNE: Receive Data register not empty interrupt - * @arg UART_IT_IDLE: Idle line detection interrupt - * @arg UART_IT_PE: Parity Error interrupt - * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt + * @arg @ref UART_IT_CM Character match interrupt + * @arg @ref UART_IT_CTS CTS change interrupt + * @arg @ref UART_IT_LBD LIN Break detection interrupt + * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref UART_IT_TC Transmission complete interrupt + * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref UART_IT_IDLE Idle line detection interrupt + * @arg @ref UART_IT_PE Parity Error interrupt + * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) * @retval None */ -#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & UART_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & UART_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & UART_IT_MASK)))) +#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 &= ~ (1U << ((__INTERRUPT__) & UART_IT_MASK))): \ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 &= ~ (1U << ((__INTERRUPT__) & UART_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 &= ~ (1U << ((__INTERRUPT__) & UART_IT_MASK)))) -/** @brief Checks whether the specified UART interrupt has occurred or not. +/** @brief Check whether the specified UART interrupt has occurred or not. * @param __HANDLE__: specifies the UART Handle. - * This parameter can be USART1, USART2 or LPUART. * @param __IT__: specifies the UART interrupt to check. * This parameter can be one of the following values: - * @arg UART_IT_WUF: Wakeup from stop mode interrupt - * @arg UART_IT_CM: Character match interrupt - * @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) - * @arg UART_IT_LBD: LIN Break detection interrupt - * @arg UART_IT_TXE: Transmit Data Register empty interrupt - * @arg UART_IT_TC: Transmission complete interrupt - * @arg UART_IT_RXNE: Receive Data register not empty interrupt - * @arg UART_IT_IDLE: Idle line detection interrupt - * @arg UART_IT_ORE: OverRun Error interrupt - * @arg UART_IT_NE: Noise Error interrupt - * @arg UART_IT_FE: Framing Error interrupt - * @arg UART_IT_PE: Parity Error interrupt + * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt + * @arg @ref UART_IT_CM Character match interrupt + * @arg @ref UART_IT_CTS CTS change interrupt + * @arg @ref UART_IT_LBD LIN Break detection interrupt + * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref UART_IT_TC Transmission complete interrupt + * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref UART_IT_IDLE Idle line detection interrupt + * @arg @ref UART_IT_ORE Overrun Error interrupt + * @arg @ref UART_IT_NE Noise Error interrupt + * @arg @ref UART_IT_FE Framing Error interrupt + * @arg @ref UART_IT_PE Parity Error interrupt * @retval The new state of __IT__ (TRUE or FALSE). */ #define __HAL_UART_GET_IT(__HANDLE__, __IT__) ((__HANDLE__)->Instance->ISR & ((uint32_t)1U << ((__IT__)>> 0x08U))) -/** @brief Checks whether the specified UART interrupt source is enabled. +/** @brief Check whether the specified UART interrupt source is enabled or not. * @param __HANDLE__: specifies the UART Handle. - * This parameter can be USART1, USART2 or LPUART. * @param __IT__: specifies the UART interrupt source to check. * This parameter can be one of the following values: - * @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) - * @arg UART_IT_LBD: LIN Break detection interrupt - * @arg UART_IT_TXE: Transmit Data Register empty interrupt - * @arg UART_IT_TC: Transmission complete interrupt - * @arg UART_IT_RXNE: Receive Data register not empty interrupt - * @arg UART_IT_IDLE: Idle line detection interrupt - * @arg UART_IT_ORE: OverRun Error interrupt - * @arg UART_IT_NE: Noise Error interrupt - * @arg UART_IT_FE: Framing Error interrupt - * @arg UART_IT_PE: Parity Error interrupt + * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt + * @arg @ref UART_IT_CM Character match interrupt + * @arg @ref UART_IT_CTS CTS change interrupt + * @arg @ref UART_IT_LBD LIN Break detection interrupt + * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref UART_IT_TC Transmission complete interrupt + * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref UART_IT_IDLE Idle line detection interrupt + * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) + * @arg @ref UART_IT_PE Parity Error interrupt * @retval The new state of __IT__ (TRUE or FALSE). */ #define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) ((((((uint8_t)(__IT__)) >> 5U) == 1U)? (__HANDLE__)->Instance->CR1:(((((uint8_t)(__IT__)) >> 5U) == 2U)? \ (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & ((uint32_t)1U << (((uint16_t)(__IT__)) & UART_IT_MASK))) -/** @brief Clears the specified UART ISR flag, in setting the proper ICR register flag. +/** @brief Clear the specified UART ISR flag, in setting the proper ICR register flag. * @param __HANDLE__: specifies the UART Handle. - * This parameter can be USART1, USART2 or LPUART. * @param __IT_CLEAR__: specifies the interrupt clear register flag that needs to be set * to clear the corresponding interrupt * This parameter can be one of the following values: - * @arg UART_CLEAR_PEF: Parity Error Clear Flag - * @arg UART_CLEAR_FEF: Framing Error Clear Flag - * @arg UART_CLEAR_NEF: Noise detected Clear Flag - * @arg UART_CLEAR_OREF: OverRun Error Clear Flag - * @arg UART_CLEAR_IDLEF: IDLE line detected Clear Flag - * @arg UART_CLEAR_TCF: Transmission Complete Clear Flag - * @arg UART_CLEAR_LBDF: LIN Break Detection Clear Flag - * @arg UART_CLEAR_CTSF: CTS Interrupt Clear Flag - * @arg UART_CLEAR_RTOF: Receiver Time Out Clear Flag - * @arg UART_CLEAR_EOBF: End Of Block Clear Flag - * @arg UART_CLEAR_CMF: Character Match Clear Flag - * @arg UART_CLEAR_WUF: Wake Up from stop mode Clear Flag + * @arg @ref UART_CLEAR_PEF Parity Error Clear Flag + * @arg @ref UART_CLEAR_FEF Framing Error Clear Flag + * @arg @ref UART_CLEAR_NEF Noise detected Clear Flag + * @arg @ref UART_CLEAR_OREF Overrun Error Clear Flag + * @arg @ref UART_CLEAR_IDLEF IDLE line detected Clear Flag + * @arg @ref UART_CLEAR_TCF Transmission Complete Clear Flag + * @arg @ref UART_CLEAR_LBDF LIN Break Detection Clear Flag + * @arg @ref UART_CLEAR_CTSF CTS Interrupt Clear Flag + * @arg @ref UART_CLEAR_RTOF Receiver Time Out Clear Flag + * @arg @ref UART_CLEAR_EOBF End Of Block Clear Flag + * @arg @ref UART_CLEAR_CMF Character Match Clear Flag + * @arg @ref UART_CLEAR_WUF Wake Up from stop mode Clear Flag * @retval None */ #define __HAL_UART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) /** @brief Set a specific UART request flag. * @param __HANDLE__: specifies the UART Handle. - * This parameter can be USART1, USART2 or LPUART. * @param __REQ__: specifies the request flag to set * This parameter can be one of the following values: - * @arg UART_AUTOBAUD_REQUEST: Auto-Baud Rate Request - * @arg UART_SENDBREAK_REQUEST: Send Break Request - * @arg UART_MUTE_MODE_REQUEST: Mute Mode Request - * @arg UART_RXDATA_FLUSH_REQUEST: Receive Data flush Request - * @arg UART_TXDATA_FLUSH_REQUEST: Transmit data flush Request + * @arg @ref UART_AUTOBAUD_REQUEST Auto-Baud Rate Request + * @arg @ref UART_SENDBREAK_REQUEST Send Break Request + * @arg @ref UART_MUTE_MODE_REQUEST Mute Mode Request + * @arg @ref UART_RXDATA_FLUSH_REQUEST Receive Data flush Request + * @arg @ref UART_TXDATA_FLUSH_REQUEST Transmit data flush Request * @retval None */ #define __HAL_UART_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint32_t)(__REQ__)) -/** @brief Enables the UART one bit sample method - * @param __HANDLE__: specifies the UART Handle. +/** @brief Enable the UART one bit sample method. + * @param __HANDLE__: specifies the UART Handle. * @retval None - */ + */ #define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) -/** @brief Disables the UART one bit sample method +/** @brief Disable the UART one bit sample method. + * @param __HANDLE__: specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT)) + +/** @brief Enable UART. * @param __HANDLE__: specifies the UART Handle. * @retval None */ -#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT)) - -/** @brief Enable UART - * @param __HANDLE__: specifies the UART Handle. - * The Handle Instance can be USART1, USART2 or LPUART. - * @retval None - */ #define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) -/** @brief Disable UART +/** @brief Disable UART. * @param __HANDLE__: specifies the UART Handle. - * The Handle Instance can be USART1, USART2 or LPUART. * @retval None */ #define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) -/** @brief Enable CTS flow control - * This macro allows to enable CTS hardware flow control for a given UART instance, +/** @brief Enable CTS flow control. + * @note This macro allows to enable CTS hardware flow control for a given UART instance, * without need to call HAL_UART_Init() function. * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : * - UART instance should have already been initialised (through call of HAL_UART_Init() ) - * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__)) - * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)). + * - macro could only be called when corresponding UART instance is disabled (i.e. __HAL_UART_DISABLE(__HANDLE__)) + * and should be followed by an Enable macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). * @param __HANDLE__: specifies the UART Handle. - * The Handle Instance can be USART1, USART2 or LPUART. * @retval None */ #define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \ @@ -1040,17 +949,16 @@ typedef struct (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \ } while(0) -/** @brief Disable CTS flow control - * This macro allows to disable CTS hardware flow control for a given UART instance, +/** @brief Disable CTS flow control. + * @note This macro allows to disable CTS hardware flow control for a given UART instance, * without need to call HAL_UART_Init() function. * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : * - UART instance should have already been initialised (through call of HAL_UART_Init() ) - * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__)) - * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)). + * - macro could only be called when corresponding UART instance is disabled (i.e. __HAL_UART_DISABLE(__HANDLE__)) + * and should be followed by an Enable macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). * @param __HANDLE__: specifies the UART Handle. - * The Handle Instance can be USART1, USART2 or LPUART. * @retval None */ #define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \ @@ -1059,17 +967,16 @@ typedef struct (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \ } while(0) -/** @brief Enable RTS flow control - * This macro allows to enable RTS hardware flow control for a given UART instance, +/** @brief Enable RTS flow control. + * @note This macro allows to enable RTS hardware flow control for a given UART instance, * without need to call HAL_UART_Init() function. * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : * - UART instance should have already been initialised (through call of HAL_UART_Init() ) - * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__)) - * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)). + * - macro could only be called when corresponding UART instance is disabled (i.e. __HAL_UART_DISABLE(__HANDLE__)) + * and should be followed by an Enable macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). * @param __HANDLE__: specifies the UART Handle. - * The Handle Instance can be USART1, USART2 or LPUART. * @retval None */ #define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \ @@ -1078,17 +985,16 @@ typedef struct (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \ } while(0) -/** @brief Disable RTS flow control - * This macro allows to disable RTS hardware flow control for a given UART instance, +/** @brief Disable RTS flow control. + * @note This macro allows to disable RTS hardware flow control for a given UART instance, * without need to call HAL_UART_Init() function. * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : * - UART instance should have already been initialised (through call of HAL_UART_Init() ) - * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__)) - * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)). + * - macro could only be called when corresponding UART instance is disabled (i.e. __HAL_UART_DISABLE(__HANDLE__)) + * and should be followed by an Enable macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). * @param __HANDLE__: specifies the UART Handle. - * The Handle Instance can be USART1, USART2 or LPUART. * @retval None */ #define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \ @@ -1110,26 +1016,34 @@ typedef struct #define __HAL_UART_ONE_BIT_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT)) -/** @brief BRR division operation to set BRR register with LPUART - * @param _PCLK_: LPUART clock - * @param _BAUD_: Baud rate set by the user - * @retval Division result +/** + * @} */ -#define __DIV_LPUART(_PCLK_, _BAUD_) ((uint32_t)(((((uint64_t)_PCLK_)*256.0) + (((uint64_t)_BAUD_)/2U)) / (((uint64_t)_BAUD_)))) - -/** @brief BRR division operation to set BRR register in 8-bit oversampling mode - * @param _PCLK_: UART clock - * @param _BAUD_: Baud rate set by the user - * @retval Division result - */ -#define UART_DIV_SAMPLING8(_PCLK_, _BAUD_) ((((_PCLK_)*2U) + ((_BAUD_)/2U)) / ((_BAUD_))) -/** @brief BRR division operation to set BRR register in 16-bit oversampling mode - * @param _PCLK_: UART clock - * @param _BAUD_: Baud rate set by the user +/* Private macros --------------------------------------------------------*/ +/** @defgroup UART_Private_Macros UART Private Macros + * @{ + */ +/** @brief BRR division operation to set BRR register with LPUART. + * @param __PCLK__: LPUART clock. + * @param __BAUD__: Baud rate set by the user. * @retval Division result */ -#define UART_DIV_SAMPLING16(_PCLK_, _BAUD_) ((((_PCLK_)) + ((_BAUD_)/2U)) / ((_BAUD_))) +#define UART_DIV_LPUART(__PCLK__, __BAUD__) ((((uint64_t)(__PCLK__)*256U) + ((__BAUD__)/2U)) / (__BAUD__)) + +/** @brief BRR division operation to set BRR register in 8-bit oversampling mode. + * @param __PCLK__: UART clock. + * @param __BAUD__: Baud rate set by the user. + * @retval Division result + */ +#define UART_DIV_SAMPLING8(__PCLK__, __BAUD__) ((((__PCLK__)*2U) + ((__BAUD__)/2U)) / (__BAUD__)) + +/** @brief BRR division operation to set BRR register in 16-bit oversampling mode. + * @param __PCLK__: UART clock. + * @param __BAUD__: Baud rate set by the user. + * @retval Division result + */ +#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__) (((__PCLK__) + ((__BAUD__)/2U)) / (__BAUD__)) /** @brief Check whether or not UART instance is Low Power UART. * @param __HANDLE__: specifies the UART Handle. @@ -1137,56 +1051,312 @@ typedef struct */ #define UART_INSTANCE_LOWPOWER(__HANDLE__) (((__HANDLE__)->Instance == LPUART1) ? SET : RESET ) -/** @brief Check UART Baud rate - * @param BAUDRATE: Baudrate specified by the user - * The maximum Baud Rate is derived from the maximum clock on L0 (i.e. 32 MHz) - * divided by the smallest oversampling used on the USART (i.e. 8) - * @retval Test result (TRUE or FALSE). +/** @brief Check UART Baud rate. + * @param __BAUDRATE__: Baudrate specified by the user. + * The maximum Baud Rate is derived from the maximum clock on L0 (i.e. 32 MHz) + * divided by the smallest oversampling used on the USART (i.e. 8) + * @retval SET (__BAUDRATE__ is valid) or RESET (__BAUDRATE__ is invalid) */ -#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 4000001) +#define IS_UART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 4000001) /** @brief Check UART byte address * @param ADDRESS: UART 8-bit address for wake-up process scheme - * @retval Test result (TRUE or FALSE). - */ + * @retval Test result (TRUE or FALSE). + */ #define IS_UART_7B_ADDRESS(ADDRESS) ((ADDRESS) <= 0x7F) /** @brief Check UART 4-bit address * @param ADDRESS: UART 4-bit address for wake-up process scheme - * @retval Test result (TRUE or FALSE). - */ + * @retval Test result (TRUE or FALSE). + */ #define IS_UART_4B_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) -/** @brief Check UART assertion time - * @param TIME: 5-bit value assertion time - * @retval Test result (TRUE or FALSE). - */ -#define IS_UART_ASSERTIONTIME(TIME) ((TIME) <= 0x1F) - -/** @brief Check UART deassertion time - * @param TIME: 5-bit value deassertion time - * @retval Test result (TRUE or FALSE). +/** @brief Check UART assertion time. + * @param __TIME__: 5-bit value assertion time. + * @retval Test result (TRUE or FALSE). */ -#define IS_UART_DEASSERTIONTIME(TIME) ((TIME) <= 0x1F) +#define IS_UART_ASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1F) + +/** @brief Check UART deassertion time. + * @param __TIME__: 5-bit value deassertion time. + * @retval Test result (TRUE or FALSE). + */ +#define IS_UART_DEASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1F) + +/** + * @brief Ensure that UART frame number of stop bits is valid. + * @param __STOPBITS__: UART frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_UART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_1) || \ + ((__STOPBITS__) == UART_STOPBITS_1_5) || \ + ((__STOPBITS__) == UART_STOPBITS_2)) + +/** + * @brief Ensure that LPUART frame number of stop bits is valid. + * @param __STOPBITS__: LPUART frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_LPUART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_1) || \ + ((__STOPBITS__) == UART_STOPBITS_2)) + +/** + * @brief Ensure that UART frame parity is valid. + * @param __PARITY__: UART frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_UART_PARITY(__PARITY__) (((__PARITY__) == UART_PARITY_NONE) || \ + ((__PARITY__) == UART_PARITY_EVEN) || \ + ((__PARITY__) == UART_PARITY_ODD)) + +/** + * @brief Ensure that UART hardware flow control is valid. + * @param __CONTROL__: UART hardware flow control. + * @retval SET (__CONTROL__ is valid) or RESET (__CONTROL__ is invalid) + */ +#define IS_UART_HARDWARE_FLOW_CONTROL(__CONTROL__)\ + (((__CONTROL__) == UART_HWCONTROL_NONE) || \ + ((__CONTROL__) == UART_HWCONTROL_RTS) || \ + ((__CONTROL__) == UART_HWCONTROL_CTS) || \ + ((__CONTROL__) == UART_HWCONTROL_RTS_CTS)) + +/** + * @brief Ensure that UART communication mode is valid. + * @param __MODE__: UART communication mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_UART_MODE(__MODE__) ((((__MODE__) & (~((uint32_t)(UART_MODE_TX_RX)))) == (uint32_t)0x00U) && ((__MODE__) != (uint32_t)0x00U)) + +/** + * @brief Ensure that UART state is valid. + * @param __STATE__: UART state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_UART_STATE(__STATE__) (((__STATE__) == UART_STATE_DISABLE) || \ + ((__STATE__) == UART_STATE_ENABLE)) + +/** + * @brief Ensure that UART oversampling is valid. + * @param __SAMPLING__: UART oversampling. + * @retval SET (__SAMPLING__ is valid) or RESET (__SAMPLING__ is invalid) + */ +#define IS_UART_OVERSAMPLING(__SAMPLING__) (((__SAMPLING__) == UART_OVERSAMPLING_16) || \ + ((__SAMPLING__) == UART_OVERSAMPLING_8)) + +/** + * @brief Ensure that UART frame sampling is valid. + * @param __ONEBIT__: UART frame sampling. + * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid) + */ +#define IS_UART_ONE_BIT_SAMPLE(__ONEBIT__) (((__ONEBIT__) == UART_ONE_BIT_SAMPLE_DISABLE) || \ + ((__ONEBIT__) == UART_ONE_BIT_SAMPLE_ENABLE)) + +/** + * @brief Ensure that UART auto Baud rate detection mode is valid. + * @param __MODE__: UART auto Baud rate detection mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(__MODE__) (((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT) || \ + ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE) || \ + ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME) || \ + ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME)) + +/** + * @brief Ensure that UART receiver timeout setting is valid. + * @param __TIMEOUT__: UART receiver timeout setting. + * @retval SET (__TIMEOUT__ is valid) or RESET (__TIMEOUT__ is invalid) + */ +#define IS_UART_RECEIVER_TIMEOUT(__TIMEOUT__) (((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_DISABLE) || \ + ((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_ENABLE)) + +/** + * @brief Ensure that UART LIN state is valid. + * @param __LIN__: UART LIN state. + * @retval SET (__LIN__ is valid) or RESET (__LIN__ is invalid) + */ +#define IS_UART_LIN(__LIN__) (((__LIN__) == UART_LIN_DISABLE) || \ + ((__LIN__) == UART_LIN_ENABLE)) + +/** + * @brief Ensure that UART LIN break detection length is valid. + * @param __LENGTH__: UART LIN break detection length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_UART_LIN_BREAK_DETECT_LENGTH(__LENGTH__) (((__LENGTH__) == UART_LINBREAKDETECTLENGTH_10B) || \ + ((__LENGTH__) == UART_LINBREAKDETECTLENGTH_11B)) + +/** + * @brief Ensure that UART DMA TX state is valid. + * @param __DMATX__: UART DMA TX state. + * @retval SET (__DMATX__ is valid) or RESET (__DMATX__ is invalid) + */ +#define IS_UART_DMA_TX(__DMATX__) (((__DMATX__) == UART_DMA_TX_DISABLE) || \ + ((__DMATX__) == UART_DMA_TX_ENABLE)) + +/** + * @brief Ensure that UART DMA RX state is valid. + * @param __DMARX__: UART DMA RX state. + * @retval SET (__DMARX__ is valid) or RESET (__DMARX__ is invalid) + */ +#define IS_UART_DMA_RX(__DMARX__) (((__DMARX__) == UART_DMA_RX_DISABLE) || \ + ((__DMARX__) == UART_DMA_RX_ENABLE)) + +/** + * @brief Ensure that UART half-duplex state is valid. + * @param __HDSEL__: UART half-duplex state. + * @retval SET (__HDSEL__ is valid) or RESET (__HDSEL__ is invalid) + */ +#define IS_UART_HALF_DUPLEX(__HDSEL__) (((__HDSEL__) == UART_HALF_DUPLEX_DISABLE) || \ + ((__HDSEL__) == UART_HALF_DUPLEX_ENABLE)) + +/** + * @brief Ensure that UART wake-up method is valid. + * @param __WAKEUP__: UART wake-up method . + * @retval SET (__WAKEUP__ is valid) or RESET (__WAKEUP__ is invalid) + */ +#define IS_UART_WAKEUPMETHOD(__WAKEUP__) (((__WAKEUP__) == UART_WAKEUPMETHOD_IDLELINE) || \ + ((__WAKEUP__) == UART_WAKEUPMETHOD_ADDRESSMARK)) + +/** + * @brief Ensure that UART request parameter is valid. + * @param __PARAM__: UART request parameter. + * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) + */ +#define IS_UART_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == UART_AUTOBAUD_REQUEST) || \ + ((__PARAM__) == UART_SENDBREAK_REQUEST) || \ + ((__PARAM__) == UART_MUTE_MODE_REQUEST) || \ + ((__PARAM__) == UART_RXDATA_FLUSH_REQUEST) || \ + ((__PARAM__) == UART_TXDATA_FLUSH_REQUEST)) + +/** + * @brief Ensure that UART advanced features initialization is valid. + * @param __INIT__: UART advanced features initialization. + * @retval SET (__INIT__ is valid) or RESET (__INIT__ is invalid) + */ +#define IS_UART_ADVFEATURE_INIT(__INIT__) ((__INIT__) <= (UART_ADVFEATURE_NO_INIT | \ + UART_ADVFEATURE_TXINVERT_INIT | \ + UART_ADVFEATURE_RXINVERT_INIT | \ + UART_ADVFEATURE_DATAINVERT_INIT | \ + UART_ADVFEATURE_SWAP_INIT | \ + UART_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ + UART_ADVFEATURE_DMADISABLEONERROR_INIT | \ + UART_ADVFEATURE_AUTOBAUDRATE_INIT | \ + UART_ADVFEATURE_MSBFIRST_INIT)) + +/** + * @brief Ensure that UART frame TX inversion setting is valid. + * @param __TXINV__: UART frame TX inversion setting. + * @retval SET (__TXINV__ is valid) or RESET (__TXINV__ is invalid) + */ +#define IS_UART_ADVFEATURE_TXINV(__TXINV__) (((__TXINV__) == UART_ADVFEATURE_TXINV_DISABLE) || \ + ((__TXINV__) == UART_ADVFEATURE_TXINV_ENABLE)) + +/** + * @brief Ensure that UART frame RX inversion setting is valid. + * @param __RXINV__: UART frame RX inversion setting. + * @retval SET (__RXINV__ is valid) or RESET (__RXINV__ is invalid) + */ +#define IS_UART_ADVFEATURE_RXINV(__RXINV__) (((__RXINV__) == UART_ADVFEATURE_RXINV_DISABLE) || \ + ((__RXINV__) == UART_ADVFEATURE_RXINV_ENABLE)) + +/** + * @brief Ensure that UART frame data inversion setting is valid. + * @param __DATAINV__: UART frame data inversion setting. + * @retval SET (__DATAINV__ is valid) or RESET (__DATAINV__ is invalid) + */ +#define IS_UART_ADVFEATURE_DATAINV(__DATAINV__) (((__DATAINV__) == UART_ADVFEATURE_DATAINV_DISABLE) || \ + ((__DATAINV__) == UART_ADVFEATURE_DATAINV_ENABLE)) + +/** + * @brief Ensure that UART frame RX/TX pins swap setting is valid. + * @param __SWAP__: UART frame RX/TX pins swap setting. + * @retval SET (__SWAP__ is valid) or RESET (__SWAP__ is invalid) + */ +#define IS_UART_ADVFEATURE_SWAP(__SWAP__) (((__SWAP__) == UART_ADVFEATURE_SWAP_DISABLE) || \ + ((__SWAP__) == UART_ADVFEATURE_SWAP_ENABLE)) + +/** + * @brief Ensure that UART frame overrun setting is valid. + * @param __OVERRUN__: UART frame overrun setting. + * @retval SET (__OVERRUN__ is valid) or RESET (__OVERRUN__ is invalid) + */ +#define IS_UART_OVERRUN(__OVERRUN__) (((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_ENABLE) || \ + ((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_DISABLE)) + +/** + * @brief Ensure that UART auto Baud rate state is valid. + * @param __AUTOBAUDRATE__: UART auto Baud rate state. + * @retval SET (__AUTOBAUDRATE__ is valid) or RESET (__AUTOBAUDRATE__ is invalid) + */ +#define IS_UART_ADVFEATURE_AUTOBAUDRATE(__AUTOBAUDRATE__) (((__AUTOBAUDRATE__) == UART_ADVFEATURE_AUTOBAUDRATE_DISABLE) || \ + ((__AUTOBAUDRATE__) == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)) + +/** + * @brief Ensure that UART DMA enabling or disabling on error setting is valid. + * @param __DMA__: UART DMA enabling or disabling on error setting. + * @retval SET (__DMA__ is valid) or RESET (__DMA__ is invalid) + */ +#define IS_UART_ADVFEATURE_DMAONRXERROR(__DMA__) (((__DMA__) == UART_ADVFEATURE_DMA_ENABLEONRXERROR) || \ + ((__DMA__) == UART_ADVFEATURE_DMA_DISABLEONRXERROR)) + +/** + * @brief Ensure that UART frame MSB first setting is valid. + * @param __MSBFIRST__: UART frame MSB first setting. + * @retval SET (__MSBFIRST__ is valid) or RESET (__MSBFIRST__ is invalid) + */ +#define IS_UART_ADVFEATURE_MSBFIRST(__MSBFIRST__) (((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_DISABLE) || \ + ((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_ENABLE)) + +/** + * @brief Ensure that UART stop mode state is valid. + * @param __STOPMODE__: UART stop mode state. + * @retval SET (__STOPMODE__ is valid) or RESET (__STOPMODE__ is invalid) + */ +#define IS_UART_ADVFEATURE_STOPMODE(__STOPMODE__) (((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_DISABLE) || \ + ((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_ENABLE)) + +/** + * @brief Ensure that UART mute mode state is valid. + * @param __MUTE__: UART mute mode state. + * @retval SET (__MUTE__ is valid) or RESET (__MUTE__ is invalid) + */ +#define IS_UART_MUTE_MODE(__MUTE__) (((__MUTE__) == UART_ADVFEATURE_MUTEMODE_DISABLE) || \ + ((__MUTE__) == UART_ADVFEATURE_MUTEMODE_ENABLE)) + +/** + * @brief Ensure that UART wake-up selection is valid. + * @param __WAKE__: UART wake-up selection. + * @retval SET (__WAKE__ is valid) or RESET (__WAKE__ is invalid) + */ +#define IS_UART_WAKEUP_SELECTION(__WAKE__) (((__WAKE__) == UART_WAKEUP_ON_ADDRESS) || \ + ((__WAKE__) == UART_WAKEUP_ON_STARTBIT) || \ + ((__WAKE__) == UART_WAKEUP_ON_READDATA_NONEMPTY)) + +/** + * @brief Ensure that UART driver enable polarity is valid. + * @param __POLARITY__: UART driver enable polarity. + * @retval SET (__POLARITY__ is valid) or RESET (__POLARITY__ is invalid) + */ +#define IS_UART_DE_POLARITY(__POLARITY__) (((__POLARITY__) == UART_DE_POLARITY_HIGH) || \ + ((__POLARITY__) == UART_DE_POLARITY_LOW)) /** * @} */ -/* Include UART HAL Extension module */ + +/* Include UART HAL Extended module */ #include "stm32l0xx_hal_uart_ex.h" -/******************************************************************************/ /* Exported functions --------------------------------------------------------*/ -/******************************************************************************/ - -/* Exported functions --------------------------------------------------------*/ -/** @defgroup UART_Exported_Functions UART Exported Functions +/** @addtogroup UART_Exported_Functions UART Exported Functions * @{ */ -/* Initialization/de-initialization functions ********************************/ -/** @defgroup UART_Exported_Functions_Group1 Initialization/de-initialization methods - * @{ - */ + +/** @addtogroup UART_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength); @@ -1194,14 +1364,16 @@ HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Add HAL_StatusTypeDef HAL_UART_DeInit (UART_HandleTypeDef *huart); void HAL_UART_MspInit(UART_HandleTypeDef *huart); void HAL_UART_MspDeInit(UART_HandleTypeDef *huart); + /** * @} */ +/** @addtogroup UART_Exported_Functions_Group2 IO operation functions + * @{ + */ + /* IO operation functions *****************************************************/ -/** @defgroup UART_Exported_Functions_Group2 IO operation functions - * @{ - */ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); @@ -1211,63 +1383,82 @@ HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart); +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart); + void HAL_UART_IRQHandler(UART_HandleTypeDef *huart); void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart); +void HAL_UART_AbortCpltCallback (UART_HandleTypeDef *huart); +void HAL_UART_AbortTransmitCpltCallback (UART_HandleTypeDef *huart); +void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart); + /** * @} */ -/* Peripheral Control and State functions ************************************/ -/** @defgroup UART_Exported_Functions_Group3 Peripheral Control funtions - * @{ - */ + +/** @addtogroup UART_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ + +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart); void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart); + +/** + * @} + */ + +/** @addtogroup UART_Exported_Functions_Group4 Peripheral State and Error functions + * @{ + */ + +/* Peripheral State and Errors functions **************************************************/ HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart); -uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart); -/** - * @} - */ +uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart); + /** * @} */ -/** @addtogroup UART_Private +/** + * @} + */ + +/* Private functions -----------------------------------------------------------*/ +/** @addtogroup UART_Private_Functions UART Private Functions * @{ */ -void UART_SetConfig(UART_HandleTypeDef *huart); + +HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart); HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart); -HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout); void UART_AdvFeatureConfig(UART_HandleTypeDef *huart); + /** * @} */ - -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup UART_Private UART Private - * @{ - */ /** * @} */ -/**************************************************************/ /** * @} - */ -/** - * @} - */ - + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart_ex.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart_ex.c index a9a90da882..adbd7af411 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart_ex.c @@ -2,30 +2,24 @@ ****************************************************************************** * @file stm32l0xx_hal_uart_ex.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Extended UART HAL module driver. - * - * This file provides firmware functions to manage the following - * functionalities of the Inter Integrated Circuit (UART) peripheral: - * + Extended Control methods - * + * This file provides firmware functions to manage the following extended + * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + * @verbatim ============================================================================== ##### UART peripheral extended features ##### ============================================================================== - - [..] Comparing to other previous devices, the UART interface for STM32L0XX - devices contains the following additional features - - (+) Possibility to disable or enable Analog Noise Filter - (+) Use of a configured Digital Noise Filter - (+) Disable or enable wakeup from Stop mode - - ##### How to use this driver ##### - ============================================================================== - [..] This driver provides functions to configure Noise Filter - + + (#) Declare a UART_HandleTypeDef handle structure. + + (#) For the UART RS485 Driver Enable mode, initialize the UART registers + by calling the HAL_RS485Ex_Init() API. + + @endverbatim ****************************************************************************** * @attention @@ -54,8 +48,8 @@ * 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. * - ****************************************************************************** - */ + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32l0xx_hal.h" @@ -64,62 +58,103 @@ * @{ */ +/** @defgroup UARTEx UARTEx + * @brief UART Extended HAL module driver + * @{ + */ + #ifdef HAL_UART_MODULE_ENABLED -/** @addtogroup UARTEx - * @brief UARTEx module driver - * @{ - */ - -/** @addtogroup UARTEx_Private - * @{ - */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -#define UART_REACK_TIMEOUT ((uint32_t) 1000U) -/* Private macro -------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ -static void UART_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); -/* Private functions ---------------------------------------------------------*/ - +/** @defgroup UARTEx_Private_Functions UARTEx Private Functions + * @{ + */ +static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); /** * @} */ -/** @addtogroup UARTEx_Exported_Functions +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions * @{ */ -/** @addtogroup UARTEx_Exported_Functions_Group1 +/** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions * @brief Extended Initialization and Configuration Functions - * -@verbatim +@verbatim =============================================================================== ##### Initialization and Configuration functions ##### - =============================================================================== + =============================================================================== [..] - The HAL_RS485Ex_Init() API follows respectively the UART RS485 mode - configuration procedures (details for the procedures are available in reference manual). + This subsection provides a set of functions allowing to initialize the USARTx or the UARTy + in asynchronous mode. + (+) For the asynchronous mode the parameters below 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. + (++) Hardware flow control + (++) Receiver/transmitter modes + (++) Over Sampling Method + (++) One-Bit Sampling Method + (+) For the asynchronous mode, the following advanced features can be configured as well: + (++) TX and/or RX pin level inversion + (++) data logical level inversion + (++) RX and TX pins swap + (++) RX overrun detection disabling + (++) DMA disabling on RX error + (++) MSB first on communication line + (++) auto Baud rate detection + [..] + The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration + procedures (details for the procedures are available in reference manual). @endverbatim + + Depending on the frame length defined by the M1 and M0 bits (7-bit, + 8-bit or 9-bit), the possible UART formats are listed in the + following table. + + Table 1. UART frame format. + +-----------------------------------------------------------------------+ + | M1 bit | M0 bit | PCE bit | UART frame | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 0 | | SB | 8 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 0 | | SB | 9 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 0 | | SB | 7 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + +-----------------------------------------------------------------------+ + * @{ */ /** - * @brief Initializes the RS485 Driver enable feature according to the specified - * parameters in the UART_InitTypeDef and creates the associated handle . - * @param huart: uart handle - * @param Polarity: select the driver enable polarity + * @brief Initialize the RS485 Driver enable feature according to the specified + * parameters in the UART_InitTypeDef and creates the associated handle. + * @param huart: UART handle. + * @param Polarity: select the driver enable polarity. * This parameter can be one of the following values: - * @arg UART_DE_POLARITY_HIGH: DE signal is active high - * @arg UART_DE_POLARITY_LOW: DE signal is active low - * @param AssertionTime: Driver Enable assertion time + * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high + * @arg @ref UART_DE_POLARITY_LOW DE signal is active low + * @param AssertionTime: Driver Enable assertion time: * 5-bit value defining the time between the activation of the DE (Driver Enable) * signal and the beginning of the start bit. It is expressed in sample time - * units (1/8 or 1/16 bit time, depending on the oversampling rate) - * @param DeassertionTime: Driver Enable deassertion time + * units (1/8 or 1/16 bit time, depending on the oversampling rate) + * @param DeassertionTime: Driver Enable deassertion time: * 5-bit value defining the time between the end of the last stop bit, in a * transmitted message, and the de-activation of the DE (Driver Enable) signal. * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the @@ -129,7 +164,7 @@ static void UART_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpType HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, uint32_t DeassertionTime) { uint32_t temp = 0x0U; - + /* Check the UART handle allocation */ if(huart == NULL) { @@ -138,15 +173,18 @@ HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, /* Check the Driver Enable polarity */ assert_param(IS_UART_DE_POLARITY(Polarity)); - + /* Check the Driver Enable assertion time */ assert_param(IS_UART_ASSERTIONTIME(AssertionTime)); - + /* Check the Driver Enable deassertion time */ assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime)); - + if(huart->gState == HAL_UART_STATE_RESET) - { + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, CORTEX */ HAL_UART_MspInit(huart); } @@ -155,30 +193,33 @@ HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, /* Disable the Peripheral */ __HAL_UART_DISABLE(huart); - + /* Set the UART Communication parameters */ - UART_SetConfig(huart); - if(huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) { UART_AdvFeatureConfig(huart); } - + + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */ - huart->Instance->CR3 |= USART_CR3_DEM; - + SET_BIT(huart->Instance->CR3, USART_CR3_DEM); + /* Set the Driver Enable polarity */ MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity); - + /* Set the Driver Enable assertion and deassertion times */ temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS); temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS); MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT|USART_CR1_DEAT), temp); - + /* Enable the Peripheral */ __HAL_UART_ENABLE(huart); - - /* TEACK and/or REACK to check before moving huart->gState and huart_RxState to Ready */ + + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ return (UART_CheckIdleState(huart)); } @@ -186,50 +227,180 @@ HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, /** * @} */ - -/** @addtogroup UARTEx_Exported_Functions_Group2 - * @brief management functions + +/** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions + * @brief Extended Peripheral Control functions * -@verbatim +@verbatim =============================================================================== - ##### Peripheral Control funtions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides the following functions: + (+) HAL_UARTEx_EnableClockStopMode() API enables the UART clock (HSI or LSE only) during stop mode + (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address detection length to more than 4 bits for multiprocessor address mark wake up. - (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode + (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode + trigger: address match, Start Bit detection or RXNE bit status. + (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode (+) HAL_UARTEx_DisableStopMode() API disables the above functionality (+) HAL_UARTEx_EnableClockStopMode() API enables the UART HSI clock during stop mode (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality - (+) UART_Wakeup_AddressConfig() API configures the wake-up from stop mode parameters + (+) HAL_UARTEx_WakeupCallback() called upon UART wakeup interrupt + @endverbatim * @{ */ - + + + + /** - * @brief Enable UART Stop Mode - * The UART is able to wake up the MCU from Stop mode as long as UART clock is HSI or LSE - * @param huart: uart handle + * @brief By default in multiprocessor mode, when the wake up method is set + * to address mark, the UART handles only 4-bit long addresses detection; + * this API allows to enable longer addresses detection (6-, 7- or 8-bit + * long). + * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode, + * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode. + * @param huart: UART handle. + * @param AddressLength: this parameter can be one of the following values: + * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address + * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength) +{ + /* Check the UART handle allocation */ + if(huart == NULL) + { + return HAL_ERROR; + } + + /* Check the address length parameter */ + assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength)); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_UART_DISABLE(huart); + + /* Set the address length */ + MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength); + + /* Enable the Peripheral */ + __HAL_UART_ENABLE(huart); + + /* TEACK and/or REACK to check before moving huart->gState and/or huart->RxState to Ready */ + return (UART_CheckIdleState(huart)); +} + + +/** + * @brief Set Wakeup from Stop mode interrupt flag selection. + * @param huart: UART handle. + * @param WakeUpSelection: address match, Start Bit detection or RXNE bit status. + * This parameter can be one of the following values: + * @arg @ref UART_WAKEUP_ON_ADDRESS + * @arg @ref UART_WAKEUP_ON_STARTBIT + * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tickstart = 0; + + /* check the wake-up from stop mode UART instance */ + assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance)); + /* check the wake-up selection parameter */ + assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_UART_DISABLE(huart); + + /* Set the wake-up selection scheme */ + MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent); + + if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS) + { + UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection); + } + + /* Enable the Peripheral */ + __HAL_UART_ENABLE(huart); + + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + + /* Wait until REACK flag is set */ + if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) + { + status = HAL_TIMEOUT; + } + else + { + /* Initialize the UART State */ + huart->gState = HAL_UART_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return status; +} + + +/** + * @brief Enable UART Stop Mode. + * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE. + * @param huart: UART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart) { /* Process Locked */ __HAL_LOCK(huart); - + huart->gState = HAL_UART_STATE_BUSY; - - /* Set the USART UESM bit */ - huart->Instance->CR1 |= USART_CR1_UESM; - + + /* Set UESM bit */ + SET_BIT(huart->Instance->CR1, USART_CR1_UESM); + huart->gState = HAL_UART_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(huart); - - return HAL_OK; + + return HAL_OK; +} + +/** + * @brief Disable UART Stop Mode. + * @param huart: UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart) +{ + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Clear UESM bit */ + CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM); + + huart->gState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; } /** @@ -245,8 +416,8 @@ HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart) huart->gState = HAL_UART_STATE_BUSY; - /* Set the USART UESM bit */ - huart->Instance->CR3 |= USART_CR3_UCESM; + /* Set UCESM bit */ + SET_BIT(huart->Instance->CR3, USART_CR3_UCESM); huart->gState = HAL_UART_STATE_READY; @@ -256,29 +427,6 @@ HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart) return HAL_OK; } -/** - * @brief Disable UART Stop Mode - * @param huart: uart handle - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart) -{ - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Clear USART UESM bit */ - huart->Instance->CR1 &= ~(USART_CR1_UESM); - - huart->gState = HAL_UART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - return HAL_OK; -} - /** * @brief Disable UART Clock in Stop Mode * @param huart: uart handle @@ -291,8 +439,8 @@ HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart) huart->gState = HAL_UART_STATE_BUSY; - /* Clear USART UESM bit */ - huart->Instance->CR3 &= ~(USART_CR3_UCESM); + /* Clear UCESM bit */ + CLEAR_BIT(huart->Instance->CR3, USART_CR3_UCESM); huart->gState = HAL_UART_STATE_READY; @@ -303,130 +451,39 @@ HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart) } /** - * @brief Set Wakeup from Stop mode interrupt flag selection - * @param huart: uart handle, - * @param WakeUpSelection: address match, Start Bit detection or RXNE bit status. - * This parameter can be one of the following values: - * @arg UART_WAKEUP_ON_ADDRESS - * @arg UART_WAKEUP_ON_STARTBIT - * @arg UART_WAKEUP_ON_READDATA_NONEMPTY - * @retval HAL status - */ -HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) -{ - - /* check the wake-up from stop mode UART instance */ - assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance)); - /* Check the wake-up selection parameter */ - assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent)); - - /* Process Locked */ - __HAL_LOCK(huart); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Disable the Peripheral */ - __HAL_UART_DISABLE(huart); - - /* Set the wake-up selection scheme */ - MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent); - - if(WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS) - { - UART_Wakeup_AddressConfig(huart, WakeUpSelection); - } - - /* Enable the Peripheral */ - __HAL_UART_ENABLE(huart); - - /* Wait until REACK flag is set before moving huart->gState to Ready */ - if(UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, UART_REACK_TIMEOUT) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Process Unlocked */ - __HAL_UNLOCK(huart); - - /* Initialize the UART state*/ - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->gState= HAL_UART_STATE_READY; - - return HAL_OK; -} -/** - * @brief By default in multiprocessor mode, when the wake up method is set - * to address mark, the UART handles only 4-bit long addresses detection. - * This API allows to enable longer addresses detection (6-, 7- or 8-bit - * long): - * - 6-bit address detection in 7-bit data mode - * - 7-bit address detection in 8-bit data mode - * - 8-bit address detection in 9-bit data mode - * @param huart: UART handle - * @param AddressLength: this parameter can be one of the following values: - * @arg UART_ADDRESS_DETECT_4B: 4-bit long address - * @arg UART_ADDRESS_DETECT_7B: 6-, 7- or 8-bit long address - * @retval HAL status - */ -HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength) -{ - /* Check the UART handle allocation */ - if(huart == NULL) - { - return HAL_ERROR; - } - - /* Check the address length parameter */ - assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength)); - - huart->gState = HAL_UART_STATE_BUSY; - - /* Disable the Peripheral */ - __HAL_UART_DISABLE(huart); - - /* Set the address length */ - MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength); - - /* Enable the Peripheral */ - __HAL_UART_ENABLE(huart); - - /* TEACK and/or REACK to check before moving huart->gState and/or huart->RxState to Ready */ - return (UART_CheckIdleState(huart)); -} - -/** - * @brief UART wakeup from Stop mode callback - * @param huart: uart handle + * @brief UART wakeup from Stop mode callback. + * @param huart: UART handle. * @retval None */ - __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart) +__weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); /* NOTE : This function should not be modified, when the callback is needed, - the HAL_UART_WakeupCallback can be implemented in the user file + the HAL_UARTEx_WakeupCallback can be implemented in the user file. */ } /** * @} - */ + */ - /** +/** * @} */ -/** @addtogroup UARTEx_Private +/** @addtogroup UARTEx_Private_Functions * @{ */ + /** - * @brief Initializes the UART wake-up from stop mode parameters when triggered by address detection. - * @param huart: uart handle - * @param WakeUpSelection: UART wake up from stop mode parameters - * @retval HAL status - */ -static void UART_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) + * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection. + * @param huart: UART handle. + * @param WakeUpSelection: UART wake up from stop mode parameters. + * @retval None + */ +static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) { assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength)); if(WakeUpSelection.AddressLength == UART_ADDRESS_DETECT_4B) @@ -445,17 +502,16 @@ static void UART_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpType MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS)); } - -/** - * @} - */ - /** * @} */ #endif /* HAL_UART_MODULE_ENABLED */ +/** + * @} + */ + /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart_ex.h index 839caf54d6..2844fca9b3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_uart_ex.h @@ -2,9 +2,7 @@ ****************************************************************************** * @file stm32l0xx_hal_uart_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief Header file of UART HAL Extension module. + * @brief Header file of UART HAL Extended module. ****************************************************************************** * @attention * @@ -32,8 +30,8 @@ * 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. * - ****************************************************************************** - */ + ****************************************************************************** + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32L0xx_HAL_UART_EX_H @@ -50,22 +48,16 @@ * @{ */ -/** @defgroup UARTEx UARTEx +/** @addtogroup UARTEx * @{ */ -/******************************************************************************/ /* Exported types ------------------------------------------------------------*/ -/******************************************************************************/ - - /** @defgroup UARTEx_Exported_Types UARTEx Exported Types +/** @defgroup UARTEx_Exported_Types UARTEx Exported Types * @{ */ -/** @defgroup UARTEx_Init_Configuration Extended initialization configuration structure - * @{ - */ -/** +/** * @brief UART wake up from stop mode parameters */ typedef struct @@ -74,89 +66,93 @@ typedef struct This parameter can be a value of @ref UART_WakeUp_from_Stop_Selection. If set to UART_WAKEUP_ON_ADDRESS, the two other fields below must be filled up. */ - - uint16_t AddressLength; /*!< Specifies whether the address is 4 or 7-bit long. - This parameter can be a value of @ref UARTEx_WakeUp_Address_Length */ - uint8_t Address; /*!< UART/USART node address (7-bit long max) */ + uint16_t AddressLength; /*!< Specifies whether the address is 4 or 7-bit long. + This parameter can be a value of @ref UARTEx_WakeUp_Address_Length. */ + + uint8_t Address; /*!< UART/USART node address (7-bit long max). */ } UART_WakeUpTypeDef; -/** - * @} - */ /** * @} */ /* Exported constants --------------------------------------------------------*/ -/** @defgroup UARTEx_Extended_Exported_Constants UARTEx Exported Constants +/** @defgroup UARTEx_Exported_Constants UARTEx Exported Constants * @{ */ + +/** @defgroup UARTEx_Word_Length UART Word Length + * @{ + */ +#define UART_WORDLENGTH_7B ((uint32_t)USART_CR1_M1) /*!< 7-bit long UART frame */ +#define UART_WORDLENGTH_8B ((uint32_t)0x00000000U) /*!< 8-bit long UART frame */ +#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) /*!< 9-bit long UART frame */ +/** + * @} + */ -/** @defgroup UARTEx_Word_Length Word length definition +/** @defgroup UARTEx_WakeUp_Address_Length UART Extended WakeUp Address Length * @{ */ -#define UART_WORDLENGTH_7B ((uint32_t)USART_CR1_M1) -#define UART_WORDLENGTH_8B ((uint32_t)0x0000U) -#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) -#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_7B) || \ - ((LENGTH) == UART_WORDLENGTH_8B) || \ - ((LENGTH) == UART_WORDLENGTH_9B)) +#define UART_ADDRESS_DETECT_4B ((uint32_t)0x00000000U) /*!< 4-bit long wake-up address */ +#define UART_ADDRESS_DETECT_7B ((uint32_t)USART_CR2_ADDM7) /*!< 7-bit long wake-up address */ /** * @} */ -/** @defgroup UARTEx_AutoBaud_Rate_Mode Auto baud rate mode definition - * @{ - */ -#define UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT ((uint32_t)0x0000U) -#define UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE ((uint32_t)USART_CR2_ABRMODE_0) -#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME ((uint32_t)USART_CR2_ABRMODE_1) -#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME ((uint32_t)USART_CR2_ABRMODE) -#define IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(MODE) (((MODE) == UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT) || \ - ((MODE) == UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE) || \ - ((MODE) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME) || \ - ((MODE) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME)) /** * @} - */ - -/** @defgroup UARTEx_WakeUp_Address_Length WakeUp address length definition - * @{ */ -#define UART_ADDRESS_DETECT_4B ((uint32_t)0x00000000U) -#define UART_ADDRESS_DETECT_7B ((uint32_t)USART_CR2_ADDM7) -#define IS_UART_ADDRESSLENGTH_DETECT(ADDRESS) (((ADDRESS) == UART_ADDRESS_DETECT_4B) || \ - ((ADDRESS) == UART_ADDRESS_DETECT_7B)) -/** - * @} - */ - -/** @defgroup UARTEx_WakeUp_Methods Wakeup methods definition +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup UARTEx_Exported_Functions * @{ */ -#define UART_WAKEUPMETHOD_IDLELINE ((uint32_t)0x00000000U) -#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)USART_CR1_WAKE) -#define IS_UART_WAKEUPMETHOD(WAKEUP) (((WAKEUP) == UART_WAKEUPMETHOD_IDLELINE) || \ - ((WAKEUP) == UART_WAKEUPMETHOD_ADDRESSMARK)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/** @defgroup UARTEx_Extended_Exported_Macros UARTEx Exported Macros +/** @addtogroup UARTEx_Exported_Functions_Group1 * @{ */ - -/** @brief Reports the UART clock source. - * @param __HANDLE__: specifies the UART Handle - * @param __CLOCKSOURCE__ : output variable + +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, uint32_t DeassertionTime); + +/** + * @} + */ + +/* IO operation functions *****************************************************/ + +/** @addtogroup UARTEx_Exported_Functions_Group3 + * @{ + */ + +/* Peripheral Control functions **********************************************/ +HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); +HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength); +HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart); +void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart); + +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup UARTEx_Private_Macros UARTEx Private Macros + * @{ + */ + +/** @brief Report the UART clock source. + * @param __HANDLE__: specifies the UART Handle. + * @param __CLOCKSOURCE__: output variable. * @retval UART clocking source, written in __CLOCKSOURCE__. */ #if defined (STM32L031xx) || defined (STM32L041xx) || defined (STM32L011xx) || defined (STM32L021xx) @@ -179,6 +175,7 @@ typedef struct (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ @@ -199,12 +196,13 @@ typedef struct (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ } while(0) -#else /* (STM32L031xx) || defined (STM32L041xx) || (STM32L011xx) || defined (STM32L021xx) */ +#elif defined (STM32L051xx) || defined (STM32L052xx) || defined (STM32L053xx) || defined (STM32L061xx) || defined (STM32L062xx) || defined (STM32L063xx) #define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ do { \ @@ -225,6 +223,7 @@ typedef struct (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ @@ -245,6 +244,7 @@ typedef struct (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ @@ -265,20 +265,98 @@ typedef struct (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + } while(0) + +#else + +#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART4) \ + { \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ + } \ + else if((__HANDLE__)->Instance == USART5) \ + { \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ + } \ + else if((__HANDLE__)->Instance == LPUART1) \ + { \ + switch(__HAL_RCC_GET_LPUART1_SOURCE()) \ + { \ + case RCC_LPUART1CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_LPUART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_LPUART1CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_LPUART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ } while(0) #endif /* (STM32L031xx) || (STM32L041xx) || (STM32L011xx) || defined (STM32L021xx) */ -/** @brief Reports the UART mask to apply to retrieve the received data +/** @brief Report the UART mask to apply to retrieve the received data * according to the word length and to the parity bits activation. - * If PCE = 1, the parity bit is not included in the data extracted + * @note If PCE = 1, the parity bit is not included in the data extracted * by the reception API(). * This masking operation is not carried out in the case of - * DMA transfers. - * @param __HANDLE__: specifies the UART Handle - * @retval mask to apply to UART RDR register value. + * DMA transfers. + * @param __HANDLE__: specifies the UART Handle. + * @retval None, the mask to apply to UART RDR register is stored in (__HANDLE__)->Mask field. */ #define UART_MASK_COMPUTATION(__HANDLE__) \ do { \ @@ -317,37 +395,29 @@ typedef struct } \ } while(0) + +/** + * @brief Ensure that UART frame length is valid. + * @param __LENGTH__: UART frame length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_UART_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == UART_WORDLENGTH_7B) || \ + ((__LENGTH__) == UART_WORDLENGTH_8B) || \ + ((__LENGTH__) == UART_WORDLENGTH_9B)) + +/** + * @brief Ensure that UART wake-up address length is valid. + * @param __ADDRESS__: UART wake-up address length. + * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid) + */ +#define IS_UART_ADDRESSLENGTH_DETECT(__ADDRESS__) (((__ADDRESS__) == UART_ADDRESS_DETECT_4B) || \ + ((__ADDRESS__) == UART_ADDRESS_DETECT_7B)) + /** * @} */ -/* Exported functions --------------------------------------------------------*/ -/** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions - * @{ - */ -/* Exported functions --------------------------------------------------------*/ -/* Initialization/de-initialization functions ********************************/ -/** @defgroup UARTEx_Exported_Functions_Group1 Extended Initialization function - * @{ - */ -HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, uint32_t DeassertionTime); -/** - * @} - */ -/* IO operation functions *****************************************************/ -/* Peripheral Control functions **********************************************/ -/** @defgroup UARTEx_Exported_Functions_Group2 Peripheral Control functions - * @{ - */ -HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); -HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart); -HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart); -void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart); - -/* Peripheral State functions ************************************************/ -HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength); +/* Private functions ---------------------------------------------------------*/ /** * @} @@ -357,24 +427,6 @@ HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *hua * @} */ -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup UARTEx_Private UARTEx Private - * @{ - */ -/** - * @} - */ -/**************************************************************/ - -/** - * @} - */ - -/** - * @} - */ - #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart.c index 3fc35648d2..944c1cba00 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart.c @@ -2,52 +2,52 @@ ****************************************************************************** * @file stm32l0xx_hal_usart.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief USART HAL module driver. - * - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter * Peripheral (USART). * + Initialization and de-initialization functions * + IO operation functions * + Peripheral Control functions - * - @verbatim + * + Peripheral State and Error functions + * + @verbatim =============================================================================== ##### How to use this driver ##### =============================================================================== [..] The USART HAL driver can be used as follows: - (#) Declare a USART_HandleTypeDef handle structure. - (#) Initialize the USART low level resources by implement the HAL_USART_MspInit ()API: - (##) Enable the USARTx interface clock. - (##) USART pins configuration: - (+++) Enable the clock for the USART GPIOs. - (+++) Configure these USART pins as alternate function pull-up. - (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(), + (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart). + (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API: + (++) Enable the USARTx interface clock. + (++) USART pins configuration: + (+++) Enable the clock for the USART GPIOs. + (+++) Configure these USART pins as alternate function pull-up. + (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(), HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs): - (+++) Configure the USARTx interrupt priority. - (+++) Enable the NVIC USART IRQ handle. - (@) The specific USART interrupts (Transmission complete interrupt, + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (++) USART interrupts handling: + -@@- The specific USART interrupts (Transmission complete interrupt, RXNE interrupt and Error Interrupts) will be managed using the macros __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process. - (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA() - HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs): - (+++) Declare a DMA handle structure for the Tx/Rx stream. - (+++) Enable the DMAx interface clock. - (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. - (+++) Configure the DMA Tx/Rx Stream. - (+++) Associate the initilalized DMA handle to the USART DMA Tx/Rx handle. - (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream. + (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA() + HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx channel. + (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. - (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware - flow control and Mode(Receiver/Transmitter) in the husart Init structure. + (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware + flow control and Mode (Receiver/Transmitter) in the husart handle Init structure. (#) Initialize the USART registers by calling the HAL_USART_Init() API: - (+) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) - by calling the customed HAL_USART_MspInit(&husart) API. + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_USART_MspInit(&husart) API. + @endverbatim ****************************************************************************** @@ -77,7 +77,7 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -87,66 +87,73 @@ * @{ */ +/** @defgroup USART USART + * @brief HAL USART Synchronous module driver + * @{ + */ + #ifdef HAL_USART_MODULE_ENABLED -/** @addtogroup USART - * @brief USART Synchronous module driver - * @{ - */ - -/** @addtogroup USART_Private - * @{ - */ - /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -#define DUMMY_DATA ((uint16_t) 0xFFFFU) -#define TEACK_REACK_TIMEOUT ((uint32_t) 1000U) -#define HAL_USART_TXDMA_TIMEOUTVALUE ((uint32_t) 22000U) +/** @defgroup USART_Private_Constants USART Private Constants + * @{ + */ +#define USART_DUMMY_DATA ((uint16_t) 0xFFFFU) /*!< USART transmitted dummy data */ +#define USART_TEACK_REACK_TIMEOUT ((uint32_t) 1000U) /*!< USART TX or RX enable acknowledge time-out value */ +#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ + USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) /*!< USART CR1 fields of parameters set by USART_SetConfig API */ +#define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \ + USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */ +/** + * @} + */ - -#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | \ - USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) -#define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \ - USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)) -/* Private macro -------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ +/** @addtogroup USART_Private_Functions + * @{ + */ +static void USART_EndTransfer(USART_HandleTypeDef *husart); static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma); -static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); -static void USART_DMAError(DMA_HandleTypeDef *hdma); -static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout); -static HAL_StatusTypeDef USART_SetConfig (USART_HandleTypeDef *husart); +static void USART_DMAError(DMA_HandleTypeDef *hdma); +static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout); +static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart); static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart); static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart); static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart); static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart); static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart); - /** * @} */ +/* Exported functions --------------------------------------------------------*/ -/** @addtogroup USART_Exported_Functions +/** @defgroup USART_Exported_Functions USART Exported Functions * @{ */ -/** @addtogroup USART_Exported_Functions_Group1 - * @brief Initialization and Configuration functions +/** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions * @verbatim =============================================================================== ##### Initialization and Configuration functions ##### =============================================================================== [..] - This subsection provides a set of functions allowing to initialize the USART + 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: + (+) For the asynchronous mode only these parameters can be configured: (++) Baud Rate - (++) Word Length + (++) 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. @@ -157,33 +164,38 @@ static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart); [..] The HAL_USART_Init() function follows the USART synchronous configuration - procedure (details for the procedure are available in reference manual (RM0329)). + procedure (details for the procedure are available in reference manual). @endverbatim - 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: - - Table 1. USART frame format. - +-------------------------------------------------------------+ - | M0 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 | | - +-------------------------------------------------------------+ + Depending on the frame length defined by the M1 and M0 bits (7-bit, + 8-bit or 9-bit), the possible USART formats are listed in the + following table. + + Table 1. USART frame format. + +-----------------------------------------------------------------------+ + | M1 bit | M0 bit | PCE bit | USART frame | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 0 | | SB | 8 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 0 | | SB | 9 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 0 | | SB | 7 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + +-----------------------------------------------------------------------+ * @{ */ /** - * @brief Initializes the USART mode according to the specified - * parameters in the USART_InitTypeDef and create the associated handle. - * @param husart: USART handle + * @brief Initialize the USART mode according to the specified + * parameters in the USART_InitTypeDef and initialize the associated handle. + * @param husart USART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart) @@ -202,42 +214,42 @@ HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart) /* Allocate lock resource and initialize it */ husart->Lock = HAL_UNLOCKED; - /* Init the low level hardware : GPIO, CLOCK, CORTEX */ + /* Init the low level hardware : GPIO, CLOCK */ HAL_USART_MspInit(husart); } - + husart->State = HAL_USART_STATE_BUSY; - + /* Disable the Peripheral */ __HAL_USART_DISABLE(husart); - + /* Set the Usart Communication parameters */ if (USART_SetConfig(husart) == HAL_ERROR) { return HAL_ERROR; } - - /* In Synchronous mode, the following bits must be kept cleared: + + /* In Synchronous mode, the following bits must be kept cleared: - LINEN bit in the USART_CR2 register - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/ husart->Instance->CR2 &= ~USART_CR2_LINEN; husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); - - /* Enable the Peripharal */ + + /* Enable the Peripheral */ __HAL_USART_ENABLE(husart); - + /* TEACK and/or REACK to check before moving husart->State to Ready */ return (USART_CheckIdleState(husart)); } /** - * @brief DeInitializes the USART peripheral. - * @param husart: USART handle + * @brief DeInitialize the USART peripheral. + * @param husart USART handle. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart) { - /* Check the USART handle allocation */ + /* Check the USART handle allocation */ if(husart == NULL) { return HAL_ERROR; @@ -247,96 +259,95 @@ HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart) assert_param(IS_USART_INSTANCE(husart->Instance)); husart->State = HAL_USART_STATE_BUSY; - + husart->Instance->CR1 = 0x0U; husart->Instance->CR2 = 0x0U; husart->Instance->CR3 = 0x0U; - + /* DeInit the low level hardware */ HAL_USART_MspDeInit(husart); husart->ErrorCode = HAL_USART_ERROR_NONE; husart->State = HAL_USART_STATE_RESET; - - /* Release Lock */ + + /* Process Unlock */ __HAL_UNLOCK(husart); - + return HAL_OK; } /** - * @brief USART MSP Init. - * @param husart: USART handle + * @brief Initialize the USART MSP. + * @param husart: USART handle. * @retval None */ - __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart) +__weak void HAL_USART_MspInit(USART_HandleTypeDef *husart) { /* Prevent unused argument(s) compilation warning */ UNUSED(husart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_USART_MspInit could be implenetd in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_MspInit can be implemented in the user file + */ } /** - * @brief USART MSP DeInit. - * @param husart: USART handle + * @brief DeInitialize the USART MSP. + * @param husart: USART handle. * @retval None */ - __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart) +__weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart) { /* Prevent unused argument(s) compilation warning */ UNUSED(husart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_USART_MspDeInit could be implenetd in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_MspDeInit can be implemented in the user file + */ } /** * @} */ -/** @addtogroup USART_Exported_Functions_Group2 - * @brief USART Transmit and Receive functions +/** @defgroup USART_Exported_Functions_Group2 IO operation functions + * @brief USART Transmit and Receive functions * @verbatim =============================================================================== ##### IO operation functions ##### =============================================================================== - [..] - This subsection provides a set of functions allowing to manage the USART synchronous + [..] This subsection provides a set of functions allowing to manage the USART synchronous data transfers. - + [..] The USART supports master mode only: it cannot receive or send data related to an input clock (SCLK is always an output). (#) There are two modes of transfer: - (++) Blocking mode: The communication is performed in polling mode. - The HAL status of all data processing is returned by the same function - after finishing transfer. - (++) No-Blocking mode: The communication is performed using Interrupts + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts or DMA, These API's return the HAL status. - The end of the data processing will be indicated through the - dedicated USART IRQ when using Interrupt mode or the DMA IRQ when + The end of the data processing will be indicated through the + dedicated USART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. - The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks - will be executed respectivelly at the end of the transmit or Receive process - The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected. + The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected (#) Blocking mode API's are : (++) HAL_USART_Transmit()in simplex mode (++) HAL_USART_Receive() in full duplex receive only (++) HAL_USART_TransmitReceive() in full duplex mode - + (#) Non-Blocking mode API's with Interrupt are : (++) HAL_USART_Transmit_IT()in simplex mode (++) HAL_USART_Receive_IT() in full duplex receive only (++) HAL_USART_TransmitReceive_IT()in full duplex mode (++) HAL_USART_IRQHandler() - (#) No-Blocking mode functions with DMA are : + (#) No-Blocking mode API's with DMA are : (++) HAL_USART_Transmit_DMA()in simplex mode (++) HAL_USART_Receive_DMA() in full duplex receive only (++) HAL_USART_TransmitReceive_DMA() in full duplex mode @@ -344,7 +355,7 @@ HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart) (++) HAL_USART_DMAResume() (++) HAL_USART_DMAStop() - (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: + (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: (++) HAL_USART_TxCpltCallback() (++) HAL_USART_RxCpltCallback() (++) HAL_USART_TxHalfCpltCallback() @@ -352,63 +363,101 @@ HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart) (++) HAL_USART_ErrorCallback() (++) HAL_USART_TxRxCpltCallback() + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (+) HAL_USART_Abort() + (+) HAL_USART_Abort_IT() + + (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided: + (+) HAL_USART_AbortCpltCallback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, + and HAL_USART_ErrorCallback() user callback is executed. Transfer is kept ongoing on USART side. + If user wants to abort it, Abort services should be called by user. + (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, and HAL_USART_ErrorCallback() user callback is executed. + @endverbatim * @{ */ /** - * @brief Simplex Send an amount of data in blocking mode - * @param husart: USART handle - * @param pTxData: Pointer to data buffer - * @param Size: Amount of data to be sent - * @param Timeout : Timeout duration + * @brief Simplex send an amount of data in blocking mode. + * @param husart USART handle. + * @param pTxData Pointer to data buffer. + * @param Size Amount of data to be sent. + * @param Timeout Timeout duration. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; + uint32_t tickstart = 0; if(husart->State == HAL_USART_STATE_READY) { - if((pTxData == NULL) || (Size == 0U)) + if((pTxData == NULL) || (Size == 0U)) { return HAL_ERROR; } + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if((((uint32_t)pTxData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(husart); husart->ErrorCode = HAL_USART_ERROR_NONE; husart->State = HAL_USART_STATE_BUSY_TX; + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + husart->TxXferSize = Size; husart->TxXferCount = Size; - + /* Check the remaining data to be sent */ while(husart->TxXferCount > 0U) { husart->TxXferCount--; - if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) { tmp = (uint16_t*) pTxData; husart->Instance->TDR = (*tmp & (uint16_t)0x01FFU); pTxData += 2U; - } + } else { husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFFU); } } - if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK) - { + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } + /* At end of Tx process, restore husart->State to Ready */ husart->State = HAL_USART_STATE_READY; /* Process Unlocked */ @@ -423,71 +472,92 @@ HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxDa } /** - * @brief Receive an amount of data in blocking mode - * To receive synchronous data, dummy data are simultaneously transmitted - * @param husart: USART handle - * @param pRxData: pointer to data buffer - * @param Size: amount of data to be received - * @param Timeout : Timeout duration + * @brief Receive an amount of data in blocking mode. + * @note To receive synchronous data, dummy data are simultaneously transmitted. + * @param husart USART handle. + * @param pRxData Pointer to data buffer. + * @param Size Amount of data to be received. + * @param Timeout Timeout duration. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint16_t uhMask; - + uint32_t tickstart = 0; + if(husart->State == HAL_USART_STATE_READY) { - if((pRxData == NULL) || (Size == 0U)) + if((pRxData == NULL) || (Size == 0U)) { return HAL_ERROR; } + + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if((((uint32_t)pRxData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(husart); husart->ErrorCode = HAL_USART_ERROR_NONE; husart->State = HAL_USART_STATE_BUSY_RX; + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + husart->RxXferSize = Size; husart->RxXferCount = Size; - + /* Computation of USART mask to apply to RDR register */ USART_MASK_COMPUTATION(husart); uhMask = husart->Mask; - + /* as long as data have to be received */ while(husart->RxXferCount > 0U) { husart->RxXferCount--; - - /* Wait until TXE flag is set to send dummy byte in order to generate the + + /* Wait until TXE flag is set to send dummy byte in order to generate the * clock for the slave to send data. - * Whatever the frame length (7, 8 or 9-bit long), the same dummy value + * Whatever the frame length (7, 8 or 9-bit long), the same dummy value * can be written for all the cases. */ - if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) - { - return HAL_TIMEOUT; - } - husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x0FFU); - - /* Wait for RXNE Flag */ - if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK) - { + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } - + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FFU); + + /* Wait for RXNE Flag */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) { tmp = (uint16_t*) pRxData ; *tmp = (uint16_t)(husart->Instance->RDR & uhMask); - pRxData +=2U; - } + pRxData +=2U; + } else { - *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); + *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); } } + /* At end of Rx process, restore husart->State to Ready */ husart->State = HAL_USART_STATE_READY; /* Process Unlocked */ @@ -502,49 +572,69 @@ HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxDat } /** - * @brief Full-Duplex Send and Receive an amount of data in blocking mode - * @param husart: USART handle - * @param pTxData: pointer to TX data buffer - * @param pRxData: pointer to RX data buffer - * @param Size: amount of data to be sent (same amount to be received) - * @param Timeout : Timeout duration + * @brief Full-Duplex Send and Receive an amount of data in blocking mode. + * @param husart USART handle. + * @param pTxData pointer to TX data buffer. + * @param pRxData pointer to RX data buffer. + * @param Size amount of data to be sent (same amount to be received). + * @param Timeout Timeout duration. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint16_t uhMask; - + uint32_t tickstart = 0; + if(husart->State == HAL_USART_STATE_READY) { - if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) { return HAL_ERROR; } + + /* In case of 9bits/No Parity transfer, pTxData and pRxData buffers provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR/retrieved from RDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if(((((uint32_t)pTxData)&1) != 0) || ((((uint32_t)pRxData)&1) != 0)) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(husart); - + husart->ErrorCode = HAL_USART_ERROR_NONE; husart->State = HAL_USART_STATE_BUSY_RX; - + + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + husart->RxXferSize = Size; husart->TxXferSize = Size; husart->TxXferCount = Size; husart->RxXferCount = Size; - + /* Computation of USART mask to apply to RDR register */ USART_MASK_COMPUTATION(husart); uhMask = husart->Mask; - + /* Check the remain data to be sent */ while(husart->TxXferCount > 0U) { husart->TxXferCount--; husart->RxXferCount--; - + /* Wait until TXE flag is set to send data */ - if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) - { + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) @@ -555,32 +645,33 @@ HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t } else { - husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask); - } - + husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask); + } + /* Wait for RXNE Flag */ - if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK) - { + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { return HAL_TIMEOUT; } - + if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) { tmp = (uint16_t*) pRxData ; *tmp = (uint16_t)(husart->Instance->RDR & uhMask); - pRxData +=2U; - } + pRxData +=2U; + } else { - *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); + *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); } } - + + /* At end of TxRx process, restore husart->State to Ready */ husart->State = HAL_USART_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(husart); - + return HAL_OK; } else @@ -590,21 +681,36 @@ HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t } /** - * @brief Send an amount of data in interrupt mode - * @param husart: USART handle - * @param pTxData: Pointer to data buffer - * @param Size: Amount of data to be sent + * @brief Send an amount of data in interrupt mode. + * @param husart USART handle. + * @param pTxData pointer to data buffer. + * @param Size amount of data to be sent. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size) { if(husart->State == HAL_USART_STATE_READY) { - if((pTxData == NULL ) || (Size == 0U)) + if((pTxData == NULL ) || (Size == 0U)) { return HAL_ERROR; } + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if((((uint32_t)pTxData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(husart); @@ -615,16 +721,16 @@ HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pT husart->ErrorCode = HAL_USART_ERROR_NONE; husart->State = HAL_USART_STATE_BUSY_TX; - /* The USART Error Interrupts: (Frame error, noise error, overrun error) + /* The USART Error Interrupts: (Frame error, noise error, overrun error) are not managed by the USART Transmit Process to avoid the overrun interrupt when the usart mode is configured for transmit and receive "USART_MODE_TX_RX" - to benefit for the frame error and noise interrupts the usart mode should be + to benefit for the frame error and noise interrupts the usart mode should be configured only for transmit "USART_MODE_TX" */ - + /* Process Unlocked */ __HAL_UNLOCK(husart); - /* Enable the USART Transmit Complete Interrupt */ + /* Enable the USART Transmit Data Register Empty Interrupt */ __HAL_USART_ENABLE_IT(husart, USART_IT_TXE); return HAL_OK; @@ -636,21 +742,37 @@ HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pT } /** - * @brief Receive an amount of data in blocking mode - * To receive synchronous data, dummy data are simultaneously transmitted - * @param husart: usart handle - * @param pRxData: pointer to data buffer - * @param Size: amount of data to be received + * @brief Receive an amount of data in interrupt mode. + * @note To receive synchronous data, dummy data are simultaneously transmitted. + * @param husart USART handle. + * @param pRxData pointer to data buffer. + * @param Size amount of data to be received. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) { if(husart->State == HAL_USART_STATE_READY) { - if((pRxData == NULL ) || (Size == 0U)) + if((pRxData == NULL ) || (Size == 0U)) { return HAL_ERROR; } + + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if((((uint32_t)pRxData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(husart); @@ -659,32 +781,29 @@ HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRx husart->RxXferCount = Size; USART_MASK_COMPUTATION(husart); - + husart->ErrorCode = HAL_USART_ERROR_NONE; husart->State = HAL_USART_STATE_BUSY_RX; - - /* Enable the USART Parity Error Interrupt */ - __HAL_USART_ENABLE_IT(husart, USART_IT_PE); - /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_USART_ENABLE_IT(husart, USART_IT_ERR); - - /* Enable the USART Data Register not empty Interrupt */ - __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE); - /* Process Unlocked */ __HAL_UNLOCK(husart); + /* Enable the USART Parity Error and Data Register not empty Interrupts */ + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + /* Send dummy byte in order to generate the clock for the Slave to send the next data */ if(husart->Init.WordLength == USART_WORDLENGTH_9B) { - husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x01FFU); - } + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x01FFU); + } else { - husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FFU); + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FFU); } - + return HAL_OK; } else @@ -694,21 +813,38 @@ HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRx } /** - * @brief Full-Duplex Send and Receive an amount of data in interrupt mode - * @param husart: USART handle - * @param pTxData: pointer to TX data buffer - * @param pRxData: pointer to RX data buffer - * @param Size: amount of data to be sent (same amount to be received) + * @brief Full-Duplex Send and Receive an amount of data in interrupt mode. + * @param husart USART handle. + * @param pTxData pointer to TX data buffer. + * @param pRxData pointer to RX data buffer. + * @param Size amount of data to be sent (same amount to be received). + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) { + if(husart->State == HAL_USART_STATE_READY) { - if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) { return HAL_ERROR; } + + /* In case of 9bits/No Parity transfer, pTxData and pRxData buffers provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR/retrieved from RDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if(((((uint32_t)pTxData)&1) != 0) || ((((uint32_t)pRxData)&1) != 0)) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(husart); @@ -718,55 +854,68 @@ HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint husart->pTxBuffPtr = pTxData; husart->TxXferSize = Size; husart->TxXferCount = Size; - + /* Computation of USART mask to apply to RDR register */ USART_MASK_COMPUTATION(husart); husart->ErrorCode = HAL_USART_ERROR_NONE; husart->State = HAL_USART_STATE_BUSY_TX_RX; - /* Enable the USART Data Register not empty Interrupt */ - __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE); - - /* Enable the USART Parity Error Interrupt */ - __HAL_USART_ENABLE_IT(husart, USART_IT_PE); - - /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_USART_ENABLE_IT(husart, USART_IT_ERR); - /* Process Unlocked */ __HAL_UNLOCK(husart); - /* Enable the USART Transmit Complete Interrupt */ - __HAL_USART_ENABLE_IT(husart, USART_IT_TXE); + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Enable the USART Parity Error and USART Data Register not empty Interrupts */ + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); + + /* Enable the USART Transmit Data Register Empty Interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE); return HAL_OK; } else { - return HAL_BUSY; + return HAL_BUSY; } } /** - * @brief Send an amount of data in DMA mode - * @param husart: USART handle - * @param pTxData: pointer to data buffer - * @param Size: amount of data to be sent + * @brief Send an amount of data in DMA mode. + * @param husart USART handle. + * @param pTxData pointer to data buffer. + * @param Size amount of data to be sent. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size) { uint32_t *tmp; - + if(husart->State == HAL_USART_STATE_READY) { - if((pTxData == NULL ) || (Size == 0U)) + if((pTxData == NULL ) || (Size == 0U)) { return HAL_ERROR; } + + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if((((uint32_t)pTxData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ - __HAL_LOCK(husart); + __HAL_LOCK(husart); husart->pTxBuffPtr = pTxData; husart->TxXferSize = Size; @@ -788,16 +937,16 @@ HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *p tmp = (uint32_t*)&pTxData; HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); - /* Clear the TC flag in the SR register by writing 0 to it */ - __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC); - - /* Enable the DMA transfer for transmit request by setting the DMAT bit - in the USART CR3 register */ - husart->Instance->CR3 |= USART_CR3_DMAT; + /* Clear the TC flag in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF); /* Process Unlocked */ __HAL_UNLOCK(husart); + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); + return HAL_OK; } else @@ -807,26 +956,42 @@ HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *p } /** - * @brief Receive an amount of data in DMA mode - * @param husart: USART handle - * @param pRxData: pointer to data buffer - * @param Size: amount of data to be received - * @note When the USART parity is enabled (PCE = 1), the received data contain - * the parity bit (MSB position) + * @brief Receive an amount of data in DMA mode. + * @param husart USART handle. + * @param pRxData pointer to data buffer. + * @param Size amount of data to be received. + * @note When the USART parity is enabled (PCE = 1), the received data contain + * the parity bit (MSB position). + * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status - * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave. */ HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) { uint32_t *tmp; - + + /* Check that a Rx process is not already ongoing */ if(husart->State == HAL_USART_STATE_READY) { - if((pRxData == NULL ) || (Size == 0U)) + if((pRxData == NULL ) || (Size == 0U)) { return HAL_ERROR; } + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if((((uint32_t)pRxData)&1) != 0) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(husart); @@ -847,31 +1012,37 @@ HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pR /* Set the USART DMA Rx transfer error callback */ husart->hdmarx->XferErrorCallback = USART_DMAError; - /* Enable the USART receive DMA Stream */ + /* Enable the USART receive DMA channel */ tmp = (uint32_t*)&pRxData; HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size); /* Enable the USART transmit DMA channel: the transmit channel is used in order - to generate in the non-blocking mode the clock to the slave device, + to generate in the non-blocking mode the clock to the slave device, this mode isn't a simplex receive mode but a full-duplex receive mode */ tmp = (uint32_t*)&pRxData; + /* Set the USART DMA Tx Complete and Error callback to Null */ + husart->hdmatx->XferErrorCallback = NULL; + husart->hdmatx->XferHalfCpltCallback = NULL; + husart->hdmatx->XferCpltCallback = NULL; HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); - - /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer - when using the USART in circular mode */ - __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF); - - /* Enable the DMA transfer for the receiver request by setting the DMAR bit - in the USART CR3 register */ - husart->Instance->CR3 |= USART_CR3_DMAR; - - /* Enable the DMA transfer for transmit request by setting the DMAT bit - in the USART CR3 register */ - husart->Instance->CR3 |= USART_CR3_DMAT; /* Process Unlocked */ __HAL_UNLOCK(husart); + /* Enable the USART Parity Error Interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); + return HAL_OK; } else @@ -881,24 +1052,40 @@ HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pR } /** - * @brief Full-Duplex Transmit Receive an amount of data in non blocking mode - * @param husart: usart handle - * @param pTxData: pointer to TX data buffer - * @param pRxData: pointer to RX data buffer - * @param Size: amount of data to be received/sent + * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode. + * @param husart USART handle. + * @param pTxData pointer to TX data buffer. + * @param pRxData pointer to RX data buffer. + * @param Size amount of data to be received/sent. * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits) + * (as sent data will be handled using u16 pointer cast). Depending on compilation chain, + * use of specific alignment compilation directives or pragmas might be required to ensure proper alignment for pTxData. * @retval HAL status */ HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) { uint32_t *tmp; - + if(husart->State == HAL_USART_STATE_READY) { - if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) { return HAL_ERROR; } + + /* In case of 9bits/No Parity transfer, pTxData and pRxData buffers provided as input paramter + should be aligned on a u16 frontier, as data to be filled into TDR/retrieved from RDR will be + handled through a u16 cast. */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + if(((((uint32_t)pTxData)&1) != 0) || ((((uint32_t)pRxData)&1) != 0)) + { + return HAL_ERROR; + } + } + /* Process Locked */ __HAL_LOCK(husart); @@ -928,31 +1115,37 @@ HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uin /* Set the USART DMA Rx transfer error callback */ husart->hdmarx->XferErrorCallback = USART_DMAError; - /* Enable the USART receive DMA Stream */ + /* Enable the USART receive DMA channel */ tmp = (uint32_t*)&pRxData; HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size); - /* Enable the USART transmit DMA Stream */ + /* Enable the USART transmit DMA channel */ tmp = (uint32_t*)&pTxData; HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); - - /* Clear the Overrun flag: mandatory for the second transfer in circular mode */ - __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF); - - /* Clear the TC flag in the SR register by writing 0 to it */ - __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC); - - /* Enable the DMA transfer for the receiver request by setting the DMAR bit - in the USART CR3 register */ - husart->Instance->CR3 |= USART_CR3_DMAR; - - /* Enable the DMA transfer for transmit request by setting the DMAT bit - in the USART CR3 register */ - husart->Instance->CR3 |= USART_CR3_DMAT; /* Process Unlocked */ __HAL_UNLOCK(husart); + /* Enable the USART Parity Error Interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Clear the Overrun flag: mandatory for the second transfer in circular mode */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF); + + /* Clear the TC flag in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); + return HAL_OK; } else @@ -962,36 +1155,39 @@ HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uin } /** - * @brief Pauses the DMA Transfer. - * @param husart: USART handle - * @retval None + * @brief Pause the DMA Transfer. + * @param husart USART handle. + * @retval HAL status */ HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart) { /* Process Locked */ __HAL_LOCK(husart); - /* Disable the USART DMA Tx request */ - husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); + if( (husart->State == HAL_USART_STATE_BUSY_TX) && + (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))) + { + /* Disable the USART DMA Tx request */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + } + else if( (husart->State == HAL_USART_STATE_BUSY_RX) || + (husart->State == HAL_USART_STATE_BUSY_TX_RX) ) + { + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable the USART DMA Tx request */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + } + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); - /* Process Unlocked */ - __HAL_UNLOCK(husart); - - return HAL_OK; -} - -/** - * @brief Resumes the DMA Transfer. - * @param husart: USART handle - * @retval None - */ -HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart) -{ - /* Process Locked */ - __HAL_LOCK(husart); - - /* Enable the USART DMA Tx request */ - husart->Instance->CR3 |= USART_CR3_DMAT; + /* Disable the USART DMA Rx request */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + } + } /* Process Unlocked */ __HAL_UNLOCK(husart); @@ -1000,104 +1196,422 @@ HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart) } /** - * @brief Stops the DMA Transfer. - * @param husart: USART handle - * @retval None + * @brief Resume the DMA Transfer. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart) +{ + /* Process Locked */ + __HAL_LOCK(husart); + + if(husart->State == HAL_USART_STATE_BUSY_TX) + { + /* Enable the USART DMA Tx request */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); + } + else if( (husart->State == HAL_USART_STATE_BUSY_RX) || + (husart->State == HAL_USART_STATE_BUSY_TX_RX) ) + { + /* Clear the Overrun flag before resuming the Rx transfer*/ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF); + + /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */ + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Enable the USART DMA Rx request before the DMA Tx request */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Enable the USART DMA Tx request */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); + } + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Stop the DMA Transfer. + * @param husart USART handle. + * @retval HAL status */ HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart) { - /* The Lock is not implemented on this API to allow the user application - to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback(): - when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated - and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() - */ + /* The Lock is not implemented on this API to allow the user application + to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() / + HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback: + indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete + interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of + the stream and the corresponding call back is executed. */ - /* Abort the USART DMA tx Stream */ + /* Disable the USART Tx/Rx DMA requests */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the USART DMA tx channel */ if(husart->hdmatx != NULL) { HAL_DMA_Abort(husart->hdmatx); } - /* Abort the USART DMA rx Stream */ + /* Abort the USART DMA rx channel */ if(husart->hdmarx != NULL) { HAL_DMA_Abort(husart->hdmarx); } - - /* Disable the USART Tx/Rx DMA requests */ - husart->Instance->CR3 &= ~USART_CR3_DMAT; - husart->Instance->CR3 &= ~USART_CR3_DMAR; + USART_EndTransfer(husart); husart->State = HAL_USART_STATE_READY; return HAL_OK; } /** - * @brief This function handles USART interrupt request. - * @param husart: USART handle + * @brief Abort ongoing transfers (blocking mode). + * @param husart USART handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable USART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart) +{ + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Disable the USART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */ + if(husart->hdmatx != NULL) + { + /* Set the USART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + husart->hdmatx->XferAbortCallback = NULL; + + HAL_DMA_Abort(husart->hdmatx); + } + } + + /* Disable the USART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */ + if(husart->hdmarx != NULL) + { + /* Set the USART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + husart->hdmarx->XferAbortCallback = NULL; + + HAL_DMA_Abort(husart->hdmarx); + } + } + + /* Reset Tx and Rx transfer counters */ + husart->TxXferCount = 0; + husart->RxXferCount = 0; + + /* Clear the Error flags in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF); + + /* Restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Reset Handle ErrorCode to No Error */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param husart USART handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable USART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart) +{ + uint32_t abortcplt = 1; + + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised + before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if(husart->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if USART DMA Tx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback; + } + else + { + husart->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if(husart->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if USART DMA Rx request if enabled. + Otherwise, set it to NULL */ + if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback; + } + else + { + husart->hdmarx->XferAbortCallback = NULL; + } + } + + /* Disable the USART DMA Tx request if enabled */ + if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable DMA Tx at USART level */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */ + if(husart->hdmatx != NULL) + { + /* USART Tx DMA Abort callback has already been initialised : + will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if(HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK) + { + husart->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0; + } + } + } + + /* Disable the USART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */ + if(husart->hdmarx != NULL) + { + /* USART Rx DMA Abort callback has already been initialised : + will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK) + { + husart->hdmarx->XferAbortCallback = NULL; + abortcplt = 1; + } + else + { + abortcplt = 0; + } + } + } + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1) + { + /* Reset Tx and Rx transfer counters */ + husart->TxXferCount = 0; + husart->RxXferCount = 0; + + /* Reset errorCode */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF); + + /* Restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ + HAL_USART_AbortCpltCallback(husart); + } + + return HAL_OK; +} + +/** + * @brief Handle USART interrupt request. + * @param husart USART handle. * @retval None */ void HAL_USART_IRQHandler(USART_HandleTypeDef *husart) { - - /* USART parity error interrupt occured ------------------------------------*/ - if((__HAL_USART_GET_IT(husart, USART_IT_PE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE) != RESET)) - { - __HAL_USART_CLEAR_PEFLAG(husart); - husart->ErrorCode |= HAL_USART_ERROR_PE; - /* Set the USART state ready to be able to start again the process */ - husart->State = HAL_USART_STATE_READY; - } - - /* USART frame error interrupt occured -------------------------------------*/ - if((__HAL_USART_GET_IT(husart, USART_IT_FE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET)) - { - __HAL_USART_CLEAR_FEFLAG(husart); - husart->ErrorCode |= HAL_USART_ERROR_FE; - /* Set the USART state ready to be able to start again the process */ - husart->State = HAL_USART_STATE_READY; - } - - /* USART noise error interrupt occured -------------------------------------*/ - if((__HAL_USART_GET_IT(husart, USART_IT_NE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET)) - { - __HAL_USART_CLEAR_NEFLAG(husart); - husart->ErrorCode |= HAL_USART_ERROR_NE; - /* Set the USART state ready to be able to start again the process */ - husart->State = HAL_USART_STATE_READY; - } - - /* USART Over-Run interrupt occured ----------------------------------------*/ - if((__HAL_USART_GET_IT(husart, USART_IT_ORE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET)) - { - __HAL_USART_CLEAR_OREFLAG(husart); - husart->ErrorCode |= HAL_USART_ERROR_ORE; - /* Set the USART state ready to be able to start again the process */ - husart->State = HAL_USART_STATE_READY; - } - - /* Call USART Error Call back function if need be --------------------------*/ - if(husart->ErrorCode != HAL_USART_ERROR_NONE) + uint32_t isrflags = READ_REG(husart->Instance->ISR); + uint32_t cr1its = READ_REG(husart->Instance->CR1); + uint32_t cr3its; + uint32_t errorflags; + + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); + if (errorflags == RESET) { - HAL_USART_ErrorCallback(husart); - } - - /* USART in mode Receiver --------------------------------------------------*/ - if((__HAL_USART_GET_IT(husart, USART_IT_RXNE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE) != RESET)) - { - if(husart->State == HAL_USART_STATE_BUSY_RX) + /* USART in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) { - USART_Receive_IT(husart); - } - else - { - USART_TransmitReceive_IT(husart); + if(husart->State == HAL_USART_STATE_BUSY_RX) + { + USART_Receive_IT(husart); + } + else + { + USART_TransmitReceive_IT(husart); + } + return; } } - - /* USART in mode Transmitter -----------------------------------------------*/ - if((__HAL_USART_GET_IT(husart, USART_IT_TXE) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE) != RESET)) - { + + /* If some errors occur */ + cr3its = READ_REG(husart->Instance->CR3); + if( (errorflags != RESET) + && ( ((cr3its & USART_CR3_EIE) != RESET) + || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)) ) + { + /* USART parity error interrupt occurred -------------------------------------*/ + if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF); + + husart->ErrorCode |= HAL_USART_ERROR_PE; + } + + /* USART frame error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF); + + husart->ErrorCode |= HAL_USART_ERROR_FE; + } + + /* USART noise error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF); + + husart->ErrorCode |= HAL_USART_ERROR_NE; + } + + /* USART Over-Run interrupt occurred -----------------------------------------*/ + if(((isrflags & USART_ISR_ORE) != RESET) && + (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF); + + husart->ErrorCode |= HAL_USART_ERROR_ORE; + } + + /* Call USART Error Call back function if need be --------------------------*/ + if(husart->ErrorCode != HAL_USART_ERROR_NONE) + { + /* USART in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + if(husart->State == HAL_USART_STATE_BUSY_RX) + { + USART_Receive_IT(husart); + } + else + { + USART_TransmitReceive_IT(husart); + } + } + + /* If Overrun error occurs, or if any error occurs in DMA mode reception, + consider error as blocking */ + if (((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET) || + (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))) + { + /* Blocking error : transfer is aborted + Set the USART state ready to be able to start again the process, + Disable Interrupts, and disable DMA requests, if ongoing */ + USART_EndTransfer(husart); + + /* Disable the USART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR); + + /* Abort the USART DMA Tx channel */ + if(husart->hdmatx != NULL) + { + /* Set the USART Tx DMA Abort callback to NULL : no callback + executed at end of DMA abort procedure */ + husart->hdmatx->XferAbortCallback = NULL; + + /* Abort DMA TX */ + HAL_DMA_Abort_IT(husart->hdmatx); + } + + /* Abort the USART DMA Rx channel */ + if(husart->hdmarx != NULL) + { + /* Set the USART Rx DMA Abort callback : + will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */ + husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK) + { + /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */ + husart->hdmarx->XferAbortCallback(husart->hdmarx); + } + } + else + { + /* Call user error callback */ + HAL_USART_ErrorCallback(husart); + } + } + else + { + /* Call user error callback */ + HAL_USART_ErrorCallback(husart); + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ + HAL_USART_ErrorCallback(husart); + husart->ErrorCode = HAL_USART_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ + + + /* USART in mode Transmitter ------------------------------------------------*/ + if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) + { if(husart->State == HAL_USART_STATE_BUSY_TX) { USART_Transmit_IT(husart); @@ -1106,48 +1620,51 @@ void HAL_USART_IRQHandler(USART_HandleTypeDef *husart) { USART_TransmitReceive_IT(husart); } + return; } - - /* USART in mode Transmitter (transmission end) -----------------------------*/ - if((__HAL_USART_GET_IT(husart, USART_IT_TC) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC) != RESET)) + + /* USART in mode Transmitter (transmission end) -----------------------------*/ + if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { USART_EndTransmit_IT(husart); - } + return; + } + } /** - * @brief Tx Transfer completed callbacks. - * @param husart: USART handle + * @brief Tx Transfer completed callback. + * @param husart: USART handle. * @retval None */ - __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart) +__weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart) { /* Prevent unused argument(s) compilation warning */ UNUSED(husart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_USART_TxCpltCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_TxCpltCallback can be implemented in the user file. */ } /** - * @brief Tx Half Transfer completed callbacks. - * @param husart: USART handle + * @brief Tx Half Transfer completed callback. + * @param husart: USART handle. * @retval None */ - __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart) +__weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart) { /* Prevent unused argument(s) compilation warning */ UNUSED(husart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_USART_TxCpltCallback could be implemented in the user file + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_USART_TxHalfCpltCallback can be implemented in the user file. */ } /** - * @brief Rx Transfer completed callbacks. - * @param husart: USART handle + * @brief Rx Transfer completed callback. + * @param husart: USART handle. * @retval None */ __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart) @@ -1155,14 +1672,14 @@ __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart) /* Prevent unused argument(s) compilation warning */ UNUSED(husart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_USART_TxCpltCallback could be implemented in the user file + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_USART_RxCpltCallback can be implemented in the user file. */ } /** - * @brief Rx Half Transfer completed callbacks. - * @param husart: USART handle + * @brief Rx Half Transfer completed callback. + * @param husart: USART handle. * @retval None */ __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart) @@ -1170,14 +1687,14 @@ __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart) /* Prevent unused argument(s) compilation warning */ UNUSED(husart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_USART_TxCpltCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_RxHalfCpltCallback can be implemented in the user file */ } /** - * @brief Tx/Rx Transfers completed callback for the non-blocking process. - * @param husart: USART handle + * @brief Tx/Rx Transfers completed callback for the non-blocking process. + * @param husart: USART handle. * @retval None */ __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart) @@ -1185,52 +1702,67 @@ __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart) /* Prevent unused argument(s) compilation warning */ UNUSED(husart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_USART_TxCpltCallback could be implemented in the user file + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_TxRxCpltCallback can be implemented in the user file */ } /** - * @brief USART error callbacks. - * @param husart: USART handle + * @brief USART error callback. + * @param husart: USART handle. * @retval None */ - __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart) +__weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart) { /* Prevent unused argument(s) compilation warning */ UNUSED(husart); - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_USART_ErrorCallback could be implemented in the user file - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_ErrorCallback can be implemented in the user file. + */ } - + +/** + * @brief USART Abort Complete callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_AbortCpltCallback (USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_AbortCpltCallback can be implemented in the user file. + */ +} + /** * @} */ -/** @addtogroup USART_Exported_Functions_Group3 - * @brief USART State functions - * -@verbatim - =============================================================================== - ##### Peripheral State functions ##### - =============================================================================== +/** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions + * @brief USART Peripheral State and Error functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== [..] - This subsection provides a set of functions allowing to control the USART. - (+) HAL_USART_GetState() API can be helpful to check in run-time the state of the USART peripheral. - (+) HAL_USART_GetError() API can be helpful to check in run-time the Error Code of the USART peripheral. - (+) USART_SetConfig() API is used to set the USART communication parameters. - (+) USART_CheckIdleState() APi ensures that TEACK and/or REACK bits are set after initialization - + This subsection provides functions allowing to : + (+) Return the USART handle state + (+) Return the USART handle error code + @endverbatim * @{ */ + /** - * @brief Returns the USART state. - * @param husart: USART handle - * @retval HAL state + * @brief Return the USART handle state. + * @param husart : pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART. + * @retval USART handle state */ HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart) { @@ -1238,10 +1770,10 @@ HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart) } /** - * @brief Return the USART error code - * @param husart : pointer to a USART_HandleTypeDef structure that contains + * @brief Return the USART error code. + * @param husart : pointer to a USART_HandleTypeDef structure that contains * the configuration information for the specified USART. - * @retval USART Error Code + * @retval USART handle Error Code */ uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart) { @@ -1256,84 +1788,34 @@ uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart) * @} */ -/** @addtogroup USART_Private - * @{ - */ +/** @defgroup USART_Private_Functions USART Private Functions + * @{ + */ + /** - * @brief This function handles USART Communication Timeout. - * @param husart: USART handle - * @param Flag: specifies the USART flag to check. - * @param Status: The new Flag status (SET or RESET). - * @param Timeout: Timeout duration - * @retval HAL status + * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion). + * @param husart USART handle. + * @retval None */ -static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +static void USART_EndTransfer(USART_HandleTypeDef *husart) { - uint32_t tickstart = 0x00U; - tickstart = HAL_GetTick(); + /* Disable TXEIE and TCIE interrupts */ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | USART_CR1_PEIE)); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); - /* Wait until flag is set */ - if(Status == RESET) - { - while(__HAL_USART_GET_FLAG(husart, Flag) == RESET) - { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); - __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); - __HAL_USART_DISABLE_IT(husart, USART_IT_PE); - __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); - - husart->State= HAL_USART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(husart); - - return HAL_TIMEOUT; - } - } - } - } - else - { - while(__HAL_USART_GET_FLAG(husart, Flag) != RESET) - { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ - __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); - __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); - __HAL_USART_DISABLE_IT(husart, USART_IT_PE); - __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); - - husart->State= HAL_USART_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(husart); - - return HAL_TIMEOUT; - } - } - } - } - return HAL_OK; + /* At end of process, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; } /** - * @brief DMA USART transmit process complete callback. - * @param hdma: DMA handle + * @brief DMA USART transmit process complete callback. + * @param hdma DMA handle. * @retval None */ static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma) { - USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); /* DMA Normal mode */ if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) @@ -1344,7 +1826,7 @@ static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma) { /* Disable the DMA transfer for transmit request by resetting the DMAT bit in the USART CR3 register */ - husart->Instance->CR3 &= ~(USART_CR3_DMAT); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); /* Enable the USART Transmit Complete Interrupt */ __HAL_USART_ENABLE_IT(husart, USART_IT_TC); @@ -1361,50 +1843,52 @@ static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma) } /** - * @brief DMA USART transmit process half complete callback - * @param hdma : DMA handle + * @brief DMA USART transmit process half complete callback. + * @param hdma DMA handle. * @retval None */ static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) { - USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); HAL_USART_TxHalfCpltCallback(husart); } /** - * @brief DMA USART receive process complete callback. - * @param hdma: DMA handle + * @brief DMA USART receive process complete callback. + * @param hdma DMA handle. * @retval None */ -static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { - USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); + /* DMA Normal mode */ - if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) + if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) { - husart->RxXferCount = 0U; + husart->RxXferCount = 0; + + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit + in USART CR3 register */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + /* similarly, disable the DMA TX transfer that was started to provide the + clock to the slave device */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); if(husart->State == HAL_USART_STATE_BUSY_RX) { - /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit - in the USART CR3 register */ - husart->Instance->CR3 &= ~(USART_CR3_DMAR); - - husart->State= HAL_USART_STATE_READY; HAL_USART_RxCpltCallback(husart); } - /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/ + /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ else { - /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit - in the USART CR3 register */ - husart->Instance->CR3 &= ~(USART_CR3_DMAR); - husart->Instance->CR3 &= ~(USART_CR3_DMAT); - - husart->State= HAL_USART_STATE_READY; HAL_USART_TxRxCpltCallback(husart); } + husart->State= HAL_USART_STATE_READY; } /* DMA circular mode */ else @@ -1413,293 +1897,213 @@ static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { HAL_USART_RxCpltCallback(husart); } - /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/ + /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ else { HAL_USART_TxRxCpltCallback(husart); } - } + } + } /** - * @brief DMA USART receive process half complete callback - * @param hdma : DMA handle + * @brief DMA USART receive process half complete callback. + * @param hdma DMA handle. * @retval None */ static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) { - USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); - HAL_USART_RxHalfCpltCallback(husart); + HAL_USART_RxHalfCpltCallback(husart); } /** - * @brief DMA USART communication error callback. - * @param hdma: DMA handle + * @brief DMA USART communication error callback. + * @param hdma: DMA handle. * @retval None */ -static void USART_DMAError(DMA_HandleTypeDef *hdma) +static void USART_DMAError(DMA_HandleTypeDef *hdma) { - USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); + + husart->RxXferCount = 0; + husart->TxXferCount = 0; + USART_EndTransfer(husart); - husart->RxXferCount = 0U; - husart->TxXferCount = 0U; husart->ErrorCode |= HAL_USART_ERROR_DMA; husart->State= HAL_USART_STATE_READY; - + HAL_USART_ErrorCallback(husart); } /** - * @brief Simplex Send an amount of data in non-blocking mode. - * Function called under interruption only, once - * interruptions have been enabled by HAL_USART_Transmit_IT() - * @param husart: USART handle - * @retval HAL status - * @note The USART errors are not managed to avoid the overrun error. + * @brief DMA USART communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None */ -static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart) +static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma) { - uint16_t* tmp = 0U; - - if(husart->State == HAL_USART_STATE_BUSY_TX) - { - if(husart->TxXferCount == 0U) - { - /* Disable the USART Transmit Complete Interrupt */ - __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); - - /* Enable the USART Transmit Complete Interrupt */ - __HAL_USART_ENABLE_IT(husart, USART_IT_TC); - - return HAL_OK; - } - else - { - if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) - { - tmp = (uint16_t*) husart->pTxBuffPtr; - husart->Instance->TDR = (*tmp & (uint16_t)0x01FFU); - husart->pTxBuffPtr += 2U; - } - else - { - husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFFU); - } + USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); + husart->RxXferCount = 0; + husart->TxXferCount = 0; - husart->TxXferCount--; - - return HAL_OK; - } - } - else - { - return HAL_BUSY; - } + HAL_USART_ErrorCallback(husart); } /** - * @brief Wraps up transmission in non blocking mode. - * @param husart: pointer to a USART_HandleTypeDef structure that contains - * the configuration information for the specified USART module. + * @brief DMA USART Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef* husart = (USART_HandleTypeDef* )(hdma->Parent); + + husart->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(husart->hdmarx != NULL) + { + if(husart->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + husart->TxXferCount = 0; + husart->RxXferCount = 0; + + /* Reset errorCode */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF); + + /* Restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Call user Abort complete callback */ + HAL_USART_AbortCpltCallback(husart); +} + + +/** + * @brief DMA USART Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef* husart = (USART_HandleTypeDef* )(hdma->Parent); + + husart->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if(husart->hdmatx != NULL) + { + if(husart->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + husart->TxXferCount = 0; + husart->RxXferCount = 0; + + /* Reset errorCode */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF); + + /* Restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Call user Abort complete callback */ + HAL_USART_AbortCpltCallback(husart); +} + + +/** + * @brief Handle USART Communication Timeout. + * @param husart USART handle. + * @param Flag Specifies the USART flag to check. + * @param Status the Flag status (SET or RESET). + * @param Tickstart Tick start value + * @param Timeout timeout duration. * @retval HAL status */ -static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart) +static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) { - /* Disable the USART Transmit Complete Interrupt */ - __HAL_USART_DISABLE_IT(husart, USART_IT_TC); - - /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); - - husart->State = HAL_USART_STATE_READY; - - HAL_USART_TxCpltCallback(husart); - + /* Wait until flag is set */ + while((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + husart->State= HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_TIMEOUT; + } + } + } return HAL_OK; } /** - * @brief Simplex Receive an amount of data in non-blocking mode. - * Function called under interruption only, once - * interruptions have been enabled by HAL_USART_Receive_IT() - * @param husart: USART handle - * @retval HAL status - */ -static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart) -{ - uint16_t* tmp; - uint16_t uhMask = husart->Mask; - - if(husart->State == HAL_USART_STATE_BUSY_RX) - { - - if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) - { - tmp = (uint16_t*) husart->pRxBuffPtr; - *tmp = (uint16_t)(husart->Instance->RDR & uhMask); - husart->pRxBuffPtr += 2U; - } - else - { - *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); - } - /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ - husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FFU); - - if(--husart->RxXferCount == 0U) - { - /* Wait for RXNE Flag */ - if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, HAL_USART_TXDMA_TIMEOUTVALUE) != HAL_OK) - { - return HAL_TIMEOUT; - } - - __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); - - /* Disable the USART Parity Error Interrupt */ - __HAL_USART_DISABLE_IT(husart, USART_IT_PE); - - /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); - - husart->State = HAL_USART_STATE_READY; - - - HAL_USART_RxCpltCallback(husart); - - return HAL_OK; - } - - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking). - * Function called under interruption only, once - * interruptions have been enabled by HAL_USART_TransmitReceive_IT() - * @param husart: USART handle - * @retval HAL status - */ -static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart) -{ - uint16_t* tmp; - uint16_t uhMask = husart->Mask; - - if(husart->State == HAL_USART_STATE_BUSY_TX_RX) - { - if(husart->TxXferCount != 0x00U) - { - if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TC) != RESET) - { - if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) - { - tmp = (uint16_t*) husart->pTxBuffPtr; - husart->Instance->TDR = (uint16_t)(*tmp & uhMask); - husart->pTxBuffPtr += 2U; - } - else - { - husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask); - } - husart->TxXferCount--; - - /* Check the latest data transmitted */ - if(husart->TxXferCount == 0U) - { - __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); - } - } - } - - if(husart->RxXferCount != 0x00U) - { - if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET) - { - if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) - { - tmp = (uint16_t*) husart->pRxBuffPtr; - *tmp = (uint16_t)(husart->Instance->RDR & uhMask); - husart->pRxBuffPtr += 2U; - } - else - { - *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); - } - husart->RxXferCount--; - } - } - - /* Check the latest data received */ - if(husart->RxXferCount == 0U) - { - __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); - - /* Disable the USART Parity Error Interrupt */ - __HAL_USART_DISABLE_IT(husart, USART_IT_PE); - - /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); - - husart->State = HAL_USART_STATE_READY; - - HAL_USART_TxRxCpltCallback(husart); - - return HAL_OK; - } - - /* Process Unlocked */ - __HAL_UNLOCK(husart); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Configure the USART peripheral - * @param husart: USART handle + * @brief Configure the USART peripheral. + * @param husart: USART handle. * @retval HAL status */ static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart) { - uint32_t tmpreg = 0x0U; - uint32_t clocksource = 0x0U; - HAL_StatusTypeDef ret = HAL_OK; - uint16_t brrtemp = 0x0000U; - uint16_t usartdiv = 0x0000U; + uint32_t tmpreg = 0x0U; + USART_ClockSourceTypeDef clocksource = USART_CLOCKSOURCE_UNDEFINED; + HAL_StatusTypeDef ret = HAL_OK; + uint16_t brrtemp = 0x0000U; + uint16_t usartdiv = 0x0000U; - /* Check the parameters */ assert_param(IS_USART_INSTANCE(husart->Instance)); assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity)); assert_param(IS_USART_PHASE(husart->Init.CLKPhase)); assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit)); - assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate)); + assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate)); assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength)); assert_param(IS_USART_STOPBITS(husart->Init.StopBits)); assert_param(IS_USART_PARITY(husart->Init.Parity)); assert_param(IS_USART_MODE(husart->Init.Mode)); + /*-------------------------- USART CR1 Configuration -----------------------*/ - /* Clear M, PCE, PS, TE and RE bits and configure - * the USART Word Length, Parity, Mode and oversampling: - * set the M bits according to husart->Init.WordLength value + /* Clear M, PCE, PS, TE and RE bits and configure + * the USART Word Length, Parity and Mode: + * set the M bits according to husart->Init.WordLength value * set PCE and PS bits according to husart->Init.Parity value - * set TE and RE bits according to husart->Init.Mode value - * Force OVER8 bit to 1 in order to reach the max USART frequencies */ + * set TE and RE bits according to husart->Init.Mode value + * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */ tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); - + /*---------------------------- USART CR2 Configuration ---------------------*/ /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits: * set CPOL bit according to husart->Init.CLKPolarity value @@ -1707,15 +2111,15 @@ static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart) * set LBCL bit according to husart->Init.CLKLastBit value * set STOP[13:12] bits according to husart->Init.StopBits value */ tmpreg = (uint32_t)(USART_CLOCK_ENABLE); - tmpreg |= (uint32_t)(husart->Init.CLKPolarity | husart->Init.CLKPhase); - tmpreg |= (uint32_t)(husart->Init.CLKLastBit | husart->Init.StopBits); + tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase); + tmpreg |= ((uint32_t)husart->Init.CLKLastBit | (uint32_t)husart->Init.StopBits); MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg); /*-------------------------- USART CR3 Configuration -----------------------*/ /* no CR3 register configuration */ /*-------------------------- USART BRR Configuration -----------------------*/ - /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */ + /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */ USART_GETCLOCKSOURCE(husart, clocksource); switch (clocksource) { @@ -1739,64 +2143,274 @@ static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart) ret = HAL_ERROR; break; } - + brrtemp = usartdiv & 0xFFF0U; brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); husart->Instance->BRR = brrtemp; - return ret; + return ret; } /** - * @brief Check the USART Idle State - * @param husart: USART handle + * @brief Check the USART Idle State. + * @param husart: USART handle. * @retval HAL status */ static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart) { - /* Initialize the USART ErrorCode */ + uint32_t tickstart = 0; + + /* Initialize the USART ErrorCode */ husart->ErrorCode = HAL_USART_ERROR_NONE; - + + /* Init tickstart for timeout managment*/ + tickstart = HAL_GetTick(); + /* Check if the Transmitter is enabled */ if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) { /* Wait until TEACK flag is set */ - if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) - { - husart->State= HAL_USART_STATE_TIMEOUT; + if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ return HAL_TIMEOUT; - } + } } /* Check if the Receiver is enabled */ if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) { /* Wait until REACK flag is set */ - if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) - { - husart->State= HAL_USART_STATE_TIMEOUT; + if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ return HAL_TIMEOUT; } } - - /* Process Unlocked */ - __HAL_UNLOCK(husart); - + /* Initialize the USART state*/ husart->State= HAL_USART_STATE_READY; - - return HAL_OK; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Simplex send an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Transmit_IT(). + * @note The USART errors are not managed to avoid the overrun error. + * @param husart USART handle. + * @retval HAL status + */ +static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart) +{ + uint16_t* tmp = 0U; + + /* Check that a Tx process is ongoing */ + if(husart->State == HAL_USART_STATE_BUSY_TX) + { + if(husart->TxXferCount == 0U) + { + /* Disable the USART Transmit data register empty interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); + + /* Enable the USART Transmit Complete Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TC); + + return HAL_OK; + } + else + { + if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + tmp = (uint16_t*) husart->pTxBuffPtr; + husart->Instance->TDR = (*tmp & (uint16_t)0x01FFU); + husart->pTxBuffPtr += 2U; + } + else + { + husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFFU); + } + + husart->TxXferCount--; + + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } } /** - * @} + * @brief Wraps up transmission in non-blocking mode. + * @param husart Pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status */ +static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart) +{ + /* Disable the USART Transmit Complete Interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TC); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); + + /* Tx process is ended, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + HAL_USART_TxCpltCallback(husart); + + return HAL_OK; +} + + +/** + * @brief Simplex receive an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Receive_IT(). + * @param husart USART handle + * @retval HAL status + */ +static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart) +{ + uint16_t* tmp; + uint16_t uhMask = husart->Mask; + + if(husart->State == HAL_USART_STATE_BUSY_RX) + { + + if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + tmp = (uint16_t*) husart->pRxBuffPtr; + *tmp = (uint16_t)(husart->Instance->RDR & uhMask); + husart->pRxBuffPtr += 2U; + } + else + { + *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); + } + /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FFU); + + if(--husart->RxXferCount == 0U) + { + /* Disable the USART Parity Error Interrupt and RXNE interrupt*/ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + HAL_USART_RxCpltCallback(husart); + + return HAL_OK; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking). + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_TransmitReceive_IT(). + * @param husart: USART handle. + * @retval HAL status + */ +static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart) +{ + uint16_t* tmp; + uint16_t uhMask = husart->Mask; + + if(husart->State == HAL_USART_STATE_BUSY_TX_RX) + { + + if(husart->TxXferCount != 0x00U) + { + if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET) + { + if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + tmp = (uint16_t*) husart->pTxBuffPtr; + husart->Instance->TDR = (uint16_t)(*tmp & uhMask); + husart->pTxBuffPtr += 2U; + } + else + { + husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask); + } + husart->TxXferCount--; + + /* Check the latest data transmitted */ + if(husart->TxXferCount == 0U) + { + __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); + } + } + } + + if(husart->RxXferCount != 0x00U) + { + if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET) + { + if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + tmp = (uint16_t*) husart->pRxBuffPtr; + *tmp = (uint16_t)(husart->Instance->RDR & uhMask); + husart->pRxBuffPtr += 2U; + } + else + { + *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); + } + husart->RxXferCount--; + } + } + + /* Check the latest data received */ + if(husart->RxXferCount == 0U) + { + /* Disable the USART Parity Error Interrupt and RXNE interrupt*/ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + HAL_USART_TxRxCpltCallback(husart); + + return HAL_OK; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} /** * @} */ #endif /* HAL_USART_MODULE_ENABLED */ +/** + * @} + */ /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart.h index ffcad4402e..57ef3b2d0b 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_usart.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of USART HAL module. ****************************************************************************** * @attention @@ -32,14 +30,8 @@ * 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. * - * 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 __STM32L0xx_HAL_USART_H @@ -56,35 +48,29 @@ * @{ */ -/** @defgroup USART USART (Synchronous UART) +/** @addtogroup USART * @{ - */ + */ -/******************************************************************************/ /* Exported types ------------------------------------------------------------*/ -/******************************************************************************/ - - /** @defgroup USART_Exported_Types USART Exported Types +/** @defgroup USART_Exported_Types USART Exported Types * @{ */ -/** @defgroup USART_Init_Configuration USART initialization configuration structure - * @{ +/** + * @brief USART Init Structure definition */ -/** - * @brief USART Init Structure definition - */ typedef struct { uint32_t BaudRate; /*!< This member configures the Usart communication baud rate. The baud rate is computed using the following formula: - Baud Rate Register = ((PCLKx) / ((huart->Init.BaudRate))) */ + Baud Rate Register = ((PCLKx) / ((huart->Init.BaudRate))). */ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref USARTEx_Word_Length */ + This parameter can be a value of @ref USARTEx_Word_Length. */ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. - This parameter can be a value of @ref USART_Stop_Bits */ + This parameter can be a value of @ref USART_Stop_Bits. */ uint32_t Parity; /*!< Specifies the parity mode. This parameter can be a value of @ref USART_Parity @@ -92,52 +78,39 @@ typedef struct 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). */ - - uint32_t Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. - This parameter can be a value of @ref USART_Mode */ + + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref USART_Mode. */ uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock. - This parameter can be a value of @ref USART_Clock_Polarity */ + This parameter can be a value of @ref USART_Clock_Polarity. */ uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made. - This parameter can be a value of @ref USART_Clock_Phase */ + This parameter can be a value of @ref USART_Clock_Phase. */ uint32_t CLKLastBit; /*!< 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 */ + This parameter can be a value of @ref USART_Last_Bit. */ }USART_InitTypeDef; /** - * @} + * @brief HAL USART State structures definition */ - -/** @defgroup USART_State_Definition USART state definition - * @{ - */ -/** - * @brief HAL State structures definition - */ typedef enum { - HAL_USART_STATE_RESET = 0x00U, /*!< Peripheral Reset state */ - HAL_USART_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ - HAL_USART_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */ - HAL_USART_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */ - HAL_USART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ + HAL_USART_STATE_RESET = 0x00U, /*!< Peripheral is not initialized */ + HAL_USART_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_USART_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */ + HAL_USART_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */ + HAL_USART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ HAL_USART_STATE_BUSY_TX_RX = 0x32U, /*!< Data Transmission Reception process is ongoing */ - HAL_USART_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ - HAL_USART_STATE_ERROR = 0x04U /*!< Error */ + HAL_USART_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_USART_STATE_ERROR = 0x04U /*!< Error */ }HAL_USART_StateTypeDef; -/** - * @} - */ -/** @defgroup USART_Error_Definition USART error definition - * @{ - */ -/** - * @brief HAL USART Error Code definition - */ +/** + * @brief HAL USART Error Code structure definition + */ #define HAL_USART_ERROR_NONE ((uint32_t)0x00U) /*!< No error */ #define HAL_USART_ERROR_PE ((uint32_t)0x01U) /*!< Parity error */ #define HAL_USART_ERROR_NE ((uint32_t)0x02U) /*!< Noise error */ @@ -146,67 +119,54 @@ typedef enum #define HAL_USART_ERROR_DMA ((uint32_t)0x10U) /*!< DMA transfer error */ /** - * @} - */ -/** @defgroup USART_Clock_SourceDefinition USART clock source definition - * @{ - */ -/** * @brief USART clock sources definitions */ typedef enum { - USART_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ - USART_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ - USART_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ - USART_CLOCKSOURCE_SYSCLK = 0x04U, /*!< SYSCLK clock source */ - USART_CLOCKSOURCE_LSE = 0x08U, /*!< LSE clock source */ + USART_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ + USART_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ + USART_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ + USART_CLOCKSOURCE_SYSCLK = 0x04U, /*!< SYSCLK clock source */ + USART_CLOCKSOURCE_LSE = 0x08U, /*!< LSE clock source */ USART_CLOCKSOURCE_UNDEFINED = 0x10U /*!< Undefined clock source */ }USART_ClockSourceTypeDef; -/** - * @} - */ -/** @defgroup USART_handle_Definition Handle structure definition - * @{ - */ -/** - * @brief USART handle Structure definition - */ + +/** + * @brief USART handle Structure definition + */ typedef struct { - USART_TypeDef *Instance; /*!< USART registers base address */ + USART_TypeDef *Instance; /*!< USART registers base address */ - USART_InitTypeDef Init; /*!< Usart communication parameters */ - - uint8_t *pTxBuffPtr; /*!< Pointer to Usart Tx transfer Buffer */ - - uint16_t TxXferSize; /*!< Usart Tx Transfer size */ - - __IO uint16_t TxXferCount; /*!< Usart Tx Transfer Counter */ - - uint8_t *pRxBuffPtr; /*!< Pointer to Usart Rx transfer Buffer */ - - uint16_t RxXferSize; /*!< Usart Rx Transfer size */ - - __IO uint16_t RxXferCount; /*!< Usart Rx Transfer Counter */ + USART_InitTypeDef Init; /*!< USART communication parameters */ + + uint8_t *pTxBuffPtr; /*!< Pointer to USART Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< USART Tx Transfer size */ + + __IO uint16_t TxXferCount; /*!< USART Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to USART Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< USART Rx Transfer size */ + + __IO uint16_t RxXferCount; /*!< USART Rx Transfer Counter */ + + uint16_t Mask; /*!< USART Rx RDR register mask */ + + DMA_HandleTypeDef *hdmatx; /*!< USART Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< USART Rx DMA Handle parameters */ + + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_USART_StateTypeDef State; /*!< USART communication state */ + + __IO uint32_t ErrorCode; /*!< USART Error code */ - uint16_t Mask; /* USART Rx RDR register mask */ - - DMA_HandleTypeDef *hdmatx; /*!< Usart Tx DMA Handle parameters */ - - DMA_HandleTypeDef *hdmarx; /*!< Usart Rx DMA Handle parameters */ - - HAL_LockTypeDef Lock; /*!< Locking object */ - - __IO HAL_USART_StateTypeDef State; /*!< Usart communication state */ - - __IO uint32_t ErrorCode; /*!< USART Error code */ - }USART_HandleTypeDef; -/** - * @} - */ + /** * @} */ @@ -216,112 +176,106 @@ typedef struct * @{ */ -/** @defgroup USART_Stop_Bits USART stop bit definition +/** @defgroup USART_Stop_Bits USART Number of Stop Bits * @{ */ -#define USART_STOPBITS_1 ((uint32_t)0x0000U) -#define USART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1) -#define USART_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP_0 | USART_CR2_STOP_1)) -#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_STOPBITS_1) || \ - ((STOPBITS) == USART_STOPBITS_1_5) || \ - ((STOPBITS) == USART_STOPBITS_2)) -/** - * @} - */ - -/** @defgroup USART_Parity USART parity definition - * @{ - */ -#define USART_PARITY_NONE ((uint32_t)0x0000U) -#define USART_PARITY_EVEN ((uint32_t)USART_CR1_PCE) -#define USART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) -#define IS_USART_PARITY(PARITY) (((PARITY) == USART_PARITY_NONE) || \ - ((PARITY) == USART_PARITY_EVEN) || \ - ((PARITY) == USART_PARITY_ODD)) -/** - * @} - */ - -/** @defgroup USART_Mode USART mode definition - * @{ - */ -#define USART_MODE_RX ((uint32_t)USART_CR1_RE) -#define USART_MODE_TX ((uint32_t)USART_CR1_TE) -#define USART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) -#define IS_USART_MODE(MODE) (((MODE) == USART_MODE_RX) || \ - ((MODE) == USART_MODE_TX) || \ - ((MODE) == USART_MODE_TX_RX)) -/** - * @} - */ - -/** @defgroup USART_Clock USART clock activation definition - * @{ - */ -#define USART_CLOCK_DISABLE ((uint32_t)0x0000U) -#define USART_CLOCK_ENABLE ((uint32_t)USART_CR2_CLKEN) -#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_CLOCK_DISABLE) || \ - ((CLOCK) == USART_CLOCK_ENABLE)) -/** - * @} - */ - -/** @defgroup USART_Clock_Polarity USART polarity level definition - * @{ - */ -#define USART_POLARITY_LOW ((uint32_t)0x0000U) -#define USART_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL) -#define IS_USART_POLARITY(CPOL) (((CPOL) == USART_POLARITY_LOW) || ((CPOL) == USART_POLARITY_HIGH)) -/** - * @} - */ - -/** @defgroup USART_Clock_Phase USART clock phase definition - * @{ - */ -#define USART_PHASE_1EDGE ((uint32_t)0x0000U) -#define USART_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA) -#define IS_USART_PHASE(CPHA) (((CPHA) == USART_PHASE_1EDGE) || ((CPHA) == USART_PHASE_2EDGE)) +#define USART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< USART frame with 0.5 stop bit */ +#define USART_STOPBITS_1 ((uint32_t)0x00000000) /*!< USART frame with 1 stop bit */ +#define USART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< USART frame with 1.5 stop bits */ +#define USART_STOPBITS_2 USART_CR2_STOP_1 /*!< USART frame with 2 stop bits */ /** * @} */ -/** @defgroup USART_Last_Bit USART last bit activation definition +/** @defgroup USART_Parity USART Parity * @{ */ -#define USART_LASTBIT_DISABLE ((uint32_t)0x0000U) -#define USART_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL) -#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LASTBIT_DISABLE) || \ - ((LASTBIT) == USART_LASTBIT_ENABLE)) +#define USART_PARITY_NONE ((uint32_t)0x00000000U) /*!< No parity */ +#define USART_PARITY_EVEN ((uint32_t)USART_CR1_PCE) /*!< Even parity */ +#define USART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) /*!< Odd parity */ /** * @} */ +/** @defgroup USART_Mode USART Mode + * @{ + */ +#define USART_MODE_RX ((uint32_t)USART_CR1_RE) /*!< RX mode */ +#define USART_MODE_TX ((uint32_t)USART_CR1_TE) /*!< TX mode */ +#define USART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) /*!< RX and TX mode */ +/** + * @} + */ -/** @defgroup USART_Flags USART flag definitions +/** @defgroup USART_Clock USART Clock + * @{ + */ +#define USART_CLOCK_DISABLE ((uint32_t)0x00000000U) /*!< USART clock disable */ +#define USART_CLOCK_ENABLE ((uint32_t)USART_CR2_CLKEN) /*!< USART clock enable */ +/** + * @} + */ + +/** @defgroup USART_Clock_Polarity USART Clock Polarity + * @{ + */ +#define USART_POLARITY_LOW ((uint32_t)0x00000000U) /*!< USART Clock signal is steady Low */ +#define USART_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL) /*!< USART Clock signal is steady High */ +/** + * @} + */ + +/** @defgroup USART_Clock_Phase USART Clock Phase + * @{ + */ +#define USART_PHASE_1EDGE ((uint32_t)0x00000000U) /*!< USART frame phase on first clock transition */ +#define USART_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA) /*!< USART frame phase on second clock transition */ +/** + * @} + */ + +/** @defgroup USART_Last_Bit USART Last Bit + * @{ + */ +#define USART_LASTBIT_DISABLE ((uint32_t)0x00000000U) /*!< USART frame last data bit clock pulse not output to SCLK pin */ +#define USART_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL) /*!< USART frame last data bit clock pulse output to SCLK pin */ +/** + * @} + */ + +/** @defgroup USART_Request_Parameters USART Request Parameters + * @{ + */ +#define USART_RXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_RXFRQ) /*!< Receive Data flush Request */ +#define USART_TXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_TXFRQ) /*!< Transmit data flush Request */ +/** + * @} + */ + +/** @defgroup USART_Flags USART Flags * Elements values convention: 0xXXXX * - 0xXXXX : Flag mask in the ISR register * @{ */ -#define USART_FLAG_REACK USART_ISR_REACK /*!< Receive Enable Acknowledge Flag */ -#define USART_FLAG_TEACK USART_ISR_TEACK /*!< Transmit Enable Acknowledge Flag */ -#define USART_FLAG_BUSY USART_ISR_BUSY /*!< Busy Flag */ -#define USART_FLAG_CTS USART_ISR_CTS /*!< CTS flag */ -#define USART_FLAG_CTSIF USART_ISR_CTSIF /*!< CTS interrupt flag */ -#define USART_FLAG_LBDF USART_ISR_LBDF /*!< LIN Break Detection Flag */ -#define USART_FLAG_TXE USART_ISR_TXE /*!< Transmit Data Register Empty */ -#define USART_FLAG_TC USART_ISR_TC /*!< Transmission Complete */ -#define USART_FLAG_RXNE USART_ISR_RXNE /*!< Read Data Register Not Empty */ -#define USART_FLAG_IDLE USART_ISR_IDLE /*!< IDLE line detected */ -#define USART_FLAG_ORE USART_ISR_ORE /*!< OverRun Error */ -#define USART_FLAG_NE USART_ISR_NE /*!< Noise detected Flag */ -#define USART_FLAG_FE USART_ISR_FE /*!< Framing Error */ -#define USART_FLAG_PE USART_ISR_PE /*!< Parity Error */ +#define USART_FLAG_REACK USART_ISR_REACK /*!< USART receive enable acknowledge flag */ +#define USART_FLAG_TEACK USART_ISR_TEACK /*!< USART transmit enable acknowledge flag */ +#define USART_FLAG_BUSY USART_ISR_BUSY /*!< USART busy flag */ +#define USART_FLAG_CTS USART_ISR_CTS /*!< USART clear to send flag */ +#define USART_FLAG_CTSIF USART_ISR_CTSIF /*!< USART clear to send interrupt flag */ +#define USART_FLAG_LBDF USART_ISR_LBDF /*!< USART LIN break detection flag */ +#define USART_FLAG_TXE USART_ISR_TXE /*!< USART transmit data register empty */ +#define USART_FLAG_TC USART_ISR_TC /*!< USART transmission complete */ +#define USART_FLAG_RXNE USART_ISR_RXNE /*!< USART read data register not empty */ +#define USART_FLAG_IDLE USART_ISR_IDLE /*!< USART idle flag */ +#define USART_FLAG_ORE USART_ISR_ORE /*!< USART overrun error */ +#define USART_FLAG_NE USART_ISR_NE /*!< USART noise error */ +#define USART_FLAG_FE USART_ISR_FE /*!< USART frame error */ +#define USART_FLAG_PE USART_ISR_PE /*!< USART parity error */ /** * @} */ -/** @defgroup USART_Interrupt_definition USART interrupt definition +/** @defgroup USART_Interrupt_definition USART Interrupts Definition * Elements values convention: 0000ZZZZ0XXYYYYYb * - YYYYY : Interrupt source position in the XX register (5bits) * - XX : Interrupt source register (2bits) @@ -331,50 +285,38 @@ typedef struct * - ZZZZ : Flag position in the ISR register(4bits) * @{ */ - -#define USART_IT_PE ((uint16_t)0x0028U) -#define USART_IT_TXE ((uint16_t)0x0727U) -#define USART_IT_TC ((uint16_t)0x0626U) -#define USART_IT_RXNE ((uint16_t)0x0525U) -#define USART_IT_IDLE ((uint16_t)0x0424U) -#define USART_IT_ERR ((uint16_t)0x0060U) -#define USART_IT_ORE ((uint16_t)0x0300U) -#define USART_IT_NE ((uint16_t)0x0200U) -#define USART_IT_FE ((uint16_t)0x0100U) +#define USART_IT_PE ((uint16_t)0x0028U) /*!< USART parity error interruption */ +#define USART_IT_TXE ((uint16_t)0x0727U) /*!< USART transmit data register empty interruption */ +#define USART_IT_TC ((uint16_t)0x0626U) /*!< USART transmission complete interruption */ +#define USART_IT_RXNE ((uint16_t)0x0525U) /*!< USART read data register not empty interruption */ +#define USART_IT_IDLE ((uint16_t)0x0424U) /*!< USART idle interruption */ +#define USART_IT_ERR ((uint16_t)0x0060U) /*!< USART error interruption */ +#define USART_IT_ORE ((uint16_t)0x0300U) /*!< USART overrun error interruption */ +#define USART_IT_NE ((uint16_t)0x0200U) /*!< USART noise error interruption */ +#define USART_IT_FE ((uint16_t)0x0100U) /*!< USART frame error interruption */ /** * @} */ -/** @defgroup USART_IT_CLEAR_Flags USART interrupt clear flags definition +/** @defgroup USART_IT_CLEAR_Flags USART Interruption Clear Flags * @{ */ -#define USART_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ -#define USART_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ -#define USART_CLEAR_NEF USART_ICR_NCF /*!< Noise detected Clear Flag */ -#define USART_CLEAR_OREF USART_ICR_ORECF /*!< OverRun Error Clear Flag */ -#define USART_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ -#define USART_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ -#define USART_CLEAR_CTSF USART_ICR_CTSCF /*!< CTS Interrupt Clear Flag */ +#define USART_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ +#define USART_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ +#define USART_CLEAR_NEF USART_ICR_NCF /*!< Noise detected Clear Flag */ +#define USART_CLEAR_OREF USART_ICR_ORECF /*!< OverRun Error Clear Flag */ +#define USART_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ +#define USART_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ +#define USART_CLEAR_CTSF USART_ICR_CTSCF /*!< CTS Interrupt Clear Flag */ /** * @} - */ + */ -/** @defgroup USART_Request_Parameters USART request parameter definition +/** @defgroup USART_Interruption_Mask USART Interruption Flags Mask * @{ */ -#define USART_RXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_RXFRQ) /*!< Receive Data flush Request */ -#define USART_TXDATA_FLUSH_REQUEST ((uint32_t)USART_RQR_TXFRQ) /*!< Transmit data flush Request */ -#define IS_USART_REQUEST_PARAMETER(PARAM) (((PARAM) == USART_RXDATA_FLUSH_REQUEST) || \ - ((PARAM) == USART_TXDATA_FLUSH_REQUEST)) -/** - * @} - */ - -/** @defgroup USART_Interruption_Mask USART interruption mask definition - * @{ - */ -#define USART_IT_MASK ((uint16_t)0x001FU) +#define USART_IT_MASK ((uint16_t)0x001FU) /*!< USART interruptions flags mask */ /** * @} */ @@ -382,16 +324,14 @@ typedef struct /** * @} */ - - -/* Exported macro ------------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ /** @defgroup USART_Exported_Macros USART Exported Macros * @{ */ -/** @brief Reset USART handle state - * @param __HANDLE__: specifies the USART Handle. - * The Handle Instance which can be USART1 or USART2. + +/** @brief Reset USART handle state. + * @param __HANDLE__: USART handle. * @retval None */ #define __HAL_USART_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_USART_STATE_RESET) @@ -406,137 +346,132 @@ typedef struct } while(0) - -/** @brief Checks whether the specified USART flag is set or not. - * @param __HANDLE__: specifies the USART Handle which can be USART1 or USART2. +/** @brief Check whether the specified USART flag is set or not. + * @param __HANDLE__: specifies the USART Handle * @param __FLAG__: specifies the flag to check. * This parameter can be one of the following values: - * @arg USART_FLAG_REACK: Receive enable ackowledge flag - * @arg USART_FLAG_TEACK: Transmit enable ackowledge flag - * @arg USART_FLAG_BUSY: Busy flag - * @arg USART_FLAG_CTS: CTS Change 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 + * @arg @ref USART_FLAG_REACK Receive enable acknowledge flag + * @arg @ref USART_FLAG_TEACK Transmit enable acknowledge flag + * @arg @ref USART_FLAG_BUSY Busy flag + * @arg @ref USART_FLAG_CTS CTS Change flag + * @arg @ref USART_FLAG_TXE Transmit data register empty flag + * @arg @ref USART_FLAG_TC Transmission Complete flag + * @arg @ref USART_FLAG_RXNE Receive data register not empty flag + * @arg @ref USART_FLAG_IDLE Idle Line detection flag + * @arg @ref USART_FLAG_ORE OverRun Error flag + * @arg @ref USART_FLAG_NE Noise Error flag + * @arg @ref USART_FLAG_FE Framing Error flag + * @arg @ref USART_FLAG_PE Parity Error flag * @retval The new state of __FLAG__ (TRUE or FALSE). */ #define __HAL_USART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) -/** @brief Clears the specified USART pending flag. +/** @brief Clear the specified USART pending flag. * @param __HANDLE__: specifies the USART Handle. * @param __FLAG__: specifies the flag to check. * This parameter can be any combination of the following values: - * @arg USART_CLEAR_PEF - * @arg USART_CLEAR_FEF - * @arg USART_CLEAR_NEF - * @arg USART_CLEAR_OREF - * @arg USART_CLEAR_IDLEF - * @arg USART_CLEAR_TCF - * @arg USART_CLEAR_LBDF - * @arg USART_CLEAR_CTSF - * @arg USART_CLEAR_RTOF - * @arg USART_CLEAR_EOBF - * @arg USART_CLEAR_CMF - * @arg USART_CLEAR_WUF + * @arg @ref USART_CLEAR_PEF + * @arg @ref USART_CLEAR_FEF + * @arg @ref USART_CLEAR_NEF + * @arg @ref USART_CLEAR_OREF + * @arg @ref USART_CLEAR_IDLEF + * @arg @ref USART_CLEAR_TCF + * @arg @ref USART_CLEAR_CTSF * @retval None */ #define __HAL_USART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) /** @brief Clear the USART PE pending flag. - * @param __HANDLE__: specifies the UART Handle. + * @param __HANDLE__: specifies the USART Handle. * @retval None */ -#define __HAL_USART_CLEAR_PEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG(__HANDLE__,USART_CLEAR_PEF) +#define __HAL_USART_CLEAR_PEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_PEF) /** @brief Clear the USART FE pending flag. - * @param __HANDLE__: specifies the UART Handle. + * @param __HANDLE__: specifies the USART Handle. * @retval None */ -#define __HAL_USART_CLEAR_FEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG(__HANDLE__,USART_CLEAR_FEF) +#define __HAL_USART_CLEAR_FEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_FEF) -/** @brief Clear the UART NE pending flag. - * @param __HANDLE__: specifies the UART Handle. +/** @brief Clear the USART NE pending flag. + * @param __HANDLE__: specifies the USART Handle. * @retval None */ -#define __HAL_USART_CLEAR_NEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG(__HANDLE__,USART_CLEAR_NEF) +#define __HAL_USART_CLEAR_NEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_NEF) -/** @brief Clear the UART ORE pending flag. - * @param __HANDLE__: specifies the UART Handle. +/** @brief Clear the USART ORE pending flag. + * @param __HANDLE__: specifies the USART Handle. * @retval None */ -#define __HAL_USART_CLEAR_OREFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG(__HANDLE__,USART_CLEAR_OREF) +#define __HAL_USART_CLEAR_OREFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_OREF) -/** @brief Clear the UART IDLE pending flag. - * @param __HANDLE__: specifies the UART Handle. +/** @brief Clear the USART IDLE pending flag. + * @param __HANDLE__: specifies the USART Handle. * @retval None */ -#define __HAL_USART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG(__HANDLE__,USART_CLEAR_IDLEF) +#define __HAL_USART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_IDLEF) -/** @brief Enables the specified USART interrupt. - * @param __HANDLE__: specifies the USART Handle which can be USART1 or USART2. +/** @brief Enable the specified USART interrupt. + * @param __HANDLE__: specifies the USART Handle. * @param __INTERRUPT__: specifies the USART interrupt source to enable. * This parameter can be one of the following values: - * @arg USART_IT_TXE: Transmit 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) + * @arg @ref USART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref USART_IT_TC Transmission complete interrupt + * @arg @ref USART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref USART_IT_IDLE Idle line detection interrupt + * @arg @ref USART_IT_PE Parity Error interrupt + * @arg @ref USART_IT_ERR Error interrupt(Frame error, noise error, overrun error) * @retval None */ -#define __HAL_USART_ENABLE_IT(__HANDLE__, __INTERRUPT__)(((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & USART_IT_MASK)))) +#define __HAL_USART_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & USART_IT_MASK)))) -/** @brief Disables the specified USART interrupt. - * @param __HANDLE__: specifies the USART Handle which can be USART1 or USART2. +/** @brief Disable the specified USART interrupt. + * @param __HANDLE__: specifies the USART Handle. * @param __INTERRUPT__: specifies the USART interrupt source to disable. * This parameter can be one of the following values: - * @arg USART_IT_TXE: Transmit 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) + * @arg @ref USART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref USART_IT_TC Transmission complete interrupt + * @arg @ref USART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref USART_IT_IDLE Idle line detection interrupt + * @arg @ref USART_IT_PE Parity Error interrupt + * @arg @ref USART_IT_ERR Error interrupt(Frame error, noise error, overrun error) * @retval None */ -#define __HAL_USART_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & USART_IT_MASK))): \ - ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & USART_IT_MASK))): \ - ((__HANDLE__)->Instance->CR3 &= ~ ((uint32_t)1U << ((__INTERRUPT__) & USART_IT_MASK)))) +#define __HAL_USART_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)? ((__HANDLE__)->Instance->CR1 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)? ((__HANDLE__)->Instance->CR2 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK)))) -/** @brief Checks whether the specified USART interrupt has occurred or not. - * @param __HANDLE__: specifies the USART Handle which can be USART1 or USART2. + +/** @brief Check whether the specified USART interrupt has occurred or not. + * @param __HANDLE__: specifies the USART Handle. * @param __IT__: specifies the USART interrupt source to check. * This parameter can be one of the following values: - * @arg USART_IT_TXE: Transmit 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: OverRun Error interrupt - * @arg USART_IT_NE: Noise Error interrupt - * @arg USART_IT_FE: Framing Error interrupt - * @arg USART_IT_PE: Parity Error interrupt + * @arg @ref USART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref USART_IT_TC Transmission complete interrupt + * @arg @ref USART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref USART_IT_IDLE Idle line detection interrupt + * @arg @ref USART_IT_ORE OverRun Error interrupt + * @arg @ref USART_IT_NE Noise Error interrupt + * @arg @ref USART_IT_FE Framing Error interrupt + * @arg @ref USART_IT_PE Parity Error interrupt * @retval The new state of __IT__ (TRUE or FALSE). */ -#define __HAL_USART_GET_IT(__HANDLE__, __IT__) ((__HANDLE__)->Instance->ISR & ((uint32_t)1U << ((__IT__)>> 0x08U))) +#define __HAL_USART_GET_IT(__HANDLE__, __IT__) ((__HANDLE__)->Instance->ISR & ((uint32_t)1U << ((__IT__)>> 0x08U))) -/** @brief Checks whether the specified USART interrupt source is enabled. - * @param __HANDLE__: specifies the USART Handle which can be USART1 or USART2. +/** @brief Check whether the specified USART interrupt source is enabled or not. + * @param __HANDLE__: specifies the USART Handle. * @param __IT__: specifies the USART interrupt source to check. * This parameter can be one of the following values: - * @arg USART_IT_TXE: Transmit 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: OverRun Error interrupt - * @arg USART_IT_NE: Noise Error interrupt - * @arg USART_IT_FE: Framing Error interrupt - * @arg USART_IT_PE: Parity Error interrupt + * @arg @ref USART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref USART_IT_TC Transmission complete interrupt + * @arg @ref USART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref USART_IT_IDLE Idle line detection interrupt + * @arg @ref USART_IT_ORE OverRun Error interrupt + * @arg @ref USART_IT_NE Noise Error interrupt + * @arg @ref USART_IT_FE Framing Error interrupt + * @arg @ref USART_IT_PE Parity Error interrupt * @retval The new state of __IT__ (TRUE or FALSE). */ #define __HAL_USART_GET_IT_SOURCE(__HANDLE__, __IT__) ((((((uint8_t)(__IT__)) >> 5U) == 1U)? (__HANDLE__)->Instance->CR1:(((((uint8_t)(__IT__)) >> 5U) == 2U)? \ @@ -544,93 +479,172 @@ typedef struct (((uint16_t)(__IT__)) & USART_IT_MASK))) -/** @brief Clears the specified USART ISR flag, in setting the proper ICR register flag. - * @param __HANDLE__: specifies the USART Handle which can be USART1 or USART2. +/** @brief Clear the specified USART ISR flag, in setting the proper ICR register flag. + * @param __HANDLE__: specifies the USART Handle. * @param __IT_CLEAR__: specifies the interrupt clear register flag that needs to be set - * to clear the corresponding interrupt + * to clear the corresponding interrupt. * This parameter can be one of the following values: - * @arg USART_CLEAR_PEF: Parity Error Clear Flag - * @arg USART_CLEAR_FEF: Framing Error Clear Flag - * @arg USART_CLEAR_NEF: Noise detected Clear Flag - * @arg USART_CLEAR_OREF: OverRun Error Clear Flag - * @arg USART_CLEAR_IDLEF: IDLE line detected Clear Flag - * @arg USART_CLEAR_TCF: Transmission Complete Clear Flag - * @arg USART_CLEAR_CTSF: CTS Interrupt Clear Flag + * @arg @ref USART_CLEAR_PEF Parity Error Clear Flag + * @arg @ref USART_CLEAR_FEF Framing Error Clear Flag + * @arg @ref USART_CLEAR_NEF Noise detected Clear Flag + * @arg @ref USART_CLEAR_OREF OverRun Error Clear Flag + * @arg @ref USART_CLEAR_IDLEF IDLE line detected Clear Flag + * @arg @ref USART_CLEAR_TCF Transmission Complete Clear Flag + * @arg @ref USART_CLEAR_CTSF CTS Interrupt Clear Flag * @retval None */ -#define __HAL_USART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) +#define __HAL_USART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) /** @brief Set a specific USART request flag. - * @param __HANDLE__: specifies the USART Handle which can be USART1 or USART2. - * @param __REQ__: specifies the request flag to set + * @param __HANDLE__: specifies the USART Handle. + * @param __REQ__: specifies the request flag to set. * This parameter can be one of the following values: - * @arg USART_RXDATA_FLUSH_REQUEST: Receive Data flush Request - * @arg USART_TXDATA_FLUSH_REQUEST: Transmit data flush Request + * @arg @ref USART_RXDATA_FLUSH_REQUEST Receive Data flush Request + * @arg @ref USART_TXDATA_FLUSH_REQUEST Transmit data flush Request * * @retval None - */ -#define __HAL_USART_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint32_t)(__REQ__)) + */ +#define __HAL_USART_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint32_t)(__REQ__)) -/** @brief Enables the USART one bit sample method - * @param __HANDLE__: specifies the USART Handle. +/** @brief Enable the USART one bit sample method. + * @param __HANDLE__: specifies the USART Handle. * @retval None */ #define __HAL_USART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) -/** @brief Disables the UART one bit sample method - * @param __HANDLE__: specifies the UART Handle. +/** @brief Disable the USART one bit sample method. + * @param __HANDLE__: specifies the USART Handle. * @retval None */ #define __HAL_USART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT)) -/** @brief Enable USART +/** @brief Enable USART. * @param __HANDLE__: specifies the USART Handle. - * The Handle Instance which can be USART1 or USART2. * @retval None - */ -#define __HAL_USART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) - -/** @brief Disable USART - * @param __HANDLE__: specifies the USART Handle. - * The Handle Instance which can be USART1 or USART2. - * @retval None - */ -#define __HAL_USART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) - - -/** @brief Check USART Baud rate - * @param BAUDRATE: Baudrate specified by the user - * The maximum Baud Rate is derived from the maximum clock on L0 (i.e. 32 MHz) - * divided by the smallest oversampling used on the USART (i.e. 8) - * @retval Test result (TRUE or FALSE). */ -#define IS_USART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 4000001U) +#define __HAL_USART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable USART. + * @param __HANDLE__: specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) /** * @} */ - -/* Include USART HAL Extension module */ -#include "stm32l0xx_hal_usart_ex.h" -/* Exported functions --------------------------------------------------------*/ -/** @defgroup USART_Exported_Functions USART Exported Functions + +/* Private macros --------------------------------------------------------*/ +/** @defgroup USART_Private_Macros USART Private Macros * @{ */ -/* Initialization/de-initialization functions ********************************/ -/** @defgroup USART_Exported_Functions_Group1 Initialization/de-initialization functions - * @{ - */ + +/** @brief Check USART Baud rate. + * @param __BAUDRATE__: Baudrate specified by the user. + * The maximum Baud Rate is derived from the maximum clock on L0 (i.e. 32 MHz) + * divided by the smallest oversampling used on the USART (i.e. 8). + * @retval Test result (TRUE or FALSE). + */ +#define IS_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 4000001U) + + +/** + * @brief Ensure that USART frame number of stop bits is valid. + * @param __STOPBITS__: USART frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_USART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == USART_STOPBITS_0_5) || \ + ((__STOPBITS__) == USART_STOPBITS_1) || \ + ((__STOPBITS__) == USART_STOPBITS_1_5) || \ + ((__STOPBITS__) == USART_STOPBITS_2)) + +/** + * @brief Ensure that USART frame parity is valid. + * @param __PARITY__: USART frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_USART_PARITY(__PARITY__) (((__PARITY__) == USART_PARITY_NONE) || \ + ((__PARITY__) == USART_PARITY_EVEN) || \ + ((__PARITY__) == USART_PARITY_ODD)) + +/** + * @brief Ensure that USART communication mode is valid. + * @param __MODE__: USART communication mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_USART_MODE(MODE) (((MODE) == USART_MODE_RX) || \ + ((MODE) == USART_MODE_TX) || \ + ((MODE) == USART_MODE_TX_RX)) + +/** + * @brief Ensure that USART clock state is valid. + * @param __CLOCK__: USART clock state. + * @retval SET (__CLOCK__ is valid) or RESET (__CLOCK__ is invalid) + */ +#define IS_USART_CLOCK(__CLOCK__) (((__CLOCK__) == USART_CLOCK_DISABLE) || \ + ((__CLOCK__) == USART_CLOCK_ENABLE)) + +/** + * @brief Ensure that USART frame polarity is valid. + * @param __CPOL__: USART frame polarity. + * @retval SET (__CPOL__ is valid) or RESET (__CPOL__ is invalid) + */ +#define IS_USART_POLARITY(__CPOL__) (((__CPOL__) == USART_POLARITY_LOW) || ((__CPOL__) == USART_POLARITY_HIGH)) + +/** + * @brief Ensure that USART frame phase is valid. + * @param __CPHA__: USART frame phase. + * @retval SET (__CPHA__ is valid) or RESET (__CPHA__ is invalid) + */ +#define IS_USART_PHASE(__CPHA__) (((__CPHA__) == USART_PHASE_1EDGE) || ((__CPHA__) == USART_PHASE_2EDGE)) + +/** + * @brief Ensure that USART frame last bit clock pulse setting is valid. + * @param __LASTBIT__: USART frame last bit clock pulse setting. + * @retval SET (__LASTBIT__ is valid) or RESET (__LASTBIT__ is invalid) + */ +#define IS_USART_LASTBIT(__LASTBIT__) (((__LASTBIT__) == USART_LASTBIT_DISABLE) || \ + ((__LASTBIT__) == USART_LASTBIT_ENABLE)) + +/** + * @brief Ensure that USART request parameter is valid. + * @param __PARAM__: USART request parameter. + * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) + */ +#define IS_USART_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == USART_RXDATA_FLUSH_REQUEST) || \ + ((__PARAM__) == USART_TXDATA_FLUSH_REQUEST)) + +/** + * @} + */ + +/* Include USART HAL Extended module */ +#include "stm32l0xx_hal_usart_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USART_Exported_Functions USART Exported Functions + * @{ + */ + +/** @addtogroup USART_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart); HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart); void HAL_USART_MspInit(USART_HandleTypeDef *husart); void HAL_USART_MspDeInit(USART_HandleTypeDef *husart); + /** * @} */ + +/** @addtogroup USART_Exported_Functions_Group2 IO operation functions + * @{ + */ + /* IO operation functions *****************************************************/ -/** @defgroup USART_Exported_Functions_Group2 IO operation functions - * @{ - */ HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); @@ -643,6 +657,10 @@ HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uin HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart); HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart); HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart); +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart); + void HAL_USART_IRQHandler(USART_HandleTypeDef *husart); void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart); void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart); @@ -650,42 +668,38 @@ void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart); void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart); void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart); void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart); -/** - * @} - */ -/* IO operation functions *****************************************************/ -/** @defgroup USART_Exported_Functions_Group3 Peripheral State functions - * @{ - */ -/* Peripheral State functions ************************************************/ -HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart); -uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart); -/** - * @} - */ +void HAL_USART_AbortCpltCallback (USART_HandleTypeDef *husart); /** * @} */ -/* Define the private group ***********************************/ -/**************************************************************/ -/** @defgroup USART_Private USART Private +/* Peripheral Control functions ***********************************************/ + +/** @addtogroup USART_Exported_Functions_Group4 Peripheral State and Error functions * @{ */ -/** - * @} - */ -/**************************************************************/ -/** - * @} - */ +/* Peripheral State and Error functions ***************************************/ +HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart); +uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart); /** * @} */ - + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart_ex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart_ex.h index 424c613460..d5a2d423c7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart_ex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_usart_ex.h @@ -2,12 +2,10 @@ ****************************************************************************** * @file stm32l0xx_hal_usart_ex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief Header file of USART HAL Extension module. + * @brief Header file of USART HAL Extended module. ****************************************************************************** * @attention - * + * *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, @@ -32,7 +30,7 @@ * 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. * - ****************************************************************************** + ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ @@ -49,7 +47,8 @@ /** @addtogroup STM32L0xx_HAL_Driver * @{ */ -/** @defgroup USARTEx USARTEx + +/** @addtogroup USARTEx * @{ */ @@ -59,65 +58,39 @@ * @{ */ -/** @defgroup USARTEx_Word_Length Word length definition +/** @defgroup USARTEx_Word_Length USARTEx Word Length * @{ */ -#define USART_WORDLENGTH_7B ((uint32_t)USART_CR1_M1) -#define USART_WORDLENGTH_8B ((uint32_t)0x00000000U) -#define USART_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) -#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WORDLENGTH_7B) || \ - ((LENGTH) == USART_WORDLENGTH_8B) || \ - ((LENGTH) == USART_WORDLENGTH_9B)) +#define USART_WORDLENGTH_7B ((uint32_t)USART_CR1_M1) /*!< 7-bit long USART frame */ +#define USART_WORDLENGTH_8B ((uint32_t)0x00000000U) /*!< 8-bit long USART frame */ +#define USART_WORDLENGTH_9B ((uint32_t)USART_CR1_M0) /*!< 9-bit long USART frame */ /** * @} - */ - -/** - * @} - */ -/* Exported macro ------------------------------------------------------------*/ + */ -/** @defgroup USARTEx_Extended_Exported_Macros USARTEx Exported Macros +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup USARTEx_Private_Macros USARTEx Private Macros * @{ */ -/** @brief Reports the USART clock source. - * @param __HANDLE__: specifies the USART Handle - * @param __CLOCKSOURCE__ : output variable +/** @brief Report the USART clock source. + * @param __HANDLE__: specifies the USART Handle. + * @param __CLOCKSOURCE__: output variable. * @retval the USART clocking source, written in __CLOCKSOURCE__. */ -#if defined (STM32L031xx) || defined (STM32L041xx) || defined (STM32L011xx) || defined (STM32L021xx) -#define USART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ - do { \ - if((__HANDLE__)->Instance == USART2) \ - { \ - switch(__HAL_RCC_GET_USART2_SOURCE()) \ - { \ - case RCC_USART2CLKSOURCE_PCLK1: \ - (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ - break; \ - case RCC_USART2CLKSOURCE_HSI: \ - (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ - break; \ - case RCC_USART2CLKSOURCE_SYSCLK: \ - (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK; \ - break; \ - case RCC_USART2CLKSOURCE_LSE: \ - (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ - break; \ - default: \ - break; \ - } \ - } \ - } while(0) - -#else /* (STM32L031xx) || defined (STM32L041xx) || (STM32L011xx) || defined (STM32L021xx) */ +#if defined (STM32L051xx) || defined (STM32L052xx) || defined (STM32L053xx) || defined (STM32L061xx) || defined (STM32L062xx) || defined (STM32L063xx) #define USART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ do { \ if((__HANDLE__)->Instance == USART1) \ { \ - switch(__HAL_RCC_GET_USART1_SOURCE()) \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ { \ case RCC_USART1CLKSOURCE_PCLK2: \ (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK2; \ @@ -132,6 +105,7 @@ (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ @@ -152,22 +126,107 @@ (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ break; \ default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ break; \ } \ } \ } while(0) -#endif /* (STM32L031xx) || (STM32L041xx) || (STM32L011xx) || defined (STM32L021xx) */ -/** @brief Reports the USART mask to apply to retrieve the received data +#elif defined(STM32L071xx) || defined (STM32L081xx) || defined(STM32L072xx) || defined (STM32L082xx) || defined(STM32L073xx) || defined (STM32L083xx) + +#define USART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART4) \ + { \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + } \ + else if((__HANDLE__)->Instance == USART5) \ + { \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + } \ + } while(0) + +#else + +#define USART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_SYSCLK: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + } while(0) + +#endif + +/** @brief Compute the USART mask to apply to retrieve the received data * according to the word length and to the parity bits activation. - * If PCE = 1, the parity bit is not included in the data extracted + * @note If PCE = 1, the parity bit is not included in the data extracted * by the reception API(). * This masking operation is not carried out in the case of - * DMA transfers. - * @param __HANDLE__: specifies the USART Handle - * @retval mask to apply to USART RDR register value. - */ -#define USART_MASK_COMPUTATION(__HANDLE__) \ + * DMA transfers. + * @param __HANDLE__: specifies the USART Handle. + * @retval None, the mask to apply to USART RDR register is stored in (__HANDLE__)->Mask field. + */ +#define USART_MASK_COMPUTATION(__HANDLE__) \ do { \ if ((__HANDLE__)->Init.WordLength == USART_WORDLENGTH_9B) \ { \ @@ -204,25 +263,30 @@ } \ } while(0) + +/** + * @brief Ensure that USART frame length is valid. + * @param __LENGTH__: USART frame length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_USART_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == USART_WORDLENGTH_7B) || \ + ((__LENGTH__) == USART_WORDLENGTH_8B) || \ + ((__LENGTH__) == USART_WORDLENGTH_9B)) + /** * @} - */ + */ /* Exported functions --------------------------------------------------------*/ -/* Initialization/de-initialization methods **********************************/ -/* IO operation methods *******************************************************/ -/* Peripheral Control methods ************************************************/ -/* Peripheral State methods **************************************************/ - /** * @} - */ + */ /** * @} - */ - + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_wwdg.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_wwdg.c index 3a8a20b333..77d6ad4c66 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_wwdg.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_wwdg.c @@ -2,64 +2,93 @@ ****************************************************************************** * @file stm32l0xx_hal_wwdg.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief WWDG HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Window Watchdog (WWDG) peripheral: - * + Initialization and de-initialization functions + * + Initialization and Configuration function * + IO operation functions - * + Peripheral State functions @verbatim ============================================================================== ##### WWDG specific features ##### ============================================================================== - [..] + [..] Once enabled the WWDG generates a system reset on expiry of a programmed - time period, unless the program refreshes the counter (downcounter) - before reaching 0x3F value (i.e. a reset is generated when the counter - value rolls over from 0x40 to 0x3F). + time period, unless the program refreshes the counter (T[6;0] downcounter) + before reaching 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 @32 MHz(PCLK1): ~128.0 us / ~65.54 ms + (+) 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 informs when a WWDG reset has + occurred (check available with __HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST)). + + (+) The WWDG downcounter input clock is derived from the APB clock divided + by a programmable prescaler. + + (+) WWDG downcounter clock (Hz) = PCLK1 / (4096 * Prescaler) + + (+) WWDG timeout (ms) = (1000 * (T[5;0] + 1)) / (WWDG downcounter clock) + where T[5;0] are the lowest 6 bits of downcounter. + + (+) WWDG Counter refresh is allowed between the following limits : + (++) min time (ms) = (1000 * (T[5;0] - Window)) / (WWDG downcounter clock) + (++) max time (ms) = (1000 * (T[5;0] - 0x40)) / (WWDG downcounter clock) + + (+) Min-max timeout value @32 MHz(PCLK1): ~128.0 us / ~65.54 ms + + (+) The Early Wakeup Interrupt (EWI) can be used if specific safety + operations or data logging must be performed before the actual reset is + generated. When the downcounter reaches the value 0x40, an EWI interrupt + is generated and the corresponding interrupt service routine (ISR) can + be used to trigger specific actions (such as communications or data + logging), before resetting the device. + In some applications, the EWI interrupt can be used to manage a software + system check and/or system recovery/graceful degradation, without + generating a WWDG reset. In this case, the corresponding interrupt + service routine (ISR) should reload the WWDG counter to avoid the WWDG + reset, then trigger the required actions. + Note:When the EWI interrupt cannot be served, e.g. due to a system lock + in a higher priority task, the WWDG reset will eventually be generated. + + (+) Debug mode : When the microcontroller enters debug mode (core halted), + the WWDG counter either continues to work normally or stops, depending + on DBG_WWDG_STOP configuration bit in DBG module, accessible through + __HAL_DBGMCU_FREEZE_WWDG() and __HAL_DBGMCU_UNFREEZE_WWDG() macros ##### How to use this driver ##### ============================================================================== [..] (+) Enable WWDG APB1 clock using __HAL_RCC_WWDG_CLK_ENABLE(). - (+) Set the WWDG prescaler, refresh window and counter value - using HAL_WWDG_Init() function. - (+) Start the WWDG using HAL_WWDG_Start() 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 (EWI) which is - generated when the counter reaches 0x40, and then start the WWDG using - HAL_WWDG_Start_IT(). - Once enabled, EWI 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 + + (+) Set the WWDG prescaler, refresh window, counter value and Early Wakeup + Interrupt mode using using HAL_WWDG_Init() function. + This enables WWDG peripheral and the downcounter starts downcounting + from given counter value. + Init function can be called again to modify all watchdog parameters, + however if EWI mode has been set once, it can't be clear until next + reset. + + (+) The application program must refresh the WWDG counter at regular + intervals during normal operation to prevent an MCU reset using HAL_WWDG_Refresh() function. This operation must occur only when - the counter is lower than the refresh window value already programmed. - + the counter is lower than the window value already programmed. + + (+) if Early Wakeup Interrupt mode is enable an interrupt is generated when + the counter reaches 0x40. User can add his own code in weak function + HAL_WWDG_EarlyWakeupCallback(). + *** WWDG HAL driver macros list *** ================================== [..] Below the list of most used macros in WWDG HAL driver. - - (+) __HAL_WWDG_ENABLE: Enable the WWDG peripheral - (+) __HAL_WWDG_GET_FLAG: Get the selected WWDG's flag status - (+) __HAL_WWDG_CLEAR_FLAG: Clear the WWDG's pending flags - (+) __HAL_WWDG_ENABLE_IT: Enables the WWDG early wakeup interrupt + + (+) __HAL_WWDG_GET_IT_SOURCE: Check the selected WWDG's interrupt source. + (+) __HAL_WWDG_GET_FLAG: Get the selected WWDG's flag status. + (+) __HAL_WWDG_CLEAR_FLAG: Clear the WWDG's pending flags. @endverbatim ****************************************************************************** @@ -100,46 +129,48 @@ */ #ifdef HAL_WWDG_MODULE_ENABLED - -/** @addtogroup WWDG +/** @defgroup WWDG WWDG * @brief WWDG HAL module driver. * @{ */ +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ -/** @addtogroup WWDG_Exported_Functions WWDG Exported Functions +/** @defgroup WWDG_Exported_Functions WWDG Exported Functions * @{ */ -/** @addtogroup WWDG_Exported_Functions_Group1 +/** @defgroup WWDG_Exported_Functions_Group1 Initialization and Configuration functions * @brief Initialization and Configuration functions. * @verbatim ============================================================================== - ##### Initialization and de-initialization functions ##### + ##### Initialization and Configuration functions ##### ============================================================================== [..] This section provides functions allowing to: - (+) Initialize the WWDG according to the specified parameters - in the WWDG_InitTypeDef and create the associated handle - (+) DeInitialize the WWDG peripheral - (+) Initialize the WWDG MSP - (+) DeInitialize the WWDG MSP + (+) Initialize and start the WWDG according to the specified parameters + in the WWDG_InitTypeDef of associated handle. + (+) Initialize the WWDG MSP. @endverbatim * @{ */ /** - * @brief Initializes the WWDG according to the specified - * parameters in the WWDG_InitTypeDef and creates the associated handle. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. + * @brief Initialize the WWDG according to the specified. + * parameters in the WWDG_InitTypeDef of associated handle. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. * @retval HAL status */ HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg) { - /* Check the WWDG handle allocation */ if(hwwdg == NULL) { @@ -151,67 +182,29 @@ HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg) assert_param(IS_WWDG_PRESCALER(hwwdg->Init.Prescaler)); assert_param(IS_WWDG_WINDOW(hwwdg->Init.Window)); assert_param(IS_WWDG_COUNTER(hwwdg->Init.Counter)); - - if(hwwdg->State == HAL_WWDG_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - hwwdg->Lock = HAL_UNLOCKED; + assert_param(IS_WWDG_EWI_MODE(hwwdg->Init.EWIMode)); - /* Init the low level hardware */ - HAL_WWDG_MspInit(hwwdg); - } + /* Init the low level hardware */ + HAL_WWDG_MspInit(hwwdg); - /* Take lock and change peripheral state */ - __HAL_LOCK(hwwdg); - hwwdg->State = HAL_WWDG_STATE_BUSY; + /* Set WWDG Counter */ + WRITE_REG(hwwdg->Instance->CR, (WWDG_CR_WDGA | hwwdg->Init.Counter)); - /* Set WWDG Prescaler and Window and Counter*/ - MODIFY_REG(hwwdg->Instance->CFR, (WWDG_CFR_WDGTB | WWDG_CFR_W), (hwwdg->Init.Prescaler | hwwdg->Init.Window)); - MODIFY_REG(hwwdg->Instance->CR, WWDG_CR_T, hwwdg->Init.Counter); - - /* Change peripheral state and release lock*/ - hwwdg->State = HAL_WWDG_STATE_READY; - __HAL_UNLOCK(hwwdg); + /* Set WWDG Prescaler and Window */ + WRITE_REG(hwwdg->Instance->CFR, (hwwdg->Init.EWIMode | hwwdg->Init.Prescaler | hwwdg->Init.Window)); /* Return function status */ return HAL_OK; } -/** - * @brief DeInitializes the WWDG peripheral. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_WWDG_DeInit(WWDG_HandleTypeDef *hwwdg) -{ - /* Check the parameters */ - assert_param(IS_WWDG_ALL_INSTANCE(hwwdg->Instance)); - - /* Take lock and change peripheral state */ - __HAL_LOCK(hwwdg); - hwwdg->State = HAL_WWDG_STATE_BUSY; - - /* DeInit the low level hardware */ - HAL_WWDG_MspDeInit(hwwdg); - - /* Reset WWDG Control, configuration and status register */ - MODIFY_REG(hwwdg->Instance->CR, (WWDG_CR_T | WWDG_CR_WDGA),0x0000007FU); - MODIFY_REG(hwwdg->Instance->CFR, (WWDG_CFR_WDGTB | WWDG_CFR_W | WWDG_CFR_EWI),0x0000007FU); - MODIFY_REG(hwwdg->Instance->SR,WWDG_SR_EWIF,0x0U); - - /* Change peripheral state and release lock*/ - hwwdg->State = HAL_WWDG_STATE_RESET; - __HAL_UNLOCK(hwwdg); - - /* Return function status */ - return HAL_OK; -} /** - * @brief Initializes the WWDG MSP. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. + * @brief Initialize the WWDG MSP. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @note When rewriting this function in user file, mechanism may be added + * to avoid multiple initialize when HAL_WWDG_Init function is called + * again to change parameters. * @retval None */ __weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg) @@ -219,128 +212,58 @@ __weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg) /* Prevent unused argument(s) compilation warning */ UNUSED(hwwdg); - /* NOTE: This function Should not be modified, when the callback is needed, + /* NOTE: This function should not be modified, when the callback is needed, the HAL_WWDG_MspInit could be implemented in the user file */ } -/** - * @brief DeInitializes the WWDG MSP. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. - * @retval None - */ -__weak void HAL_WWDG_MspDeInit(WWDG_HandleTypeDef *hwwdg) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hwwdg); - - /* NOTE: This function Should not be modified, when the callback is needed, - the HAL_WWDG_MspDeInit could be implemented in the user file - */ -} - /** * @} */ -/** @addtogroup WWDG_Exported_Functions_Group2 +/** @defgroup WWDG_Exported_Functions_Group2 IO operation functions * @brief IO operation functions * @verbatim ============================================================================== ##### IO operation functions ##### ============================================================================== - [..] + [..] This section provides functions allowing to: - (+) Start the WWDG. - (+) Refresh the WWDG. - (+) Handle WWDG interrupt request. + (+) Refresh the WWDG. + (+) Handle WWDG interrupt request and associated function callback. @endverbatim * @{ */ /** - * @brief Starts the WWDG. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. + * @brief Refresh the WWDG. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. * @retval HAL status */ -HAL_StatusTypeDef HAL_WWDG_Start(WWDG_HandleTypeDef *hwwdg) +HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg) { - /* Take lock and change peripheral state */ - __HAL_LOCK(hwwdg); - hwwdg->State = HAL_WWDG_STATE_BUSY; - - /* Enable the peripheral */ - __HAL_WWDG_ENABLE(hwwdg); - - /* Change peripheral state and release lock*/ - hwwdg->State = HAL_WWDG_STATE_READY; - __HAL_UNLOCK(hwwdg); - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Starts the WWDG with interrupt enabled. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_WWDG_Start_IT(WWDG_HandleTypeDef *hwwdg) -{ - /* Take lock and change peripheral state */ - __HAL_LOCK(hwwdg); - hwwdg->State = HAL_WWDG_STATE_BUSY; - - /* Enable the Early Wakeup Interrupt */ - __HAL_WWDG_ENABLE_IT(hwwdg,WWDG_IT_EWI); - - /* Enable the peripheral */ - __HAL_WWDG_ENABLE(hwwdg); - - /* Change peripheral state and release lock*/ - hwwdg->State = HAL_WWDG_STATE_READY; - __HAL_UNLOCK(hwwdg); - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Refreshes the WWDG. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. - * @param Counter: value of counter to put in WWDG counter - * @retval HAL status - */ -HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg, uint32_t Counter) -{ - - /* Check the parameters */ - assert_param(IS_WWDG_COUNTER(Counter)); - /* Write to WWDG CR the WWDG Counter value to refresh with */ - MODIFY_REG(hwwdg->Instance->CR, (uint32_t)WWDG_CR_T, Counter); - + WRITE_REG(hwwdg->Instance->CR, (hwwdg->Init.Counter)); + /* Return function status */ return HAL_OK; } /** - * @brief Handles WWDG interrupt request. + * @brief Handle WWDG interrupt request. * @note The Early Wakeup Interrupt (EWI) can be used if specific safety operations * or data logging must be performed before the actual reset is generated. - * The EWI interrupt is enabled using __HAL_WWDG_ENABLE_IT() macro. + * The EWI interrupt is enabled by calling HAL_WWDG_Init function with + * EWIMode set to WWDG_EWI_ENABLE. * When the downcounter reaches the value 0x40, and EWI interrupt is * generated and the corresponding Interrupt Service Routine (ISR) can * be used to trigger specific actions (such as communications or data * logging), before resetting the device. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. * @retval None */ void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) @@ -351,61 +274,32 @@ void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) /* Check if WWDG Early Wakeup Interrupt occurred */ if(__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET) { - /* Early Wakeup callback */ - HAL_WWDG_WakeupCallback(hwwdg); + /* Clear the WWDG Early Wakeup flag */ + __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF); - /* Clear the WWDG Data Ready flag */ - __HAL_WWDG_CLEAR_IT(hwwdg, WWDG_FLAG_EWIF); + /* Early Wakeup callback */ + HAL_WWDG_EarlyWakeupCallback(hwwdg); } } } + /** - * @brief Early Wakeup WWDG callback. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. + * @brief WWDG Early Wakeup callback. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. * @retval None */ -__weak void HAL_WWDG_WakeupCallback(WWDG_HandleTypeDef* hwwdg) +__weak void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg) { /* Prevent unused argument(s) compilation warning */ UNUSED(hwwdg); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_WWDG_EarlyWakeupCallback could be implemented in the user file + */ } -/** - * @} - */ - -/** @addtogroup WWDG_Exported_Functions_Group3 - * @brief Peripheral State functions. - * -@verbatim - ============================================================================== - ##### Peripheral State functions ##### - ============================================================================== - [..] - This subsection permits to get in run-time the status of the peripheral - and the data flow. - -@endverbatim - * @{ - */ - -/** - * @brief Returns the WWDG state. - * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains - * the configuration information for the specified WWDG module. - * @retval HAL state - */ -HAL_WWDG_StateTypeDef HAL_WWDG_GetState(WWDG_HandleTypeDef *hwwdg) -{ - return hwwdg->State; -} - -/** - * @} - */ - /** * @} */ @@ -415,10 +309,12 @@ HAL_WWDG_StateTypeDef HAL_WWDG_GetState(WWDG_HandleTypeDef *hwwdg) */ #endif /* HAL_WWDG_MODULE_ENABLED */ +/** + * @} + */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_wwdg.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_wwdg.h index 34f1d10599..89819260d8 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_wwdg.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_wwdg.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_hal_wwdg.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of WWDG HAL module. ****************************************************************************** * @attention @@ -50,7 +48,7 @@ * @{ */ -/** @defgroup WWDG WWDG (Window watchdog) +/** @addtogroup WWDG * @{ */ @@ -60,50 +58,25 @@ * @{ */ -/** @defgroup WWDG_State WWDG state definition - * @{ - */ -/** - * @brief WWDG HAL State Structure definition - */ -typedef enum -{ - HAL_WWDG_STATE_RESET = 0x00U, /*!< WWDG not yet initialized or disabled */ - HAL_WWDG_STATE_READY = 0x01U, /*!< WWDG initialized and ready for use */ - HAL_WWDG_STATE_BUSY = 0x02U, /*!< WWDG internal process is ongoing */ - HAL_WWDG_STATE_TIMEOUT = 0x03U, /*!< WWDG timeout state */ - HAL_WWDG_STATE_ERROR = 0x04U /*!< WWDG error state */ -}HAL_WWDG_StateTypeDef; - -/** - * @} - */ - -/** @defgroup WWDG_Init WWDG init configuration structure - * @{ - */ /** - * @brief WWDG Init configuration structure + * @brief WWDG Init structure definition */ typedef struct { - uint32_t Prescaler; /*!< Specifies the prescaler value of the WWDG. - This parameter can be a value of @ref WWDG_Prescaler */ + uint32_t Prescaler; /*!< Specifies the prescaler value of the WWDG. + This parameter can be a value of @ref WWDG_Prescaler */ - uint32_t Window; /*!< Specifies the WWDG window value to be compared to the downcounter. - This parameter must be a number lower than Max_Data = 0x80 */ + uint32_t Window; /*!< Specifies the WWDG window value to be compared to the downcounter. + This parameter must be a number Min_Data = 0x40 and Max_Data = 0x7F */ - uint32_t Counter; /*!< Specifies the WWDG free-running downcounter value. - This parameter must be a number between Min_Data = 0x40 and Max_Data = 0x7F */ + uint32_t Counter; /*!< Specifies the WWDG free-running downcounter value. + This parameter must be a number between Min_Data = 0x40 and Max_Data = 0x7F */ + + uint32_t EWIMode ; /*!< Specifies if WWDG Early Wakeup Interupt is enable or not. + This parameter can be a value of @ref WWDG_EWI_Mode */ }WWDG_InitTypeDef; -/** - * @} - */ -/** @defgroup WWDG_handle WWDG handler - * @{ - */ /** * @brief WWDG handle Structure definition */ @@ -113,16 +86,7 @@ typedef struct WWDG_InitTypeDef Init; /*!< WWDG required parameters */ - HAL_LockTypeDef Lock; /*!< WWDG locking object */ - - __IO HAL_WWDG_StateTypeDef State; /*!< WWDG communication state */ - }WWDG_HandleTypeDef; - -/** - * @} - */ - /** * @} */ @@ -133,23 +97,10 @@ typedef struct * @{ */ -/** @defgroup WWDG_BitAddress_AliasRegion WWDG BitAddress AliasRegion - * @brief WWDG registers bit address in the alias region - * @{ - */ - -/* --- CFR Register ---*/ -/* Alias word address of EWI bit */ -#define WWDG_CFR_BASE (uint32_t)(WWDG_BASE + 0x04U) - -/** - * @} - */ - /** @defgroup WWDG_Interrupt_definition WWDG Interrupt definition * @{ */ -#define WWDG_IT_EWI ((uint32_t)WWDG_CFR_EWI) +#define WWDG_IT_EWI WWDG_CFR_EWI /*!< Early wakeup interrupt */ /** * @} */ @@ -158,7 +109,7 @@ typedef struct * @brief WWDG Flag definition * @{ */ -#define WWDG_FLAG_EWIF ((uint32_t)WWDG_SR_EWIF) /*!< Early wakeup interrupt flag */ +#define WWDG_FLAG_EWIF WWDG_SR_EWIF /*!< Early wakeup interrupt flag */ /** * @} */ @@ -166,122 +117,115 @@ typedef struct /** @defgroup WWDG_Prescaler WWDG Prescaler * @{ */ -#define WWDG_PRESCALER_1 ((uint32_t)0x00000000U) /*!< WWDG counter clock = (PCLK1/4096)/1 */ -#define WWDG_PRESCALER_2 ((uint32_t)WWDG_CFR_WDGTB0) /*!< WWDG counter clock = (PCLK1/4096)/2 */ -#define WWDG_PRESCALER_4 ((uint32_t)WWDG_CFR_WDGTB1) /*!< WWDG counter clock = (PCLK1/4096)/4 */ -#define WWDG_PRESCALER_8 ((uint32_t)WWDG_CFR_WDGTB) /*!< WWDG counter clock = (PCLK1/4096)/8 */ +#define WWDG_PRESCALER_1 0x00000000U /*!< WWDG counter clock = (PCLK1/4096)/1 */ +#define WWDG_PRESCALER_2 WWDG_CFR_WDGTB_0 /*!< WWDG counter clock = (PCLK1/4096)/2 */ +#define WWDG_PRESCALER_4 WWDG_CFR_WDGTB_1 /*!< WWDG counter clock = (PCLK1/4096)/4 */ +#define WWDG_PRESCALER_8 WWDG_CFR_WDGTB /*!< WWDG counter clock = (PCLK1/4096)/8 */ /** * @} */ -#define IS_WWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == WWDG_PRESCALER_1) || \ - ((__PRESCALER__) == WWDG_PRESCALER_2) || \ - ((__PRESCALER__) == WWDG_PRESCALER_4) || \ - ((__PRESCALER__) == WWDG_PRESCALER_8)) - - -/* Check for window */ -#define IS_WWDG_WINDOW(__WINDOW__) ((__WINDOW__) <= 0x7FU) - -/* Check for counter */ -#define IS_WWDG_COUNTER(__COUNTER__) (((__COUNTER__) >= 0x40U) && ((__COUNTER__) <= 0x7FU)) +/** @defgroup WWDG_EWI_Mode WWDG Early Wakeup Interrupt Mode + * @{ + */ +#define WWDG_EWI_DISABLE 0x00000000U /*!< EWI Disable */ +#define WWDG_EWI_ENABLE WWDG_CFR_EWI /*!< EWI Enable */ +/** + * @} + */ /** * @} */ -/* Exported macro ------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup WWDG_Private_Macros WWDG Private Macros + * @{ + */ +#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(__WINDOW__) (((__WINDOW__) >= WWDG_CFR_W_6) && ((__WINDOW__) <= WWDG_CFR_W)) + +#define IS_WWDG_COUNTER(__COUNTER__) (((__COUNTER__) >= WWDG_CR_T_6) && ((__COUNTER__) <= WWDG_CR_T)) + +#define IS_WWDG_EWI_MODE(__MODE__) (((__MODE__) == WWDG_EWI_ENABLE) || \ + ((__MODE__) == WWDG_EWI_DISABLE)) +/** + * @} + */ + + +/* Exported macros ------------------------------------------------------------*/ /** @defgroup WWDG_Exported_Macros WWDG Exported Macros * @{ */ -/** @brief Reset WWDG handle state - * @param __HANDLE__: WWDG handle +/** + * @brief Enable the WWDG peripheral. + * @param __HANDLE__ WWDG handle * @retval None */ -#define __HAL_WWDG_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_WWDG_STATE_RESET) +#define __HAL_WWDG_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, WWDG_CR_WDGA) /** - * @brief Enables the WWDG peripheral. + * @brief Enable the WWDG early wakeup interrupt. * @param __HANDLE__: WWDG handle - * @retval None - */ -#define __HAL_WWDG_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, WWDG_CR_WDGA) - -/** - * @brief Disables the WWDG peripheral. - * @param __HANDLE__: WWDG handle - * @note WARNING: This is a dummy macro for HAL code alignment. - * Once enable, WWDG Peripheral cannot be disabled except by a system reset. - * @retval None - */ -#define __HAL_WWDG_DISABLE(__HANDLE__) /* dummy macro */ - -/** - * @brief Enables the WWDG early wakeup interrupt. - * @param __HANDLE__: WWDG handle - * @param __INTERRUPT__: specifies the interrupt to enable. + * @param __INTERRUPT__ specifies the interrupt to enable. * This parameter can be one of the following values: * @arg WWDG_IT_EWI: Early wakeup interrupt * @note Once enabled this interrupt cannot be disabled except by a system reset. * @retval None */ -#define __HAL_WWDG_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CFR |= (__INTERRUPT__)) -/** - * @brief Disables the WWDG early wakeup interrupt. - * @param __HANDLE__: WWDG handle: - * @param __INTERRUPT__: specifies the interrupt to disable. - * @arg WWDG_IT_EWI: Early wakeup interrupt - * @note WARNING: This is a dummy macro for HAL code alignment. - * Once enabled this interrupt cannot be disabled except by a system reset. - * @retval None - */ -#define __HAL_WWDG_DISABLE_IT(__HANDLE__, __INTERRUPT__) /* dummy macro */ +#define __HAL_WWDG_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CFR, (__INTERRUPT__)) /** - * @brief Gets the selected WWDG's it status. - * @param __HANDLE__: WWDG handle - * @param __INTERRUPT__: specifies the it to check. + * @brief Check whether the selected WWDG interrupt has occurred or not. + * @param __HANDLE__ WWDG handle + * @param __INTERRUPT__ specifies the it to check. * This parameter can be one of the following values: * @arg WWDG_FLAG_EWIF: Early wakeup interrupt IT * @retval The new state of WWDG_FLAG (SET or RESET). */ -#define __HAL_WWDG_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->SR & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __HAL_WWDG_GET_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_GET_FLAG((__HANDLE__),(__INTERRUPT__)) -/** @brief Clear the WWDG's interrupt pending bits +/** @brief Clear the WWDG interrupt pending bits. * bits to clear the selected interrupt pending bits. - * @param __HANDLE__: WWDG handle - * @param __INTERRUPT__: specifies the interrupt pending bit to clear. + * @param __HANDLE__ WWDG handle + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. * This parameter can be one of the following values: * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag */ -#define __HAL_WWDG_CLEAR_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_CLEAR_FLAG((__HANDLE__), (__INTERRUPT__)) +#define __HAL_WWDG_CLEAR_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_CLEAR_FLAG((__HANDLE__), (__INTERRUPT__)) /** - * @brief Gets the selected WWDG's flag status. - * @param __HANDLE__: WWDG handle - * @param __FLAG__: specifies the flag to check. + * @brief Check whether the specified WWDG flag is set or not. + * @param __HANDLE__ WWDG handle + * @param __FLAG__ specifies the flag to check. * This parameter can be one of the following values: * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag * @retval The new state of WWDG_FLAG (SET or RESET). */ -#define __HAL_WWDG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) +#define __HAL_WWDG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) /** - * @brief Clears the WWDG's pending flags. - * @param __HANDLE__: WWDG handle - * @param __FLAG__: specifies the flag to clear. + * @brief Clear the WWDG's pending flags. + * @param __HANDLE__ WWDG handle + * @param __FLAG__ specifies the flag to clear. * This parameter can be one of the following values: * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag * @retval None */ -#define __HAL_WWDG_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = ~(__FLAG__)) +#define __HAL_WWDG_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) -/** @brief Checks if the specified WWDG interrupt source is enabled or disabled. - * @param __HANDLE__: WWDG Handle. - * @param __INTERRUPT__: specifies the WWDG interrupt source to check. - * This parameter can be one of the following values: +/** @brief Check whether the specified WWDG interrupt source is enabled or not. + * @param __HANDLE__ WWDG Handle. + * @param __INTERRUPT__ specifies the WWDG interrupt source to check. + * This parameter can be one of the following values: * @arg WWDG_IT_EWI: Early Wakeup Interrupt * @retval state of __INTERRUPT__ (TRUE or FALSE). */ @@ -291,38 +235,29 @@ typedef struct * @} */ +/* Exported functions --------------------------------------------------------*/ -/** @defgroup WWDG_Exported_Functions WWDG Exported Functions +/** @addtogroup WWDG_Exported_Functions * @{ */ -/** @defgroup WWDG_Exported_Functions_Group1 Initialization and de-initialization functions +/** @addtogroup WWDG_Exported_Functions_Group1 * @{ */ -HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg); -HAL_StatusTypeDef HAL_WWDG_DeInit(WWDG_HandleTypeDef *hwwdg); -void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg); -void HAL_WWDG_MspDeInit(WWDG_HandleTypeDef *hwwdg); -void HAL_WWDG_WakeupCallback(WWDG_HandleTypeDef* hwwdg); +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg); /** * @} */ -/** @defgroup WWDG_Exported_Functions_Group2 IO operation functions +/** @addtogroup WWDG_Exported_Functions_Group2 * @{ */ -HAL_StatusTypeDef HAL_WWDG_Start(WWDG_HandleTypeDef *hwwdg); -HAL_StatusTypeDef HAL_WWDG_Start_IT(WWDG_HandleTypeDef *hwwdg); -HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg, uint32_t Counter); -void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg); -/** - * @} - */ - -/** @defgroup WWDG_Exported_Functions_Group3 Peripheral State functions - * @{ - */ -HAL_WWDG_StateTypeDef HAL_WWDG_GetState(WWDG_HandleTypeDef *hwwdg); +/* I/O operation functions ******************************************************/ +HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg); /** * @} */ @@ -346,4 +281,3 @@ HAL_WWDG_StateTypeDef HAL_WWDG_GetState(WWDG_HandleTypeDef *hwwdg); #endif /* __STM32L0xx_HAL_WWDG_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_adc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_adc.c index 8db0c2bc98..966a5f2eca 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_adc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_adc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_adc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief ADC LL module driver ****************************************************************************** * @attention @@ -215,7 +213,7 @@ ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON) /* Force reset of ADC clock (core clock) */ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_ADC1); - + /* Release reset of ADC clock (core clock) */ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_ADC1); @@ -385,10 +383,10 @@ ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx) /* Reset register CFGR1 */ CLEAR_BIT(ADCx->CFGR1, - ( ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | ADC_CFGR1_DISCEN - | ADC_CFGR1_AUTOFF | ADC_CFGR1_WAIT | ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD - | ADC_CFGR1_EXTEN | ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN | ADC_CFGR1_RES - | ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN ) + ( ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | ADC_CFGR1_DISCEN + | ADC_CFGR1_AUTOFF | ADC_CFGR1_WAIT | ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD + | ADC_CFGR1_EXTEN | ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN | ADC_CFGR1_RES + | ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN ) ); /* Reset register CFGR2 */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_adc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_adc.h index 1b388d2f3a..05fc80c492 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_adc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_adc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_adc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of ADC LL module. ****************************************************************************** * @attention @@ -211,9 +209,14 @@ extern "C" { #define VREFINT_CAL_ADDR ((uint16_t*) ((uint32_t)0x1FF80078U)) /* Internal voltage reference, address of parameter VREFINT_CAL: VrefInt ADC raw data acquired at temperature 30 DegC (tolerance: +-5 DegC), Vref+ = 3.0 V (tolerance: +-10 mV). */ #define VREFINT_CAL_VREF ((uint32_t) 3000U) /* Analog voltage reference (Vref+) value with which temperature sensor has been calibrated in production (tolerance: +-10 mV) (unit: mV). */ /* Temperature sensor */ +/* Note: On device STM32L011, calibration parameter TS_CAL1 is not available. */ +#if !defined(STM32L011xx) #define TEMPSENSOR_CAL1_ADDR ((uint16_t*) ((uint32_t)0x1FF8007AU)) /* Internal temperature sensor, address of parameter TS_CAL1: On STM32L0, temperature sensor ADC raw data acquired at temperature 30 DegC (tolerance: +-5 DegC), Vref+ = 3.0 V (tolerance: +-10 mV). */ +#endif #define TEMPSENSOR_CAL2_ADDR ((uint16_t*) ((uint32_t)0x1FF8007EU)) /* Internal temperature sensor, address of parameter TS_CAL2: On STM32L0, temperature sensor ADC raw data acquired at temperature 130 DegC (tolerance: +-5 DegC), Vref+ = 3.0 V (tolerance: +-10 mV). */ +#if !defined(STM32L011xx) #define TEMPSENSOR_CAL1_TEMP (( int32_t) 30) /* Internal temperature sensor, temperature at which temperature sensor has been calibrated in production for data into TEMPSENSOR_CAL1_ADDR (tolerance: +-5 DegC) (unit: DegC). */ +#endif #define TEMPSENSOR_CAL2_TEMP (( int32_t) 130) /* Internal temperature sensor, temperature at which temperature sensor has been calibrated in production for data into TEMPSENSOR_CAL2_ADDR (tolerance: +-5 DegC) (unit: DegC). */ #define TEMPSENSOR_CAL_VREFANALOG ((uint32_t) 3000U) /* Analog voltage reference (Vref+) voltage with which temperature sensor has been calibrated in production (+-10 mV) (unit: mV). */ @@ -492,7 +495,7 @@ typedef struct /** @defgroup ADC_LL_EC_LP_MODE ADC instance - Low power mode * @{ */ -#define LL_ADC_LP_MODE_NONE ((uint32_t)0x00000000U) /*!< No ADC low power mode activated */ +#define LL_ADC_LP_MODE_NONE ((uint32_t)0x00000000U) /*!< No ADC low power mode activated */ #define LL_ADC_LP_AUTOWAIT (ADC_CFGR1_WAIT) /*!< ADC low power mode auto delay: Dynamic low power mode, ADC conversions are performed only when necessary (when previous ADC conversion data is read). See description with function @ref LL_ADC_SetLowPowerMode(). */ #define LL_ADC_LP_AUTOPOWEROFF (ADC_CFGR1_AUTOFF) /*!< ADC low power mode auto power-off: the ADC automatically powers-off after a ADC conversion and automatically wakes up when a new ADC conversion is triggered (with startup time between trigger and start of sampling). See description with function @ref LL_ADC_SetLowPowerMode(). */ #define LL_ADC_LP_AUTOWAIT_AUTOPOWEROFF (ADC_CFGR1_WAIT | ADC_CFGR1_AUTOFF) /*!< ADC low power modes auto wait and auto power-off combined. See description with function @ref LL_ADC_SetLowPowerMode(). */ @@ -550,7 +553,7 @@ typedef struct #define LL_ADC_REG_TRIG_EXT_TIM22_TRGO (ADC_CFGR1_EXTSEL_2 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM22 TRGO. Trigger edge set to rising edge (default setting). */ #define LL_ADC_REG_TRIG_EXT_TIM2_CH3 (ADC_CFGR1_EXTSEL_2 | ADC_CFGR1_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM2 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ #define LL_ADC_REG_TRIG_EXT_TIM3_TRGO (ADC_CFGR1_EXTSEL_2 | ADC_CFGR1_EXTSEL_1 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: TIM3 TRG0. Trigger edge set to rising edge (default setting). */ -#define LL_ADC_REG_TRIG_EXT_EXTI_LINE11 (ADC_CFGR1_EXTSEL_2 | ADC_CFGR1_EXTSEL_1 | ADC_CFGR1_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger external interrupt line 11. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_EXTI_LINE11 (ADC_CFGR1_EXTSEL_2 | ADC_CFGR1_EXTSEL_1 | ADC_CFGR1_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from external IP: external interrupt line 11. Trigger edge set to rising edge (default setting). */ /** * @} */ @@ -615,13 +618,13 @@ typedef struct * @{ */ #define LL_ADC_SAMPLINGTIME_1CYCLE_5 ((uint32_t)0x00000000U) /*!< Sampling time 1.5 ADC clock cycle */ -#define LL_ADC_SAMPLINGTIME_7CYCLES_5 (ADC_SMPR_SMP_0) /*!< Sampling time 7.5 ADC clock cycles */ -#define LL_ADC_SAMPLINGTIME_13CYCLES_5 (ADC_SMPR_SMP_1) /*!< Sampling time 13.5 ADC clock cycles */ -#define LL_ADC_SAMPLINGTIME_28CYCLES_5 (ADC_SMPR_SMP_1 | ADC_SMPR_SMP_0) /*!< Sampling time 28.5 ADC clock cycles */ -#define LL_ADC_SAMPLINGTIME_41CYCLES_5 (ADC_SMPR_SMP_2) /*!< Sampling time 41.5 ADC clock cycles */ -#define LL_ADC_SAMPLINGTIME_55CYCLES_5 (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_0) /*!< Sampling time 55.5 ADC clock cycles */ -#define LL_ADC_SAMPLINGTIME_71CYCLES_5 (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1) /*!< Sampling time 71.5 ADC clock cycles */ -#define LL_ADC_SAMPLINGTIME_239CYCLES_5 (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_0) /*!< Sampling time 239.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_3CYCLES_5 (ADC_SMPR_SMP_0) /*!< Sampling time 3.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_7CYCLES_5 (ADC_SMPR_SMP_1) /*!< Sampling time 7.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_12CYCLES_5 (ADC_SMPR_SMP_1 | ADC_SMPR_SMP_0) /*!< Sampling time 12.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_19CYCLES_5 (ADC_SMPR_SMP_2) /*!< Sampling time 19.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_39CYCLES_5 (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_0) /*!< Sampling time 39.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_79CYCLES_5 (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1) /*!< Sampling time 79.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_160CYCLES_5 (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_0) /*!< Sampling time 160.5 ADC clock cycles */ /** * @} */ @@ -1072,8 +1075,8 @@ typedef struct * @arg @ref LL_ADC_CHANNEL_VLCD (1) * * (1) On STM32L0, parameter not available on all devices: only on STM32L053xx, STM32L063xx, STM32L073xx, STM32L083xx. - * @retval - 0 if the channel corresponds to a parameter definition of a ADC external channel (channel connected to a GPIO pin) - * - 1 if the channel corresponds to a parameter definition of a ADC internal channel + * @retval Value "0" if the channel corresponds to a parameter definition of a ADC external channel (channel connected to a GPIO pin). + * Value "1" if the channel corresponds to a parameter definition of a ADC internal channel. */ #define __LL_ADC_IS_CHANNEL_INTERNAL(__CHANNEL__) \ (((__CHANNEL__) & ADC_CHANNEL_ID_INTERNAL_CH_MASK) != 0U) @@ -1161,8 +1164,8 @@ typedef struct * * (1) On STM32L0, parameter not available on all devices: only on STM32L053xx, STM32L063xx, STM32L073xx, STM32L083xx. - * @retval - 0 if the internal channel selected is not available on the ADC instance selected. - * - 1 if the internal channel selected is available on the ADC instance selected. + * @retval Value "0" if the internal channel selected is not available on the ADC instance selected. + * Value "1" if the internal channel selected is available on the ADC instance selected. */ #if defined(ADC_CCR_VLCDEN) #define __LL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE(__ADC_INSTANCE__, __CHANNEL__) \ @@ -1342,10 +1345,10 @@ typedef struct * with devices featuring several ADC common instances). * @param __ADCXY_COMMON__ ADC common instance * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) - * @retval - 0 All ADC instances sharing the same ADC common instance - * are disabled. - * - 1 At least one ADC instance sharing the same ADC common instance - * is enabled + * @retval Value "0" if all ADC instances sharing the same ADC common instance + * are disabled. + * Value "1" if at least one ADC instance sharing the same ADC common instance + * is enabled. */ #define __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) \ LL_ADC_IsEnabled(ADC1) @@ -1446,6 +1449,10 @@ typedef struct LL_ADC_RESOLUTION_12B) \ ) +/* Note: On device STM32L011, calibration parameter TS_CAL1 is not available. */ +/* Therefore, helper macro __LL_ADC_CALC_TEMPERATURE() is not available.*/ +/* Use helper macro @ref __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(). */ +#if !defined(STM32L011xx) /** * @brief Helper macro to calculate the temperature (unit: degree Celsius) * from ADC conversion data of internal temperature sensor. @@ -1504,6 +1511,7 @@ typedef struct ) / (int32_t)((int32_t)*TEMPSENSOR_CAL2_ADDR - (int32_t)*TEMPSENSOR_CAL1_ADDR) \ ) + TEMPSENSOR_CAL1_TEMP \ ) +#endif /** * @brief Helper macro to calculate the temperature (unit: degree Celsius) @@ -1711,7 +1719,6 @@ __STATIC_INLINE uint32_t LL_ADC_GetCommonClock(ADC_Common_TypeDef *ADCxy_COMMON) __STATIC_INLINE void LL_ADC_SetCommonFrequencyMode(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t Resolution) { MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_LFMEN, Resolution); - } /** @@ -2110,13 +2117,13 @@ __STATIC_INLINE uint32_t LL_ADC_GetLowPowerMode(ADC_TypeDef *ADCx) * @param ADCx ADC instance * @param SamplingTime This parameter can be one of the following values: * @arg @ref LL_ADC_SAMPLINGTIME_1CYCLE_5 + * @arg @ref LL_ADC_SAMPLINGTIME_3CYCLES_5 * @arg @ref LL_ADC_SAMPLINGTIME_7CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_13CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_28CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_41CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_55CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_71CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_239CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_12CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_19CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_39CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_79CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_160CYCLES_5 * @retval None */ __STATIC_INLINE void LL_ADC_SetSamplingTimeCommonChannels(ADC_TypeDef *ADCx, uint32_t SamplingTime) @@ -2137,13 +2144,13 @@ __STATIC_INLINE void LL_ADC_SetSamplingTimeCommonChannels(ADC_TypeDef *ADCx, uin * @param ADCx ADC instance * @retval Returned value can be one of the following values: * @arg @ref LL_ADC_SAMPLINGTIME_1CYCLE_5 + * @arg @ref LL_ADC_SAMPLINGTIME_3CYCLES_5 * @arg @ref LL_ADC_SAMPLINGTIME_7CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_13CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_28CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_41CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_55CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_71CYCLES_5 - * @arg @ref LL_ADC_SAMPLINGTIME_239CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_12CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_19CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_39CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_79CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_160CYCLES_5 */ __STATIC_INLINE uint32_t LL_ADC_GetSamplingTimeCommonChannels(ADC_TypeDef *ADCx) { @@ -2248,8 +2255,8 @@ __STATIC_INLINE uint32_t LL_ADC_REG_GetTriggerSource(ADC_TypeDef *ADCx) * use function @ref LL_ADC_REG_GetTriggerSource(). * @rmtoll CFGR1 EXTEN LL_ADC_REG_IsTriggerSourceSWStart * @param ADCx ADC instance - * @retval - 0 trigger source external trigger - * - 1 trigger source SW start. + * @retval Value "0" if trigger source external trigger + * Value "1" if trigger source SW start. */ __STATIC_INLINE uint32_t LL_ADC_REG_IsTriggerSourceSWStart(ADC_TypeDef *ADCx) { @@ -3254,7 +3261,7 @@ __STATIC_INLINE uint32_t LL_ADC_GetOverSamplingShift(ADC_TypeDef *ADCx) * @note On this STM32 serie, there are three possibilities to enable * the voltage regulator: * - by enabling it manually - * using this function (@ref LL_ADC_EnableInternalRegulator() ). + * using function @ref LL_ADC_EnableInternalRegulator(). * - by launching a calibration * using function @ref LL_ADC_StartCalibration(). * - by enabling the ADC @@ -3262,7 +3269,7 @@ __STATIC_INLINE uint32_t LL_ADC_GetOverSamplingShift(ADC_TypeDef *ADCx) * @note On this STM32 serie, after ADC internal voltage regulator enable, * a delay for ADC internal voltage regulator stabilization * is required before performing a ADC calibration or ADC enable. - * Refer to device datasheet, parameter tUP_LDO. + * Refer to device datasheet, parameter "tUP_LDO". * Refer to literal @ref LL_ADC_DELAY_INTERNAL_REGUL_STAB_US. * @note On this STM32 serie, setting of this feature is conditioned to * ADC state: @@ -3443,7 +3450,8 @@ __STATIC_INLINE uint32_t LL_ADC_IsCalibrationOnGoing(ADC_TypeDef *ADCx) * @note On this STM32 serie, setting of this feature is conditioned to * ADC state: * ADC must be enabled without conversion on going on group regular, - * without conversion stop command on going on group regular. + * without conversion stop command on going on group regular, + * without ADC disable command on going. * @rmtoll CR ADSTART LL_ADC_REG_StartConversion * @param ADCx ADC instance * @retval None diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_bus.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_bus.h index 3fcb91c777..dada43c348 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_bus.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_bus.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_bus.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of BUS LL module. @verbatim diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_comp.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_comp.c index 9b5dbd643d..4777f01fc3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_comp.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_comp.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_comp.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief COMP LL module driver ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_comp.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_comp.h index d7643d4801..89fbd87b9e 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_comp.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_comp.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_comp.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of COMP LL module. ****************************************************************************** * @attention @@ -285,7 +283,7 @@ typedef struct /** * @brief Set window mode of a pair of comparators instances * (2 consecutive COMP instances odd and even COMP and COMP). - * @rmtoll COMP1_CSR COMP1WM LL_COMP_SetCommonWindowMode + * @rmtoll COMP1_CSR COMP1WM LL_COMP_SetCommonWindowMode * @param COMPxy_COMMON Comparator common instance * (can be set directly from CMSIS definition or by using helper macro @ref __LL_COMP_COMMON_INSTANCE() ) * @param WindowMode This parameter can be one of the following values: @@ -301,7 +299,7 @@ __STATIC_INLINE void LL_COMP_SetCommonWindowMode(COMP_Common_TypeDef *COMPxy_COM /** * @brief Get window mode of a pair of comparators instances * (2 consecutive COMP instances odd and even COMP and COMP). - * @rmtoll COMP1_CSR COMP1WM LL_COMP_GetCommonWindowMode + * @rmtoll COMP1_CSR COMP1WM LL_COMP_GetCommonWindowMode * @param COMPxy_COMMON Comparator common instance * (can be set directly from CMSIS definition or by using helper macro @ref __LL_COMP_COMMON_INSTANCE() ) * @retval Returned value can be one of the following values: @@ -323,7 +321,7 @@ __STATIC_INLINE uint32_t LL_COMP_GetCommonWindowMode(COMP_Common_TypeDef *COMPxy /** * @brief Set comparator instance operating mode to adjust power and speed. - * @rmtoll COMP2_CSR COMP2SPEED LL_COMP_SetPowerMode + * @rmtoll COMP2_CSR COMP2SPEED LL_COMP_SetPowerMode * @param COMPx Comparator instance * @param PowerMode This parameter can be one of the following values: * @arg @ref LL_COMP_POWERMODE_MEDIUMSPEED (1) @@ -340,7 +338,7 @@ __STATIC_INLINE void LL_COMP_SetPowerMode(COMP_TypeDef *COMPx, uint32_t PowerMod /** * @brief Get comparator instance operating mode to adjust power and speed. * @note Available only on COMP instance: COMP2. - * @rmtoll COMP2_CSR COMP2SPEED LL_COMP_GetPowerMode\n + * @rmtoll COMP2_CSR COMP2SPEED LL_COMP_GetPowerMode\n * @param COMPx Comparator instance * @retval Returned value can be one of the following values: * @arg @ref LL_COMP_POWERMODE_MEDIUMSPEED (1) @@ -372,8 +370,8 @@ __STATIC_INLINE uint32_t LL_COMP_GetPowerMode(COMP_TypeDef *COMPx) * of VrefInt): scaler bridge is based on VrefInt and requires * to enable path from VrefInt (refer to literal * SYSCFG_CFGR3_ENBUFLP_VREFINT_COMP). - * @rmtoll COMP2_CSR COMP2INNSEL LL_COMP_ConfigInputs\n - * COMP2_CSR COMP2INPSEL LL_COMP_ConfigInputs + * @rmtoll COMP2_CSR COMP2INNSEL LL_COMP_ConfigInputs\n + * COMP2_CSR COMP2INPSEL LL_COMP_ConfigInputs * @param COMPx Comparator instance * @param InputMinus This parameter can be one of the following values: * @arg @ref LL_COMP_INPUT_MINUS_VREFINT @@ -407,7 +405,7 @@ __STATIC_INLINE void LL_COMP_ConfigInputs(COMP_TypeDef *COMPx, uint32_t InputMin * @brief Set comparator input plus (non-inverting). * @note Only COMP2 allows to set the input plus (non-inverting). * For COMP1 it is always PA1 IO, except when Windows Mode is selected. - * @rmtoll COMP2_CSR COMP2INPSEL LL_COMP_SetInputPlus + * @rmtoll COMP2_CSR COMP2INPSEL LL_COMP_SetInputPlus * @param COMPx Comparator instance * @param InputPlus This parameter can be one of the following values: * @arg @ref LL_COMP_INPUT_PLUS_IO1 (1) @@ -430,7 +428,7 @@ __STATIC_INLINE void LL_COMP_SetInputPlus(COMP_TypeDef *COMPx, uint32_t InputPlu * @brief Get comparator input plus (non-inverting). * @note Only COMP2 allows to set the input plus (non-inverting). * For COMP1 it is always PA1 IO, except when Windows Mode is selected. - * @rmtoll COMP2_CSR COMP2INPSEL LL_COMP_GetInputPlus + * @rmtoll COMP2_CSR COMP2INPSEL LL_COMP_GetInputPlus * @param COMPx Comparator instance * @retval Returned value can be one of the following values: * @arg @ref LL_COMP_INPUT_PLUS_IO1 (1) @@ -458,8 +456,8 @@ __STATIC_INLINE uint32_t LL_COMP_GetInputPlus(COMP_TypeDef *COMPx) * of VrefInt): scaler bridge is based on VrefInt and requires * to enable path from VrefInt (refer to literal * SYSCFG_CFGR3_ENBUFLP_VREFINT_COMP). - * @rmtoll COMP1_CSR COMP1INNSEL LL_COMP_SetInputMinus\n - * COMP2_CSR COMP2INNSEL LL_COMP_SetInputMinus + * @rmtoll COMP1_CSR COMP1INNSEL LL_COMP_SetInputMinus\n + * COMP2_CSR COMP2INNSEL LL_COMP_SetInputMinus * @param COMPx Comparator instance * @param InputMinus This parameter can be one of the following values: * @arg @ref LL_COMP_INPUT_MINUS_VREFINT @@ -484,8 +482,8 @@ __STATIC_INLINE void LL_COMP_SetInputMinus(COMP_TypeDef *COMPx, uint32_t InputMi * @note In case of comparator input selected to be connected to IO: * GPIO pins are specific to each comparator instance. * Refer to description of parameters or to reference manual. - * @rmtoll COMP1_CSR COMP1INNSEL LL_COMP_GetInputMinus\n - * COMP2_CSR COMP2INNSEL LL_COMP_GetInputMinus + * @rmtoll COMP1_CSR COMP1INNSEL LL_COMP_GetInputMinus\n + * COMP2_CSR COMP2INNSEL LL_COMP_GetInputMinus * @param COMPx Comparator instance * @retval Returned value can be one of the following values: * @arg @ref LL_COMP_INPUT_MINUS_VREFINT @@ -514,9 +512,9 @@ __STATIC_INLINE uint32_t LL_COMP_GetInputMinus(COMP_TypeDef *COMPx) /** * @brief Set comparator output LPTIM. - * @rmtoll COMP1_CSR COMP1LPTIMIN1 LL_COMP_SetOutputLPTIM\n - * COMP2_CSR COMP2LPTIMIN1 LL_COMP_SetOutputLPTIM\n - * COMP2_CSR COMP2LPTIMIN2 LL_COMP_SetOutputLPTIM + * @rmtoll COMP1_CSR COMP1LPTIMIN1 LL_COMP_SetOutputLPTIM\n + * COMP2_CSR COMP2LPTIMIN1 LL_COMP_SetOutputLPTIM\n + * COMP2_CSR COMP2LPTIMIN2 LL_COMP_SetOutputLPTIM * @param COMPx Comparator instance * @param OutputLptim This parameter can be one of the following values: * @arg @ref LL_COMP_OUTPUT_LPTIM1_IN1_COMP1 (*) @@ -534,9 +532,9 @@ __STATIC_INLINE void LL_COMP_SetOutputLPTIM(COMP_TypeDef *COMPx, uint32_t Output /** * @brief Get comparator output LPTIM. - * @rmtoll COMP1_CSR COMP1LPTIMIN1 LL_COMP_GetOutputLPTIM\n - * COMP2_CSR COMP2LPTIMIN1 LL_COMP_GetOutputLPTIM\n - * COMP2_CSR COMP2LPTIMIN2 LL_COMP_GetOutputLPTIM + * @rmtoll COMP1_CSR COMP1LPTIMIN1 LL_COMP_GetOutputLPTIM\n + * COMP2_CSR COMP2LPTIMIN1 LL_COMP_GetOutputLPTIM\n + * COMP2_CSR COMP2LPTIMIN2 LL_COMP_GetOutputLPTIM * @param COMPx Comparator instance * @retval Returned value can be one of the following values: * @arg @ref LL_COMP_OUTPUT_LPTIM1_IN1_COMP1 (*) @@ -591,8 +589,8 @@ __STATIC_INLINE uint32_t LL_COMP_GetOutputPolarity(COMP_TypeDef *COMPx) * @note After enable from off state, comparator requires a delay * to reach reach propagation delay specification. * Refer to device datasheet, parameter "tSTART". - * @rmtoll COMP1_CSR COMP1EN LL_COMP_Enable\n - * COMP2_CSR COMP2EN LL_COMP_Enable + * @rmtoll COMP1_CSR COMP1EN LL_COMP_Enable\n + * COMP2_CSR COMP2EN LL_COMP_Enable * @param COMPx Comparator instance * @retval None */ @@ -603,8 +601,8 @@ __STATIC_INLINE void LL_COMP_Enable(COMP_TypeDef *COMPx) /** * @brief Disable comparator instance. - * @rmtoll COMP1_CSR COMP1EN LL_COMP_Disable\n - * COMP2_CSR COMP2EN LL_COMP_Disable + * @rmtoll COMP1_CSR COMP1EN LL_COMP_Disable\n + * COMP2_CSR COMP2EN LL_COMP_Disable * @param COMPx Comparator instance * @retval None */ @@ -616,8 +614,8 @@ __STATIC_INLINE void LL_COMP_Disable(COMP_TypeDef *COMPx) /** * @brief Get comparator enable state * (0: COMP is disabled, 1: COMP is enabled) - * @rmtoll COMP1_CSR COMP1EN LL_COMP_IsEnabled\n - * COMP2_CSR COMP2EN LL_COMP_IsEnabled + * @rmtoll COMP1_CSR COMP1EN LL_COMP_IsEnabled\n + * COMP2_CSR COMP2EN LL_COMP_IsEnabled * @param COMPx Comparator instance * @retval State of bit (1 or 0). */ @@ -630,8 +628,8 @@ __STATIC_INLINE uint32_t LL_COMP_IsEnabled(COMP_TypeDef *COMPx) * @brief Lock comparator instance. * @note Once locked, comparator configuration can be accessed in read-only. * @note The only way to unlock the comparator is a device hardware reset. - * @rmtoll COMP1_CSR COMP1LOCK LL_COMP_Lock\n - * COMP2_CSR COMP2LOCK LL_COMP_Lock + * @rmtoll COMP1_CSR COMP1LOCK LL_COMP_Lock\n + * COMP2_CSR COMP2LOCK LL_COMP_Lock * @param COMPx Comparator instance * @retval None */ @@ -645,8 +643,8 @@ __STATIC_INLINE void LL_COMP_Lock(COMP_TypeDef *COMPx) * (0: COMP is unlocked, 1: COMP is locked). * @note Once locked, comparator configuration can be accessed in read-only. * @note The only way to unlock the comparator is a device hardware reset. - * @rmtoll COMP1_CSR COMP1LOCK LL_COMP_IsLocked\n - * COMP2_CSR COMP2LOCK LL_COMP_IsLocked + * @rmtoll COMP1_CSR COMP1LOCK LL_COMP_IsLocked\n + * COMP2_CSR COMP2LOCK LL_COMP_IsLocked * @param COMPx Comparator instance * @retval State of bit (1 or 0). */ @@ -669,8 +667,8 @@ __STATIC_INLINE uint32_t LL_COMP_IsLocked(COMP_TypeDef *COMPx) * is at a lower voltage than the input minus * - Comparator output is low when the input plus * is at a higher voltage than the input minus - * @rmtoll COMP1_CSR COMP1VALUE LL_COMP_ReadOutputLevel\n - * COMP2_CSR COMP2VALUE LL_COMP_ReadOutputLevel + * @rmtoll COMP1_CSR COMP1VALUE LL_COMP_ReadOutputLevel\n + * COMP2_CSR COMP2VALUE LL_COMP_ReadOutputLevel * @param COMPx Comparator instance * @retval Returned value can be one of the following values: * @arg @ref LL_COMP_OUTPUT_LEVEL_LOW diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_cortex.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_cortex.h index b1fe6d4572..1303255403 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_cortex.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_cortex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_cortex.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of CORTEX LL module. @verbatim ============================================================================== diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crc.c index 991d29f44e..3baa92ff5b 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_crc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CRC LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crc.h index e0a404511c..e57fd67f84 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_crc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of CRC LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crs.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crs.c index f7696d679e..0a9f9b9378 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crs.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crs.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_crs.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CRS LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crs.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crs.h index 7d39c809ce..5706e8299b 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crs.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_crs.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_crs.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of CRS LL module. ****************************************************************************** * @attention @@ -65,10 +63,9 @@ extern "C" { */ /* Defines used for the bit position in the register and perform offsets*/ -#define CRS_POSITION_TRIM (uint32_t)8U /* bit position in CR reg */ -#define CRS_POSITION_FECAP (uint32_t)16U /* bit position in ISR reg */ -#define CRS_POSITION_RELOAD (uint32_t)0U /* bit position in CFGR reg */ -#define CRS_POSITION_FELIM (uint32_t)16U /* bit position in CFGR reg */ +#define CRS_POSITION_TRIM (CRS_CR_TRIM_Pos) /* bit position in CR reg */ +#define CRS_POSITION_FECAP (CRS_ISR_FECAP_Pos) /* bit position in ISR reg */ +#define CRS_POSITION_FELIM (CRS_CFGR_FELIM_Pos) /* bit position in CFGR reg */ /** diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dac.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dac.c index c5d7637783..9e75d9184a 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dac.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dac.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_dac.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief DAC LL module driver ****************************************************************************** * @attention @@ -40,7 +38,7 @@ #include "stm32l0xx_ll_dac.h" #include "stm32l0xx_ll_bus.h" -#ifdef USE_FULL_ASSERT +#ifdef USE_FULL_ASSERT #include "stm32_assert.h" #else #define assert_param(expr) ((void)0U) @@ -175,7 +173,7 @@ ErrorStatus LL_DAC_DeInit(DAC_TypeDef *DACx) * @arg @ref LL_DAC_CHANNEL_1 * @arg @ref LL_DAC_CHANNEL_2 (1) * - * (1) On this STM32 family, parameter not available on all devices. + * (1) On this STM32 serie, parameter not available on all devices. * Refer to device datasheet for channels availability. * @param DAC_InitStruct Pointer to a @ref LL_DAC_InitTypeDef structure * @retval An ErrorStatus enumeration value: diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dac.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dac.h index 989c4233ee..90fbb07972 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dac.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dac.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_dac.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of DAC LL module. ****************************************************************************** * @attention @@ -70,8 +68,8 @@ extern "C" { /* - channel bits position into register SWTRIG */ /* - channel register offset of data holding register DHRx */ /* - channel register offset of data output register DORx */ -#define DAC_CR_CH1_BITOFFSET ((uint32_t) 0U) /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 1 */ -#define DAC_CR_CH2_BITOFFSET ((uint32_t)16U) /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 2 */ +#define DAC_CR_CH1_BITOFFSET 0U /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 1 */ +#define DAC_CR_CH2_BITOFFSET 16U /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 2 */ #define DAC_CR_CHX_BITOFFSET_MASK (DAC_CR_CH1_BITOFFSET | DAC_CR_CH2_BITOFFSET) #define DAC_SWTR_CH1 (DAC_SWTRIGR_SWTRIG1) /* Channel bit into register SWTRIGR of channel 1. This bit is into area of LL_DAC_CR_CHx_BITOFFSET but excluded by mask DAC_CR_CHX_BITOFFSET_MASK (done to be enable to trig SW start of both DAC channels simultaneously). */ @@ -82,43 +80,43 @@ extern "C" { #define DAC_SWTR_CHX_MASK (DAC_SWTR_CH1) #endif /* DAC_CHANNEL2_SUPPORT */ -#define DAC_REG_DHR12R1_REGOFFSET ((uint32_t)0x00000000U) /* Register DHR12Rx channel 1 taken as reference */ -#define DAC_REG_DHR12L1_REGOFFSET ((uint32_t)0x00100000U) /* Register offset of DHR12Lx channel 1 versus DHR12Rx channel 1 (shifted left of 20 bits) */ -#define DAC_REG_DHR8R1_REGOFFSET ((uint32_t)0x02000000U) /* Register offset of DHR8Rx channel 1 versus DHR12Rx channel 1 (shifted left of 24 bits) */ +#define DAC_REG_DHR12R1_REGOFFSET 0x00000000U /* Register DHR12Rx channel 1 taken as reference */ +#define DAC_REG_DHR12L1_REGOFFSET 0x00100000U /* Register offset of DHR12Lx channel 1 versus DHR12Rx channel 1 (shifted left of 20 bits) */ +#define DAC_REG_DHR8R1_REGOFFSET 0x02000000U /* Register offset of DHR8Rx channel 1 versus DHR12Rx channel 1 (shifted left of 24 bits) */ #if defined(DAC_CHANNEL2_SUPPORT) -#define DAC_REG_DHR12R2_REGOFFSET ((uint32_t)0x00030000U) /* Register offset of DHR12Rx channel 2 versus DHR12Rx channel 1 (shifted left of 16 bits) */ -#define DAC_REG_DHR12L2_REGOFFSET ((uint32_t)0x00400000U) /* Register offset of DHR12Lx channel 2 versus DHR12Rx channel 1 (shifted left of 20 bits) */ -#define DAC_REG_DHR8R2_REGOFFSET ((uint32_t)0x05000000U) /* Register offset of DHR8Rx channel 2 versus DHR12Rx channel 1 (shifted left of 24 bits) */ +#define DAC_REG_DHR12R2_REGOFFSET 0x00030000U /* Register offset of DHR12Rx channel 2 versus DHR12Rx channel 1 (shifted left of 16 bits) */ +#define DAC_REG_DHR12L2_REGOFFSET 0x00400000U /* Register offset of DHR12Lx channel 2 versus DHR12Rx channel 1 (shifted left of 20 bits) */ +#define DAC_REG_DHR8R2_REGOFFSET 0x05000000U /* Register offset of DHR8Rx channel 2 versus DHR12Rx channel 1 (shifted left of 24 bits) */ #endif /* DAC_CHANNEL2_SUPPORT */ -#define DAC_REG_DHR12RX_REGOFFSET_MASK ((uint32_t)0x000F0000U) -#define DAC_REG_DHR12LX_REGOFFSET_MASK ((uint32_t)0x00F00000U) -#define DAC_REG_DHR8RX_REGOFFSET_MASK ((uint32_t)0x0F000000U) +#define DAC_REG_DHR12RX_REGOFFSET_MASK 0x000F0000U +#define DAC_REG_DHR12LX_REGOFFSET_MASK 0x00F00000U +#define DAC_REG_DHR8RX_REGOFFSET_MASK 0x0F000000U #define DAC_REG_DHRX_REGOFFSET_MASK (DAC_REG_DHR12RX_REGOFFSET_MASK | DAC_REG_DHR12LX_REGOFFSET_MASK | DAC_REG_DHR8RX_REGOFFSET_MASK) -#define DAC_REG_DOR1_REGOFFSET ((uint32_t)0x00000000U) /* Register DORx channel 1 taken as reference */ +#define DAC_REG_DOR1_REGOFFSET 0x00000000U /* Register DORx channel 1 taken as reference */ #if defined(DAC_CHANNEL2_SUPPORT) -#define DAC_REG_DOR2_REGOFFSET ((uint32_t)0x10000000U)/* Register offset of DORx channel 1 versus DORx channel 2 (shifted left of 28 bits) */ +#define DAC_REG_DOR2_REGOFFSET 0x10000000U /* Register offset of DORx channel 1 versus DORx channel 2 (shifted left of 28 bits) */ #define DAC_REG_DORX_REGOFFSET_MASK (DAC_REG_DOR1_REGOFFSET | DAC_REG_DOR2_REGOFFSET) #else #define DAC_REG_DORX_REGOFFSET_MASK (DAC_REG_DOR1_REGOFFSET) #endif /* DAC_CHANNEL2_SUPPORT */ -#define DAC_REG_REGOFFSET_MASK_POSBIT0 ((uint32_t)0x0000000FU) /* Mask of registers offset (DHR12Rx, DHR12Lx, DHR8Rx, DORx, ...) when shifted to position 0 */ +#define DAC_REG_REGOFFSET_MASK_POSBIT0 0x0000000FU /* Mask of registers offset (DHR12Rx, DHR12Lx, DHR8Rx, DORx, ...) when shifted to position 0 */ -#define DAC_REG_DHR12RX_REGOFFSET_BITOFFSET_POS ((uint32_t)16U) /* Position of bits register offset of DHR12Rx channel 1 or 2 versus DHR12Rx channel 1 (shifted left of 16 bits) */ -#define DAC_REG_DHR12LX_REGOFFSET_BITOFFSET_POS ((uint32_t)20U) /* Position of bits register offset of DHR12Lx channel 1 or 2 versus DHR12Rx channel 1 (shifted left of 20 bits) */ -#define DAC_REG_DHR8RX_REGOFFSET_BITOFFSET_POS ((uint32_t)24U) /* Position of bits register offset of DHR8Rx channel 1 or 2 versus DHR12Rx channel 1 (shifted left of 24 bits) */ -#define DAC_REG_DORX_REGOFFSET_BITOFFSET_POS ((uint32_t)28U) /* Position of bits register offset of DORx channel 1 or 2 versus DORx channel 1 (shifted left of 28 bits) */ +#define DAC_REG_DHR12RX_REGOFFSET_BITOFFSET_POS 16U /* Position of bits register offset of DHR12Rx channel 1 or 2 versus DHR12Rx channel 1 (shifted left of 16 bits) */ +#define DAC_REG_DHR12LX_REGOFFSET_BITOFFSET_POS 20U /* Position of bits register offset of DHR12Lx channel 1 or 2 versus DHR12Rx channel 1 (shifted left of 20 bits) */ +#define DAC_REG_DHR8RX_REGOFFSET_BITOFFSET_POS 24U /* Position of bits register offset of DHR8Rx channel 1 or 2 versus DHR12Rx channel 1 (shifted left of 24 bits) */ +#define DAC_REG_DORX_REGOFFSET_BITOFFSET_POS 28U /* Position of bits register offset of DORx channel 1 or 2 versus DORx channel 1 (shifted left of 28 bits) */ /* DAC registers bits positions */ #if defined(DAC_CHANNEL2_SUPPORT) -#define DAC_DHR12RD_DACC2DHR_BITOFFSET_POS ((uint32_t)16U) /* Value equivalent to POSITION_VAL(DAC_DHR12RD_DACC2DHR) */ -#define DAC_DHR12LD_DACC2DHR_BITOFFSET_POS ((uint32_t)20U) /* Value equivalent to POSITION_VAL(DAC_DHR12LD_DACC2DHR) */ -#define DAC_DHR8RD_DACC2DHR_BITOFFSET_POS ((uint32_t) 8U) /* Value equivalent to POSITION_VAL(DAC_DHR8RD_DACC2DHR) */ +#define DAC_DHR12RD_DACC2DHR_BITOFFSET_POS 16U /* Value equivalent to POSITION_VAL(DAC_DHR12RD_DACC2DHR) */ +#define DAC_DHR12LD_DACC2DHR_BITOFFSET_POS 20U /* Value equivalent to POSITION_VAL(DAC_DHR12LD_DACC2DHR) */ +#define DAC_DHR8RD_DACC2DHR_BITOFFSET_POS 8U /* Value equivalent to POSITION_VAL(DAC_DHR8RD_DACC2DHR) */ #endif /* DAC_CHANNEL2_SUPPORT */ /* Miscellaneous data */ -#define DAC_DIGITAL_SCALE_12BITS ((uint32_t)4095U) /* Full-scale digital value with a resolution of 12 bits (voltage range determined by analog voltage references Vref+ and Vref-, refer to reference manual) */ +#define DAC_DIGITAL_SCALE_12BITS 4095U /* Full-scale digital value with a resolution of 12 bits (voltage range determined by analog voltage references Vref+ and Vref-, refer to reference manual) */ /** * @} @@ -236,7 +234,7 @@ typedef struct #define LL_DAC_TRIG_EXT_TIM2_TRGO (DAC_CR_TSEL1_2 ) /*!< DAC channel conversion trigger from external IP: TIM2 TRGO. */ #define LL_DAC_TRIG_EXT_TIM3_TRGO ( DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM3 TRGO. */ #define LL_DAC_TRIG_EXT_TIM3_CH3 ( DAC_CR_TSEL1_1 ) /*!< DAC channel conversion trigger from external IP: TIM3 CH3 event. */ -#define LL_DAC_TRIG_EXT_TIM6_TRGO ((uint32_t)0x00000000U) /*!< DAC channel conversion trigger from external IP: TIM6 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM6_TRGO 0x00000000U /*!< DAC channel conversion trigger from external IP: TIM6 TRGO. */ #define LL_DAC_TRIG_EXT_TIM7_TRGO (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM7 TRGO. */ #define LL_DAC_TRIG_EXT_TIM21_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM21 TRGO. */ #define LL_DAC_TRIG_EXT_EXTI_LINE9 (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 ) /*!< DAC channel conversion trigger from external IP: external interrupt line 9. */ @@ -247,7 +245,7 @@ typedef struct /** @defgroup DAC_LL_EC_WAVE_AUTO_GENERATION_MODE DAC waveform automatic generation mode * @{ */ -#define LL_DAC_WAVE_AUTO_GENERATION_NONE ((uint32_t)0x00000000U) /*!< DAC channel wave auto generation mode disabled. */ +#define LL_DAC_WAVE_AUTO_GENERATION_NONE 0x00000000U /*!< DAC channel wave auto generation mode disabled. */ #define LL_DAC_WAVE_AUTO_GENERATION_NOISE (DAC_CR_WAVE1_0) /*!< DAC channel wave auto generation mode enabled, set generated noise waveform. */ #define LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE (DAC_CR_WAVE1_1) /*!< DAC channel wave auto generation mode enabled, set generated triangle waveform. */ /** @@ -257,7 +255,7 @@ typedef struct /** @defgroup DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS DAC wave generation - Noise LFSR unmask bits * @{ */ -#define LL_DAC_NOISE_LFSR_UNMASK_BIT0 ((uint32_t)0x00000000U) /*!< Noise wave generation, unmask LFSR bit0, for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BIT0 0x00000000U /*!< Noise wave generation, unmask LFSR bit0, for the selected DAC channel */ #define LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 ( DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[1:0], for the selected DAC channel */ #define LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 ( DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[2:0], for the selected DAC channel */ #define LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[3:0], for the selected DAC channel */ @@ -276,7 +274,7 @@ typedef struct /** @defgroup DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE DAC wave generation - Triangle amplitude * @{ */ -#define LL_DAC_TRIANGLE_AMPLITUDE_1 ((uint32_t)0x00000000U) /*!< Triangle wave generation, amplitude of 1 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_1 0x00000000U /*!< Triangle wave generation, amplitude of 1 LSB of DAC output range, for the selected DAC channel */ #define LL_DAC_TRIANGLE_AMPLITUDE_3 ( DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 3 LSB of DAC output range, for the selected DAC channel */ #define LL_DAC_TRIANGLE_AMPLITUDE_7 ( DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 7 LSB of DAC output range, for the selected DAC channel */ #define LL_DAC_TRIANGLE_AMPLITUDE_15 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 15 LSB of DAC output range, for the selected DAC channel */ @@ -295,7 +293,7 @@ typedef struct /** @defgroup DAC_LL_EC_OUTPUT_BUFFER DAC channel output buffer * @{ */ -#define LL_DAC_OUTPUT_BUFFER_ENABLE ((uint32_t)0x00000000U) /*!< The selected DAC channel output is buffered: higher drive current capability, but also higher current consumption */ +#define LL_DAC_OUTPUT_BUFFER_ENABLE 0x00000000U /*!< The selected DAC channel output is buffered: higher drive current capability, but also higher current consumption */ #define LL_DAC_OUTPUT_BUFFER_DISABLE (DAC_CR_BOFF1) /*!< The selected DAC channel output is not buffered: lower drive current capability, but also lower current consumption */ /** * @} @@ -305,8 +303,8 @@ typedef struct /** @defgroup DAC_LL_EC_RESOLUTION DAC channel output resolution * @{ */ -#define LL_DAC_RESOLUTION_12B ((uint32_t)0x00000000U) /*!< DAC channel resolution 12 bits */ -#define LL_DAC_RESOLUTION_8B ((uint32_t)0x00000002U) /*!< DAC channel resolution 8 bits */ +#define LL_DAC_RESOLUTION_12B 0x00000000U /*!< DAC channel resolution 12 bits */ +#define LL_DAC_RESOLUTION_8B 0x00000002U /*!< DAC channel resolution 8 bits */ /** * @} */ @@ -344,7 +342,7 @@ typedef struct /* Literal set to maximum value (refer to device datasheet, */ /* parameter "tWAKEUP"). */ /* Unit: us */ -#define LL_DAC_DELAY_STARTUP_VOLTAGE_SETTLING_US ((uint32_t) 15U) /*!< Delay for DAC channel voltage settling time from DAC channel startup (transition from disable to enable) */ +#define LL_DAC_DELAY_STARTUP_VOLTAGE_SETTLING_US 15U /*!< Delay for DAC channel voltage settling time from DAC channel startup (transition from disable to enable) */ /* Delay for DAC channel voltage settling time. */ /* Note: DAC channel startup time depends on board application environment: */ @@ -357,7 +355,7 @@ typedef struct /* Literal set to maximum value (refer to device datasheet, */ /* parameter "tSETTLING"). */ /* Unit: us */ -#define LL_DAC_DELAY_VOLTAGE_SETTLING_US ((uint32_t) 12U) /*!< Delay for DAC channel voltage settling time */ +#define LL_DAC_DELAY_VOLTAGE_SETTLING_US 12U /*!< Delay for DAC channel voltage settling time */ /** * @} */ @@ -477,7 +475,7 @@ typedef struct * @retval ADC conversion data equivalent voltage value (unit: mVolt) */ #define __LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) \ - (((uint32_t)0xFFFU) >> ((__DAC_RESOLUTION__) << 1U)) + ((0x00000FFFU) >> ((__DAC_RESOLUTION__) << 1U)) /** * @brief Helper macro to calculate the DAC conversion data (unit: digital diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dma.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dma.c index 1cf459876d..77742c9b86 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dma.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dma.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_dma.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief DMA LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dma.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dma.h index 0b93dfce43..1b42034715 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dma.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_dma.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_dma.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of DMA LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_exti.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_exti.c index 1ef8efc602..c326279189 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_exti.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_exti.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_exti.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief EXTI LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_exti.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_exti.h index bae10d4498..e6a6e7027f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_exti.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_exti.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_exti.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of EXTI LL module. ****************************************************************************** * @attention @@ -122,7 +120,9 @@ typedef struct #define LL_EXTI_LINE_16 EXTI_IMR_IM16 /*!< Extended line 16 */ #endif #define LL_EXTI_LINE_17 EXTI_IMR_IM17 /*!< Extended line 17 */ +#if defined(EXTI_IMR_IM18) #define LL_EXTI_LINE_18 EXTI_IMR_IM18 /*!< Extended line 18 */ +#endif #define LL_EXTI_LINE_19 EXTI_IMR_IM19 /*!< Extended line 19 */ #if defined(EXTI_IMR_IM20) #define LL_EXTI_LINE_20 EXTI_IMR_IM20 /*!< Extended line 20 */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_gpio.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_gpio.c index 40e1e43827..1819911ad0 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_gpio.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_gpio.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_gpio.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief GPIO LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_gpio.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_gpio.h index a1591d01e6..dca7307bb5 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_gpio.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_gpio.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_gpio.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of GPIO LL module. ****************************************************************************** * @attention @@ -184,7 +182,6 @@ typedef struct #define LL_GPIO_SPEED_FAST LL_GPIO_SPEED_FREQ_HIGH #define LL_GPIO_SPEED_HIGH LL_GPIO_SPEED_FREQ_VERY_HIGH - /** @defgroup GPIO_LL_EC_PULL Pull Up Pull Down * @{ */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_i2c.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_i2c.c index 5920bb3774..c17c264e85 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_i2c.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_i2c.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief I2C LL module driver. ****************************************************************************** * @attention @@ -73,7 +71,7 @@ #define IS_LL_I2C_DIGITAL_FILTER(__VALUE__) ((__VALUE__) <= 0x0000000FU) -#define IS_LL_I2C_OWN_ADDRESS1(__VALUE__) ((__VALUE__) <= (uint32_t)0x000003FFU) +#define IS_LL_I2C_OWN_ADDRESS1(__VALUE__) ((__VALUE__) <= 0x000003FFU) #define IS_LL_I2C_TYPE_ACKNOWLEDGE(__VALUE__) (((__VALUE__) == LL_I2C_ACK) || \ ((__VALUE__) == LL_I2C_NACK)) @@ -194,7 +192,12 @@ uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct) */ LL_I2C_DisableOwnAddress1(I2Cx); LL_I2C_SetOwnAddress1(I2Cx, I2C_InitStruct->OwnAddress1, I2C_InitStruct->OwnAddrSize); - LL_I2C_EnableOwnAddress1(I2Cx); + + /* OwnAdress1 == 0 is reserved for General Call address */ + if (I2C_InitStruct->OwnAddress1 != 0U) + { + LL_I2C_EnableOwnAddress1(I2Cx); + } /*---------------------------- I2Cx MODE Configuration ----------------------- * Configure I2Cx peripheral mode with parameter : diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_i2c.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_i2c.h index 1031f782e9..ad6e46624b 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_i2c.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_i2c.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_i2c.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of I2C LL module. ****************************************************************************** * @attention @@ -63,16 +61,6 @@ extern "C" { /** @defgroup I2C_LL_Private_Constants I2C Private Constants * @{ */ -/* Defines used for the bit position in the register and perform offsets */ -#define I2C_POSITION_CR1_DNF (uint32_t)8U -#define I2C_POSITION_CR2_NBYTES (uint32_t)16U -#define I2C_POSITION_TIMINGR_PRESC (uint32_t)28U -#define I2C_POSITION_TIMINGR_SCLDEL (uint32_t)20U -#define I2C_POSITION_TIMINGR_SDADEL (uint32_t)16U -#define I2C_POSITION_TIMINGR_SCLH (uint32_t)8U -#define I2C_POSITION_TIMINGR_SCLL (uint32_t)0U -#define I2C_POSITION_ISR_ADDCODE (uint32_t)17U -#define I2C_POSITION_TIMEOUTR_TIMEOUTB (uint32_t)16U /** * @} */ @@ -198,9 +186,9 @@ typedef struct /** @defgroup I2C_LL_EC_PERIPHERAL_MODE Peripheral Mode * @{ */ -#define LL_I2C_MODE_I2C ((uint32_t)0x00000000U) /*!< I2C Master or Slave mode */ +#define LL_I2C_MODE_I2C 0x00000000U /*!< I2C Master or Slave mode */ #define LL_I2C_MODE_SMBUS_HOST I2C_CR1_SMBHEN /*!< SMBus Host address acknowledge */ -#define LL_I2C_MODE_SMBUS_DEVICE ((uint32_t)0x00000000U) /*!< SMBus Device default mode (Default address not acknowledge) */ +#define LL_I2C_MODE_SMBUS_DEVICE 0x00000000U /*!< SMBus Device default mode (Default address not acknowledge) */ #define LL_I2C_MODE_SMBUS_DEVICE_ARP I2C_CR1_SMBDEN /*!< SMBus Device Default address acknowledge */ /** * @} @@ -209,7 +197,7 @@ typedef struct /** @defgroup I2C_LL_EC_ANALOGFILTER_SELECTION Analog Filter Selection * @{ */ -#define LL_I2C_ANALOGFILTER_ENABLE ((uint32_t)0x00000000U) /*!< Analog filter is enabled. */ +#define LL_I2C_ANALOGFILTER_ENABLE 0x00000000U /*!< Analog filter is enabled. */ #define LL_I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF /*!< Analog filter is disabled. */ /** * @} @@ -218,7 +206,7 @@ typedef struct /** @defgroup I2C_LL_EC_ADDRESSING_MODE Master Addressing Mode * @{ */ -#define LL_I2C_ADDRESSING_MODE_7BIT ((uint32_t) 0x00000000U) /*!< Master operates in 7-bit addressing mode. */ +#define LL_I2C_ADDRESSING_MODE_7BIT 0x00000000U /*!< Master operates in 7-bit addressing mode. */ #define LL_I2C_ADDRESSING_MODE_10BIT I2C_CR2_ADD10 /*!< Master operates in 10-bit addressing mode.*/ /** * @} @@ -227,7 +215,7 @@ typedef struct /** @defgroup I2C_LL_EC_OWNADDRESS1 Own Address 1 Length * @{ */ -#define LL_I2C_OWNADDRESS1_7BIT ((uint32_t)0x00000000U) /*!< Own address 1 is a 7-bit address. */ +#define LL_I2C_OWNADDRESS1_7BIT 0x00000000U /*!< Own address 1 is a 7-bit address. */ #define LL_I2C_OWNADDRESS1_10BIT I2C_OAR1_OA1MODE /*!< Own address 1 is a 10-bit address.*/ /** * @} @@ -251,7 +239,7 @@ typedef struct /** @defgroup I2C_LL_EC_I2C_ACKNOWLEDGE Acknowledge Generation * @{ */ -#define LL_I2C_ACK ((uint32_t) 0x00000000U) /*!< ACK is sent after current received byte. */ +#define LL_I2C_ACK 0x00000000U /*!< ACK is sent after current received byte. */ #define LL_I2C_NACK I2C_CR2_NACK /*!< NACK is sent after current received byte.*/ /** * @} @@ -260,7 +248,7 @@ typedef struct /** @defgroup I2C_LL_EC_ADDRSLAVE Slave Address Length * @{ */ -#define LL_I2C_ADDRSLAVE_7BIT ((uint32_t)0x00000000U) /*!< Slave Address in 7-bit. */ +#define LL_I2C_ADDRSLAVE_7BIT 0x00000000U /*!< Slave Address in 7-bit. */ #define LL_I2C_ADDRSLAVE_10BIT I2C_CR2_ADD10 /*!< Slave Address in 10-bit.*/ /** * @} @@ -269,7 +257,7 @@ typedef struct /** @defgroup I2C_LL_EC_REQUEST Transfer Request Direction * @{ */ -#define LL_I2C_REQUEST_WRITE ((uint32_t)0x00000000U) /*!< Master request a write transfer. */ +#define LL_I2C_REQUEST_WRITE 0x00000000U /*!< Master request a write transfer. */ #define LL_I2C_REQUEST_READ I2C_CR2_RD_WRN /*!< Master request a read transfer. */ /** * @} @@ -280,7 +268,7 @@ typedef struct */ #define LL_I2C_MODE_RELOAD I2C_CR2_RELOAD /*!< Enable I2C Reload mode. */ #define LL_I2C_MODE_AUTOEND I2C_CR2_AUTOEND /*!< Enable I2C Automatic end mode with no HW PEC comparison. */ -#define LL_I2C_MODE_SOFTEND ((uint32_t)0x00000000U) /*!< Enable I2C Software end mode with no HW PEC comparison. */ +#define LL_I2C_MODE_SOFTEND 0x00000000U /*!< Enable I2C Software end mode with no HW PEC comparison. */ #define LL_I2C_MODE_SMBUS_RELOAD LL_I2C_MODE_RELOAD /*!< Enable SMBUS Automatic end mode with HW PEC comparison. */ #define LL_I2C_MODE_SMBUS_AUTOEND_NO_PEC LL_I2C_MODE_AUTOEND /*!< Enable SMBUS Automatic end mode with HW PEC comparison. */ #define LL_I2C_MODE_SMBUS_SOFTEND_NO_PEC LL_I2C_MODE_SOFTEND /*!< Enable SMBUS Software end mode with HW PEC comparison. */ @@ -293,14 +281,14 @@ typedef struct /** @defgroup I2C_LL_EC_GENERATE Start And Stop Generation * @{ */ -#define LL_I2C_GENERATE_NOSTARTSTOP ((uint32_t)0x00000000U) /*!< Don't Generate Stop and Start condition. */ -#define LL_I2C_GENERATE_STOP I2C_CR2_STOP /*!< Generate Stop condition (Size should be set to 0). */ -#define LL_I2C_GENERATE_START_READ (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN) /*!< Generate Start for read request. */ -#define LL_I2C_GENERATE_START_WRITE I2C_CR2_START /*!< Generate Start for write request. */ -#define LL_I2C_GENERATE_RESTART_7BIT_READ (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN) /*!< Generate Restart for read request, slave 7Bit address. */ -#define LL_I2C_GENERATE_RESTART_7BIT_WRITE I2C_CR2_START /*!< Generate Restart for write request, slave 7Bit address. */ -#define LL_I2C_GENERATE_RESTART_10BIT_READ (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN | I2C_CR2_HEAD10R) /*!< Generate Restart for read request, slave 10Bit address. */ -#define LL_I2C_GENERATE_RESTART_10BIT_WRITE I2C_CR2_START /*!< Generate Restart for write request, slave 10Bit address.*/ +#define LL_I2C_GENERATE_NOSTARTSTOP 0x00000000U /*!< Don't Generate Stop and Start condition. */ +#define LL_I2C_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP) /*!< Generate Stop condition (Size should be set to 0). */ +#define LL_I2C_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) /*!< Generate Start for read request. */ +#define LL_I2C_GENERATE_START_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) /*!< Generate Start for write request. */ +#define LL_I2C_GENERATE_RESTART_7BIT_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) /*!< Generate Restart for read request, slave 7Bit address. */ +#define LL_I2C_GENERATE_RESTART_7BIT_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) /*!< Generate Restart for write request, slave 7Bit address. */ +#define LL_I2C_GENERATE_RESTART_10BIT_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN | I2C_CR2_HEAD10R) /*!< Generate Restart for read request, slave 10Bit address. */ +#define LL_I2C_GENERATE_RESTART_10BIT_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) /*!< Generate Restart for write request, slave 10Bit address.*/ /** * @} */ @@ -308,7 +296,7 @@ typedef struct /** @defgroup I2C_LL_EC_DIRECTION Read Write Direction * @{ */ -#define LL_I2C_DIRECTION_WRITE ((uint32_t)0x00000000U) /*!< Write transfer request by master, slave enters receiver mode. */ +#define LL_I2C_DIRECTION_WRITE 0x00000000U /*!< Write transfer request by master, slave enters receiver mode. */ #define LL_I2C_DIRECTION_READ I2C_ISR_DIR /*!< Read transfer request by master, slave enters transmitter mode.*/ /** * @} @@ -317,8 +305,8 @@ typedef struct /** @defgroup I2C_LL_EC_DMA_REG_DATA DMA Register Data * @{ */ -#define LL_I2C_DMA_REG_DATA_TRANSMIT ((uint32_t)0x00000000U) /*!< Get address of data register used for transmission */ -#define LL_I2C_DMA_REG_DATA_RECEIVE ((uint32_t)0x00000001U) /*!< Get address of data register used for reception */ +#define LL_I2C_DMA_REG_DATA_TRANSMIT 0x00000000U /*!< Get address of data register used for transmission */ +#define LL_I2C_DMA_REG_DATA_RECEIVE 0x00000001U /*!< Get address of data register used for reception */ /** * @} */ @@ -326,7 +314,7 @@ typedef struct /** @defgroup I2C_LL_EC_SMBUS_TIMEOUTA_MODE SMBus TimeoutA Mode SCL SDA Timeout * @{ */ -#define LL_I2C_SMBUS_TIMEOUTA_MODE_SCL_LOW ((uint32_t) 0x00000000U) /*!< TimeoutA is used to detect SCL low level timeout. */ +#define LL_I2C_SMBUS_TIMEOUTA_MODE_SCL_LOW 0x00000000U /*!< TimeoutA is used to detect SCL low level timeout. */ #define LL_I2C_SMBUS_TIMEOUTA_MODE_SDA_SCL_HIGH I2C_TIMEOUTR_TIDLE /*!< TimeoutA is used to detect both SCL and SDA high level timeout.*/ /** * @} @@ -380,19 +368,19 @@ typedef struct */ /** * @brief Configure the SDA setup, hold time and the SCL high, low period. - * @param __PRESCALER__ This parameter must be a value between 0 and 0xF. - * @param __DATA_SETUP_TIME__ This parameter must be a value between 0 and 0xF. (tscldel = (SCLDEL+1)xtpresc) - * @param __DATA_HOLD_TIME__ This parameter must be a value between 0 and 0xF. (tsdadel = SDADELxtpresc) - * @param __CLOCK_HIGH_PERIOD__ This parameter must be a value between 0 and 0xFF. (tsclh = (SCLH+1)xtpresc) - * @param __CLOCK_LOW_PERIOD__ This parameter must be a value between 0 and 0xFF. (tscll = (SCLL+1)xtpresc) - * @retval Value between 0 and 0xFFFFFFFF + * @param __PRESCALER__ This parameter must be a value between Min_Data=0 and Max_Data=0xF. + * @param __DATA_SETUP_TIME__ This parameter must be a value between Min_Data=0 and Max_Data=0xF. (tscldel = (SCLDEL+1)xtpresc) + * @param __DATA_HOLD_TIME__ This parameter must be a value between Min_Data=0 and Max_Data=0xF. (tsdadel = SDADELxtpresc) + * @param __CLOCK_HIGH_PERIOD__ This parameter must be a value between Min_Data=0 and Max_Data=0xFF. (tsclh = (SCLH+1)xtpresc) + * @param __CLOCK_LOW_PERIOD__ This parameter must be a value between Min_Data=0 and Max_Data=0xFF. (tscll = (SCLL+1)xtpresc) + * @retval Value between Min_Data=0 and Max_Data=0xFFFFFFFF */ #define __LL_I2C_CONVERT_TIMINGS(__PRESCALER__, __DATA_SETUP_TIME__, __DATA_HOLD_TIME__, __CLOCK_HIGH_PERIOD__, __CLOCK_LOW_PERIOD__) \ - ((((uint32_t)(__PRESCALER__) << I2C_POSITION_TIMINGR_PRESC) & I2C_TIMINGR_PRESC) | \ - (((uint32_t)(__DATA_SETUP_TIME__) << I2C_POSITION_TIMINGR_SCLDEL) & I2C_TIMINGR_SCLDEL) | \ - (((uint32_t)(__DATA_HOLD_TIME__) << I2C_POSITION_TIMINGR_SDADEL) & I2C_TIMINGR_SDADEL) | \ - (((uint32_t)(__CLOCK_HIGH_PERIOD__) << I2C_POSITION_TIMINGR_SCLH) & I2C_TIMINGR_SCLH) | \ - (((uint32_t)(__CLOCK_LOW_PERIOD__) << I2C_POSITION_TIMINGR_SCLL) & I2C_TIMINGR_SCLL)) + ((((uint32_t)(__PRESCALER__) << I2C_TIMINGR_PRESC_Pos) & I2C_TIMINGR_PRESC) | \ + (((uint32_t)(__DATA_SETUP_TIME__) << I2C_TIMINGR_SCLDEL_Pos) & I2C_TIMINGR_SCLDEL) | \ + (((uint32_t)(__DATA_HOLD_TIME__) << I2C_TIMINGR_SDADEL_Pos) & I2C_TIMINGR_SDADEL) | \ + (((uint32_t)(__CLOCK_HIGH_PERIOD__) << I2C_TIMINGR_SCLH_Pos) & I2C_TIMINGR_SCLH) | \ + (((uint32_t)(__CLOCK_LOW_PERIOD__) << I2C_TIMINGR_SCLL_Pos) & I2C_TIMINGR_SCLL)) /** * @} */ @@ -456,14 +444,14 @@ __STATIC_INLINE uint32_t LL_I2C_IsEnabled(I2C_TypeDef *I2Cx) * @param AnalogFilter This parameter can be one of the following values: * @arg @ref LL_I2C_ANALOGFILTER_ENABLE * @arg @ref LL_I2C_ANALOGFILTER_DISABLE - * @param DigitalFilter This parameter must be a value between 0x00 (Digital filter disabled) and 0x0F (Digital filter enabled and filtering capability up to 15*ti2cclk). + * @param DigitalFilter This parameter must be a value between Min_Data=0x00 (Digital filter disabled) and Max_Data=0x0F (Digital filter enabled and filtering capability up to 15*ti2cclk). * This parameter is used to configure the digital noise filter on SDA and SCL input. * The digital filter will filter spikes with a length of up to DNF[3:0]*ti2cclk. * @retval None */ __STATIC_INLINE void LL_I2C_ConfigFilters(I2C_TypeDef *I2Cx, uint32_t AnalogFilter, uint32_t DigitalFilter) { - MODIFY_REG(I2Cx->CR1, I2C_CR1_ANFOFF | I2C_CR1_DNF, AnalogFilter | (DigitalFilter << I2C_POSITION_CR1_DNF)); + MODIFY_REG(I2Cx->CR1, I2C_CR1_ANFOFF | I2C_CR1_DNF, AnalogFilter | (DigitalFilter << I2C_CR1_DNF_Pos)); } /** @@ -472,14 +460,14 @@ __STATIC_INLINE void LL_I2C_ConfigFilters(I2C_TypeDef *I2Cx, uint32_t AnalogFilt * This filter can only be programmed when the I2C is disabled (PE = 0). * @rmtoll CR1 DNF LL_I2C_SetDigitalFilter * @param I2Cx I2C Instance. - * @param DigitalFilter This parameter must be a value between 0x00 (Digital filter disabled) and 0x0F (Digital filter enabled and filtering capability up to 15*ti2cclk). + * @param DigitalFilter This parameter must be a value between Min_Data=0x00 (Digital filter disabled) and Max_Data=0x0F (Digital filter enabled and filtering capability up to 15*ti2cclk). * This parameter is used to configure the digital noise filter on SDA and SCL input. * The digital filter will filter spikes with a length of up to DNF[3:0]*ti2cclk. * @retval None */ __STATIC_INLINE void LL_I2C_SetDigitalFilter(I2C_TypeDef *I2Cx, uint32_t DigitalFilter) { - MODIFY_REG(I2Cx->CR1, I2C_CR1_DNF, DigitalFilter << I2C_POSITION_CR1_DNF); + MODIFY_REG(I2Cx->CR1, I2C_CR1_DNF, DigitalFilter << I2C_CR1_DNF_Pos); } /** @@ -490,7 +478,7 @@ __STATIC_INLINE void LL_I2C_SetDigitalFilter(I2C_TypeDef *I2Cx, uint32_t Digital */ __STATIC_INLINE uint32_t LL_I2C_GetDigitalFilter(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->CR1, I2C_CR1_DNF) >> I2C_POSITION_CR1_DNF); + return (uint32_t)(READ_BIT(I2Cx->CR1, I2C_CR1_DNF) >> I2C_CR1_DNF_Pos); } /** @@ -798,7 +786,7 @@ __STATIC_INLINE uint32_t LL_I2C_GetMasterAddressingMode(I2C_TypeDef *I2Cx) * @rmtoll OAR1 OA1 LL_I2C_SetOwnAddress1\n * OAR1 OA1MODE LL_I2C_SetOwnAddress1 * @param I2Cx I2C Instance. - * @param OwnAddress1 This parameter must be a value between 0 and 0x3FF. + * @param OwnAddress1 This parameter must be a value between Min_Data=0 and Max_Data=0x3FF. * @param OwnAddrSize This parameter can be one of the following values: * @arg @ref LL_I2C_OWNADDRESS1_7BIT * @arg @ref LL_I2C_OWNADDRESS1_10BIT @@ -848,7 +836,7 @@ __STATIC_INLINE uint32_t LL_I2C_IsEnabledOwnAddress1(I2C_TypeDef *I2Cx) * @rmtoll OAR2 OA2 LL_I2C_SetOwnAddress2\n * OAR2 OA2MSK LL_I2C_SetOwnAddress2 * @param I2Cx I2C Instance. - * @param OwnAddress2 Value between 0 and 0x7F. + * @param OwnAddress2 Value between Min_Data=0 and Max_Data=0x7F. * @param OwnAddrMask This parameter can be one of the following values: * @arg @ref LL_I2C_OWNADDRESS2_NOMASK * @arg @ref LL_I2C_OWNADDRESS2_MASK01 @@ -903,7 +891,7 @@ __STATIC_INLINE uint32_t LL_I2C_IsEnabledOwnAddress2(I2C_TypeDef *I2Cx) * @note This bit can only be programmed when the I2C is disabled (PE = 0). * @rmtoll TIMINGR TIMINGR LL_I2C_SetTiming * @param I2Cx I2C Instance. - * @param Timing This parameter must be a value between 0 and 0xFFFFFFFF. + * @param Timing This parameter must be a value between Min_Data=0 and Max_Data=0xFFFFFFFF. * @note This parameter is computed with the STM32CubeMX Tool. * @retval None */ @@ -920,7 +908,7 @@ __STATIC_INLINE void LL_I2C_SetTiming(I2C_TypeDef *I2Cx, uint32_t Timing) */ __STATIC_INLINE uint32_t LL_I2C_GetTimingPrescaler(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_PRESC) >> I2C_POSITION_TIMINGR_PRESC); + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_PRESC) >> I2C_TIMINGR_PRESC_Pos); } /** @@ -931,7 +919,7 @@ __STATIC_INLINE uint32_t LL_I2C_GetTimingPrescaler(I2C_TypeDef *I2Cx) */ __STATIC_INLINE uint32_t LL_I2C_GetClockLowPeriod(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLL) >> I2C_POSITION_TIMINGR_SCLL); + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLL) >> I2C_TIMINGR_SCLL_Pos); } /** @@ -942,7 +930,7 @@ __STATIC_INLINE uint32_t LL_I2C_GetClockLowPeriod(I2C_TypeDef *I2Cx) */ __STATIC_INLINE uint32_t LL_I2C_GetClockHighPeriod(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLH) >> I2C_POSITION_TIMINGR_SCLH); + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLH) >> I2C_TIMINGR_SCLH_Pos); } /** @@ -953,7 +941,7 @@ __STATIC_INLINE uint32_t LL_I2C_GetClockHighPeriod(I2C_TypeDef *I2Cx) */ __STATIC_INLINE uint32_t LL_I2C_GetDataHoldTime(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SDADEL) >> I2C_POSITION_TIMINGR_SDADEL); + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SDADEL) >> I2C_TIMINGR_SDADEL_Pos); } /** @@ -964,7 +952,7 @@ __STATIC_INLINE uint32_t LL_I2C_GetDataHoldTime(I2C_TypeDef *I2Cx) */ __STATIC_INLINE uint32_t LL_I2C_GetDataSetupTime(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLDEL) >> I2C_POSITION_TIMINGR_SCLDEL); + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLDEL) >> I2C_TIMINGR_SCLDEL_Pos); } /** @@ -1106,14 +1094,13 @@ __STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPEC(I2C_TypeDef *I2Cx) * @arg @ref LL_I2C_SMBUS_TIMEOUTA_MODE_SCL_LOW * @arg @ref LL_I2C_SMBUS_TIMEOUTA_MODE_SDA_SCL_HIGH * @param TimeoutB - * @note This configuration can only be programmed when associated Timeout is disabled (TimeoutA and/orTimeoutB). * @retval None */ __STATIC_INLINE void LL_I2C_ConfigSMBusTimeout(I2C_TypeDef *I2Cx, uint32_t TimeoutA, uint32_t TimeoutAMode, - uint32_t TimeoutB) + uint32_t TimeoutB) { MODIFY_REG(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTA | I2C_TIMEOUTR_TIDLE | I2C_TIMEOUTR_TIMEOUTB, - TimeoutA | TimeoutAMode | (TimeoutB << I2C_POSITION_TIMEOUTR_TIMEOUTB)); + TimeoutA | TimeoutAMode | (TimeoutB << I2C_TIMEOUTR_TIMEOUTB_Pos)); } /** @@ -1188,7 +1175,7 @@ __STATIC_INLINE uint32_t LL_I2C_GetSMBusTimeoutAMode(I2C_TypeDef *I2Cx) */ __STATIC_INLINE void LL_I2C_SetSMBusTimeoutB(I2C_TypeDef *I2Cx, uint32_t TimeoutB) { - WRITE_REG(I2Cx->TIMEOUTR, TimeoutB << I2C_POSITION_TIMEOUTR_TIMEOUTB); + WRITE_REG(I2Cx->TIMEOUTR, TimeoutB << I2C_TIMEOUTR_TIMEOUTB_Pos); } /** @@ -1201,7 +1188,7 @@ __STATIC_INLINE void LL_I2C_SetSMBusTimeoutB(I2C_TypeDef *I2Cx, uint32_t Timeout */ __STATIC_INLINE uint32_t LL_I2C_GetSMBusTimeoutB(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTB) >> I2C_POSITION_TIMEOUTR_TIMEOUTB); + return (uint32_t)(READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTB) >> I2C_TIMEOUTR_TIMEOUTB_Pos); } /** @@ -1472,6 +1459,8 @@ __STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_TC(I2C_TypeDef *I2Cx) /** * @brief Enable Error interrupts. + * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. * @note Any of these errors will generate interrupt : * Arbitration Loss (ARLO) * Bus Error detection (BERR) @@ -1479,8 +1468,6 @@ __STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_TC(I2C_TypeDef *I2Cx) * SMBus Timeout detection (TIMEOUT) * SMBus PEC error detection (PECERR) * SMBus Alert pin event detection (ALERT) - * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not - * SMBus feature is supported by the I2Cx Instance. * @rmtoll CR1 ERRIE LL_I2C_EnableIT_ERR * @param I2Cx I2C Instance. * @retval None @@ -1492,6 +1479,8 @@ __STATIC_INLINE void LL_I2C_EnableIT_ERR(I2C_TypeDef *I2Cx) /** * @brief Disable Error interrupts. + * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. * @note Any of these errors will generate interrupt : * Arbitration Loss (ARLO) * Bus Error detection (BERR) @@ -1499,8 +1488,6 @@ __STATIC_INLINE void LL_I2C_EnableIT_ERR(I2C_TypeDef *I2Cx) * SMBus Timeout detection (TIMEOUT) * SMBus PEC error detection (PECERR) * SMBus Alert pin event detection (ALERT) - * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not - * SMBus feature is supported by the I2Cx Instance. * @rmtoll CR1 ERRIE LL_I2C_DisableIT_ERR * @param I2Cx I2C Instance. * @retval None @@ -1511,7 +1498,7 @@ __STATIC_INLINE void LL_I2C_DisableIT_ERR(I2C_TypeDef *I2Cx) } /** - * @brief Check if Error interrupts is enabled of disabled. + * @brief Check if Error interrupts are enabled or disabled. * @rmtoll CR1 ERRIE LL_I2C_IsEnabledIT_ERR * @param I2Cx I2C Instance. * @retval State of bit (1 or 0). @@ -1672,6 +1659,52 @@ __STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_OVR(I2C_TypeDef *I2Cx) return (READ_BIT(I2Cx->ISR, I2C_ISR_OVR) == (I2C_ISR_OVR)); } +/** + * @brief Indicate the status of SMBus PEC error flag in reception. + * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note RESET: Clear default value. + * SET: When the received PEC does not match with the PEC register content. + * @rmtoll ISR PECERR LL_I2C_IsActiveSMBusFlag_PECERR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_PECERR(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->ISR, I2C_ISR_PECERR) == (I2C_ISR_PECERR)); +} + +/** + * @brief Indicate the status of SMBus Timeout detection flag. + * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note RESET: Clear default value. + * SET: When a timeout or extended clock timeout occurs. + * @rmtoll ISR TIMEOUT LL_I2C_IsActiveSMBusFlag_TIMEOUT + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->ISR, I2C_ISR_TIMEOUT) == (I2C_ISR_TIMEOUT)); +} + +/** + * @brief Indicate the status of SMBus alert flag. + * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note RESET: Clear default value. + * SET: When SMBus host configuration, SMBus alert enabled and + * a falling edge event occurs on SMBA pin. + * @rmtoll ISR ALERT LL_I2C_IsActiveSMBusFlag_ALERT + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_ALERT(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->ISR, I2C_ISR_ALERT) == (I2C_ISR_ALERT)); +} + /** * @brief Indicate the status of Bus Busy flag. * @note RESET: Clear default value. @@ -1763,52 +1796,6 @@ __STATIC_INLINE void LL_I2C_ClearFlag_OVR(I2C_TypeDef *I2Cx) SET_BIT(I2Cx->ICR, I2C_ICR_OVRCF); } -/** - * @brief Indicate the status of SMBus PEC error flag in reception. - * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not - * SMBus feature is supported by the I2Cx Instance. - * @note RESET: Clear default value. - * SET: When the received PEC does not match with the PEC register content. - * @rmtoll ISR PECERR LL_I2C_IsActiveSMBusFlag_PECERR - * @param I2Cx I2C Instance. - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_PECERR(I2C_TypeDef *I2Cx) -{ - return (READ_BIT(I2Cx->ISR, I2C_ISR_PECERR) == (I2C_ISR_PECERR)); -} - -/** - * @brief Indicate the status of SMBus Timeout detection flag. - * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not - * SMBus feature is supported by the I2Cx Instance. - * @note RESET: Clear default value. - * SET: When a timeout or extended clock timeout occurs. - * @rmtoll ISR TIMEOUT LL_I2C_IsActiveSMBusFlag_TIMEOUT - * @param I2Cx I2C Instance. - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx) -{ - return (READ_BIT(I2Cx->ISR, I2C_ISR_TIMEOUT) == (I2C_ISR_TIMEOUT)); -} - -/** - * @brief Indicate the status of SMBus alert flag. - * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not - * SMBus feature is supported by the I2Cx Instance. - * @note RESET: Clear default value. - * SET: When SMBus host configuration, SMBus alert enabled and - * a falling edge event occurs on SMBA pin. - * @rmtoll ISR ALERT LL_I2C_IsActiveSMBusFlag_ALERT - * @param I2Cx I2C Instance. - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_ALERT(I2C_TypeDef *I2Cx) -{ - return (READ_BIT(I2Cx->ISR, I2C_ISR_ALERT) == (I2C_ISR_ALERT)); -} - /** * @brief Clear SMBus PEC error flag. * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not @@ -1937,7 +1924,7 @@ __STATIC_INLINE uint32_t LL_I2C_IsEnabledReloadMode(I2C_TypeDef *I2Cx) */ __STATIC_INLINE void LL_I2C_SetTransferSize(I2C_TypeDef *I2Cx, uint32_t TransferSize) { - MODIFY_REG(I2Cx->CR2, I2C_CR2_NBYTES, TransferSize << I2C_POSITION_CR2_NBYTES); + MODIFY_REG(I2Cx->CR2, I2C_CR2_NBYTES, TransferSize << I2C_CR2_NBYTES_Pos); } /** @@ -1948,7 +1935,7 @@ __STATIC_INLINE void LL_I2C_SetTransferSize(I2C_TypeDef *I2Cx, uint32_t Transfer */ __STATIC_INLINE uint32_t LL_I2C_GetTransferSize(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->CR2, I2C_CR2_NBYTES) >> I2C_POSITION_CR2_NBYTES); + return (uint32_t)(READ_BIT(I2Cx->CR2, I2C_CR2_NBYTES) >> I2C_CR2_NBYTES_Pos); } /** @@ -1966,17 +1953,6 @@ __STATIC_INLINE void LL_I2C_AcknowledgeNextData(I2C_TypeDef *I2Cx, uint32_t Type MODIFY_REG(I2Cx->CR2, I2C_CR2_NACK, TypeAcknowledge); } -/** - * @brief Generate a STOP condition after the current byte transfer (master mode). - * @rmtoll CR2 STOP LL_I2C_GenerateStopCondition - * @param I2Cx I2C Instance. - * @retval None - */ -__STATIC_INLINE void LL_I2C_GenerateStopCondition(I2C_TypeDef *I2Cx) -{ - SET_BIT(I2Cx->CR2, I2C_CR2_STOP); -} - /** * @brief Generate a START or RESTART condition * @note The START bit can be set even if bus is BUSY or I2C is in slave mode. @@ -1990,6 +1966,17 @@ __STATIC_INLINE void LL_I2C_GenerateStartCondition(I2C_TypeDef *I2Cx) SET_BIT(I2Cx->CR2, I2C_CR2_START); } +/** + * @brief Generate a STOP condition after the current byte transfer (master mode). + * @rmtoll CR2 STOP LL_I2C_GenerateStopCondition + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_GenerateStopCondition(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR2, I2C_CR2_STOP); +} + /** * @brief Enable automatic RESTART Read request condition for 10bit address header (master mode). * @note The master sends the complete 10bit slave address read sequence : @@ -2095,7 +2082,7 @@ __STATIC_INLINE uint32_t LL_I2C_GetSlaveAddr(I2C_TypeDef *I2Cx) * @arg @ref LL_I2C_ADDRSLAVE_7BIT * @arg @ref LL_I2C_ADDRSLAVE_10BIT * @param TransferSize Specifies the number of bytes to be programmed. - * This parameter must be a value between 0 and 255. + * This parameter must be a value between Min_Data=0 and Max_Data=255. * @param EndMode This parameter can be one of the following values: * @arg @ref LL_I2C_MODE_RELOAD * @arg @ref LL_I2C_MODE_AUTOEND @@ -2117,11 +2104,11 @@ __STATIC_INLINE uint32_t LL_I2C_GetSlaveAddr(I2C_TypeDef *I2Cx) * @retval None */ __STATIC_INLINE void LL_I2C_HandleTransfer(I2C_TypeDef *I2Cx, uint32_t SlaveAddr, uint32_t SlaveAddrSize, - uint32_t TransferSize, uint32_t EndMode, uint32_t Request) + uint32_t TransferSize, uint32_t EndMode, uint32_t Request) { - MODIFY_REG(I2Cx->CR2, I2C_CR2_SADD | I2C_CR2_ADD10 | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_RELOAD | + MODIFY_REG(I2Cx->CR2, I2C_CR2_SADD | I2C_CR2_ADD10 | (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_RELOAD | I2C_CR2_NBYTES | I2C_CR2_AUTOEND | I2C_CR2_HEAD10R, - SlaveAddr | SlaveAddrSize | TransferSize << I2C_POSITION_CR2_NBYTES | EndMode | Request); + SlaveAddr | SlaveAddrSize | TransferSize << I2C_CR2_NBYTES_Pos | EndMode | Request); } /** @@ -2147,11 +2134,11 @@ __STATIC_INLINE uint32_t LL_I2C_GetTransferDirection(I2C_TypeDef *I2Cx) */ __STATIC_INLINE uint32_t LL_I2C_GetAddressMatchCode(I2C_TypeDef *I2Cx) { - return (uint32_t)(READ_BIT(I2Cx->ISR, I2C_ISR_ADDCODE) >> I2C_POSITION_ISR_ADDCODE << 1); + return (uint32_t)(READ_BIT(I2Cx->ISR, I2C_ISR_ADDCODE) >> I2C_ISR_ADDCODE_Pos << 1); } /** - * @brief Enable internal comparison of Packet Error byte (transmission or reception mode). + * @brief Enable internal comparison of the SMBus Packet Error byte (transmission or reception mode). * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not * SMBus feature is supported by the I2Cx Instance. * @note This feature is cleared by hardware when the PEC byte is transferred, or when a STOP condition or an Address Matched is received. @@ -2167,7 +2154,7 @@ __STATIC_INLINE void LL_I2C_EnableSMBusPECCompare(I2C_TypeDef *I2Cx) } /** - * @brief Check if Packet Error byte internal comparison is requested or not. + * @brief Check if the SMBus Packet Error byte internal comparison is requested or not. * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not * SMBus feature is supported by the I2Cx Instance. * @rmtoll CR2 PECBYTE LL_I2C_IsEnabledSMBusPECCompare @@ -2180,7 +2167,7 @@ __STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPECCompare(I2C_TypeDef *I2Cx) } /** - * @brief Get the Packet Error byte calculated. + * @brief Get the SMBus Packet Error byte calculated. * @note Macro @ref IS_SMBUS_INSTANCE(I2Cx) can be used to check whether or not * SMBus feature is supported by the I2Cx Instance. * @rmtoll PECR PEC LL_I2C_GetSMBusPEC diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_iwdg.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_iwdg.h index 2429630ab3..0870b60ac2 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_iwdg.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_iwdg.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_iwdg.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of IWDG LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lptim.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lptim.c index 047daca030..33055e8d3d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lptim.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lptim.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_lptim.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief LPTIM LL module driver. ****************************************************************************** * @attention @@ -114,7 +112,7 @@ ErrorStatus LL_LPTIM_DeInit(LPTIM_TypeDef* LPTIMx) LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_LPTIM1); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_LPTIM1); } -#if defined(LPTIM2) +#if defined(LPTIM2) else if (LPTIMx == LPTIM2) { LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_LPTIM2); diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lptim.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lptim.h index 42c6916ca1..9e9eca32ac 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lptim.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lptim.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_lptim.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of LPTIM LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lpuart.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lpuart.c index ef88e97d51..41d900e937 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lpuart.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lpuart.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_lpuart.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief LPUART LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lpuart.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lpuart.h index da161ad838..d9306edff2 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lpuart.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_lpuart.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_lpuart.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of LPUART LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_pwr.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_pwr.c index 3d2ea8f92e..5a958de1b3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_pwr.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_pwr.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_pwr.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief PWR LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_pwr.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_pwr.h index c115c07b6f..280438e373 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_pwr.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_pwr.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_pwr.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of PWR LL module. ****************************************************************************** * @attention @@ -58,11 +56,8 @@ extern "C" { /* Private types -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ - /* Private constants ---------------------------------------------------------*/ - /* Private macros ------------------------------------------------------------*/ - /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /** @defgroup PWR_LL_Exported_Constants PWR Exported Constants @@ -85,17 +80,17 @@ extern "C" { */ #define LL_PWR_CSR_WUF PWR_CSR_WUF /*!< Wakeup flag */ #define LL_PWR_CSR_SBF PWR_CSR_SBF /*!< Standby flag */ -#if defined (PWR_PVD_SUPPORT) +#if defined(PWR_PVD_SUPPORT) #define LL_PWR_CSR_PVDO PWR_CSR_PVDO /*!< Power voltage detector output flag */ -#endif -#if defined (PWR_CSR_VREFINTRDYF) +#endif /* PWR_PVD_SUPPORT */ +#if defined(PWR_CSR_VREFINTRDYF) #define LL_PWR_CSR_VREFINTRDYF PWR_CSR_VREFINTRDYF /*!< VREFINT ready flag */ -#endif -#define LL_PWR_CSR_VOSF PWR_CSR_VOSF /*!< Voltage scaling select flag */ +#endif /* PWR_CSR_VREFINTRDYF */ +#define LL_PWR_CSR_VOS PWR_CSR_VOSF /*!< Voltage scaling select flag */ #define LL_PWR_CSR_REGLPF PWR_CSR_REGLPF /*!< Regulator low power flag */ #define LL_PWR_CSR_EWUP1 PWR_CSR_EWUP1 /*!< Enable WKUP pin 1 */ #define LL_PWR_CSR_EWUP2 PWR_CSR_EWUP2 /*!< Enable WKUP pin 2 */ -#if defined (PWR_CSR_EWUP3) +#if defined(PWR_CSR_EWUP3) #define LL_PWR_CSR_EWUP3 PWR_CSR_EWUP3 /*!< Enable WKUP pin 3 */ #endif /* PWR_CSR_EWUP3 */ /** @@ -115,8 +110,8 @@ extern "C" { /** @defgroup PWR_LL_EC_MODE_PWR Mode Power * @{ */ -#define LL_PWR_MODE_STOP ((uint32_t)0x00000000U) /*!< Enter Stop mode when the CPU enters deepsleep */ -#define LL_PWR_MODE_STANDBY (PWR_CR_PDDS) /*!< Enter Standby mode when the CPU enters deepsleep */ +#define LL_PWR_MODE_STOP 0x00000000U /*!< Enter Stop mode when the CPU enters deepsleep */ +#define LL_PWR_MODE_STANDBY (PWR_CR_PDDS) /*!< Enter Standby mode when the CPU enters deepsleep */ /** * @} */ @@ -124,24 +119,23 @@ extern "C" { /** @defgroup PWR_LL_EC_REGU_MODE_LP_MODES Regulator Mode In Low Power Modes * @{ */ -#define LL_PWR_REGU_LPMODES_MAIN ((uint32_t)0x00000000U) /*!< Voltage regulator in main mode during deepsleep/sleep/low-power run mode */ -#define LL_PWR_REGU_LPMODES_LOW_POWER (PWR_CR_LPSDSR) /*!< Voltage regulator in low-power mode during deepsleep/sleep/low-power run mode */ +#define LL_PWR_REGU_LPMODES_MAIN 0x00000000U /*!< Voltage regulator in main mode during deepsleep/sleep/low-power run mode */ +#define LL_PWR_REGU_LPMODES_LOW_POWER (PWR_CR_LPSDSR) /*!< Voltage regulator in low-power mode during deepsleep/sleep/low-power run mode */ /** * @} */ - #if defined(PWR_CR_LPDS) /** @defgroup PWR_LL_EC_REGU_MODE_DS_MODE Regulator Mode In Deep Sleep Mode * @{ */ -#define LL_PWR_REGU_DSMODE_MAIN ((uint32_t)0x00000000U) /*!< Voltage regulator in main mode during deepsleep mode when PWR_CR_LPSDSR = 0 */ -#define LL_PWR_REGU_DSMODE_LOW_POWER (PWR_CR_LPDS) /*!< Voltage regulator in low-power mode during deepsleep mode when PWR_CR_LPSDSR = 0 */ +#define LL_PWR_REGU_DSMODE_MAIN 0x00000000U /*!< Voltage regulator in main mode during deepsleep mode when PWR_CR_LPSDSR = 0 */ +#define LL_PWR_REGU_DSMODE_LOW_POWER (PWR_CR_LPDS) /*!< Voltage regulator in low-power mode during deepsleep mode when PWR_CR_LPSDSR = 0 */ /** - * @} - */ + * @} + */ #endif /* PWR_CR_LPDS */ -#if defined (PWR_PVD_SUPPORT) +#if defined(PWR_PVD_SUPPORT) /** @defgroup PWR_LL_EC_PVDLEVEL Power Voltage Detector Level * @{ */ @@ -156,14 +150,13 @@ extern "C" { /** * @} */ -#endif - +#endif /* PWR_PVD_SUPPORT */ /** @defgroup PWR_LL_EC_WAKEUP_PIN Wakeup Pins -* @{ -*/ + * @{ + */ #define LL_PWR_WAKEUP_PIN1 (PWR_CSR_EWUP1) /*!< WKUP pin 1 : PA0 */ #define LL_PWR_WAKEUP_PIN2 (PWR_CSR_EWUP2) /*!< WKUP pin 2 : PC13 */ -#if defined (PWR_CSR_EWUP3) +#if defined(PWR_CSR_EWUP3) #define LL_PWR_WAKEUP_PIN3 (PWR_CSR_EWUP3) /*!< WKUP pin 3 : PE6 or PA2 according to device */ #endif /* PWR_CSR_EWUP3 */ /** @@ -206,7 +199,6 @@ extern "C" { * @} */ - /* Exported functions --------------------------------------------------------*/ /** @defgroup PWR_LL_Exported_Functions PWR Exported Functions * @{ @@ -215,7 +207,6 @@ extern "C" { /** @defgroup PWR_LL_EF_Configuration Configuration * @{ */ - /** * @brief Switch the regulator from main mode to low-power mode * @rmtoll CR LPRUN LL_PWR_EnableLowPowerRunMode @@ -285,7 +276,6 @@ __STATIC_INLINE void LL_PWR_ExitLowPowerRunMode(void) CLEAR_BIT(PWR->CR, PWR_CR_LPRUN); /* => LL_PWR_DisableLowPowerRunMode() */ CLEAR_BIT(PWR->CR, PWR_CR_LPSDSR); /* => LL_PWR_SetRegulModeLP(LL_PWR_REGU_LPMODES_MAIN) */ } - /** * @brief Set the main internal regulator output voltage * @rmtoll CR VOS LL_PWR_SetRegulVoltageScaling @@ -424,7 +414,7 @@ __STATIC_INLINE uint32_t LL_PWR_GetPowerMode(void) return (uint32_t)(READ_BIT(PWR->CR, PWR_CR_PDDS)); } -#if defined (PWR_PVD_SUPPORT) +#if defined(PWR_PVD_SUPPORT) /** * @brief Configure the voltage threshold detected by the Power Voltage Detector * @rmtoll CR PLS LL_PWR_SetPVDLevel @@ -491,13 +481,13 @@ __STATIC_INLINE uint32_t LL_PWR_IsEnabledPVD(void) { return (READ_BIT(PWR->CR, PWR_CR_PVDE) == (PWR_CR_PVDE)); } -#endif +#endif /* PWR_PVD_SUPPORT */ /** * @brief Enable the WakeUp PINx functionality * @rmtoll CSR EWUP1 LL_PWR_EnableWakeUpPin\n - * CSR EWUP2 LL_PWR_EnableWakeUpPin\n - * CSR EWUP3 LL_PWR_EnableWakeUpPin + * @rmtoll CSR EWUP2 LL_PWR_EnableWakeUpPin\n + * @rmtoll CSR EWUP3 LL_PWR_EnableWakeUpPin * @param WakeUpPin This parameter can be one of the following values: * @arg @ref LL_PWR_WAKEUP_PIN1 * @arg @ref LL_PWR_WAKEUP_PIN2 @@ -514,8 +504,8 @@ __STATIC_INLINE void LL_PWR_EnableWakeUpPin(uint32_t WakeUpPin) /** * @brief Disable the WakeUp PINx functionality * @rmtoll CSR EWUP1 LL_PWR_DisableWakeUpPin\n - * CSR EWUP2 LL_PWR_DisableWakeUpPin\n - * CSR EWUP3 LL_PWR_DisableWakeUpPin + * @rmtoll CSR EWUP2 LL_PWR_DisableWakeUpPin\n + * @rmtoll CSR EWUP3 LL_PWR_DisableWakeUpPin * @param WakeUpPin This parameter can be one of the following values: * @arg @ref LL_PWR_WAKEUP_PIN1 * @arg @ref LL_PWR_WAKEUP_PIN2 @@ -532,8 +522,8 @@ __STATIC_INLINE void LL_PWR_DisableWakeUpPin(uint32_t WakeUpPin) /** * @brief Check if the WakeUp PINx functionality is enabled * @rmtoll CSR EWUP1 LL_PWR_IsEnabledWakeUpPin\n - * CSR EWUP2 LL_PWR_IsEnabledWakeUpPin\n - * CSR EWUP3 LL_PWR_IsEnabledWakeUpPin + * @rmtoll CSR EWUP2 LL_PWR_IsEnabledWakeUpPin\n + * @rmtoll CSR EWUP3 LL_PWR_IsEnabledWakeUpPin * @param WakeUpPin This parameter can be one of the following values: * @arg @ref LL_PWR_WAKEUP_PIN1 * @arg @ref LL_PWR_WAKEUP_PIN2 @@ -671,7 +661,7 @@ __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_SB(void) return (READ_BIT(PWR->CSR, PWR_CSR_SBF) == (PWR_CSR_SBF)); } -#if defined (PWR_PVD_SUPPORT) +#if defined(PWR_PVD_SUPPORT) /** * @brief Indicate whether VDD voltage is below the selected PVD threshold * @rmtoll CSR PVDO LL_PWR_IsActiveFlag_PVDO @@ -681,9 +671,9 @@ __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_PVDO(void) { return (READ_BIT(PWR->CSR, PWR_CSR_PVDO) == (PWR_CSR_PVDO)); } -#endif +#endif /* PWR_PVD_SUPPORT */ -#if defined (PWR_CSR_VREFINTRDYF) +#if defined(PWR_CSR_VREFINTRDYF) /** * @brief Get Internal Reference VrefInt Flag * @rmtoll CSR VREFINTRDYF LL_PWR_IsActiveFlag_VREFINTRDY @@ -693,8 +683,7 @@ __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VREFINTRDY(void) { return (READ_BIT(PWR->CSR, PWR_CSR_VREFINTRDYF) == (PWR_CSR_VREFINTRDYF)); } -#endif - +#endif /* PWR_CSR_VREFINTRDYF */ /** * @brief Indicate whether the regulator is ready in the selected voltage range or if its output voltage is still changing to the required voltage level * @rmtoll CSR VOSF LL_PWR_IsActiveFlag_VOSF @@ -702,9 +691,8 @@ __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VREFINTRDY(void) */ __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VOSF(void) { - return (READ_BIT(PWR->CSR, PWR_CSR_VOSF) == (PWR_CSR_VOSF)); + return (READ_BIT(PWR->CSR, LL_PWR_CSR_VOS) == (LL_PWR_CSR_VOS)); } - /** * @brief Indicate whether the regulator is ready in main mode or is in low-power mode * @rmtoll CSR REGLPF LL_PWR_IsActiveFlag_REGLPF @@ -715,7 +703,6 @@ __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_REGLPF(void) { return (READ_BIT(PWR->CSR, PWR_CSR_REGLPF) == (PWR_CSR_REGLPF)); } - /** * @brief Clear Standby Flag * @rmtoll CR CSBF LL_PWR_ClearFlag_SB @@ -735,8 +722,6 @@ __STATIC_INLINE void LL_PWR_ClearFlag_WU(void) { SET_BIT(PWR->CR, PWR_CR_CWUF); } - - #if defined(USE_FULL_LL_DRIVER) /** @defgroup PWR_LL_EF_Init De-initialization function * @{ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rcc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rcc.c index 40208589bd..8800614593 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rcc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rcc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_rcc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief RCC LL module driver. ****************************************************************************** * @attention @@ -172,7 +170,7 @@ ErrorStatus LL_RCC_DeInit(void) /* Set RCC_CR_RTCPRE to 0b00*/ CLEAR_BIT(vl_mask, RCC_CR_RTCPRE); LL_RCC_WriteReg(CR, vl_mask); - + /* Reset CFGR register */ LL_RCC_WriteReg(CFGR, 0x00000000U); diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rcc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rcc.h index 670a0c20c0..7add2fb6bf 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rcc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rcc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_rcc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of RCC LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rng.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rng.c index fcfe4bfc72..1a62a32fcb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rng.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rng.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_rng.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief RNG LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rng.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rng.h index 594f9a53ce..e80c51f2e8 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rng.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rng.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_rng.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of RNG LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rtc.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rtc.c index 4bf231f6fb..2f976ecda3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rtc.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rtc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_rtc.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief RTC LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rtc.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rtc.h index b72ff1cc97..f5b9b740c9 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rtc.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_rtc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_rtc.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of RTC LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_spi.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_spi.c index 8bad9fdea8..c1966904a8 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_spi.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_spi.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_spi.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief SPI LL module driver. ****************************************************************************** * @attention @@ -410,22 +408,15 @@ ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct) * - AudioFreq: SPI_I2SPR_I2SDIV[7:0] and SPI_I2SPR_ODD bits */ - /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/ - if (I2S_InitStruct->AudioFreq == LL_I2S_AUDIOFREQ_DEFAULT) + /* If the requested audio frequency is not the default, compute the prescaler (i2sodd, i2sdiv) + * else, default values are used: i2sodd = 0U, i2sdiv = 2U. + */ + if (I2S_InitStruct->AudioFreq != LL_I2S_AUDIOFREQ_DEFAULT) { - i2sodd = 0U; - i2sdiv = 2U; - } - /* If the requested audio frequency is not the default, compute the prescaler */ - else - { - /* Check the frame length (For the Prescaler computing) */ - if (I2S_InitStruct->DataFormat == LL_I2S_DATAFORMAT_16B) - { - /* Packet length is 16 bits */ - packetlength = 1U; - } - else + /* Check the frame length (For the Prescaler computing) + * Default value: LL_I2S_DATAFORMAT_16B (packetlength = 1U). + */ + if (I2S_InitStruct->DataFormat != LL_I2S_DATAFORMAT_16B) { /* Packet length is 32 bits */ packetlength = 2U; diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_spi.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_spi.h index e4b962184e..19c9951bb7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_spi.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_spi.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_spi.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of SPI LL module. ****************************************************************************** * @attention @@ -1423,7 +1421,7 @@ __STATIC_INLINE uint32_t LL_I2S_IsEnabled(SPI_TypeDef *SPIx) } /** - * @brief Set I2S Data frame length + * @brief Set I2S data frame length * @rmtoll I2SCFGR DATLEN LL_I2S_SetDataFormat\n * I2SCFGR CHLEN LL_I2S_SetDataFormat * @param SPIx SPI Instance @@ -1440,7 +1438,7 @@ __STATIC_INLINE void LL_I2S_SetDataFormat(SPI_TypeDef *SPIx, uint32_t DataFormat } /** - * @brief Get I2S Data frame length + * @brief Get I2S data frame length * @rmtoll I2SCFGR DATLEN LL_I2S_GetDataFormat\n * I2SCFGR CHLEN LL_I2S_GetDataFormat * @param SPIx SPI Instance @@ -1483,7 +1481,7 @@ __STATIC_INLINE uint32_t LL_I2S_GetClockPolarity(SPI_TypeDef *SPIx) } /** - * @brief Set I2S Standard Protocol + * @brief Set I2S standard protocol * @rmtoll I2SCFGR I2SSTD LL_I2S_SetStandard\n * I2SCFGR PCMSYNC LL_I2S_SetStandard * @param SPIx SPI Instance @@ -1501,7 +1499,7 @@ __STATIC_INLINE void LL_I2S_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard) } /** - * @brief Get I2S Standard Protocol + * @brief Get I2S standard protocol * @rmtoll I2SCFGR I2SSTD LL_I2S_GetStandard\n * I2SCFGR PCMSYNC LL_I2S_GetStandard * @param SPIx SPI Instance @@ -1518,7 +1516,7 @@ __STATIC_INLINE uint32_t LL_I2S_GetStandard(SPI_TypeDef *SPIx) } /** - * @brief Set I2S Transfer Mode + * @brief Set I2S transfer mode * @rmtoll I2SCFGR I2SCFG LL_I2S_SetTransferMode * @param SPIx SPI Instance * @param Mode This parameter can be one of the following values: @@ -1534,7 +1532,7 @@ __STATIC_INLINE void LL_I2S_SetTransferMode(SPI_TypeDef *SPIx, uint32_t Mode) } /** - * @brief Get I2S Transfer Mode + * @brief Get I2S transfer mode * @rmtoll I2SCFGR I2SCFG LL_I2S_GetTransferMode * @param SPIx SPI Instance * @retval Returned value can be one of the following values: @@ -1599,7 +1597,7 @@ __STATIC_INLINE uint32_t LL_I2S_GetPrescalerParity(SPI_TypeDef *SPIx) } /** - * @brief Enable the Master Clock Ouput (Pin MCK) + * @brief Enable the master clock ouput (Pin MCK) * @rmtoll I2SPR MCKOE LL_I2S_EnableMasterClock * @param SPIx SPI Instance * @retval None @@ -1610,7 +1608,7 @@ __STATIC_INLINE void LL_I2S_EnableMasterClock(SPI_TypeDef *SPIx) } /** - * @brief Disable the Master Clock Ouput (Pin MCK) + * @brief Disable the master clock ouput (Pin MCK) * @rmtoll I2SPR MCKOE LL_I2S_DisableMasterClock * @param SPIx SPI Instance * @retval None @@ -1621,7 +1619,7 @@ __STATIC_INLINE void LL_I2S_DisableMasterClock(SPI_TypeDef *SPIx) } /** - * @brief Check if the Master Clock Ouput (Pin MCK) is enabled + * @brief Check if the master clock ouput (Pin MCK) is enabled * @rmtoll I2SPR MCKOE LL_I2S_IsEnabledMasterClock * @param SPIx SPI Instance * @retval State of bit (1 or 0). @@ -1633,7 +1631,7 @@ __STATIC_INLINE uint32_t LL_I2S_IsEnabledMasterClock(SPI_TypeDef *SPIx) #if defined(SPI_I2SCFGR_ASTRTEN) /** - * @brief Enable Asynchronous Start + * @brief Enable asynchronous start * @rmtoll I2SCFGR ASTRTEN LL_I2S_EnableAsyncStart * @param SPIx SPI Instance * @retval None @@ -1644,7 +1642,7 @@ __STATIC_INLINE void LL_I2S_EnableAsyncStart(SPI_TypeDef *SPIx) } /** - * @brief Disable Asynchronous Start + * @brief Disable asynchronous start * @rmtoll I2SCFGR ASTRTEN LL_I2S_DisableAsyncStart * @param SPIx SPI Instance * @retval None @@ -1655,7 +1653,7 @@ __STATIC_INLINE void LL_I2S_DisableAsyncStart(SPI_TypeDef *SPIx) } /** - * @brief Check if Asynchronous Start is enabled + * @brief Check if asynchronous start is enabled * @rmtoll I2SCFGR ASTRTEN LL_I2S_IsEnabledAsyncStart * @param SPIx SPI Instance * @retval State of bit (1 or 0). @@ -1697,7 +1695,7 @@ __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_TXE(SPI_TypeDef *SPIx) } /** - * @brief Get Busy flag + * @brief Get busy flag * @rmtoll SR BSY LL_I2S_IsActiveFlag_BSY * @param SPIx SPI Instance * @retval State of bit (1 or 0). @@ -1708,7 +1706,7 @@ __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_BSY(SPI_TypeDef *SPIx) } /** - * @brief Get Overrun error flag + * @brief Get overrun error flag * @rmtoll SR OVR LL_I2S_IsActiveFlag_OVR * @param SPIx SPI Instance * @retval State of bit (1 or 0). @@ -1719,7 +1717,7 @@ __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_OVR(SPI_TypeDef *SPIx) } /** - * @brief Get Underrun error flag + * @brief Get underrun error flag * @rmtoll SR UDR LL_I2S_IsActiveFlag_UDR * @param SPIx SPI Instance * @retval State of bit (1 or 0). @@ -1730,7 +1728,7 @@ __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_UDR(SPI_TypeDef *SPIx) } /** - * @brief Get Frame format error flag + * @brief Get frame format error flag * @rmtoll SR FRE LL_I2S_IsActiveFlag_FRE * @param SPIx SPI Instance * @retval State of bit (1 or 0). @@ -1741,7 +1739,7 @@ __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_FRE(SPI_TypeDef *SPIx) } /** - * @brief Get Channel side flag. + * @brief Get channel side flag. * @note 0: Channel Left has to be transmitted or has been received\n * 1: Channel Right has to be transmitted or has been received\n * It has no significance in PCM mode. @@ -1755,7 +1753,7 @@ __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_CHSIDE(SPI_TypeDef *SPIx) } /** - * @brief Clear Overrun error flag + * @brief Clear overrun error flag * @rmtoll SR OVR LL_I2S_ClearFlag_OVR * @param SPIx SPI Instance * @retval None @@ -1766,7 +1764,7 @@ __STATIC_INLINE void LL_I2S_ClearFlag_OVR(SPI_TypeDef *SPIx) } /** - * @brief Clear Underrun error flag + * @brief Clear underrun error flag * @rmtoll SR UDR LL_I2S_ClearFlag_UDR * @param SPIx SPI Instance * @retval None @@ -1779,7 +1777,7 @@ __STATIC_INLINE void LL_I2S_ClearFlag_UDR(SPI_TypeDef *SPIx) } /** - * @brief Clear Frame format error flag + * @brief Clear frame format error flag * @rmtoll SR FRE LL_I2S_ClearFlag_FRE * @param SPIx SPI Instance * @retval None @@ -1832,7 +1830,7 @@ __STATIC_INLINE void LL_I2S_EnableIT_TXE(SPI_TypeDef *SPIx) } /** - * @brief Disable Error IT + * @brief Disable error IT * @note This bit controls the generation of an interrupt when an error condition occurs (OVR, UDR and FRE in I2S mode). * @rmtoll CR2 ERRIE LL_I2S_DisableIT_ERR * @param SPIx SPI Instance diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_system.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_system.h index 94d90a1309..f9a0205280 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_system.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_system.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_system.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of SYSTEM LL module. @verbatim ============================================================================== @@ -230,41 +228,41 @@ extern "C" { -/** @defgroup SYSTEM_LL_EC_ABP1_GRP1_STOP_IP DBGMCU ABP1 GRP1 STOP IP +/** @defgroup SYSTEM_LL_EC_APB1_GRP1_STOP_IP DBGMCU APB1 GRP1 STOP IP * @{ */ -#define LL_DBGMCU_ABP1_GRP1_TIM2_STOP DBGMCU_APB1_FZ_DBG_TIM2_STOP /*!< TIM2 counter stopped when core is halted */ +#define LL_DBGMCU_APB1_GRP1_TIM2_STOP DBGMCU_APB1_FZ_DBG_TIM2_STOP /*!< TIM2 counter stopped when core is halted */ #if defined(TIM3) -#define LL_DBGMCU_ABP1_GRP1_TIM3_STOP DBGMCU_APB1_FZ_DBG_TIM3_STOP /*!< TIM3 counter stopped when core is halted */ +#define LL_DBGMCU_APB1_GRP1_TIM3_STOP DBGMCU_APB1_FZ_DBG_TIM3_STOP /*!< TIM3 counter stopped when core is halted */ #endif /*TIM3*/ #if defined(TIM6) -#define LL_DBGMCU_ABP1_GRP1_TIM6_STOP DBGMCU_APB1_FZ_DBG_TIM6_STOP /*!< TIM6 counter stopped when core is halted */ +#define LL_DBGMCU_APB1_GRP1_TIM6_STOP DBGMCU_APB1_FZ_DBG_TIM6_STOP /*!< TIM6 counter stopped when core is halted */ #endif /*TIM6*/ #if defined(TIM7) -#define LL_DBGMCU_ABP1_GRP1_TIM7_STOP DBGMCU_APB1_FZ_DBG_TIM7_STOP /*!< TIM7 counter stopped when core is halted */ +#define LL_DBGMCU_APB1_GRP1_TIM7_STOP DBGMCU_APB1_FZ_DBG_TIM7_STOP /*!< TIM7 counter stopped when core is halted */ #endif /*TIM7*/ -#define LL_DBGMCU_ABP1_GRP1_RTC_STOP DBGMCU_APB1_FZ_DBG_RTC_STOP /*!< RTC Calendar frozen when core is halted */ -#define LL_DBGMCU_ABP1_GRP1_WWDG_STOP DBGMCU_APB1_FZ_DBG_WWDG_STOP /*!< Debug Window Watchdog stopped when Core is halted */ -#define LL_DBGMCU_ABP1_GRP1_IWDG_STOP DBGMCU_APB1_FZ_DBG_IWDG_STOP /*!< Debug Independent Watchdog stopped when Core is halted */ -#define LL_DBGMCU_ABP1_GRP1_I2C1_STOP DBGMCU_APB1_FZ_DBG_I2C1_STOP /*!< I2C1 SMBUS timeout mode stopped when Core is halted */ +#define LL_DBGMCU_APB1_GRP1_RTC_STOP DBGMCU_APB1_FZ_DBG_RTC_STOP /*!< RTC Calendar frozen when core is halted */ +#define LL_DBGMCU_APB1_GRP1_WWDG_STOP DBGMCU_APB1_FZ_DBG_WWDG_STOP /*!< Debug Window Watchdog stopped when Core is halted */ +#define LL_DBGMCU_APB1_GRP1_IWDG_STOP DBGMCU_APB1_FZ_DBG_IWDG_STOP /*!< Debug Independent Watchdog stopped when Core is halted */ +#define LL_DBGMCU_APB1_GRP1_I2C1_STOP DBGMCU_APB1_FZ_DBG_I2C1_STOP /*!< I2C1 SMBUS timeout mode stopped when Core is halted */ #if defined(I2C2) -#define LL_DBGMCU_ABP1_GRP1_I2C2_STOP DBGMCU_APB1_FZ_DBG_I2C2_STOP /*!< I2C2 SMBUS timeout mode stopped when Core is halted */ +#define LL_DBGMCU_APB1_GRP1_I2C2_STOP DBGMCU_APB1_FZ_DBG_I2C2_STOP /*!< I2C2 SMBUS timeout mode stopped when Core is halted */ #endif /*I2C2*/ #if defined(I2C3) -#define LL_DBGMCU_ABP1_GRP1_I2C3_STOP DBGMCU_APB1_FZ_DBG_I2C3_STOP /*!< I2C3 SMBUS timeout mode stopped when Core is halted */ +#define LL_DBGMCU_APB1_GRP1_I2C3_STOP DBGMCU_APB1_FZ_DBG_I2C3_STOP /*!< I2C3 SMBUS timeout mode stopped when Core is halted */ #endif /*I2C3*/ -#define LL_DBGMCU_ABP1_GRP1_LPTIM1_STOP DBGMCU_APB1_FZ_DBG_LPTIMER_STOP /*!< LPTIM1 counter stopped when core is halted */ +#define LL_DBGMCU_APB1_GRP1_LPTIM1_STOP DBGMCU_APB1_FZ_DBG_LPTIMER_STOP /*!< LPTIM1 counter stopped when core is halted */ /** * @} */ -/** @defgroup SYSTEM_LL_EC_ABP2_GRP1_STOP_IP DBGMCU ABP2 GRP1 STOP IP +/** @defgroup SYSTEM_LL_EC_APB2_GRP1_STOP_IP DBGMCU APB2 GRP1 STOP IP * @{ */ #if defined(TIM22) -#define LL_DBGMCU_ABP2_GRP1_TIM22_STOP DBGMCU_APB2_FZ_DBG_TIM22_STOP /*!< TIM22 counter stopped when core is halted */ +#define LL_DBGMCU_APB2_GRP1_TIM22_STOP DBGMCU_APB2_FZ_DBG_TIM22_STOP /*!< TIM22 counter stopped when core is halted */ #endif /*TIM22*/ -#define LL_DBGMCU_ABP2_GRP1_TIM21_STOP DBGMCU_APB2_FZ_DBG_TIM21_STOP /*!< TIM21 counter stopped when core is halted */ +#define LL_DBGMCU_APB2_GRP1_TIM21_STOP DBGMCU_APB2_FZ_DBG_TIM21_STOP /*!< TIM21 counter stopped when core is halted */ /** * @} */ @@ -816,100 +814,100 @@ __STATIC_INLINE void LL_DBGMCU_DisableDBGStandbyMode(void) /** * @brief Freeze APB1 peripherals (group1 peripherals) - * @rmtoll APB1FZ DBG_TIM2_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_TIM3_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_TIM6_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_TIM7_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_RTC_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_WWDG_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_IWDG_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_I2C1_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_I2C2_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_I2C3_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph\n - * APB1FZ DBG_LPTIMER_STOP LL_DBGMCU_ABP1_GRP1_FreezePeriph + * @rmtoll APB1FZ DBG_TIM2_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_TIM3_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_TIM6_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_TIM7_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_RTC_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_WWDG_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_IWDG_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_I2C1_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_I2C2_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_I2C3_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * APB1FZ DBG_LPTIMER_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph * @param Periphs This parameter can be a combination of the following values: - * @arg @ref LL_DBGMCU_ABP1_GRP1_TIM2_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_TIM3_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_TIM6_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_TIM7_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_RTC_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_WWDG_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_IWDG_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_I2C1_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_I2C2_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_I2C3_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_LPTIM1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_RTC_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C3_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_LPTIM1_STOP * * (*) value not defined in all devices * @retval None */ -__STATIC_INLINE void LL_DBGMCU_ABP1_GRP1_FreezePeriph(uint32_t Periphs) +__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_FreezePeriph(uint32_t Periphs) { SET_BIT(DBGMCU->APB1FZ, Periphs); } /** * @brief Unfreeze APB1 peripherals (group1 peripherals) - * @rmtoll APB1FZ DBG_TIM2_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_TIM3_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_TIM6_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_TIM7_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_RTC_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_WWDG_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_IWDG_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_I2C1_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_I2C2_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_I2C3_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph\n - * APB1FZ DBG_LPTIMER_STOP LL_DBGMCU_ABP1_GRP1_UnFreezePeriph + * @rmtoll APB1FZ DBG_TIM2_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_TIM3_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_TIM6_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_TIM7_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_RTC_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_WWDG_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_IWDG_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_I2C1_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_I2C2_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_I2C3_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * APB1FZ DBG_LPTIMER_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph * @param Periphs This parameter can be a combination of the following values: - * @arg @ref LL_DBGMCU_ABP1_GRP1_TIM2_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_TIM3_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_TIM6_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_TIM7_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_RTC_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_WWDG_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_IWDG_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_I2C1_STOP - * @arg @ref LL_DBGMCU_ABP1_GRP1_I2C2_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_I2C3_STOP (*) - * @arg @ref LL_DBGMCU_ABP1_GRP1_LPTIM1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_RTC_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C3_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_LPTIM1_STOP * * (*) value not defined in all devices * @retval None */ -__STATIC_INLINE void LL_DBGMCU_ABP1_GRP1_UnFreezePeriph(uint32_t Periphs) +__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_UnFreezePeriph(uint32_t Periphs) { CLEAR_BIT(DBGMCU->APB1FZ, Periphs); } /** * @brief Freeze APB2 peripherals - * @rmtoll APB2FZ DBG_TIM22_STOP LL_DBGMCU_ABP2_GRP1_FreezePeriph\n - * APB2FZ DBG_TIM21_STOP LL_DBGMCU_ABP2_GRP1_FreezePeriph + * @rmtoll APB2FZ DBG_TIM22_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n + * APB2FZ DBG_TIM21_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph * @param Periphs This parameter can be a combination of the following values: - * @arg @ref LL_DBGMCU_ABP2_GRP1_TIM22_STOP (*) - * @arg @ref LL_DBGMCU_ABP2_GRP1_TIM21_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM22_STOP (*) + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM21_STOP * * (*) value not defined in all devices * @retval None */ -__STATIC_INLINE void LL_DBGMCU_ABP2_GRP1_FreezePeriph(uint32_t Periphs) +__STATIC_INLINE void LL_DBGMCU_APB2_GRP1_FreezePeriph(uint32_t Periphs) { SET_BIT(DBGMCU->APB2FZ, Periphs); } /** * @brief Unfreeze APB2 peripherals - * @rmtoll APB2FZ DBG_TIM22_STOP LL_DBGMCU_ABP2_GRP1_UnFreezePeriph\n - * APB2FZ DBG_TIM21_STOP LL_DBGMCU_ABP2_GRP1_UnFreezePeriph + * @rmtoll APB2FZ DBG_TIM22_STOP LL_DBGMCU_APB2_GRP1_UnFreezePeriph\n + * APB2FZ DBG_TIM21_STOP LL_DBGMCU_APB2_GRP1_UnFreezePeriph * @param Periphs This parameter can be a combination of the following values: - * @arg @ref LL_DBGMCU_ABP2_GRP1_TIM22_STOP (*) - * @arg @ref LL_DBGMCU_ABP2_GRP1_TIM21_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM22_STOP (*) + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM21_STOP * * (*) value not defined in all devices * @retval None */ -__STATIC_INLINE void LL_DBGMCU_ABP2_GRP1_UnFreezePeriph(uint32_t Periphs) +__STATIC_INLINE void LL_DBGMCU_APB2_GRP1_UnFreezePeriph(uint32_t Periphs) { CLEAR_BIT(DBGMCU->APB2FZ, Periphs); } diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_tim.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_tim.c index 7dcb0226e4..00fd420863 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_tim.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_tim.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_tim.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief TIM LL module driver. ****************************************************************************** * @attention @@ -41,9 +39,9 @@ #include "stm32l0xx_ll_bus.h" #ifdef USE_FULL_ASSERT - #include "stm32_assert.h" +#include "stm32_assert.h" #else - #define assert_param(expr) ((void)0U) +#define assert_param(expr) ((void)0U) #endif /** @addtogroup STM32L0xx_LL_Driver @@ -133,20 +131,20 @@ /** @defgroup TIM_LL_Private_Functions TIM Private Functions * @{ */ -static ErrorStatus OC1Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCInitStruct); -static ErrorStatus OC2Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCInitStruct); -static ErrorStatus OC3Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCInitStruct); -static ErrorStatus OC4Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCInitStruct); -static ErrorStatus IC1Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICInitStruct); -static ErrorStatus IC2Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICInitStruct); -static ErrorStatus IC3Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICInitStruct); -static ErrorStatus IC4Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICInitStruct); +static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); /** * @} */ /* Exported functions --------------------------------------------------------*/ -/** @addtogroup TIM_LL_Exported_Functions +/** @addtogroup TIM_LL_Exported_Functions * @{ */ @@ -161,47 +159,47 @@ static ErrorStatus IC4Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni * - SUCCESS: TIMx registers are de-initialized * - ERROR: invalid TIMx instance */ -ErrorStatus LL_TIM_DeInit(TIM_TypeDef* TIMx) +ErrorStatus LL_TIM_DeInit(TIM_TypeDef *TIMx) { ErrorStatus result = SUCCESS; /* Check the parameters */ - assert_param(IS_TIM_INSTANCE(TIMx)); + assert_param(IS_TIM_INSTANCE(TIMx)); -if (TIMx == TIM2) - { + if (TIMx == TIM2) + { LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2); } -#if defined(TIM3) +#if defined(TIM3) else if (TIMx == TIM3) - { + { LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM3); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM3); } #endif /* TIM3 */ -#if defined(TIM6) +#if defined(TIM6) else if (TIMx == TIM6) - { + { LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM6); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM6); } #endif /* TIM6 */ -#if defined(TIM7) +#if defined(TIM7) else if (TIMx == TIM7) - { + { LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM7); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM7); } #endif /* TIM7 */ else if (TIMx == TIM21) - { + { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM21); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM21); } -#if defined(TIM22) +#if defined(TIM22) else if (TIMx == TIM22) - { + { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM22); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM22); } @@ -210,7 +208,7 @@ if (TIMx == TIM2) { result = ERROR; } - + return result; } @@ -220,7 +218,7 @@ if (TIMx == TIM2) * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (time base unit configuration data structure) * @retval None */ -void LL_TIM_StructInit(LL_TIM_InitTypeDef* TIM_InitStruct) +void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct) { /* Set the default configuration */ TIM_InitStruct->Prescaler = (uint16_t)0x0000U; @@ -237,29 +235,27 @@ void LL_TIM_StructInit(LL_TIM_InitTypeDef* TIM_InitStruct) * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -ErrorStatus LL_TIM_Init(TIM_TypeDef * TIMx, LL_TIM_InitTypeDef* TIM_InitStruct) +ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, LL_TIM_InitTypeDef *TIM_InitStruct) { - uint16_t tmpcr1 = 0U; + uint32_t tmpcr1 = 0U; /* Check the parameters */ - assert_param(IS_TIM_INSTANCE(TIMx)); + assert_param(IS_TIM_INSTANCE(TIMx)); assert_param(IS_LL_TIM_COUNTERMODE(TIM_InitStruct->CounterMode)); assert_param(IS_LL_TIM_CLOCKDIVISION(TIM_InitStruct->ClockDivision)); - tmpcr1 = LL_TIM_ReadReg(TIMx, CR1); + tmpcr1 = LL_TIM_ReadReg(TIMx, CR1); - if(IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx)) + if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx)) { /* Select the Counter Mode */ - tmpcr1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS)); - tmpcr1 |= (uint32_t)TIM_InitStruct->CounterMode; + MODIFY_REG(tmpcr1, (TIM_CR1_DIR | TIM_CR1_CMS), TIM_InitStruct->CounterMode); } - - if(IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx)) + + if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx)) { /* Set the clock division */ - tmpcr1 &= (uint16_t)(~TIM_CR1_CKD); - tmpcr1 |= (uint32_t)TIM_InitStruct->ClockDivision; + MODIFY_REG(tmpcr1, TIM_CR1_CKD, TIM_InitStruct->ClockDivision); } /* Write to TIMx CR1 */ @@ -267,23 +263,23 @@ ErrorStatus LL_TIM_Init(TIM_TypeDef * TIMx, LL_TIM_InitTypeDef* TIM_InitStruct) /* Set the Autoreload value */ LL_TIM_SetAutoReload(TIMx, TIM_InitStruct->Autoreload); - + /* Set the Prescaler value */ LL_TIM_SetPrescaler(TIMx, TIM_InitStruct->Prescaler); - /* Generate an update event to reload the Prescaler + /* Generate an update event to reload the Prescaler and the repetition counter value (if applicable) immediately */ LL_TIM_GenerateEvent_UPDATE(TIMx); - + return SUCCESS; } /** - * @brief Set the fields of the TIMx output channel configuration data + * @brief Set the fields of the TIMx output channel configuration data * structure to their default values. * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (the output channel configuration data structure) * @retval None */ -void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef* TIM_OC_InitStruct) +void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct) { /* Set the default configuration */ TIM_OC_InitStruct->OCMode = LL_TIM_OCMODE_FROZEN; @@ -305,38 +301,38 @@ void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef* TIM_OC_InitStruct) * - SUCCESS: TIMx output channel is initialized * - ERROR: TIMx output channel is not initialized */ -ErrorStatus LL_TIM_OC_Init(TIM_TypeDef* TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef* TIM_OC_InitStruct) +ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct) { ErrorStatus result = ERROR; - - switch(Channel) + + switch (Channel) { - case LL_TIM_CHANNEL_CH1: - result = OC1Config(TIMx, TIM_OC_InitStruct); - break; - case LL_TIM_CHANNEL_CH2: - result = OC2Config(TIMx, TIM_OC_InitStruct); - break; - case LL_TIM_CHANNEL_CH3: - result = OC3Config(TIMx, TIM_OC_InitStruct); - break; - case LL_TIM_CHANNEL_CH4: - result = OC4Config(TIMx, TIM_OC_InitStruct); - break; - default: - break; + case LL_TIM_CHANNEL_CH1: + result = OC1Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH2: + result = OC2Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH3: + result = OC3Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH4: + result = OC4Config(TIMx, TIM_OC_InitStruct); + break; + default: + break; } - + return result; } /** - * @brief Set the fields of the TIMx input channel configuration data + * @brief Set the fields of the TIMx input channel configuration data * structure to their default values. * @param TIM_ICInitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (the input channel configuration data structure) * @retval None */ -void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef* TIM_ICInitStruct) +void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) { /* Set the default configuration */ TIM_ICInitStruct->ICPolarity = LL_TIM_IC_POLARITY_RISING; @@ -358,28 +354,28 @@ void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef* TIM_ICInitStruct) * - SUCCESS: TIMx output channel is initialized * - ERROR: TIMx output channel is not initialized */ -ErrorStatus LL_TIM_IC_Init(TIM_TypeDef* TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef* TIM_IC_InitStruct) +ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct) { ErrorStatus result = ERROR; - - switch(Channel) + + switch (Channel) { - case LL_TIM_CHANNEL_CH1: - result = IC1Config(TIMx, TIM_IC_InitStruct); - break; - case LL_TIM_CHANNEL_CH2: - result = IC2Config(TIMx, TIM_IC_InitStruct); - break; - case LL_TIM_CHANNEL_CH3: - result = IC3Config(TIMx, TIM_IC_InitStruct); - break; - case LL_TIM_CHANNEL_CH4: - result = IC4Config(TIMx, TIM_IC_InitStruct); - break; - default: - break; + case LL_TIM_CHANNEL_CH1: + result = IC1Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH2: + result = IC2Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH3: + result = IC3Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH4: + result = IC4Config(TIMx, TIM_IC_InitStruct); + break; + default: + break; } - + return result; } @@ -388,7 +384,7 @@ ErrorStatus LL_TIM_IC_Init(TIM_TypeDef* TIMx, uint32_t Channel, LL_TIM_IC_InitTy * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (encoder interface configuration data structure) * @retval None */ -void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef* TIM_EncoderInitStruct) +void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct) { /* Set the default configuration */ TIM_EncoderInitStruct->EncoderMode = LL_TIM_ENCODERMODE_X2_TI1; @@ -410,7 +406,7 @@ void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef* TIM_EncoderInitStruct * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef* TIMx, LL_TIM_ENCODER_InitTypeDef* TIM_EncoderInitStruct) +ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct) { uint32_t tmpccmr1 = 0U; uint32_t tmpccer = 0U; @@ -426,40 +422,40 @@ ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef* TIMx, LL_TIM_ENCODER_InitTypeDef* T assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC2ActiveInput)); assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC2Prescaler)); assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC2Filter)); - + /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */ TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E); - + /* Get the TIMx CCMR1 register value */ tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); /* Get the TIMx CCER register value */ - tmpccer = LL_TIM_ReadReg(TIMx, CCER); + tmpccer = LL_TIM_ReadReg(TIMx, CCER); /* Configure TI1 */ tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC); tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1ActiveInput >> 16U); tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Filter >> 16U); tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Prescaler >> 16U); - + /* Configure TI2 */ tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC); tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2ActiveInput >> 8U); tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Filter >> 8U); tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Prescaler >> 8U); - + /* Set TI1 and TI2 polarity and enable TI1 and TI2 */ tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP); tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC1Polarity); tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC2Polarity << 4U); tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E); - /* Set encoder mode */ + /* Set encoder mode */ LL_TIM_SetEncoderMode(TIMx, TIM_EncoderInitStruct->EncoderMode); - - /* Write to TIMx CCMR1 */ + + /* Write to TIMx CCMR1 */ LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); - + /* Write to TIMx CCER */ LL_TIM_WriteReg(TIMx, CCER, tmpccer); @@ -487,51 +483,51 @@ ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef* TIMx, LL_TIM_ENCODER_InitTypeDef* T * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -static ErrorStatus OC1Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCInitStruct) +static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) { uint32_t tmpccmr1 = 0U; uint32_t tmpccer = 0U; uint32_t tmpcr2 = 0U; - + /* Check the parameters */ - assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); - assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); /* Disable the Channel 1: Reset the CC1E Bit */ CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1E); - + /* Get the TIMx CCER register value */ - tmpccer = LL_TIM_ReadReg(TIMx, CCER); - + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + /* Get the TIMx CR2 register value */ - tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); - + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + /* Get the TIMx CCMR1 register value */ tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); - + /* Reset Capture/Compare selection Bits */ CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC1S); - + /* Set the Output Compare Mode */ MODIFY_REG(tmpccmr1, TIM_CCMR1_OC1M, TIM_OCInitStruct->OCMode); - + /* Set the Output Compare Polarity */ MODIFY_REG(tmpccer, TIM_CCER_CC1P, TIM_OCInitStruct->OCPolarity); - + /* Set the Output State */ MODIFY_REG(tmpccer, TIM_CCER_CC1E, TIM_OCInitStruct->OCState); - + /* Write to TIMx CR2 */ LL_TIM_WriteReg(TIMx, CR2, tmpcr2); - + /* Write to TIMx CCMR1 */ LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); - + /* Set the Capture Compare Register value */ LL_TIM_OC_SetCompareCH1(TIMx, TIM_OCInitStruct->CompareValue); - + /* Write to TIMx CCER */ LL_TIM_WriteReg(TIMx, CCER, tmpccer); @@ -546,54 +542,54 @@ static ErrorStatus OC1Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCIni * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -static ErrorStatus OC2Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCInitStruct) +static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) { uint32_t tmpccmr1 = 0U; uint32_t tmpccer = 0U; uint32_t tmpcr2 = 0U; - + /* Check the parameters */ - assert_param(IS_TIM_CC2_INSTANCE(TIMx)); + assert_param(IS_TIM_CC2_INSTANCE(TIMx)); assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); - assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); /* Disable the Channel 2: Reset the CC2E Bit */ CLEAR_BIT(TIMx->CCER, TIM_CCER_CC2E); - - /* Get the TIMx CCER register value */ - tmpccer = LL_TIM_ReadReg(TIMx, CCER); - + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + /* Get the TIMx CR2 register value */ - tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); - + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + /* Get the TIMx CCMR1 register value */ tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); - + /* Reset Capture/Compare selection Bits */ CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC2S); - + /* Select the Output Compare Mode */ MODIFY_REG(tmpccmr1, TIM_CCMR1_OC2M, TIM_OCInitStruct->OCMode << 8U); - + /* Set the Output Compare Polarity */ - MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity<< 4U); - + MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity << 4U); + /* Set the Output State */ MODIFY_REG(tmpccer, TIM_CCER_CC2E, TIM_OCInitStruct->OCState << 4U); - + /* Write to TIMx CR2 */ LL_TIM_WriteReg(TIMx, CR2, tmpcr2); - + /* Write to TIMx CCMR1 */ LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); - + /* Set the Capture Compare Register value */ LL_TIM_OC_SetCompareCH2(TIMx, TIM_OCInitStruct->CompareValue); - + /* Write to TIMx CCER */ LL_TIM_WriteReg(TIMx, CCER, tmpccer); - + return SUCCESS; } @@ -605,51 +601,51 @@ static ErrorStatus OC2Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCIni * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -static ErrorStatus OC3Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCInitStruct) +static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) { uint32_t tmpccmr2 = 0U; uint32_t tmpccer = 0U; uint32_t tmpcr2 = 0U; - + /* Check the parameters */ - assert_param(IS_TIM_CC3_INSTANCE(TIMx)); + assert_param(IS_TIM_CC3_INSTANCE(TIMx)); assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); - assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); /* Disable the Channel 3: Reset the CC3E Bit */ CLEAR_BIT(TIMx->CCER, TIM_CCER_CC3E); - + /* Get the TIMx CCER register value */ - tmpccer = LL_TIM_ReadReg(TIMx, CCER); - + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + /* Get the TIMx CR2 register value */ - tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); - + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + /* Get the TIMx CCMR2 register value */ tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2); - + /* Reset Capture/Compare selection Bits */ CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC3S); - + /* Select the Output Compare Mode */ MODIFY_REG(tmpccmr2, TIM_CCMR2_OC3M, TIM_OCInitStruct->OCMode); - + /* Set the Output Compare Polarity */ MODIFY_REG(tmpccer, TIM_CCER_CC3P, TIM_OCInitStruct->OCPolarity << 8U); - + /* Set the Output State */ MODIFY_REG(tmpccer, TIM_CCER_CC3E, TIM_OCInitStruct->OCState << 8U); - + /* Write to TIMx CR2 */ LL_TIM_WriteReg(TIMx, CR2, tmpcr2); - + /* Write to TIMx CCMR2 */ LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2); - + /* Set the Capture Compare Register value */ LL_TIM_OC_SetCompareCH3(TIMx, TIM_OCInitStruct->CompareValue); - + /* Write to TIMx CCER */ LL_TIM_WriteReg(TIMx, CCER, tmpccer); @@ -664,51 +660,51 @@ static ErrorStatus OC3Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCIni * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -static ErrorStatus OC4Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCInitStruct) +static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) { uint32_t tmpccmr2 = 0U; uint32_t tmpccer = 0U; uint32_t tmpcr2 = 0U; - + /* Check the parameters */ - assert_param(IS_TIM_CC4_INSTANCE(TIMx)); + assert_param(IS_TIM_CC4_INSTANCE(TIMx)); assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); - assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); /* Disable the Channel 4: Reset the CC4E Bit */ CLEAR_BIT(TIMx->CCER, TIM_CCER_CC4E); - + /* Get the TIMx CCER register value */ - tmpccer = LL_TIM_ReadReg(TIMx, CCER); - + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + /* Get the TIMx CR2 register value */ - tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); - + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + /* Get the TIMx CCMR2 register value */ tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2); - + /* Reset Capture/Compare selection Bits */ CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC4S); - + /* Select the Output Compare Mode */ MODIFY_REG(tmpccmr2, TIM_CCMR2_OC4M, TIM_OCInitStruct->OCMode << 8U); - + /* Set the Output Compare Polarity */ MODIFY_REG(tmpccer, TIM_CCER_CC4P, TIM_OCInitStruct->OCPolarity << 12U); - + /* Set the Output State */ MODIFY_REG(tmpccer, TIM_CCER_CC4E, TIM_OCInitStruct->OCState << 12U); - + /* Write to TIMx CR2 */ LL_TIM_WriteReg(TIMx, CR2, tmpcr2); - - /* Write to TIMx CCMR2 */ + + /* Write to TIMx CCMR2 */ LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2); - + /* Set the Capture Compare Register value */ LL_TIM_OC_SetCompareCH4(TIMx, TIM_OCInitStruct->CompareValue); - + /* Write to TIMx CCER */ LL_TIM_WriteReg(TIMx, CCER, tmpccer); @@ -724,7 +720,7 @@ static ErrorStatus OC4Config(TIM_TypeDef* TIMx, LL_TIM_OC_InitTypeDef* TIM_OCIni * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -static ErrorStatus IC1Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICInitStruct) +static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) { /* Check the parameters */ assert_param(IS_TIM_CC1_INSTANCE(TIMx)); @@ -732,17 +728,17 @@ static ErrorStatus IC1Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); - + /* Disable the Channel 1: Reset the CC1E Bit */ TIMx->CCER &= (uint32_t)~TIM_CCER_CC1E; - + /* Select the Input and set the filter and the prescaler value */ - MODIFY_REG(TIMx->CCMR1, + MODIFY_REG(TIMx->CCMR1, (TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC), (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U); /* Select the Polarity and set the CC1E Bit */ - MODIFY_REG(TIMx->CCER, + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P | TIM_CCER_CC1NP), (TIM_ICInitStruct->ICPolarity | TIM_CCER_CC1E)); @@ -757,7 +753,7 @@ static ErrorStatus IC1Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -static ErrorStatus IC2Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICInitStruct) +static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) { /* Check the parameters */ assert_param(IS_TIM_CC2_INSTANCE(TIMx)); @@ -765,20 +761,20 @@ static ErrorStatus IC2Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); - + /* Disable the Channel 2: Reset the CC2E Bit */ TIMx->CCER &= (uint32_t)~TIM_CCER_CC2E; - + /* Select the Input and set the filter and the prescaler value */ - MODIFY_REG(TIMx->CCMR1, + MODIFY_REG(TIMx->CCMR1, (TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC), (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U); /* Select the Polarity and set the CC2E Bit */ - MODIFY_REG(TIMx->CCER, + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC2P | TIM_CCER_CC2NP), - ((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E) ); - + ((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E)); + return SUCCESS; } @@ -790,7 +786,7 @@ static ErrorStatus IC2Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -static ErrorStatus IC3Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICInitStruct) +static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) { /* Check the parameters */ assert_param(IS_TIM_CC3_INSTANCE(TIMx)); @@ -798,19 +794,19 @@ static ErrorStatus IC3Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); - + /* Disable the Channel 3: Reset the CC3E Bit */ TIMx->CCER &= (uint32_t)~TIM_CCER_CC3E; - + /* Select the Input and set the filter and the prescaler value */ - MODIFY_REG(TIMx->CCMR2, + MODIFY_REG(TIMx->CCMR2, (TIM_CCMR2_CC3S | TIM_CCMR2_IC3F | TIM_CCMR2_IC3PSC), (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U); /* Select the Polarity and set the CC3E Bit */ - MODIFY_REG(TIMx->CCER, + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC3P | TIM_CCER_CC3NP), - ((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E) ); + ((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E)); return SUCCESS; } @@ -823,7 +819,7 @@ static ErrorStatus IC3Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni * - SUCCESS: TIMx registers are de-initialized * - ERROR: not applicable */ -static ErrorStatus IC4Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICInitStruct) +static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) { /* Check the parameters */ assert_param(IS_TIM_CC4_INSTANCE(TIMx)); @@ -831,19 +827,19 @@ static ErrorStatus IC4Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); - + /* Disable the Channel 4: Reset the CC4E Bit */ TIMx->CCER &= (uint32_t)~TIM_CCER_CC4E; - + /* Select the Input and set the filter and the prescaler value */ - MODIFY_REG(TIMx->CCMR2, + MODIFY_REG(TIMx->CCMR2, (TIM_CCMR2_CC4S | TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC), (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U); /* Select the Polarity and set the CC2E Bit */ - MODIFY_REG(TIMx->CCER, + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC4P | TIM_CCER_CC4NP), - ((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E) ); + ((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E)); return SUCCESS; } @@ -862,7 +858,7 @@ static ErrorStatus IC4Config(TIM_TypeDef* TIMx, LL_TIM_IC_InitTypeDef* TIM_ICIni /** * @} */ - + #endif /* USE_FULL_LL_DRIVER */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_tim.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_tim.h index ec72b2cba0..d33ab776f5 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_tim.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_tim.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_tim.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of TIM LL module. ****************************************************************************** * @attention @@ -61,16 +59,16 @@ extern "C" { /** @defgroup TIM_LL_Private_Variables TIM Private Variables * @{ */ -static const uint8_t OFFSET_TAB_CCMRx[] = - { - 0x00U, /* 0: TIMx_CH1 */ - 0x00U, /* 1: NA */ - 0x00U, /* 2: TIMx_CH2 */ - 0x00U, /* 3: NA */ - 0x04U, /* 4: TIMx_CH3 */ - 0x00U, /* 5: NA */ - 0x04U /* 6: TIMx_CH4 */ - }; +static const uint8_t OFFSET_TAB_CCMRx[] = +{ + 0x00U, /* 0: TIMx_CH1 */ + 0x00U, /* 1: NA */ + 0x00U, /* 2: TIMx_CH2 */ + 0x00U, /* 3: NA */ + 0x04U, /* 4: TIMx_CH3 */ + 0x00U, /* 5: NA */ + 0x04U /* 6: TIMx_CH4 */ +}; static const uint8_t SHIFT_TAB_OCxx[] = { @@ -114,15 +112,6 @@ static const uint8_t SHIFT_TAB_CCxP[] = /** @defgroup TIM_LL_Private_Constants TIM Private Constants * @{ */ -/** @defgroup TIM_LL_POSITION_VAL Bit Position Value - * @brief Position of the bit in the register. - * @{ - */ -/* Defines used for the bit position in the register and perform offsets*/ -#define TIM_POSITION_ICPSC (uint32_t)2U /*!< field position in half register TIMx_CCMRx (8 bits)*/ -/** - * @} - */ /* Remap mask definitions */ @@ -147,7 +136,7 @@ static const uint8_t SHIFT_TAB_CCxP[] = * @{ */ /** @brief Convert channel id into channel index. - * @param __CHANNEL__ This parameter can be one of the following values: + * @param __CHANNEL__ This parameter can be one of the following values: * @arg @ref LL_TIM_CHANNEL_CH1 * @arg @ref LL_TIM_CHANNEL_CH2 * @arg @ref LL_TIM_CHANNEL_CH3 @@ -170,13 +159,13 @@ static const uint8_t SHIFT_TAB_CCxP[] = * @{ */ -/** - * @brief TIM Time Base configuration structure definition. +/** + * @brief TIM Time Base configuration structure definition. */ typedef struct { uint16_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. - This parameter can be a number between 0x0000 and 0xFFFF. + This parameter can be a number between Min_Data=0x0000 and Max_Data=0xFFFF. This feature can be modified afterwards using unitary function @ref LL_TIM_SetPrescaler().*/ @@ -187,19 +176,19 @@ typedef struct uint32_t Autoreload; /*!< Specifies the auto reload 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. - Some timer instances may support 32 bits counters. In that case this parameter must be a number between 0x0000 and 0xFFFFFFFF. + This parameter must be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + Some timer instances may support 32 bits counters. In that case this parameter must be a number between 0x0000 and 0xFFFFFFFF. - This feature can be modified afterwards using unitary function @ref LL_TIM_SetAutoReload().*/ + This feature can be modified afterwards using unitary function @ref LL_TIM_SetAutoReload().*/ uint32_t ClockDivision; /*!< Specifies the clock division. - This parameter can be a value of @ref TIM_LL_EC_CLOCKDIVISION. - - This feature can be modified afterwards using unitary function @ref LL_TIM_SetClockDivision().*/ -} LL_TIM_InitTypeDef; + This parameter can be a value of @ref TIM_LL_EC_CLOCKDIVISION. -/** - * @brief TIM Output Compare configuration structure definition. + This feature can be modified afterwards using unitary function @ref LL_TIM_SetClockDivision().*/ +} LL_TIM_InitTypeDef; + +/** + * @brief TIM Output Compare configuration structure definition. */ typedef struct { @@ -214,7 +203,7 @@ typedef struct This feature can be modified afterwards using unitary functions @ref LL_TIM_CC_EnableChannel() or @ref LL_TIM_CC_DisableChannel().*/ uint32_t CompareValue; /*!< Specifies the Compare value to be loaded into the Capture Compare Register. - This parameter can be a number between 0x0000 and 0xFFFF. + This parameter can be a number between Min_Data=0x0000 and Max_Data=0xFFFF. This feature can be modified afterwards using unitary function LL_TIM_OC_SetCompareCHx (x=1..6).*/ @@ -225,8 +214,8 @@ typedef struct } LL_TIM_OC_InitTypeDef; -/** - * @brief TIM Input Capture configuration structure definition. +/** + * @brief TIM Input Capture configuration structure definition. */ typedef struct @@ -316,7 +305,7 @@ typedef struct /** @defgroup TIM_LL_Exported_Constants TIM Exported Constants * @{ */ - + /** @defgroup TIM_LL_EC_GET_FLAG Get Flags Defines * @brief Flags defines which can be used with LL_TIM_ReadReg function. * @{ @@ -352,8 +341,8 @@ typedef struct /** @defgroup TIM_LL_EC_UPDATESOURCE Update Source * @{ */ -#define LL_TIM_UPDATESOURCE_REGULAR ((uint32_t)0x00000000U) /*!< Counter overflow/underflow, Setting the UG bit or Update generation through the slave mode controller generates an update request */ -#define LL_TIM_UPDATESOURCE_COUNTER TIM_CR1_URS /*!< Only counter overflow/underflow generates an update request */ +#define LL_TIM_UPDATESOURCE_REGULAR ((uint32_t)0x00000000U) /*!< Counter overflow/underflow, Setting the UG bit or Update generation through the slave mode controller generates an update request */ +#define LL_TIM_UPDATESOURCE_COUNTER TIM_CR1_URS /*!< Only counter overflow/underflow generates an update request */ /** * @} */ @@ -361,8 +350,8 @@ typedef struct /** @defgroup TIM_LL_EC_ONEPULSEMODE One Pulse Mode * @{ */ -#define LL_TIM_ONEPULSEMODE_SINGLE TIM_CR1_OPM /*!< Counter is not stopped at update event */ -#define LL_TIM_ONEPULSEMODE_REPETITIVE ((uint32_t)0x00000000U) /*!< Counter stops counting at the next update event */ +#define LL_TIM_ONEPULSEMODE_SINGLE TIM_CR1_OPM /*!< Counter is not stopped at update event */ +#define LL_TIM_ONEPULSEMODE_REPETITIVE ((uint32_t)0x00000000U) /*!< Counter stops counting at the next update event */ /** * @} */ @@ -370,11 +359,11 @@ typedef struct /** @defgroup TIM_LL_EC_COUNTERMODE Counter Mode * @{ */ -#define LL_TIM_COUNTERMODE_UP ((uint32_t)0x00000000U) /*!TIMx_CCRy else active.*/ -#define LL_TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!TIMx_CCRy else inactive*/ +#define LL_TIM_OCMODE_FROZEN ((uint32_t)0x00000000U) /*!TIMx_CCRy else active.*/ +#define LL_TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!TIMx_CCRy else inactive*/ /** * @} */ @@ -449,8 +438,8 @@ typedef struct /** @defgroup TIM_LL_EC_OCPOLARITY Output Configuration Polarity * @{ */ -#define LL_TIM_OCPOLARITY_HIGH ((uint32_t)0x00000000U) /*!< OCxactive high*/ -#define LL_TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< OCxactive low*/ +#define LL_TIM_OCPOLARITY_HIGH ((uint32_t)0x00000000U) /*!< OCxactive high*/ +#define LL_TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< OCxactive low*/ /** * @} */ @@ -460,9 +449,9 @@ typedef struct /** @defgroup TIM_LL_EC_ACTIVEINPUT Active Input Selection * @{ */ -#define LL_TIM_ACTIVEINPUT_DIRECTTI (uint32_t)(TIM_CCMR1_CC1S_0 << 16U) /*!< ICx is mapped on TIx */ -#define LL_TIM_ACTIVEINPUT_INDIRECTTI (uint32_t)(TIM_CCMR1_CC1S_1 << 16U) /*!< ICx is mapped on TIy */ -#define LL_TIM_ACTIVEINPUT_TRC (uint32_t)(TIM_CCMR1_CC1S << 16U) /*!< ICx is mapped on TRC */ +#define LL_TIM_ACTIVEINPUT_DIRECTTI (uint32_t)(TIM_CCMR1_CC1S_0 << 16U) /*!< ICx is mapped on TIx */ +#define LL_TIM_ACTIVEINPUT_INDIRECTTI (uint32_t)(TIM_CCMR1_CC1S_1 << 16U) /*!< ICx is mapped on TIy */ +#define LL_TIM_ACTIVEINPUT_TRC (uint32_t)(TIM_CCMR1_CC1S << 16U) /*!< ICx is mapped on TRC */ /** * @} */ @@ -470,10 +459,10 @@ typedef struct /** @defgroup TIM_LL_EC_ICPSC Input Configuration Prescaler * @{ */ -#define LL_TIM_ICPSC_DIV1 ((uint32_t)0x00000000U) /*!< No prescaler, capture is done each time an edge is detected on the capture input */ -#define LL_TIM_ICPSC_DIV2 (uint32_t)(TIM_CCMR1_IC1PSC_0 << 16U) /*!< Capture is done once every 2 events */ -#define LL_TIM_ICPSC_DIV4 (uint32_t)(TIM_CCMR1_IC1PSC_1 << 16U) /*!< Capture is done once every 4 events */ -#define LL_TIM_ICPSC_DIV8 (uint32_t)(TIM_CCMR1_IC1PSC << 16U) /*!< Capture is done once every 8 events */ +#define LL_TIM_ICPSC_DIV1 ((uint32_t)0x00000000U) /*!< No prescaler, capture is done each time an edge is detected on the capture input */ +#define LL_TIM_ICPSC_DIV2 (uint32_t)(TIM_CCMR1_IC1PSC_0 << 16U) /*!< Capture is done once every 2 events */ +#define LL_TIM_ICPSC_DIV4 (uint32_t)(TIM_CCMR1_IC1PSC_1 << 16U) /*!< Capture is done once every 4 events */ +#define LL_TIM_ICPSC_DIV8 (uint32_t)(TIM_CCMR1_IC1PSC << 16U) /*!< Capture is done once every 8 events */ /** * @} */ @@ -481,22 +470,22 @@ typedef struct /** @defgroup TIM_LL_EC_IC_FILTER Input Configuration Filter * @{ */ -#define LL_TIM_IC_FILTER_FDIV1 ((uint32_t)0x00000000U) /*!< No filter, sampling is done at fDTS */ -#define LL_TIM_IC_FILTER_FDIV1_N2 (uint32_t)(TIM_CCMR1_IC1F_0 << 16U) /*!< fSAMPLING=fCK_INT, N=2 */ -#define LL_TIM_IC_FILTER_FDIV1_N4 (uint32_t)(TIM_CCMR1_IC1F_1 << 16U) /*!< fSAMPLING=fCK_INT, N=4 */ -#define LL_TIM_IC_FILTER_FDIV1_N8 (uint32_t)((TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fCK_INT, N=8 */ -#define LL_TIM_IC_FILTER_FDIV2_N6 (uint32_t)(TIM_CCMR1_IC1F_2 << 16U) /*!< fSAMPLING=fDTS/2, N=6 */ -#define LL_TIM_IC_FILTER_FDIV2_N8 (uint32_t)((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/2, N=8 */ -#define LL_TIM_IC_FILTER_FDIV4_N6 (uint32_t)((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/4, N=6 */ -#define LL_TIM_IC_FILTER_FDIV4_N8 (uint32_t)((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/4, N=8 */ -#define LL_TIM_IC_FILTER_FDIV8_N6 (uint32_t)(TIM_CCMR1_IC1F_3 << 16U) /*!< fSAMPLING=fDTS/8, N=6 */ -#define LL_TIM_IC_FILTER_FDIV8_N8 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/8, N=8 */ -#define LL_TIM_IC_FILTER_FDIV16_N5 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/16, N=5 */ -#define LL_TIM_IC_FILTER_FDIV16_N6 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/16, N=6 */ -#define LL_TIM_IC_FILTER_FDIV16_N8 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2) << 16U) /*!< fSAMPLING=fDTS/16, N=8 */ -#define LL_TIM_IC_FILTER_FDIV32_N5 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/32, N=5 */ -#define LL_TIM_IC_FILTER_FDIV32_N6 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/32, N=6 */ -#define LL_TIM_IC_FILTER_FDIV32_N8 (uint32_t)(TIM_CCMR1_IC1F << 16U) /*!< fSAMPLING=fDTS/32, N=8 */ +#define LL_TIM_IC_FILTER_FDIV1 ((uint32_t)0x00000000U) /*!< No filter, sampling is done at fDTS */ +#define LL_TIM_IC_FILTER_FDIV1_N2 (uint32_t)(TIM_CCMR1_IC1F_0 << 16U) /*!< fSAMPLING=fCK_INT, N=2 */ +#define LL_TIM_IC_FILTER_FDIV1_N4 (uint32_t)(TIM_CCMR1_IC1F_1 << 16U) /*!< fSAMPLING=fCK_INT, N=4 */ +#define LL_TIM_IC_FILTER_FDIV1_N8 (uint32_t)((TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fCK_INT, N=8 */ +#define LL_TIM_IC_FILTER_FDIV2_N6 (uint32_t)(TIM_CCMR1_IC1F_2 << 16U) /*!< fSAMPLING=fDTS/2, N=6 */ +#define LL_TIM_IC_FILTER_FDIV2_N8 (uint32_t)((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/2, N=8 */ +#define LL_TIM_IC_FILTER_FDIV4_N6 (uint32_t)((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/4, N=6 */ +#define LL_TIM_IC_FILTER_FDIV4_N8 (uint32_t)((TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/4, N=8 */ +#define LL_TIM_IC_FILTER_FDIV8_N6 (uint32_t)(TIM_CCMR1_IC1F_3 << 16U) /*!< fSAMPLING=fDTS/8, N=6 */ +#define LL_TIM_IC_FILTER_FDIV8_N8 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/8, N=8 */ +#define LL_TIM_IC_FILTER_FDIV16_N5 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/16, N=5 */ +#define LL_TIM_IC_FILTER_FDIV16_N6 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/16, N=6 */ +#define LL_TIM_IC_FILTER_FDIV16_N8 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2) << 16U) /*!< fSAMPLING=fDTS/16, N=8 */ +#define LL_TIM_IC_FILTER_FDIV32_N5 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_0) << 16U) /*!< fSAMPLING=fDTS/32, N=5 */ +#define LL_TIM_IC_FILTER_FDIV32_N6 (uint32_t)((TIM_CCMR1_IC1F_3 | TIM_CCMR1_IC1F_2 | TIM_CCMR1_IC1F_1) << 16U) /*!< fSAMPLING=fDTS/32, N=6 */ +#define LL_TIM_IC_FILTER_FDIV32_N8 (uint32_t)(TIM_CCMR1_IC1F << 16U) /*!< fSAMPLING=fDTS/32, N=8 */ /** * @} */ @@ -504,9 +493,9 @@ typedef struct /** @defgroup TIM_LL_EC_IC_POLARITY Input Configuration Polarity * @{ */ -#define LL_TIM_IC_POLARITY_RISING ((uint32_t)0x00000000U) /*!< The circuit is sensitive to TIxFP1 rising edge, TIxFP1 is not inverted */ -#define LL_TIM_IC_POLARITY_FALLING TIM_CCER_CC1P /*!< The circuit is sensitive to TIxFP1 falling edge, TIxFP1 is inverted */ -#define LL_TIM_IC_POLARITY_BOTHEDGE (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< The circuit is sensitive to both TIxFP1 rising and falling edges, TIxFP1 is not inverted */ +#define LL_TIM_IC_POLARITY_RISING ((uint32_t)0x00000000U) /*!< The circuit is sensitive to TIxFP1 rising edge, TIxFP1 is not inverted */ +#define LL_TIM_IC_POLARITY_FALLING TIM_CCER_CC1P /*!< The circuit is sensitive to TIxFP1 falling edge, TIxFP1 is inverted */ +#define LL_TIM_IC_POLARITY_BOTHEDGE (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< The circuit is sensitive to both TIxFP1 rising and falling edges, TIxFP1 is not inverted */ /** * @} */ @@ -524,8 +513,8 @@ typedef struct /** @defgroup TIM_LL_EC_ENCODERMODE Encoder Mode * @{ */ -#define LL_TIM_ENCODERMODE_X2_TI1 TIM_SMCR_SMS_0 /*!< Encoder mode 1 - Counter counts up/down on TI2FP2 edge depending on TI1FP1 level */ -#define LL_TIM_ENCODERMODE_X2_TI2 TIM_SMCR_SMS_1 /*!< Encoder mode 2 - Counter counts up/down on TI1FP1 edge depending on TI2FP2 level */ +#define LL_TIM_ENCODERMODE_X2_TI1 TIM_SMCR_SMS_0 /*!< Encoder mode 1 - Counter counts up/down on TI2FP2 edge depending on TI1FP1 level */ +#define LL_TIM_ENCODERMODE_X2_TI2 TIM_SMCR_SMS_1 /*!< Encoder mode 2 - Counter counts up/down on TI1FP1 edge depending on TI2FP2 level */ #define LL_TIM_ENCODERMODE_X4_TI12 (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input l */ /** * @} @@ -534,14 +523,14 @@ typedef struct /** @defgroup TIM_LL_EC_TRGO Trigger Output * @{ */ -#define LL_TIM_TRGO_RESET ((uint32_t)0x00000000U) /*!< UG bit from the TIMx_EGR register is used as trigger output */ -#define LL_TIM_TRGO_ENABLE TIM_CR2_MMS_0 /*!< Counter Enable signal (CNT_EN) is used as trigger output */ -#define LL_TIM_TRGO_UPDATE TIM_CR2_MMS_1 /*!< Update event is used as trigger output */ -#define LL_TIM_TRGO_CC1IF (TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< CC1 capture or a compare match is used as trigger output */ -#define LL_TIM_TRGO_OC1REF TIM_CR2_MMS_2 /*!< OC1REF signal is used as trigger output */ -#define LL_TIM_TRGO_OC2REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_0) /*!< OC2REF signal is used as trigger output */ -#define LL_TIM_TRGO_OC3REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1) /*!< OC3REF signal is used as trigger output */ -#define LL_TIM_TRGO_OC4REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< OC4REF signal is used as trigger output */ +#define LL_TIM_TRGO_RESET ((uint32_t)0x00000000U) /*!< UG bit from the TIMx_EGR register is used as trigger output */ +#define LL_TIM_TRGO_ENABLE TIM_CR2_MMS_0 /*!< Counter Enable signal (CNT_EN) is used as trigger output */ +#define LL_TIM_TRGO_UPDATE TIM_CR2_MMS_1 /*!< Update event is used as trigger output */ +#define LL_TIM_TRGO_CC1IF (TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< CC1 capture or a compare match is used as trigger output */ +#define LL_TIM_TRGO_OC1REF TIM_CR2_MMS_2 /*!< OC1REF signal is used as trigger output */ +#define LL_TIM_TRGO_OC2REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_0) /*!< OC2REF signal is used as trigger output */ +#define LL_TIM_TRGO_OC3REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1) /*!< OC3REF signal is used as trigger output */ +#define LL_TIM_TRGO_OC4REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< OC4REF signal is used as trigger output */ /** * @} */ @@ -550,10 +539,10 @@ typedef struct /** @defgroup TIM_LL_EC_SLAVEMODE Slave Mode * @{ */ -#define LL_TIM_SLAVEMODE_DISABLED ((uint32_t)0x00000000U) /*!< Slave mode disabled */ -#define LL_TIM_SLAVEMODE_RESET TIM_SMCR_SMS_2 /*!< Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter */ -#define LL_TIM_SLAVEMODE_GATED (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0) /*!< Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high */ -#define LL_TIM_SLAVEMODE_TRIGGER (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) /*!< Trigger Mode - The counter starts at a rising edge of the trigger TRGI */ +#define LL_TIM_SLAVEMODE_DISABLED ((uint32_t)0x00000000U) /*!< Slave mode disabled */ +#define LL_TIM_SLAVEMODE_RESET TIM_SMCR_SMS_2 /*!< Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter */ +#define LL_TIM_SLAVEMODE_GATED (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0) /*!< Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high */ +#define LL_TIM_SLAVEMODE_TRIGGER (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) /*!< Trigger Mode - The counter starts at a rising edge of the trigger TRGI */ /** * @} */ @@ -561,14 +550,14 @@ typedef struct /** @defgroup TIM_LL_EC_TS Trigger Selection * @{ */ -#define LL_TIM_TS_ITR0 ((uint32_t)0x00000000U) /*!< Internal Trigger 0 (ITR0) is used as trigger input */ -#define LL_TIM_TS_ITR1 TIM_SMCR_TS_0 /*!< Internal Trigger 1 (ITR1) is used as trigger input */ -#define LL_TIM_TS_ITR2 TIM_SMCR_TS_1 /*!< Internal Trigger 2 (ITR2) is used as trigger input */ -#define LL_TIM_TS_ITR3 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1) /*!< Internal Trigger 3 (ITR3) is used as trigger input */ -#define LL_TIM_TS_TI1F_ED TIM_SMCR_TS_2 /*!< TI1 Edge Detector (TI1F_ED) is used as trigger input */ -#define LL_TIM_TS_TI1FP1 (TIM_SMCR_TS_2 | TIM_SMCR_TS_0) /*!< Filtered Timer Input 1 (TI1FP1) is used as trigger input */ -#define LL_TIM_TS_TI2FP2 (TIM_SMCR_TS_2 | TIM_SMCR_TS_1) /*!< Filtered Timer Input 2 (TI12P2) is used as trigger input */ -#define LL_TIM_TS_ETRF TIM_SMCR_TS /*!< Filtered external Trigger (ETRF) is used as trigger input */ +#define LL_TIM_TS_ITR0 ((uint32_t)0x00000000U) /*!< Internal Trigger 0 (ITR0) is used as trigger input */ +#define LL_TIM_TS_ITR1 TIM_SMCR_TS_0 /*!< Internal Trigger 1 (ITR1) is used as trigger input */ +#define LL_TIM_TS_ITR2 TIM_SMCR_TS_1 /*!< Internal Trigger 2 (ITR2) is used as trigger input */ +#define LL_TIM_TS_ITR3 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1) /*!< Internal Trigger 3 (ITR3) is used as trigger input */ +#define LL_TIM_TS_TI1F_ED TIM_SMCR_TS_2 /*!< TI1 Edge Detector (TI1F_ED) is used as trigger input */ +#define LL_TIM_TS_TI1FP1 (TIM_SMCR_TS_2 | TIM_SMCR_TS_0) /*!< Filtered Timer Input 1 (TI1FP1) is used as trigger input */ +#define LL_TIM_TS_TI2FP2 (TIM_SMCR_TS_2 | TIM_SMCR_TS_1) /*!< Filtered Timer Input 2 (TI12P2) is used as trigger input */ +#define LL_TIM_TS_ETRF (TIM_SMCR_TS_2 | TIM_SMCR_TS_1 | TIM_SMCR_TS_0) /*!< Filtered external Trigger (ETRF) is used as trigger input */ /** * @} */ @@ -576,8 +565,8 @@ typedef struct /** @defgroup TIM_LL_EC_ETR_POLARITY External Trigger Polarity * @{ */ -#define LL_TIM_ETR_POLARITY_NONINVERTED ((uint32_t)0x00000000U) /*!< ETR is non-inverted, active at high level or rising edge */ -#define LL_TIM_ETR_POLARITY_INVERTED TIM_SMCR_ETP /*!< ETR is inverted, active at low level or falling edge */ +#define LL_TIM_ETR_POLARITY_NONINVERTED ((uint32_t)0x00000000U) /*!< ETR is non-inverted, active at high level or rising edge */ +#define LL_TIM_ETR_POLARITY_INVERTED TIM_SMCR_ETP /*!< ETR is inverted, active at low level or falling edge */ /** * @} */ @@ -585,10 +574,10 @@ typedef struct /** @defgroup TIM_LL_EC_ETR_PRESCALER External Trigger Prescaler * @{ */ -#define LL_TIM_ETR_PRESCALER_DIV1 ((uint32_t)0x00000000U) /*!< ETR prescaler OFF */ -#define LL_TIM_ETR_PRESCALER_DIV2 TIM_SMCR_ETPS_0 /*!< ETR frequency is divided by 2 */ -#define LL_TIM_ETR_PRESCALER_DIV4 TIM_SMCR_ETPS_1 /*!< ETR frequency is divided by 4 */ -#define LL_TIM_ETR_PRESCALER_DIV8 TIM_SMCR_ETPS /*!< ETR frequency is divided by 8 */ +#define LL_TIM_ETR_PRESCALER_DIV1 ((uint32_t)0x00000000U) /*!< ETR prescaler OFF */ +#define LL_TIM_ETR_PRESCALER_DIV2 TIM_SMCR_ETPS_0 /*!< ETR frequency is divided by 2 */ +#define LL_TIM_ETR_PRESCALER_DIV4 TIM_SMCR_ETPS_1 /*!< ETR frequency is divided by 4 */ +#define LL_TIM_ETR_PRESCALER_DIV8 TIM_SMCR_ETPS /*!< ETR frequency is divided by 8 */ /** * @} */ @@ -596,22 +585,22 @@ typedef struct /** @defgroup TIM_LL_EC_ETR_FILTER External Trigger Filter * @{ */ -#define LL_TIM_ETR_FILTER_FDIV1 ((uint32_t)0x00000000U) /*!< No filter, sampling is done at fDTS */ -#define LL_TIM_ETR_FILTER_FDIV1_N2 TIM_SMCR_ETF_0 /*!< fSAMPLING=fCK_INT, N=2 */ -#define LL_TIM_ETR_FILTER_FDIV1_N4 TIM_SMCR_ETF_1 /*!< fSAMPLING=fCK_INT, N=4 */ -#define LL_TIM_ETR_FILTER_FDIV1_N8 (TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fCK_INT, N=8 */ -#define LL_TIM_ETR_FILTER_FDIV2_N6 TIM_SMCR_ETF_2 /*!< fSAMPLING=fDTS/2, N=6 */ -#define LL_TIM_ETR_FILTER_FDIV2_N8 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/2, N=8 */ -#define LL_TIM_ETR_FILTER_FDIV4_N6 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1 ) /*!< fSAMPLING=fDTS/4, N=6 */ -#define LL_TIM_ETR_FILTER_FDIV4_N8 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/4, N=8 */ -#define LL_TIM_ETR_FILTER_FDIV8_N6 TIM_SMCR_ETF_3 /*!< fSAMPLING=fDTS/8, N=8 */ -#define LL_TIM_ETR_FILTER_FDIV8_N8 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/16, N=5 */ -#define LL_TIM_ETR_FILTER_FDIV16_N5 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_1 ) /*!< fSAMPLING=fDTS/16, N=6 */ -#define LL_TIM_ETR_FILTER_FDIV16_N6 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/16, N=8 */ -#define LL_TIM_ETR_FILTER_FDIV16_N8 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2 ) /*!< fSAMPLING=fDTS/16, N=5 */ -#define LL_TIM_ETR_FILTER_FDIV32_N5 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/32, N=5 */ -#define LL_TIM_ETR_FILTER_FDIV32_N6 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1) /*!< fSAMPLING=fDTS/32, N=6 */ -#define LL_TIM_ETR_FILTER_FDIV32_N8 TIM_SMCR_ETF /*!< fSAMPLING=fDTS/32, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV1 ((uint32_t)0x00000000U) /*!< No filter, sampling is done at fDTS */ +#define LL_TIM_ETR_FILTER_FDIV1_N2 TIM_SMCR_ETF_0 /*!< fSAMPLING=fCK_INT, N=2 */ +#define LL_TIM_ETR_FILTER_FDIV1_N4 TIM_SMCR_ETF_1 /*!< fSAMPLING=fCK_INT, N=4 */ +#define LL_TIM_ETR_FILTER_FDIV1_N8 (TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fCK_INT, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV2_N6 TIM_SMCR_ETF_2 /*!< fSAMPLING=fDTS/2, N=6 */ +#define LL_TIM_ETR_FILTER_FDIV2_N8 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/2, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV4_N6 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1 ) /*!< fSAMPLING=fDTS/4, N=6 */ +#define LL_TIM_ETR_FILTER_FDIV4_N8 (TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/4, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV8_N6 TIM_SMCR_ETF_3 /*!< fSAMPLING=fDTS/8, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV8_N8 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/16, N=5 */ +#define LL_TIM_ETR_FILTER_FDIV16_N5 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_1 ) /*!< fSAMPLING=fDTS/16, N=6 */ +#define LL_TIM_ETR_FILTER_FDIV16_N6 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/16, N=8 */ +#define LL_TIM_ETR_FILTER_FDIV16_N8 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2 ) /*!< fSAMPLING=fDTS/16, N=5 */ +#define LL_TIM_ETR_FILTER_FDIV32_N5 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2 | TIM_SMCR_ETF_0) /*!< fSAMPLING=fDTS/32, N=5 */ +#define LL_TIM_ETR_FILTER_FDIV32_N6 (TIM_SMCR_ETF_3 | TIM_SMCR_ETF_2 | TIM_SMCR_ETF_1) /*!< fSAMPLING=fDTS/32, N=6 */ +#define LL_TIM_ETR_FILTER_FDIV32_N8 TIM_SMCR_ETF /*!< fSAMPLING=fDTS/32, N=8 */ /** * @} */ @@ -625,30 +614,30 @@ typedef struct /** @defgroup TIM_LL_EC_DMABURST_BASEADDR DMA Burst Base Address * @{ */ -#define LL_TIM_DMABURST_BASEADDR_CR1 ((uint32_t)0x00000000U) /*!< TIMx_CR1 register is the DMA base address for DMA burst */ /*!< TIMx_CR1 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CR2 TIM_DCR_DBA_0 /*!< TIMx_CR2 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_SMCR TIM_DCR_DBA_1 /*!< TIMx_SMCR register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_DIER (TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_DIER register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_SR TIM_DCR_DBA_2 /*!< TIMx_SR register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_EGR (TIM_DCR_DBA_2 | TIM_DCR_DBA_0) /*!< TIMx_EGR register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCMR1 (TIM_DCR_DBA_2 | TIM_DCR_DBA_1) /*!< TIMx_CCMR1 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCMR2 (TIM_DCR_DBA_2 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_CCMR2 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCER TIM_DCR_DBA_3 /*!< TIMx_CCER register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CNT (TIM_DCR_DBA_3 | TIM_DCR_DBA_0) /*!< TIMx_CNT register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_PSC (TIM_DCR_DBA_3 | TIM_DCR_DBA_1) /*!< TIMx_PSC register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_ARR (TIM_DCR_DBA_3 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_ARR register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_RCR (TIM_DCR_DBA_3 | TIM_DCR_DBA_2) /*!< TIMx_RCR register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCR1 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_0) /*!< TIMx_CCR1 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCR2 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1) /*!< TIMx_CCR2 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCR3 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_CCR3 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCR4 TIM_DCR_DBA_4 /*!< TIMx_CCR4 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_BDTR (TIM_DCR_DBA_4 | TIM_DCR_DBA_0) /*!< TIMx_BDTR register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCMR3 (TIM_DCR_DBA_4 | TIM_DCR_DBA_1) /*!< TIMx_CCMR3 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCR5 (TIM_DCR_DBA_4 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_CCR5 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_CCR6 (TIM_DCR_DBA_4 | TIM_DCR_DBA_2) /*!< TIMx_CCR6 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_OR1 (TIM_DCR_DBA_4 | TIM_DCR_DBA_2 | TIM_DCR_DBA_0) /*!< TIMx_OR1 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_OR2 (TIM_DCR_DBA_4 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1) /*!< TIMx_OR2 register is the DMA base address for DMA burst */ -#define LL_TIM_DMABURST_BASEADDR_OR3 (TIM_DCR_DBA_4 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_OR3 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CR1 ((uint32_t)0x00000000U) /*!< TIMx_CR1 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CR2 TIM_DCR_DBA_0 /*!< TIMx_CR2 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_SMCR TIM_DCR_DBA_1 /*!< TIMx_SMCR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_DIER (TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_DIER register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_SR TIM_DCR_DBA_2 /*!< TIMx_SR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_EGR (TIM_DCR_DBA_2 | TIM_DCR_DBA_0) /*!< TIMx_EGR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCMR1 (TIM_DCR_DBA_2 | TIM_DCR_DBA_1) /*!< TIMx_CCMR1 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCMR2 (TIM_DCR_DBA_2 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_CCMR2 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCER TIM_DCR_DBA_3 /*!< TIMx_CCER register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CNT (TIM_DCR_DBA_3 | TIM_DCR_DBA_0) /*!< TIMx_CNT register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_PSC (TIM_DCR_DBA_3 | TIM_DCR_DBA_1) /*!< TIMx_PSC register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_ARR (TIM_DCR_DBA_3 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_ARR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_RCR (TIM_DCR_DBA_3 | TIM_DCR_DBA_2) /*!< TIMx_RCR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR1 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_0) /*!< TIMx_CCR1 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR2 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1) /*!< TIMx_CCR2 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR3 (TIM_DCR_DBA_3 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_CCR3 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR4 TIM_DCR_DBA_4 /*!< TIMx_CCR4 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_BDTR (TIM_DCR_DBA_4 | TIM_DCR_DBA_0) /*!< TIMx_BDTR register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCMR3 (TIM_DCR_DBA_4 | TIM_DCR_DBA_1) /*!< TIMx_CCMR3 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR5 (TIM_DCR_DBA_4 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_CCR5 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_CCR6 (TIM_DCR_DBA_4 | TIM_DCR_DBA_2) /*!< TIMx_CCR6 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_OR1 (TIM_DCR_DBA_4 | TIM_DCR_DBA_2 | TIM_DCR_DBA_0) /*!< TIMx_OR1 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_OR2 (TIM_DCR_DBA_4 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1) /*!< TIMx_OR2 register is the DMA base address for DMA burst */ +#define LL_TIM_DMABURST_BASEADDR_OR3 (TIM_DCR_DBA_4 | TIM_DCR_DBA_2 | TIM_DCR_DBA_1 | TIM_DCR_DBA_0) /*!< TIMx_OR3 register is the DMA base address for DMA burst */ /** * @} */ @@ -656,162 +645,161 @@ typedef struct /** @defgroup TIM_LL_EC_DMABURST_LENGTH DMA Burst Length * @{ */ -#define LL_TIM_DMABURST_LENGTH_1TRANSFER ((uint32_t)0x00000000U) /*!< Transfer is done to 1 register starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_2TRANSFERS TIM_DCR_DBL_0 /*!< Transfer is done to 2 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_3TRANSFERS TIM_DCR_DBL_1 /*!< Transfer is done to 3 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_4TRANSFERS (TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 4 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_5TRANSFERS TIM_DCR_DBL_2 /*!< Transfer is done to 5 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_6TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_0) /*!< Transfer is done to 6 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_7TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_1) /*!< Transfer is done to 7 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_8TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 1 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_9TRANSFERS TIM_DCR_DBL_3 /*!< Transfer is done to 9 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_10TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_0) /*!< Transfer is done to 10 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_11TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_1) /*!< Transfer is done to 11 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_12TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 12 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_13TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2) /*!< Transfer is done to 13 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_14TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_0) /*!< Transfer is done to 14 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_15TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_1) /*!< Transfer is done to 15 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_16TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 16 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_17TRANSFERS TIM_DCR_DBL_4 /*!< Transfer is done to 17 registers starting from the DMA burst base address */ -#define LL_TIM_DMABURST_LENGTH_18TRANSFERS (TIM_DCR_DBL_4 | TIM_DCR_DBL_0) /*!< Transfer is done to 18 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_1TRANSFER ((uint32_t)0x00000000U) /*!< Transfer is done to 1 register starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_2TRANSFERS TIM_DCR_DBL_0 /*!< Transfer is done to 2 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_3TRANSFERS TIM_DCR_DBL_1 /*!< Transfer is done to 3 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_4TRANSFERS (TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 4 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_5TRANSFERS TIM_DCR_DBL_2 /*!< Transfer is done to 5 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_6TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_0) /*!< Transfer is done to 6 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_7TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_1) /*!< Transfer is done to 7 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_8TRANSFERS (TIM_DCR_DBL_2 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 1 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_9TRANSFERS TIM_DCR_DBL_3 /*!< Transfer is done to 9 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_10TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_0) /*!< Transfer is done to 10 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_11TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_1) /*!< Transfer is done to 11 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_12TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 12 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_13TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2) /*!< Transfer is done to 13 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_14TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_0) /*!< Transfer is done to 14 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_15TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_1) /*!< Transfer is done to 15 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_16TRANSFERS (TIM_DCR_DBL_3 | TIM_DCR_DBL_2 | TIM_DCR_DBL_1 | TIM_DCR_DBL_0) /*!< Transfer is done to 16 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_17TRANSFERS TIM_DCR_DBL_4 /*!< Transfer is done to 17 registers starting from the DMA burst base address */ +#define LL_TIM_DMABURST_LENGTH_18TRANSFERS (TIM_DCR_DBL_4 | TIM_DCR_DBL_0) /*!< Transfer is done to 18 registers starting from the DMA burst base address */ /** * @} */ -/** @defgroup TIM_LL_EC_TIM2_ETR_RMP TIM2 External Trigger Remap +/** @defgroup TIM_LL_EC_TIM2_ETR_RMP TIM2 External Trigger Remap * @{ */ -#define LL_TIM_TIM2_ETR_RMP_GPIO ((uint32_t)0x00000000U | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to Ored GPIO */ +#define LL_TIM_TIM2_ETR_RMP_GPIO ((uint32_t)0x00000000U | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to Ored GPIO */ #if defined(TIM_TIM2_REMAP_HSI_SUPPORT) -#define LL_TIM_TIM2_ETR_RMP_HSI (TIM2_OR_ETR_RMP_1 | TIM2_OR_ETR_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to HSI */ +#define LL_TIM_TIM2_ETR_RMP_HSI (TIM2_OR_ETR_RMP_1 | TIM2_OR_ETR_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to HSI */ #endif /* defined(TIM_TIM2_REMAP_HSI_SUPPORT) */ #if defined(TIM_TIM2_REMAP_HSI48_SUPPORT) -#define LL_TIM_TIM2_ETR_RMP_HSI48 (TIM2_OR_ETR_RMP_2 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to HSI48 */ +#define LL_TIM_TIM2_ETR_RMP_HSI48 (TIM2_OR_ETR_RMP_2 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to HSI48 */ #endif /* defined(TIM_TIM2_REMAP_HSI48_SUPPORT) */ -#define LL_TIM_TIM2_ETR_RMP_LSE (TIM2_OR_ETR_RMP_2 | TIM2_OR_ETR_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to LSE */ -#define LL_TIM_TIM2_ETR_RMP_COMP2 (TIM2_OR_ETR_RMP_2 | TIM2_OR_ETR_RMP_1 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to COMP2_OUT */ -#define LL_TIM_TIM2_ETR_RMP_COMP1 (TIM2_OR_ETR_RMP | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to COMP1_OUT */ +#define LL_TIM_TIM2_ETR_RMP_LSE (TIM2_OR_ETR_RMP_2 | TIM2_OR_ETR_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to LSE */ +#define LL_TIM_TIM2_ETR_RMP_COMP2 (TIM2_OR_ETR_RMP_2 | TIM2_OR_ETR_RMP_1 | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to COMP2_OUT */ +#define LL_TIM_TIM2_ETR_RMP_COMP1 (TIM2_OR_ETR_RMP | TIM2_OR_RMP_MASK) /*!< TIM2_ETR is connected to COMP1_OUT */ /** * @} */ - + /** @defgroup TIM_LL_EC_TIM2_TI4_RMP TIM2 Timer Input Ch4 Remap * @{ */ -#define LL_TIM_TIM2_TI4_RMP_GPIO ((uint32_t)0x00000000U | TIM2_OR_RMP_MASK) /*!< TIM2 input capture 4 is connected to GPIO */ -#define LL_TIM_TIM2_TI4_RMP_COMP2 (TIM2_OR_TI4_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2 input capture 4 is connected to COMP2_OUT */ -#define LL_TIM_TIM2_TI4_RMP_COMP1 (TIM2_OR_TI4_RMP_1 | TIM2_OR_RMP_MASK) /*!< TIM2 input capture 4 is connected to COMP1_OUT */ +#define LL_TIM_TIM2_TI4_RMP_GPIO ((uint32_t)0x00000000U | TIM2_OR_RMP_MASK) /*!< TIM2 input capture 4 is connected to GPIO */ +#define LL_TIM_TIM2_TI4_RMP_COMP2 (TIM2_OR_TI4_RMP_0 | TIM2_OR_RMP_MASK) /*!< TIM2 input capture 4 is connected to COMP2_OUT */ +#define LL_TIM_TIM2_TI4_RMP_COMP1 (TIM2_OR_TI4_RMP_1 | TIM2_OR_RMP_MASK) /*!< TIM2 input capture 4 is connected to COMP1_OUT */ /** * @} */ #if defined(TIM3_OR_ETR_RMP) -/** @defgroup TIM_LL_EC_TIM3_ETR_RMP TIM3 External Trigger Remap +/** @defgroup TIM_LL_EC_TIM3_ETR_RMP TIM3 External Trigger Remap * @{ */ -#define LL_TIM_TIM3_ETR_RMP_GPIO ((uint32_t)0x00000000U | TIM3_OR_RMP_MASK) /*!< TIM3_ETR is connected to GPIO */ -#define LL_TIM_TIM3_ETR_RMP_HSI48DIV6 (TIM3_OR_ETR_RMP_1 | TIM3_OR_RMP_MASK) /*!< TIM3_ETR is connected to HSI48 divided by 6 */ +#define LL_TIM_TIM3_ETR_RMP_GPIO ((uint32_t)0x00000000U | TIM3_OR_RMP_MASK) /*!< TIM3_ETR is connected to GPIO */ +#define LL_TIM_TIM3_ETR_RMP_HSI48DIV6 (TIM3_OR_ETR_RMP_1 | TIM3_OR_RMP_MASK) /*!< TIM3_ETR is connected to HSI48 divided by 6 */ /** * @} */ -#endif /* defined(TIM3_OR_ETR_RMP) */ +#endif /* defined(TIM3_OR_ETR_RMP) */ -#if defined(TIM3_OR_TI1_RMP) || defined(TIM3_OR_TI2_RMP) || defined(TIM3_OR_TI4_RMP) +#if defined(TIM3_OR_TI1_RMP) || defined(TIM3_OR_TI2_RMP) || defined(TIM3_OR_TI4_RMP) /** @defgroup TIM_LL_EC_TIM3_TI_RMP TIM3 External Inputs Remap * @{ */ -#define LL_TIM_TIM3_TI_RMP_TI1_USB_SOF ((uint32_t)0x00000000U | TIM3_OR_RMP_MASK) /*!< TIM3_TI1 input is connected to USB_SOF */ -#define LL_TIM_TIM3_TI_RMP_TI1_GPIO (TIM3_OR_TI1_RMP | TIM3_OR_RMP_MASK) /*!< TIM3_TI1 input is connected to PE3, PA6, PC6 or PB4 */ +#define LL_TIM_TIM3_TI_RMP_TI1_USB_SOF ((uint32_t)0x00000000U | TIM3_OR_RMP_MASK) /*!< TIM3_TI1 input is connected to USB_SOF */ +#define LL_TIM_TIM3_TI_RMP_TI1_GPIO (TIM3_OR_TI1_RMP | TIM3_OR_RMP_MASK) /*!< TIM3_TI1 input is connected to PE3, PA6, PC6 or PB4 */ -#define LL_TIM_TIM3_TI_RMP_TI2_GPIO_DEF ((uint32_t)0x00000000U | TIM3_OR_RMP_MASK) /*!< Mapping PB5 to TIM22_CH2 */ -#define LL_TIM_TIM3_TI_RMP_TI2_GPIOB5_AF4 (TIM3_OR_TI2_RMP | TIM3_OR_RMP_MASK) /*!< Mapping PB5 to TIM3_CH2 */ +#define LL_TIM_TIM3_TI_RMP_TI2_GPIO_DEF ((uint32_t)0x00000000U | TIM3_OR_RMP_MASK) /*!< Mapping PB5 to TIM22_CH2 */ +#define LL_TIM_TIM3_TI_RMP_TI2_GPIOB5_AF4 (TIM3_OR_TI2_RMP | TIM3_OR_RMP_MASK) /*!< Mapping PB5 to TIM3_CH2 */ -#define LL_TIM_TIM3_TI_RMP_TI4_GPIO_DEF ((uint32_t)0x00000000U | TIM3_OR_RMP_MASK) /*!< Mapping PC9 to USB_OE */ -#define LL_TIM_TIM3_TI_RMP_TI4_GPIOC9_AF2 (TIM3_OR_TI4_RMP | TIM3_OR_RMP_MASK) /*!< Mapping PC9 to TIM3_CH4 */ +#define LL_TIM_TIM3_TI_RMP_TI4_GPIO_DEF ((uint32_t)0x00000000U | TIM3_OR_RMP_MASK) /*!< Mapping PC9 to USB_OE */ +#define LL_TIM_TIM3_TI_RMP_TI4_GPIOC9_AF2 (TIM3_OR_TI4_RMP | TIM3_OR_RMP_MASK) /*!< Mapping PC9 to TIM3_CH4 */ /** * @} */ #endif /*defined(TIM3_OR_TI1_RMP) or defined(TIM3_OR_TI2_RMP) or defined(TIM3_OR_TI4_RMP)*/ -/** @defgroup TIM_LL_EC_TIM21_ETR_RMP TIM21 External Trigger Remap +/** @defgroup TIM_LL_EC_TIM21_ETR_RMP TIM21 External Trigger Remap * @{ */ -#define LL_TIM_TIM21_ETR_RMP_GPIO ((uint32_t)0x00000000U | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to Ored GPIO1 */ -#define LL_TIM_TIM21_ETR_RMP_COMP2 (TIM21_OR_ETR_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to COMP2_OUT */ -#define LL_TIM_TIM21_ETR_RMP_COMP1 (TIM21_OR_ETR_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to COMP1_OUT */ -#define LL_TIM_TIM21_ETR_RMP_LSE (TIM21_OR_ETR_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to LSE */ +#define LL_TIM_TIM21_ETR_RMP_GPIO ((uint32_t)0x00000000U | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to Ored GPIO1 */ +#define LL_TIM_TIM21_ETR_RMP_COMP2 (TIM21_OR_ETR_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to COMP2_OUT */ +#define LL_TIM_TIM21_ETR_RMP_COMP1 (TIM21_OR_ETR_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to COMP1_OUT */ +#define LL_TIM_TIM21_ETR_RMP_LSE (TIM21_OR_ETR_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_ETR is connected to LSE */ /** * @} */ -/** @defgroup TIM_LL_EC_TIM21_TI1_RMP TIM21 External Input Ch1 Remap +/** @defgroup TIM_LL_EC_TIM21_TI1_RMP TIM21 External Input Ch1 Remap * @{ */ -#define LL_TIM_TIM21_TI1_RMP_GPIO ((uint32_t)0x00000000U | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to Ored GPIO1 */ -#define LL_TIM_TIM21_TI1_RMP_RTC_WK (TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to RTC_WAKEUP */ -#define LL_TIM_TIM21_TI1_RMP_HSE_RTC (TIM21_OR_TI1_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to HSE_RTC */ -#define LL_TIM_TIM21_TI1_RMP_MSI (TIM21_OR_TI1_RMP_1 | TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to MSI */ -#define LL_TIM_TIM21_TI1_RMP_LSE (TIM21_OR_TI1_RMP_2 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to LSE */ -#define LL_TIM_TIM21_TI1_RMP_LSI (TIM21_OR_TI1_RMP_2 | TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to LSI */ -#define LL_TIM_TIM21_TI1_RMP_COMP1 (TIM21_OR_TI1_RMP_2 | TIM21_OR_TI1_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to COMP1_OUT */ -#define LL_TIM_TIM21_TI1_RMP_MCO (TIM21_OR_TI1_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to MCO */ +#define LL_TIM_TIM21_TI1_RMP_GPIO ((uint32_t)0x00000000U | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to Ored GPIO1 */ +#define LL_TIM_TIM21_TI1_RMP_RTC_WK (TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to RTC_WAKEUP */ +#define LL_TIM_TIM21_TI1_RMP_HSE_RTC (TIM21_OR_TI1_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to HSE_RTC */ +#define LL_TIM_TIM21_TI1_RMP_MSI (TIM21_OR_TI1_RMP_1 | TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to MSI */ +#define LL_TIM_TIM21_TI1_RMP_LSE (TIM21_OR_TI1_RMP_2 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to LSE */ +#define LL_TIM_TIM21_TI1_RMP_LSI (TIM21_OR_TI1_RMP_2 | TIM21_OR_TI1_RMP_0 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to LSI */ +#define LL_TIM_TIM21_TI1_RMP_COMP1 (TIM21_OR_TI1_RMP_2 | TIM21_OR_TI1_RMP_1 | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to COMP1_OUT */ +#define LL_TIM_TIM21_TI1_RMP_MCO (TIM21_OR_TI1_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_TI1 is connected to MCO */ /** * @} */ -/** @defgroup TIM_LL_EC_TIM21_TI2_RMP TIM21 External Input Ch2 Remap +/** @defgroup TIM_LL_EC_TIM21_TI2_RMP TIM21 External Input Ch2 Remap * @{ */ -#define LL_TIM_TIM21_TI2_RMP_GPIO ((uint32_t)0x00000000U | TIM21_OR_RMP_MASK) /*!< TIM21_TI2 is connected to Ored GPIO1 */ -#define LL_TIM_TIM21_TI2_RMP_COMP2 (TIM21_OR_TI2_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_TI2 is connected to COMP2_OUT */ +#define LL_TIM_TIM21_TI2_RMP_GPIO ((uint32_t)0x00000000U | TIM21_OR_RMP_MASK) /*!< TIM21_TI2 is connected to Ored GPIO1 */ +#define LL_TIM_TIM21_TI2_RMP_COMP2 (TIM21_OR_TI2_RMP | TIM21_OR_RMP_MASK) /*!< TIM21_TI2 is connected to COMP2_OUT */ /** * @} */ -#if defined(TIM22_OR_ETR_RMP) +#if defined(TIM22_OR_ETR_RMP) -/** @defgroup TIM_LL_EC_TIM22_ETR_RMP TIM22 External Trigger Remap +/** @defgroup TIM_LL_EC_TIM22_ETR_RMP TIM22 External Trigger Remap * @{ */ -#define LL_TIM_TIM22_ETR_RMP_GPIO ((uint32_t)0x00000000U | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to GPIO */ -#define LL_TIM_TIM22_ETR_RMP_COMP2 (TIM22_OR_ETR_RMP_0 | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to COMP2_OUT */ -#define LL_TIM_TIM22_ETR_RMP_COMP1 (TIM22_OR_ETR_RMP_1 | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to COMP1_OUT */ -#define LL_TIM_TIM22_ETR_RMP_LSE (TIM22_OR_ETR_RMP | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to LSE */ +#define LL_TIM_TIM22_ETR_RMP_GPIO ((uint32_t)0x00000000U | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to GPIO */ +#define LL_TIM_TIM22_ETR_RMP_COMP2 (TIM22_OR_ETR_RMP_0 | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to COMP2_OUT */ +#define LL_TIM_TIM22_ETR_RMP_COMP1 (TIM22_OR_ETR_RMP_1 | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to COMP1_OUT */ +#define LL_TIM_TIM22_ETR_RMP_LSE (TIM22_OR_ETR_RMP | TIM22_OR_RMP_MASK) /*!< TIM22_ETR is connected to LSE */ /** * @} */ -#endif /* defined(TIM22_OR_ETR_RMP) */ +#endif /* defined(TIM22_OR_ETR_RMP) */ -#if defined(TIM22_OR_TI1_RMP) -/** @defgroup TIM_LL_EC_TIM22_TI1_RMP TIM22 External Input Ch1 Remap +#if defined(TIM22_OR_TI1_RMP) +/** @defgroup TIM_LL_EC_TIM22_TI1_RMP TIM22 External Input Ch1 Remap * @{ */ -#define LL_TIM_TIM22_TI1_RMP_GPIO1 ((uint32_t)0x00000000U | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to GPIO1 */ -#define LL_TIM_TIM22_TI1_RMP_COMP2 (TIM22_OR_TI1_RMP_0 | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to COMP2_OUT */ -#define LL_TIM_TIM22_TI1_RMP_COMP1 (TIM22_OR_TI1_RMP_1 | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to COMP1_OUT */ -#define LL_TIM_TIM22_TI1_RMP_GPIO2 (TIM22_OR_TI1_RMP | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to GPIO2 */ +#define LL_TIM_TIM22_TI1_RMP_GPIO1 ((uint32_t)0x00000000U | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to GPIO1 */ +#define LL_TIM_TIM22_TI1_RMP_COMP2 (TIM22_OR_TI1_RMP_0 | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to COMP2_OUT */ +#define LL_TIM_TIM22_TI1_RMP_COMP1 (TIM22_OR_TI1_RMP_1 | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to COMP1_OUT */ +#define LL_TIM_TIM22_TI1_RMP_GPIO2 (TIM22_OR_TI1_RMP | TIM22_OR_RMP_MASK) /*!< TIM22_TI1 is connected to GPIO2 */ /** * @} */ -#endif /* defined(TIM22_OR_TI1_RMP) */ +#endif /* defined(TIM22_OR_TI1_RMP) */ /** @defgroup TIM_LL_EC_OCREF_CLR_INT OCREF clear input selection * @{ */ -#define LL_TIM_OCREF_CLR_INT_NC ((uint32_t)0x00000000U ) /*!< OCREF_CLR_INT is not connected */ -#define LL_TIM_OCREF_CLR_INT_ETR TIM_SMCR_OCCS /*!< OCREF_CLR_INT is connected to ETRF */ +#define LL_TIM_OCREF_CLR_INT_NC ((uint32_t)0x00000000U ) /*!< OCREF_CLR_INT is not connected */ +#define LL_TIM_OCREF_CLR_INT_ETR TIM_SMCR_OCCS /*!< OCREF_CLR_INT is connected to ETRF */ /** * @} */ - /** * @} */ - + /* Exported macro ------------------------------------------------------------*/ /** @defgroup TIM_LL_Exported_Macros TIM Exported Macros * @{ @@ -892,7 +880,7 @@ typedef struct + __LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__DELAY__)))) /** - * @brief HELPER macro retrieving the ratio of the input capture prescaler + * @brief HELPER macro retrieving the ratio of the input capture prescaler * @note ex: @ref __LL_TIM_GET_ICPSC_RATIO (@ref LL_TIM_IC_GetPrescaler ()); * @param __ICPSC__ This parameter can be one of the following values: * @arg @ref LL_TIM_ICPSC_DIV1 @@ -902,9 +890,9 @@ typedef struct * @retval Input capture prescaler ratio (1, 2, 4 or 8) */ #define __LL_TIM_GET_ICPSC_RATIO(__ICPSC__) \ - ((uint32_t)((uint32_t)0x01U << (((__ICPSC__) >> 16U) >> TIM_POSITION_ICPSC))) + ((uint32_t)((uint32_t)0x01U << (((__ICPSC__) >> 16U) >> TIM_CCMR1_IC1PSC_Pos))) + - /** * @} */ @@ -918,7 +906,7 @@ typedef struct /** @defgroup TIM_LL_Exported_Functions TIM Exported Functions * @{ */ - + /** @defgroup TIM_LL_EF_Time_Base Time Base configuration * @{ */ @@ -928,7 +916,7 @@ typedef struct * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableCounter(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableCounter(TIM_TypeDef *TIMx) { SET_BIT(TIMx->CR1, TIM_CR1_CEN); } @@ -939,7 +927,7 @@ __STATIC_INLINE void LL_TIM_EnableCounter(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableCounter(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableCounter(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->CR1, TIM_CR1_CEN); } @@ -950,7 +938,7 @@ __STATIC_INLINE void LL_TIM_DisableCounter(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledCounter(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledCounter(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->CR1, TIM_CR1_CEN) == (TIM_CR1_CEN)); } @@ -961,7 +949,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledCounter(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableUpdateEvent(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableUpdateEvent(TIM_TypeDef *TIMx) { SET_BIT(TIMx->CR1, TIM_CR1_UDIS); } @@ -972,7 +960,7 @@ __STATIC_INLINE void LL_TIM_EnableUpdateEvent(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableUpdateEvent(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableUpdateEvent(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->CR1, TIM_CR1_UDIS); } @@ -983,19 +971,19 @@ __STATIC_INLINE void LL_TIM_DisableUpdateEvent(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledUpdateEvent(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledUpdateEvent(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->CR1, TIM_CR1_UDIS) == (TIM_CR1_UDIS)); } /** * @brief Set update event source - * @note Update event source set to LL_TIM_UPDATESOURCE_REGULAR: any of the following events + * @note Update event source set to LL_TIM_UPDATESOURCE_REGULAR: any of the following events * generate an update interrupt or DMA request if enabled: * - Counter overflow/underflow * - Setting the UG bit * - Update generation through the slave mode controller - * @note Update event source set to LL_TIM_UPDATESOURCE_COUNTER: only counter + * @note Update event source set to LL_TIM_UPDATESOURCE_COUNTER: only counter * overflow/underflow generates an update interrupt or DMA request if enabled. * @rmtoll CR1 URS LL_TIM_SetUpdateSource * @param TIMx Timer instance @@ -1004,7 +992,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledUpdateEvent(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_UPDATESOURCE_COUNTER * @retval None */ -__STATIC_INLINE void LL_TIM_SetUpdateSource(TIM_TypeDef * TIMx, uint32_t UpdateSource) +__STATIC_INLINE void LL_TIM_SetUpdateSource(TIM_TypeDef *TIMx, uint32_t UpdateSource) { MODIFY_REG(TIMx->CR1, TIM_CR1_URS, UpdateSource); } @@ -1017,7 +1005,7 @@ __STATIC_INLINE void LL_TIM_SetUpdateSource(TIM_TypeDef * TIMx, uint32_t UpdateS * @arg @ref LL_TIM_UPDATESOURCE_REGULAR * @arg @ref LL_TIM_UPDATESOURCE_COUNTER */ -__STATIC_INLINE uint32_t LL_TIM_GetUpdateSource(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_GetUpdateSource(TIM_TypeDef *TIMx) { return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_URS)); } @@ -1031,7 +1019,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetUpdateSource(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE * @retval None */ -__STATIC_INLINE void LL_TIM_SetOnePulseMode(TIM_TypeDef * TIMx, uint32_t OnePulseMode) +__STATIC_INLINE void LL_TIM_SetOnePulseMode(TIM_TypeDef *TIMx, uint32_t OnePulseMode) { MODIFY_REG(TIMx->CR1, TIM_CR1_OPM, OnePulseMode); } @@ -1044,7 +1032,7 @@ __STATIC_INLINE void LL_TIM_SetOnePulseMode(TIM_TypeDef * TIMx, uint32_t OnePuls * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE */ -__STATIC_INLINE uint32_t LL_TIM_GetOnePulseMode(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_GetOnePulseMode(TIM_TypeDef *TIMx) { return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_OPM)); } @@ -1052,7 +1040,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetOnePulseMode(TIM_TypeDef * TIMx) /** * @brief Set the timer counter counting mode. * @note Macro @ref IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to - * check whether or not the counter mode selection feature is supported + * check whether or not the counter mode selection feature is supported * by a timer instance. * @rmtoll CR1 DIR LL_TIM_SetCounterMode\n * CR1 CMS LL_TIM_SetCounterMode @@ -1065,7 +1053,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetOnePulseMode(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN * @retval None */ -__STATIC_INLINE void LL_TIM_SetCounterMode(TIM_TypeDef * TIMx, uint32_t CounterMode) +__STATIC_INLINE void LL_TIM_SetCounterMode(TIM_TypeDef *TIMx, uint32_t CounterMode) { MODIFY_REG(TIMx->CR1, TIM_CR1_DIR | TIM_CR1_CMS, CounterMode); } @@ -1073,7 +1061,7 @@ __STATIC_INLINE void LL_TIM_SetCounterMode(TIM_TypeDef * TIMx, uint32_t CounterM /** * @brief Get actual counter mode. * @note Macro @ref IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to - * check whether or not the counter mode selection feature is supported + * check whether or not the counter mode selection feature is supported * by a timer instance. * @rmtoll CR1 DIR LL_TIM_GetCounterMode\n * CR1 CMS LL_TIM_GetCounterMode @@ -1085,7 +1073,7 @@ __STATIC_INLINE void LL_TIM_SetCounterMode(TIM_TypeDef * TIMx, uint32_t CounterM * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN */ -__STATIC_INLINE uint32_t LL_TIM_GetCounterMode(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_GetCounterMode(TIM_TypeDef *TIMx) { return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR | TIM_CR1_CMS)); } @@ -1096,7 +1084,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetCounterMode(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableARRPreload(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableARRPreload(TIM_TypeDef *TIMx) { SET_BIT(TIMx->CR1, TIM_CR1_ARPE); } @@ -1107,7 +1095,7 @@ __STATIC_INLINE void LL_TIM_EnableARRPreload(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableARRPreload(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableARRPreload(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->CR1, TIM_CR1_ARPE); } @@ -1118,14 +1106,14 @@ __STATIC_INLINE void LL_TIM_DisableARRPreload(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledARRPreload(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledARRPreload(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->CR1, TIM_CR1_ARPE) == (TIM_CR1_ARPE)); } /** * @brief Set the division ratio between the timer clock and the sampling clock used by the dead-time generators (when supported) and the digital filters. - * @note Macro @ref IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check * whether or not the clock division feature is supported by the timer * instance. * @rmtoll CR1 CKD LL_TIM_SetClockDivision @@ -1136,14 +1124,14 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledARRPreload(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 * @retval None */ -__STATIC_INLINE void LL_TIM_SetClockDivision(TIM_TypeDef * TIMx, uint32_t ClockDivision) +__STATIC_INLINE void LL_TIM_SetClockDivision(TIM_TypeDef *TIMx, uint32_t ClockDivision) { MODIFY_REG(TIMx->CR1, TIM_CR1_CKD, ClockDivision); } /** * @brief Get the actual division ratio between the timer clock and the sampling clock used by the dead-time generators (when supported) and the digital filters. - * @note Macro @ref IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check * whether or not the clock division feature is supported by the timer * instance. * @rmtoll CR1 CKD LL_TIM_GetClockDivision @@ -1153,7 +1141,7 @@ __STATIC_INLINE void LL_TIM_SetClockDivision(TIM_TypeDef * TIMx, uint32_t ClockD * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 */ -__STATIC_INLINE uint32_t LL_TIM_GetClockDivision(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_GetClockDivision(TIM_TypeDef *TIMx) { return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CKD)); } @@ -1165,7 +1153,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetClockDivision(TIM_TypeDef * TIMx) * @param Counter Counter value (between Min_Data=0 and Max_Data=0xFFFF) * @retval None */ -__STATIC_INLINE void LL_TIM_SetCounter(TIM_TypeDef * TIMx, uint32_t Counter) +__STATIC_INLINE void LL_TIM_SetCounter(TIM_TypeDef *TIMx, uint32_t Counter) { WRITE_REG(TIMx->CNT, Counter); } @@ -1176,7 +1164,7 @@ __STATIC_INLINE void LL_TIM_SetCounter(TIM_TypeDef * TIMx, uint32_t Counter) * @param TIMx Timer instance * @retval Counter value (between Min_Data=0 and Max_Data=0xFFFF) */ -__STATIC_INLINE uint32_t LL_TIM_GetCounter(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_GetCounter(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CNT)); } @@ -1189,7 +1177,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetCounter(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_COUNTERDIRECTION_UP * @arg @ref LL_TIM_COUNTERDIRECTION_DOWN */ -__STATIC_INLINE uint32_t LL_TIM_GetDirection(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_GetDirection(TIM_TypeDef *TIMx) { return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); } @@ -1205,7 +1193,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetDirection(TIM_TypeDef * TIMx) * @param Prescaler between Min_Data=0 and Max_Data=65535 * @retval None */ -__STATIC_INLINE void LL_TIM_SetPrescaler(TIM_TypeDef * TIMx, uint32_t Prescaler) +__STATIC_INLINE void LL_TIM_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Prescaler) { WRITE_REG(TIMx->PSC, Prescaler); } @@ -1216,7 +1204,7 @@ __STATIC_INLINE void LL_TIM_SetPrescaler(TIM_TypeDef * TIMx, uint32_t Prescaler) * @param TIMx Timer instance * @retval Prescaler value between Min_Data=0 and Max_Data=65535 */ -__STATIC_INLINE uint32_t LL_TIM_GetPrescaler(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_GetPrescaler(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->PSC)); } @@ -1230,7 +1218,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetPrescaler(TIM_TypeDef * TIMx) * @param AutoReload between Min_Data=0 and Max_Data=65535 * @retval None */ -__STATIC_INLINE void LL_TIM_SetAutoReload(TIM_TypeDef * TIMx, uint32_t AutoReload) +__STATIC_INLINE void LL_TIM_SetAutoReload(TIM_TypeDef *TIMx, uint32_t AutoReload) { WRITE_REG(TIMx->ARR, AutoReload); } @@ -1241,13 +1229,11 @@ __STATIC_INLINE void LL_TIM_SetAutoReload(TIM_TypeDef * TIMx, uint32_t AutoReloa * @param TIMx Timer instance * @retval Auto-reload value */ -__STATIC_INLINE uint32_t LL_TIM_GetAutoReload(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_GetAutoReload(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->ARR)); } - - /** * @} */ @@ -1255,7 +1241,6 @@ __STATIC_INLINE uint32_t LL_TIM_GetAutoReload(TIM_TypeDef * TIMx) /** @defgroup TIM_LL_EF_Capture_Compare Capture Compare configuration * @{ */ - /** * @brief Set the trigger of the capture/compare DMA request. * @rmtoll CR2 CCDS LL_TIM_CC_SetDMAReqTrigger @@ -1265,7 +1250,7 @@ __STATIC_INLINE uint32_t LL_TIM_GetAutoReload(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE * @retval None */ -__STATIC_INLINE void LL_TIM_CC_SetDMAReqTrigger(TIM_TypeDef * TIMx, uint32_t DMAReqTrigger) +__STATIC_INLINE void LL_TIM_CC_SetDMAReqTrigger(TIM_TypeDef *TIMx, uint32_t DMAReqTrigger) { MODIFY_REG(TIMx->CR2, TIM_CR2_CCDS, DMAReqTrigger); } @@ -1278,12 +1263,11 @@ __STATIC_INLINE void LL_TIM_CC_SetDMAReqTrigger(TIM_TypeDef * TIMx, uint32_t DMA * @arg @ref LL_TIM_CCDMAREQUEST_CC * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE */ -__STATIC_INLINE uint32_t LL_TIM_CC_GetDMAReqTrigger(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_CC_GetDMAReqTrigger(TIM_TypeDef *TIMx) { return (uint32_t)(READ_BIT(TIMx->CR2, TIM_CR2_CCDS)); } - /** * @brief Enable capture/compare channels. * @rmtoll CCER CC1E LL_TIM_CC_EnableChannel\n @@ -1298,7 +1282,7 @@ __STATIC_INLINE uint32_t LL_TIM_CC_GetDMAReqTrigger(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_CHANNEL_CH4 * @retval None */ -__STATIC_INLINE void LL_TIM_CC_EnableChannel(TIM_TypeDef * TIMx, uint32_t Channels) +__STATIC_INLINE void LL_TIM_CC_EnableChannel(TIM_TypeDef *TIMx, uint32_t Channels) { SET_BIT(TIMx->CCER, Channels); } @@ -1317,7 +1301,7 @@ __STATIC_INLINE void LL_TIM_CC_EnableChannel(TIM_TypeDef * TIMx, uint32_t Channe * @arg @ref LL_TIM_CHANNEL_CH4 * @retval None */ -__STATIC_INLINE void LL_TIM_CC_DisableChannel(TIM_TypeDef * TIMx, uint32_t Channels) +__STATIC_INLINE void LL_TIM_CC_DisableChannel(TIM_TypeDef *TIMx, uint32_t Channels) { CLEAR_BIT(TIMx->CCER, Channels); } @@ -1336,9 +1320,9 @@ __STATIC_INLINE void LL_TIM_CC_DisableChannel(TIM_TypeDef * TIMx, uint32_t Chann * @arg @ref LL_TIM_CHANNEL_CH4 * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_CC_IsEnabledChannel(TIM_TypeDef * TIMx, uint32_t Channels) +__STATIC_INLINE uint32_t LL_TIM_CC_IsEnabledChannel(TIM_TypeDef *TIMx, uint32_t Channels) { - return (READ_BIT(TIMx->CCER, Channels) == (Channels)); + return (READ_BIT(TIMx->CCER, Channels) == (Channels)); } /** @@ -1368,12 +1352,13 @@ __STATIC_INLINE uint32_t LL_TIM_CC_IsEnabledChannel(TIM_TypeDef * TIMx, uint32_t * @arg @ref LL_TIM_OCPOLARITY_HIGH or @ref LL_TIM_OCPOLARITY_LOW * @retval None */ -__STATIC_INLINE void LL_TIM_OC_ConfigOutput(TIM_TypeDef * TIMx, uint32_t Channel, uint32_t Configuration) +__STATIC_INLINE void LL_TIM_OC_ConfigOutput(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Configuration) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); CLEAR_BIT(*pReg, (TIM_CCMR1_CC1S << SHIFT_TAB_OCxx[iChannel])); - MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), (Configuration & TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), + (Configuration & TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]); } /** @@ -1400,10 +1385,10 @@ __STATIC_INLINE void LL_TIM_OC_ConfigOutput(TIM_TypeDef * TIMx, uint32_t Channel * @arg @ref LL_TIM_OCMODE_PWM2 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_SetMode(TIM_TypeDef * TIMx, uint32_t Channel, uint32_t Mode) +__STATIC_INLINE void LL_TIM_OC_SetMode(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Mode) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); MODIFY_REG(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel]), Mode << SHIFT_TAB_OCxx[iChannel]); } @@ -1429,10 +1414,10 @@ __STATIC_INLINE void LL_TIM_OC_SetMode(TIM_TypeDef * TIMx, uint32_t Channel, uin * @arg @ref LL_TIM_OCMODE_PWM1 * @arg @ref LL_TIM_OCMODE_PWM2 */ -__STATIC_INLINE uint32_t LL_TIM_OC_GetMode(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_OC_GetMode(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); return (READ_BIT(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel])) >> SHIFT_TAB_OCxx[iChannel]); } @@ -1453,7 +1438,7 @@ __STATIC_INLINE uint32_t LL_TIM_OC_GetMode(TIM_TypeDef * TIMx, uint32_t Channel) * @arg @ref LL_TIM_OCPOLARITY_LOW * @retval None */ -__STATIC_INLINE void LL_TIM_OC_SetPolarity(TIM_TypeDef * TIMx, uint32_t Channel, uint32_t Polarity) +__STATIC_INLINE void LL_TIM_OC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Polarity) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), Polarity << SHIFT_TAB_CCxP[iChannel]); @@ -1475,13 +1460,12 @@ __STATIC_INLINE void LL_TIM_OC_SetPolarity(TIM_TypeDef * TIMx, uint32_t Channel, * @arg @ref LL_TIM_OCPOLARITY_HIGH * @arg @ref LL_TIM_OCPOLARITY_LOW */ -__STATIC_INLINE uint32_t LL_TIM_OC_GetPolarity(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_OC_GetPolarity(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); return (READ_BIT(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel])) >> SHIFT_TAB_CCxP[iChannel]); } - /** * @brief Enable fast mode for the output channel. * @note Acts only if the channel is configured in PWM1 or PWM2 mode. @@ -1497,10 +1481,10 @@ __STATIC_INLINE uint32_t LL_TIM_OC_GetPolarity(TIM_TypeDef * TIMx, uint32_t Chan * @arg @ref LL_TIM_CHANNEL_CH4 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_EnableFast(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE void LL_TIM_OC_EnableFast(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); SET_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); } @@ -1519,10 +1503,10 @@ __STATIC_INLINE void LL_TIM_OC_EnableFast(TIM_TypeDef * TIMx, uint32_t Channel) * @arg @ref LL_TIM_CHANNEL_CH4 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_DisableFast(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE void LL_TIM_OC_DisableFast(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); CLEAR_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); } @@ -1541,10 +1525,10 @@ __STATIC_INLINE void LL_TIM_OC_DisableFast(TIM_TypeDef * TIMx, uint32_t Channel) * @arg @ref LL_TIM_CHANNEL_CH4 * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledFast(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledFast(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); register uint32_t bitfield = TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel]; return (READ_BIT(*pReg, bitfield) == bitfield); } @@ -1563,10 +1547,10 @@ __STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledFast(TIM_TypeDef * TIMx, uint32_t Ch * @arg @ref LL_TIM_CHANNEL_CH4 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_EnablePreload(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE void LL_TIM_OC_EnablePreload(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); SET_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); } @@ -1584,10 +1568,10 @@ __STATIC_INLINE void LL_TIM_OC_EnablePreload(TIM_TypeDef * TIMx, uint32_t Channe * @arg @ref LL_TIM_CHANNEL_CH4 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_DisablePreload(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE void LL_TIM_OC_DisablePreload(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); CLEAR_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); } @@ -1605,10 +1589,10 @@ __STATIC_INLINE void LL_TIM_OC_DisablePreload(TIM_TypeDef * TIMx, uint32_t Chann * @arg @ref LL_TIM_CHANNEL_CH4 * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledPreload(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledPreload(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); register uint32_t bitfield = TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel]; return (READ_BIT(*pReg, bitfield) == bitfield); } @@ -1630,10 +1614,10 @@ __STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledPreload(TIM_TypeDef * TIMx, uint32_t * @arg @ref LL_TIM_CHANNEL_CH4 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_EnableClear(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE void LL_TIM_OC_EnableClear(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); SET_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); } @@ -1653,10 +1637,10 @@ __STATIC_INLINE void LL_TIM_OC_EnableClear(TIM_TypeDef * TIMx, uint32_t Channel) * @arg @ref LL_TIM_CHANNEL_CH4 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_DisableClear(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE void LL_TIM_OC_DisableClear(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); CLEAR_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); } @@ -1678,15 +1662,14 @@ __STATIC_INLINE void LL_TIM_OC_DisableClear(TIM_TypeDef * TIMx, uint32_t Channel * @arg @ref LL_TIM_CHANNEL_CH4 * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledClear(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledClear(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); register uint32_t bitfield = TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel]; return (READ_BIT(*pReg, bitfield) == bitfield); } - /** * @brief Set compare value for output channel 1 (TIMx_CCR1). * @note Macro @ref IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not @@ -1696,7 +1679,7 @@ __STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledClear(TIM_TypeDef * TIMx, uint32_t C * @param CompareValue between Min_Data=0 and Max_Data=65535 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_SetCompareCH1(TIM_TypeDef * TIMx, uint32_t CompareValue) +__STATIC_INLINE void LL_TIM_OC_SetCompareCH1(TIM_TypeDef *TIMx, uint32_t CompareValue) { WRITE_REG(TIMx->CCR1, CompareValue); } @@ -1710,7 +1693,7 @@ __STATIC_INLINE void LL_TIM_OC_SetCompareCH1(TIM_TypeDef * TIMx, uint32_t Compar * @param CompareValue between Min_Data=0 and Max_Data=65535 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_SetCompareCH2(TIM_TypeDef * TIMx, uint32_t CompareValue) +__STATIC_INLINE void LL_TIM_OC_SetCompareCH2(TIM_TypeDef *TIMx, uint32_t CompareValue) { WRITE_REG(TIMx->CCR2, CompareValue); } @@ -1724,7 +1707,7 @@ __STATIC_INLINE void LL_TIM_OC_SetCompareCH2(TIM_TypeDef * TIMx, uint32_t Compar * @param CompareValue between Min_Data=0 and Max_Data=65535 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_SetCompareCH3(TIM_TypeDef * TIMx, uint32_t CompareValue) +__STATIC_INLINE void LL_TIM_OC_SetCompareCH3(TIM_TypeDef *TIMx, uint32_t CompareValue) { WRITE_REG(TIMx->CCR3, CompareValue); } @@ -1738,12 +1721,11 @@ __STATIC_INLINE void LL_TIM_OC_SetCompareCH3(TIM_TypeDef * TIMx, uint32_t Compar * @param CompareValue between Min_Data=0 and Max_Data=65535 * @retval None */ -__STATIC_INLINE void LL_TIM_OC_SetCompareCH4(TIM_TypeDef * TIMx, uint32_t CompareValue) +__STATIC_INLINE void LL_TIM_OC_SetCompareCH4(TIM_TypeDef *TIMx, uint32_t CompareValue) { WRITE_REG(TIMx->CCR4, CompareValue); } - /** * @brief Get compare value (TIMx_CCR1) set for output channel 1. * @note Macro @ref IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not @@ -1752,7 +1734,7 @@ __STATIC_INLINE void LL_TIM_OC_SetCompareCH4(TIM_TypeDef * TIMx, uint32_t Compar * @param TIMx Timer instance * @retval CompareValue (between Min_Data=0 and Max_Data=65535) */ -__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH1(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH1(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CCR1)); } @@ -1765,7 +1747,7 @@ __STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval CompareValue (between Min_Data=0 and Max_Data=65535) */ -__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH2(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH2(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CCR2)); } @@ -1778,7 +1760,7 @@ __STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval CompareValue (between Min_Data=0 and Max_Data=65535) */ -__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH3(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH3(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CCR3)); } @@ -1791,13 +1773,11 @@ __STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval CompareValue (between Min_Data=0 and Max_Data=65535) */ -__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH4(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH4(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CCR4)); } - - /** * @} */ @@ -1840,12 +1820,14 @@ __STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH4(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_IC_POLARITY_RISING or @ref LL_TIM_IC_POLARITY_FALLING or @ref LL_TIM_IC_POLARITY_BOTHEDGE * @retval None */ -__STATIC_INLINE void LL_TIM_IC_Config(TIM_TypeDef * TIMx, uint32_t Channel, uint32_t Configuration) +__STATIC_INLINE void LL_TIM_IC_Config(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Configuration) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); - MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), ((Configuration >> 16U) & (TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S)) << SHIFT_TAB_ICxx[iChannel]); - MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), (Configuration & (TIM_CCER_CC1NP | TIM_CCER_CC1P)) << SHIFT_TAB_CCxP[iChannel]); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), + ((Configuration >> 16U) & (TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S)) << SHIFT_TAB_ICxx[iChannel]); + MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + (Configuration & (TIM_CCER_CC1NP | TIM_CCER_CC1P)) << SHIFT_TAB_CCxP[iChannel]); } /** @@ -1866,11 +1848,11 @@ __STATIC_INLINE void LL_TIM_IC_Config(TIM_TypeDef * TIMx, uint32_t Channel, uint * @arg @ref LL_TIM_ACTIVEINPUT_TRC * @retval None */ -__STATIC_INLINE void LL_TIM_IC_SetActiveInput(TIM_TypeDef * TIMx, uint32_t Channel, uint32_t ICActiveInput) +__STATIC_INLINE void LL_TIM_IC_SetActiveInput(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICActiveInput) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); - MODIFY_REG(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), (ICActiveInput >> 16U) << SHIFT_TAB_ICxx[iChannel]); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), (ICActiveInput >> 16U) << SHIFT_TAB_ICxx[iChannel]); } /** @@ -1890,10 +1872,10 @@ __STATIC_INLINE void LL_TIM_IC_SetActiveInput(TIM_TypeDef * TIMx, uint32_t Chann * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI * @arg @ref LL_TIM_ACTIVEINPUT_TRC */ -__STATIC_INLINE uint32_t LL_TIM_IC_GetActiveInput(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_IC_GetActiveInput(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); return ((READ_BIT(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); } @@ -1916,11 +1898,11 @@ __STATIC_INLINE uint32_t LL_TIM_IC_GetActiveInput(TIM_TypeDef * TIMx, uint32_t C * @arg @ref LL_TIM_ICPSC_DIV8 * @retval None */ -__STATIC_INLINE void LL_TIM_IC_SetPrescaler(TIM_TypeDef * TIMx, uint32_t Channel, uint32_t ICPrescaler) +__STATIC_INLINE void LL_TIM_IC_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICPrescaler) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); - MODIFY_REG(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel]), (ICPrescaler >> 16U) << SHIFT_TAB_ICxx[iChannel]); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel]), (ICPrescaler >> 16U) << SHIFT_TAB_ICxx[iChannel]); } /** @@ -1941,10 +1923,10 @@ __STATIC_INLINE void LL_TIM_IC_SetPrescaler(TIM_TypeDef * TIMx, uint32_t Channel * @arg @ref LL_TIM_ICPSC_DIV4 * @arg @ref LL_TIM_ICPSC_DIV8 */ -__STATIC_INLINE uint32_t LL_TIM_IC_GetPrescaler(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_IC_GetPrescaler(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); } @@ -1979,11 +1961,11 @@ __STATIC_INLINE uint32_t LL_TIM_IC_GetPrescaler(TIM_TypeDef * TIMx, uint32_t Cha * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 * @retval None */ -__STATIC_INLINE void LL_TIM_IC_SetFilter(TIM_TypeDef * TIMx, uint32_t Channel, uint32_t ICFilter) +__STATIC_INLINE void LL_TIM_IC_SetFilter(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICFilter) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); - MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel]), (ICFilter >> 16U) << SHIFT_TAB_ICxx[iChannel]); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel]), (ICFilter >> 16U) << SHIFT_TAB_ICxx[iChannel]); } /** @@ -2016,11 +1998,11 @@ __STATIC_INLINE void LL_TIM_IC_SetFilter(TIM_TypeDef * TIMx, uint32_t Channel, u * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 */ -__STATIC_INLINE uint32_t LL_TIM_IC_GetFilter(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_IC_GetFilter(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - register uint32_t * pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1)+ OFFSET_TAB_CCMRx[iChannel])); - return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U ); + register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); } /** @@ -2045,10 +2027,11 @@ __STATIC_INLINE uint32_t LL_TIM_IC_GetFilter(TIM_TypeDef * TIMx, uint32_t Channe * @arg @ref LL_TIM_IC_POLARITY_BOTHEDGE * @retval None */ -__STATIC_INLINE void LL_TIM_IC_SetPolarity(TIM_TypeDef * TIMx, uint32_t Channel, uint32_t ICPolarity) +__STATIC_INLINE void LL_TIM_IC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICPolarity) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), ICPolarity << SHIFT_TAB_CCxP[iChannel]); + MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + ICPolarity << SHIFT_TAB_CCxP[iChannel]); } /** @@ -2072,10 +2055,11 @@ __STATIC_INLINE void LL_TIM_IC_SetPolarity(TIM_TypeDef * TIMx, uint32_t Channel, * @arg @ref LL_TIM_IC_POLARITY_FALLING * @arg @ref LL_TIM_IC_POLARITY_BOTHEDGE */ -__STATIC_INLINE uint32_t LL_TIM_IC_GetPolarity(TIM_TypeDef * TIMx, uint32_t Channel) +__STATIC_INLINE uint32_t LL_TIM_IC_GetPolarity(TIM_TypeDef *TIMx, uint32_t Channel) { register uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); - return (READ_BIT(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel])) >> SHIFT_TAB_CCxP[iChannel]); + return (READ_BIT(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel])) >> + SHIFT_TAB_CCxP[iChannel]); } /** @@ -2086,7 +2070,7 @@ __STATIC_INLINE uint32_t LL_TIM_IC_GetPolarity(TIM_TypeDef * TIMx, uint32_t Chan * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_IC_EnableXORCombination(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_IC_EnableXORCombination(TIM_TypeDef *TIMx) { SET_BIT(TIMx->CR2, TIM_CR2_TI1S); } @@ -2099,7 +2083,7 @@ __STATIC_INLINE void LL_TIM_IC_EnableXORCombination(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_IC_DisableXORCombination(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_IC_DisableXORCombination(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->CR2, TIM_CR2_TI1S); } @@ -2112,7 +2096,7 @@ __STATIC_INLINE void LL_TIM_IC_DisableXORCombination(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IC_IsEnabledXORCombination(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IC_IsEnabledXORCombination(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->CR2, TIM_CR2_TI1S) == (TIM_CR2_TI1S)); } @@ -2125,7 +2109,7 @@ __STATIC_INLINE uint32_t LL_TIM_IC_IsEnabledXORCombination(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) */ -__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH1(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH1(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CCR1)); } @@ -2138,7 +2122,7 @@ __STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) */ -__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH2(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH2(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CCR2)); } @@ -2151,7 +2135,7 @@ __STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) */ -__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH3(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH3(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CCR3)); } @@ -2164,7 +2148,7 @@ __STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) */ -__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH4(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH4(TIM_TypeDef *TIMx) { return (uint32_t)(READ_REG(TIMx->CCR4)); } @@ -2179,52 +2163,52 @@ __STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH4(TIM_TypeDef * TIMx) /** * @brief Enable external clock mode 2. * @note When external clock mode 2 is enabled the counter is clocked by any active edge on the ETRF signal. - * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check * whether or not a timer instance supports external clock mode2. * @rmtoll SMCR ECE LL_TIM_EnableExternalClock * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableExternalClock(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableExternalClock(TIM_TypeDef *TIMx) { SET_BIT(TIMx->SMCR, TIM_SMCR_ECE); } /** * @brief Disable external clock mode 2. - * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check * whether or not a timer instance supports external clock mode2. * @rmtoll SMCR ECE LL_TIM_DisableExternalClock * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableExternalClock(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableExternalClock(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->SMCR, TIM_SMCR_ECE); } /** * @brief Indicate whether external clock mode 2 is enabled. - * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check * whether or not a timer instance supports external clock mode2. * @rmtoll SMCR ECE LL_TIM_IsEnabledExternalClock * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledExternalClock(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledExternalClock(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SMCR, TIM_SMCR_ECE) == (TIM_SMCR_ECE)); } /** * @brief Set the clock source of the counter clock. - * @note when selected clock source is external clock mode 1, the timer input - * the external clock is applied is selected by calling the @ref LL_TIM_SetTriggerInput() - * function. This timer input must be configured by calling + * @note when selected clock source is external clock mode 1, the timer input + * the external clock is applied is selected by calling the @ref LL_TIM_SetTriggerInput() + * function. This timer input must be configured by calling * the @ref LL_TIM_IC_Config() function. - * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(TIMx) can be used to check * whether or not a timer instance supports external clock mode1. - * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check * whether or not a timer instance supports external clock mode2. * @rmtoll SMCR SMS LL_TIM_SetClockSource\n * SMCR ECE LL_TIM_SetClockSource @@ -2235,14 +2219,14 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledExternalClock(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE2 * @retval None */ -__STATIC_INLINE void LL_TIM_SetClockSource(TIM_TypeDef * TIMx, uint32_t ClockSource) +__STATIC_INLINE void LL_TIM_SetClockSource(TIM_TypeDef *TIMx, uint32_t ClockSource) { MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS | TIM_SMCR_ECE, ClockSource); } /** * @brief Set the encoder interface mode. - * @note Macro @ref IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx) can be used to check * whether or not a timer instance supports the encoder mode. * @rmtoll SMCR SMS LL_TIM_SetEncoderMode * @param TIMx Timer instance @@ -2252,7 +2236,7 @@ __STATIC_INLINE void LL_TIM_SetClockSource(TIM_TypeDef * TIMx, uint32_t ClockSou * @arg @ref LL_TIM_ENCODERMODE_X4_TI12 * @retval None */ -__STATIC_INLINE void LL_TIM_SetEncoderMode(TIM_TypeDef * TIMx, uint32_t EncoderMode) +__STATIC_INLINE void LL_TIM_SetEncoderMode(TIM_TypeDef *TIMx, uint32_t EncoderMode) { MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, EncoderMode); } @@ -2266,7 +2250,7 @@ __STATIC_INLINE void LL_TIM_SetEncoderMode(TIM_TypeDef * TIMx, uint32_t EncoderM */ /** * @brief Set the trigger output (TRGO) used for timer synchronization . - * @note Macro @ref IS_TIM_MASTER_INSTANCE(TIMx) can be used to check + * @note Macro @ref IS_TIM_MASTER_INSTANCE(TIMx) can be used to check * whether or not a timer instance can operate as a master timer. * @rmtoll CR2 MMS LL_TIM_SetTriggerOutput * @param TIMx Timer instance @@ -2281,15 +2265,14 @@ __STATIC_INLINE void LL_TIM_SetEncoderMode(TIM_TypeDef * TIMx, uint32_t EncoderM * @arg @ref LL_TIM_TRGO_OC4REF * @retval None */ -__STATIC_INLINE void LL_TIM_SetTriggerOutput(TIM_TypeDef * TIMx, uint32_t TimerSynchronization) +__STATIC_INLINE void LL_TIM_SetTriggerOutput(TIM_TypeDef *TIMx, uint32_t TimerSynchronization) { MODIFY_REG(TIMx->CR2, TIM_CR2_MMS, TimerSynchronization); } - /** * @brief Set the synchronization mode of a slave timer. - * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not * a timer instance can operate as a slave timer. * @rmtoll SMCR SMS LL_TIM_SetSlaveMode * @param TIMx Timer instance @@ -2300,14 +2283,14 @@ __STATIC_INLINE void LL_TIM_SetTriggerOutput(TIM_TypeDef * TIMx, uint32_t TimerS * @arg @ref LL_TIM_SLAVEMODE_TRIGGER * @retval None */ -__STATIC_INLINE void LL_TIM_SetSlaveMode(TIM_TypeDef * TIMx, uint32_t SlaveMode) +__STATIC_INLINE void LL_TIM_SetSlaveMode(TIM_TypeDef *TIMx, uint32_t SlaveMode) { MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, SlaveMode); } /** * @brief Set the selects the trigger input to be used to synchronize the counter. - * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not * a timer instance can operate as a slave timer. * @rmtoll SMCR TS LL_TIM_SetTriggerInput * @param TIMx Timer instance @@ -2322,53 +2305,53 @@ __STATIC_INLINE void LL_TIM_SetSlaveMode(TIM_TypeDef * TIMx, uint32_t SlaveMode) * @arg @ref LL_TIM_TS_ETRF * @retval None */ -__STATIC_INLINE void LL_TIM_SetTriggerInput(TIM_TypeDef * TIMx, uint32_t TriggerInput) +__STATIC_INLINE void LL_TIM_SetTriggerInput(TIM_TypeDef *TIMx, uint32_t TriggerInput) { MODIFY_REG(TIMx->SMCR, TIM_SMCR_TS, TriggerInput); } /** * @brief Enable the Master/Slave mode. - * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not * a timer instance can operate as a slave timer. * @rmtoll SMCR MSM LL_TIM_EnableMasterSlaveMode * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableMasterSlaveMode(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableMasterSlaveMode(TIM_TypeDef *TIMx) { SET_BIT(TIMx->SMCR, TIM_SMCR_MSM); } /** * @brief Disable the Master/Slave mode. - * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not * a timer instance can operate as a slave timer. * @rmtoll SMCR MSM LL_TIM_DisableMasterSlaveMode * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableMasterSlaveMode(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableMasterSlaveMode(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->SMCR, TIM_SMCR_MSM); } /** * @brief Indicates whether the Master/Slave mode is enabled. - * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * @note Macro @ref IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not * a timer instance can operate as a slave timer. * @rmtoll SMCR MSM LL_TIM_IsEnabledMasterSlaveMode * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledMasterSlaveMode(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledMasterSlaveMode(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SMCR, TIM_SMCR_MSM) == (TIM_SMCR_MSM)); } /** * @brief Configure the external trigger (ETR) input. - * @note Macro @ref IS_TIM_ETR_INSTANCE(TIMx) can be used to check whether or not + * @note Macro @ref IS_TIM_ETR_INSTANCE(TIMx) can be used to check whether or not * a timer instance provides an external trigger input. * @rmtoll SMCR ETP LL_TIM_ConfigETR\n * SMCR ETPS LL_TIM_ConfigETR\n @@ -2401,17 +2384,16 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledMasterSlaveMode(TIM_TypeDef * TIMx) * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N8 * @retval None */ -__STATIC_INLINE void LL_TIM_ConfigETR(TIM_TypeDef * TIMx, uint32_t ETRPolarity, uint32_t ETRPrescaler, uint32_t ETRFilter) +__STATIC_INLINE void LL_TIM_ConfigETR(TIM_TypeDef *TIMx, uint32_t ETRPolarity, uint32_t ETRPrescaler, + uint32_t ETRFilter) { MODIFY_REG(TIMx->SMCR, TIM_SMCR_ETP | TIM_SMCR_ETPS | TIM_SMCR_ETF, ETRPolarity | ETRPrescaler | ETRFilter); } - /** * @} */ - /** @defgroup TIM_LL_EF_DMA_Burst_Mode DMA burst mode configuration * @{ */ @@ -2468,7 +2450,7 @@ __STATIC_INLINE void LL_TIM_ConfigETR(TIM_TypeDef * TIMx, uint32_t ETRPolarity, * @arg @ref LL_TIM_DMABURST_LENGTH_18TRANSFERS * @retval None */ -__STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef * TIMx, uint32_t DMABurstBaseAddress, uint32_t DMABurstLength) +__STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef *TIMx, uint32_t DMABurstBaseAddress, uint32_t DMABurstLength) { MODIFY_REG(TIMx->DCR, TIM_DCR_DBL | TIM_DCR_DBA, DMABurstBaseAddress | DMABurstLength); } @@ -2495,12 +2477,12 @@ __STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef * TIMx, uint32_t DMABurst * TIM3_OR TI1_RMP LL_TIM_SetRemap\n * TIM3_OR TI2_RMP LL_TIM_SetRemap\n * TIM3_OR TI4_RMP LL_TIM_SetRemap - * @param TIMx Timer instance + * @param TIMx Timer instance * @param Remap Remap params depends on the TIMx. Description available only - * in CHM version of the User Manual (not in .pdf). + * in CHM version of the User Manual (not in .pdf). * Otherwise see Reference Manual description of OR registers. * - * Below description summarizes "Timer Instance" and "Remap" param combinations: + * Below description summarizes "Timer Instance" and "Remap" param combinations: * * TIM2: any combination of ETR_RMP, TI4_RMP where * @@ -2521,22 +2503,22 @@ __STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef * TIMx, uint32_t DMABurst * * . . ETR_RMP can be one of the following values (**) * @arg @ref LL_TIM_TIM3_ETR_RMP_GPIO - * @arg @ref LL_TIM_TIM3_ETR_RMP_HSI48DIV6 + * @arg @ref LL_TIM_TIM3_ETR_RMP_HSI48DIV6 * * . . TI_RMP_TI1 can be one of the following values (**) * @arg @ref LL_TIM_TIM3_TI_RMP_TI1_USB_SOF - * @arg @ref LL_TIM_TIM3_TI_RMP_TI1_GPIO + * @arg @ref LL_TIM_TIM3_TI_RMP_TI1_GPIO * * . . TI_RMP_TI2 can be one of the following values (**) * @arg @ref LL_TIM_TIM3_TI_RMP_TI2_GPIO_DEF - * @arg @ref LL_TIM_TIM3_TI_RMP_TI2_GPIOB5_AF4 + * @arg @ref LL_TIM_TIM3_TI_RMP_TI2_GPIOB5_AF4 * * . . TI_RMP_TI4 can be one of the following values (**) * @arg @ref LL_TIM_TIM3_TI_RMP_TI4_GPIO_DEF - * @arg @ref LL_TIM_TIM3_TI_RMP_TI4_GPIOC9_AF2 + * @arg @ref LL_TIM_TIM3_TI_RMP_TI4_GPIOC9_AF2 * * TIM21: any combination of ETR_RMP, TI1_RMP, TI2_RMP where - * + * * . . ETR_RMP can be one of the following values * @arg @ref LL_TIM_TIM21_ETR_RMP_GPIO * @arg @ref LL_TIM_TIM21_ETR_RMP_COMP2 @@ -2560,22 +2542,22 @@ __STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef * TIMx, uint32_t DMABurst * TIM22: any combination of ETR_RMP, TI1_RMP where (**) * * . . ETR_RMP can be one of the following values (**) - * @arg @ref LL_TIM_TIM22_ETR_RMP_GPIO - * @arg @ref LL_TIM_TIM22_ETR_RMP_COMP2 - * @arg @ref LL_TIM_TIM22_ETR_RMP_COMP1 - * @arg @ref LL_TIM_TIM22_ETR_RMP_LSE + * @arg @ref LL_TIM_TIM22_ETR_RMP_GPIO + * @arg @ref LL_TIM_TIM22_ETR_RMP_COMP2 + * @arg @ref LL_TIM_TIM22_ETR_RMP_COMP1 + * @arg @ref LL_TIM_TIM22_ETR_RMP_LSE * * . . TI1_RMP can be one of the following values (**) - * @arg @ref LL_TIM_TIM22_TI1_RMP_GPIO1 - * @arg @ref LL_TIM_TIM22_TI1_RMP_COMP2 - * @arg @ref LL_TIM_TIM22_TI1_RMP_COMP1 - * @arg @ref LL_TIM_TIM22_TI1_RMP_GPIO2 + * @arg @ref LL_TIM_TIM22_TI1_RMP_GPIO1 + * @arg @ref LL_TIM_TIM22_TI1_RMP_COMP2 + * @arg @ref LL_TIM_TIM22_TI1_RMP_COMP1 + * @arg @ref LL_TIM_TIM22_TI1_RMP_GPIO2 * * (*) Value not defined in all devices. \n * (*) Register not available in all devices. * @retval None */ -__STATIC_INLINE void LL_TIM_SetRemap(TIM_TypeDef * TIMx, uint32_t Remap) +__STATIC_INLINE void LL_TIM_SetRemap(TIM_TypeDef *TIMx, uint32_t Remap) { MODIFY_REG(TIMx->OR, (Remap >> TIMx_OR_RMP_SHIFT), (Remap & TIMx_OR_RMP_MASK)); } @@ -2588,18 +2570,17 @@ __STATIC_INLINE void LL_TIM_SetRemap(TIM_TypeDef * TIMx, uint32_t Remap) * @{ */ /** - * @brief Set the OCREF clear source + * @brief Set the OCREF clear input source * @note The OCxREF signal of a given channel can be cleared when a high level is applied on the OCREF_CLR_INPUT * @note This function can only be used in Output compare and PWM modes. - * @rmtoll SMCR OCCS LL_TIM_SetOCRefClearInputSource + * @rmtoll SMCR OCCS LL_TIM_SetOCRefClearInputSource * @param TIMx Timer instance * @param OCRefClearInputSource This parameter can be one of the following values: * @arg @ref LL_TIM_OCREF_CLR_INT_NC * @arg @ref LL_TIM_OCREF_CLR_INT_ETR * @retval None */ - -__STATIC_INLINE void LL_TIM_SetOCRefClearInputSource(TIM_TypeDef * TIMx, uint32_t OCRefClearInputSource) +__STATIC_INLINE void LL_TIM_SetOCRefClearInputSource(TIM_TypeDef *TIMx, uint32_t OCRefClearInputSource) { MODIFY_REG(TIMx->SMCR, TIM_SMCR_OCCS, OCRefClearInputSource); } @@ -2616,7 +2597,7 @@ __STATIC_INLINE void LL_TIM_SetOCRefClearInputSource(TIM_TypeDef * TIMx, uint32_ * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_UPDATE(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_UIF)); } @@ -2627,7 +2608,7 @@ __STATIC_INLINE void LL_TIM_ClearFlag_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_UPDATE(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_UIF) == (TIM_SR_UIF)); } @@ -2638,7 +2619,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_CC1(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_CC1IF)); } @@ -2649,7 +2630,7 @@ __STATIC_INLINE void LL_TIM_ClearFlag_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_CC1IF) == (TIM_SR_CC1IF)); } @@ -2660,7 +2641,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_CC2(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_CC2IF)); } @@ -2671,7 +2652,7 @@ __STATIC_INLINE void LL_TIM_ClearFlag_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_CC2IF) == (TIM_SR_CC2IF)); } @@ -2682,7 +2663,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_CC3(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_CC3IF)); } @@ -2693,7 +2674,7 @@ __STATIC_INLINE void LL_TIM_ClearFlag_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_CC3IF) == (TIM_SR_CC3IF)); } @@ -2704,7 +2685,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_CC4(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_CC4IF)); } @@ -2715,21 +2696,18 @@ __STATIC_INLINE void LL_TIM_ClearFlag_CC4(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_CC4IF) == (TIM_SR_CC4IF)); } - - - /** * @brief Clear the trigger interrupt flag (TIF). * @rmtoll SR TIF LL_TIM_ClearFlag_TRIG * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_TRIG(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_TIF)); } @@ -2740,20 +2718,18 @@ __STATIC_INLINE void LL_TIM_ClearFlag_TRIG(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_TRIG(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_TIF) == (TIM_SR_TIF)); } - - /** * @brief Clear the Capture/Compare 1 over-capture interrupt flag (CC1OF). * @rmtoll SR CC1OF LL_TIM_ClearFlag_CC1OVR * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_CC1OVR(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_CC1OVR(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_CC1OF)); } @@ -2764,7 +2740,7 @@ __STATIC_INLINE void LL_TIM_ClearFlag_CC1OVR(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1OVR(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1OVR(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_CC1OF) == (TIM_SR_CC1OF)); } @@ -2775,7 +2751,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1OVR(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_CC2OVR(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_CC2OVR(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_CC2OF)); } @@ -2786,7 +2762,7 @@ __STATIC_INLINE void LL_TIM_ClearFlag_CC2OVR(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2OVR(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2OVR(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_CC2OF) == (TIM_SR_CC2OF)); } @@ -2797,7 +2773,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2OVR(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_CC3OVR(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_CC3OVR(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_CC3OF)); } @@ -2808,7 +2784,7 @@ __STATIC_INLINE void LL_TIM_ClearFlag_CC3OVR(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3OVR(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3OVR(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_CC3OF) == (TIM_SR_CC3OF)); } @@ -2819,7 +2795,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3OVR(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_ClearFlag_CC4OVR(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_ClearFlag_CC4OVR(TIM_TypeDef *TIMx) { WRITE_REG(TIMx->SR, ~(TIM_SR_CC4OF)); } @@ -2830,12 +2806,11 @@ __STATIC_INLINE void LL_TIM_ClearFlag_CC4OVR(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4OVR(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4OVR(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->SR, TIM_SR_CC4OF) == (TIM_SR_CC4OF)); } - /** * @} */ @@ -2849,7 +2824,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4OVR(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableIT_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableIT_UPDATE(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_UIE); } @@ -2860,7 +2835,7 @@ __STATIC_INLINE void LL_TIM_EnableIT_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableIT_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableIT_UPDATE(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_UIE); } @@ -2871,7 +2846,7 @@ __STATIC_INLINE void LL_TIM_DisableIT_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_UPDATE(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_UIE) == (TIM_DIER_UIE)); } @@ -2882,7 +2857,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableIT_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableIT_CC1(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_CC1IE); } @@ -2893,7 +2868,7 @@ __STATIC_INLINE void LL_TIM_EnableIT_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableIT_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableIT_CC1(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1IE); } @@ -2904,7 +2879,7 @@ __STATIC_INLINE void LL_TIM_DisableIT_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC1(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_CC1IE) == (TIM_DIER_CC1IE)); } @@ -2915,7 +2890,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableIT_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableIT_CC2(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_CC2IE); } @@ -2926,7 +2901,7 @@ __STATIC_INLINE void LL_TIM_EnableIT_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableIT_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableIT_CC2(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2IE); } @@ -2937,7 +2912,7 @@ __STATIC_INLINE void LL_TIM_DisableIT_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC2(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_CC2IE) == (TIM_DIER_CC2IE)); } @@ -2948,7 +2923,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableIT_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableIT_CC3(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_CC3IE); } @@ -2959,7 +2934,7 @@ __STATIC_INLINE void LL_TIM_EnableIT_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableIT_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableIT_CC3(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3IE); } @@ -2970,7 +2945,7 @@ __STATIC_INLINE void LL_TIM_DisableIT_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC3(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_CC3IE) == (TIM_DIER_CC3IE)); } @@ -2981,7 +2956,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableIT_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableIT_CC4(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_CC4IE); } @@ -2992,7 +2967,7 @@ __STATIC_INLINE void LL_TIM_EnableIT_CC4(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableIT_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableIT_CC4(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4IE); } @@ -3003,19 +2978,18 @@ __STATIC_INLINE void LL_TIM_DisableIT_CC4(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC4(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_CC4IE) == (TIM_DIER_CC4IE)); } - /** * @brief Enable trigger interrupt (TIE). * @rmtoll DIER TIE LL_TIM_EnableIT_TRIG * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableIT_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableIT_TRIG(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_TIE); } @@ -3026,7 +3000,7 @@ __STATIC_INLINE void LL_TIM_EnableIT_TRIG(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableIT_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableIT_TRIG(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_TIE); } @@ -3037,12 +3011,11 @@ __STATIC_INLINE void LL_TIM_DisableIT_TRIG(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_TRIG(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_TIE) == (TIM_DIER_TIE)); } - /** * @} */ @@ -3056,7 +3029,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_TRIG(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableDMAReq_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableDMAReq_UPDATE(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_UDE); } @@ -3067,7 +3040,7 @@ __STATIC_INLINE void LL_TIM_EnableDMAReq_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableDMAReq_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableDMAReq_UPDATE(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_UDE); } @@ -3078,7 +3051,7 @@ __STATIC_INLINE void LL_TIM_DisableDMAReq_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_UPDATE(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_UDE) == (TIM_DIER_UDE)); } @@ -3089,7 +3062,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableDMAReq_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC1(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_CC1DE); } @@ -3100,7 +3073,7 @@ __STATIC_INLINE void LL_TIM_EnableDMAReq_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableDMAReq_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC1(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1DE); } @@ -3111,7 +3084,7 @@ __STATIC_INLINE void LL_TIM_DisableDMAReq_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC1(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_CC1DE) == (TIM_DIER_CC1DE)); } @@ -3122,7 +3095,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableDMAReq_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC2(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_CC2DE); } @@ -3133,7 +3106,7 @@ __STATIC_INLINE void LL_TIM_EnableDMAReq_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableDMAReq_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC2(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2DE); } @@ -3144,7 +3117,7 @@ __STATIC_INLINE void LL_TIM_DisableDMAReq_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC2(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_CC2DE) == (TIM_DIER_CC2DE)); } @@ -3155,7 +3128,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableDMAReq_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC3(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_CC3DE); } @@ -3166,7 +3139,7 @@ __STATIC_INLINE void LL_TIM_EnableDMAReq_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableDMAReq_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC3(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3DE); } @@ -3177,7 +3150,7 @@ __STATIC_INLINE void LL_TIM_DisableDMAReq_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC3(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_CC3DE) == (TIM_DIER_CC3DE)); } @@ -3188,7 +3161,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableDMAReq_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC4(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_CC4DE); } @@ -3199,7 +3172,7 @@ __STATIC_INLINE void LL_TIM_EnableDMAReq_CC4(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableDMAReq_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC4(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4DE); } @@ -3210,19 +3183,18 @@ __STATIC_INLINE void LL_TIM_DisableDMAReq_CC4(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC4(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_CC4DE) == (TIM_DIER_CC4DE)); } - /** * @brief Enable trigger interrupt (TDE). * @rmtoll DIER TDE LL_TIM_EnableDMAReq_TRIG * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_EnableDMAReq_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_EnableDMAReq_TRIG(TIM_TypeDef *TIMx) { SET_BIT(TIMx->DIER, TIM_DIER_TDE); } @@ -3233,7 +3205,7 @@ __STATIC_INLINE void LL_TIM_EnableDMAReq_TRIG(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_DisableDMAReq_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_DisableDMAReq_TRIG(TIM_TypeDef *TIMx) { CLEAR_BIT(TIMx->DIER, TIM_DIER_TDE); } @@ -3244,7 +3216,7 @@ __STATIC_INLINE void LL_TIM_DisableDMAReq_TRIG(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval State of bit (1 or 0). */ -__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_TRIG(TIM_TypeDef *TIMx) { return (READ_BIT(TIMx->DIER, TIM_DIER_TDE) == (TIM_DIER_TDE)); } @@ -3262,7 +3234,7 @@ __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_TRIG(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_GenerateEvent_UPDATE(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_GenerateEvent_UPDATE(TIM_TypeDef *TIMx) { SET_BIT(TIMx->EGR, TIM_EGR_UG); } @@ -3273,7 +3245,7 @@ __STATIC_INLINE void LL_TIM_GenerateEvent_UPDATE(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_GenerateEvent_CC1(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_GenerateEvent_CC1(TIM_TypeDef *TIMx) { SET_BIT(TIMx->EGR, TIM_EGR_CC1G); } @@ -3284,7 +3256,7 @@ __STATIC_INLINE void LL_TIM_GenerateEvent_CC1(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_GenerateEvent_CC2(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_GenerateEvent_CC2(TIM_TypeDef *TIMx) { SET_BIT(TIMx->EGR, TIM_EGR_CC2G); } @@ -3295,7 +3267,7 @@ __STATIC_INLINE void LL_TIM_GenerateEvent_CC2(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_GenerateEvent_CC3(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_GenerateEvent_CC3(TIM_TypeDef *TIMx) { SET_BIT(TIMx->EGR, TIM_EGR_CC3G); } @@ -3306,25 +3278,22 @@ __STATIC_INLINE void LL_TIM_GenerateEvent_CC3(TIM_TypeDef * TIMx) * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_GenerateEvent_CC4(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_GenerateEvent_CC4(TIM_TypeDef *TIMx) { SET_BIT(TIMx->EGR, TIM_EGR_CC4G); } - /** * @brief Generate trigger event. * @rmtoll EGR TG LL_TIM_GenerateEvent_TRIG * @param TIMx Timer instance * @retval None */ -__STATIC_INLINE void LL_TIM_GenerateEvent_TRIG(TIM_TypeDef * TIMx) +__STATIC_INLINE void LL_TIM_GenerateEvent_TRIG(TIM_TypeDef *TIMx) { SET_BIT(TIMx->EGR, TIM_EGR_TG); } - - /** * @} */ @@ -3333,16 +3302,16 @@ __STATIC_INLINE void LL_TIM_GenerateEvent_TRIG(TIM_TypeDef * TIMx) /** @defgroup TIM_LL_EF_Init Initialisation and deinitialisation functions * @{ */ - -ErrorStatus LL_TIM_DeInit(TIM_TypeDef* TIMx); -void LL_TIM_StructInit(LL_TIM_InitTypeDef* TIM_InitStruct); -ErrorStatus LL_TIM_Init(TIM_TypeDef* TIMx, LL_TIM_InitTypeDef* TIM_InitStruct); -void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef* TIM_OC_InitStruct); -ErrorStatus LL_TIM_OC_Init(TIM_TypeDef* TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef* TIM_OC_InitStruct); -void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef* TIM_ICInitStruct); -ErrorStatus LL_TIM_IC_Init(TIM_TypeDef* TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef* TIM_IC_InitStruct); -void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef* TIM_EncoderInitStruct); -ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef* TIMx, LL_TIM_ENCODER_InitTypeDef* TIM_EncoderInitStruct); + +ErrorStatus LL_TIM_DeInit(TIM_TypeDef *TIMx); +void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct); +ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, LL_TIM_InitTypeDef *TIM_InitStruct); +void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); +ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); +void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct); +void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); +ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_usart.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_usart.c index 8547805ec1..e442a67fb9 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_usart.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_usart.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_usart.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief USART LL module driver. ****************************************************************************** * @attention @@ -153,7 +151,7 @@ ErrorStatus LL_USART_DeInit(USART_TypeDef *USARTx) /* Release reset of USART clock */ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_USART1); } -#endif +#endif /* USART1 */ #if defined(USART1) else if (USARTx == USART2) #else @@ -263,7 +261,7 @@ ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_Ini { periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE); } -#endif +#endif /* USART1 */ #if defined(USART1) else if (USARTx == USART2) #else @@ -279,7 +277,7 @@ ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_Ini LL_RCC_GetSystemClocksFreq(&RCC_Clocks); periphclk = RCC_Clocks.PCLK1_Frequency; } -#endif +#endif /* USART4 */ #if defined(USART5) else if (USARTx == USART5) { @@ -287,7 +285,7 @@ ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_Ini LL_RCC_GetSystemClocksFreq(&RCC_Clocks); periphclk = RCC_Clocks.PCLK1_Frequency; } -#endif +#endif /* USART5 */ else { /* Nothing to do, as error code is already assigned to ERROR value */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_usart.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_usart.h index 782a71a0fb..460dce2480 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_usart.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_usart.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_usart.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of USART LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_utils.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_utils.c index aa6150fbb7..66521381a2 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_utils.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_utils.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_utils.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief UTILS LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_utils.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_utils.h index aff9108120..398e8763b3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_utils.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_utils.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_utils.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of UTILS LL module. @verbatim ============================================================================== @@ -75,7 +73,7 @@ extern "C" { */ /* Max delay can be used in LL_mDelay */ -#define LL_MAX_DELAY (uint32_t)0xFFFFFFFFU +#define LL_MAX_DELAY 0xFFFFFFFFU /** * @brief Unique device ID register base address @@ -87,6 +85,7 @@ extern "C" { */ #define FLASHSIZE_BASE_ADDRESS FLASHSIZE_BASE + /** * @} */ @@ -157,12 +156,13 @@ typedef struct /** @defgroup UTILS_EC_HSE_BYPASS HSE Bypass activation * @{ */ -#define LL_UTILS_HSEBYPASS_OFF (uint32_t)0x00000000U /*!< HSE Bypass is not enabled */ -#define LL_UTILS_HSEBYPASS_ON (uint32_t)0x00000001U /*!< HSE Bypass is enabled */ +#define LL_UTILS_HSEBYPASS_OFF 0x00000000U /*!< HSE Bypass is not enabled */ +#define LL_UTILS_HSEBYPASS_ON 0x00000001U /*!< HSE Bypass is enabled */ /** * @} */ + /** * @} */ @@ -216,6 +216,7 @@ __STATIC_INLINE uint32_t LL_GetFlashSize(void) return (uint16_t)(READ_REG(*((uint32_t *)FLASHSIZE_BASE_ADDRESS))); } + /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_wwdg.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_wwdg.h index 0db7d8eddc..3e60ad580d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_wwdg.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_ll_wwdg.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32l0xx_ll_wwdg.h * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief Header file of WWDG LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/system_stm32l0xx.c b/targets/TARGET_STM/TARGET_STM32L0/device/system_stm32l0xx.c index 16d835199c..6d4c296593 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/system_stm32l0xx.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/system_stm32l0xx.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file system_stm32l0xx.c * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. * * This file provides two functions and one global variable to be called from @@ -24,7 +22,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2015 STMicroelectronics

+ *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -99,7 +97,7 @@ Internal SRAM. */ /* #define VECT_TAB_SRAM */ #define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. - This value must be a multiple of 0x100. */ + This value must be a multiple of 0x200. */ /******************************************************************************/ /** * @} From bd54fa4b107be6f8571d4149a31bbb5c0f6b19b2 Mon Sep 17 00:00:00 2001 From: bcostm Date: Mon, 9 Apr 2018 11:42:01 +0200 Subject: [PATCH 08/46] L0 ST CUBE V1.10.0: spi and i2c corrections --- .../TARGET_STM32L0/device/stm32l0xx_hal_def.h | 1 + .../TARGET_STM32L0/device/stm32l0xx_hal_i2c.c | 115 ++---------------- .../TARGET_STM32L0/device/stm32l0xx_hal_i2c.h | 69 ----------- .../TARGET_STM32L0/device/stm32l0xx_hal_spi.c | 9 +- 4 files changed, 21 insertions(+), 173 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_def.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_def.h index 01f5b99771..e8050fc752 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_def.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_def.h @@ -203,3 +203,4 @@ typedef enum #endif /* ___STM32L0xx_HAL_DEF */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c index 91fde8d78d..d99695721c 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c @@ -348,10 +348,6 @@ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32 static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); static HAL_StatusTypeDef I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); -/* Private functions to centralize the enable/disable of Interrupts */ -static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); -static HAL_StatusTypeDef I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); - /* Private functions to flush TXDR register */ static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c); @@ -2158,10 +2154,6 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre hi2c->Mode = HAL_I2C_MODE_MEM; hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - /* Prepare transfer parameters */ - hi2c->Mode = HAL_I2C_MODE_MEM; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; @@ -2600,7 +2592,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); + hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED commit 23926a2418 hi2c->XferISR = I2C_Master_ISR_IT; /* If size > MAX_NBYTE_SIZE, use reload mode */ @@ -2615,12 +2607,13 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, xfermode = hi2c->XferOptions; } + // MBED commit 23926a2418 /* If transfer direction not change, do not generate Restart Condition */ /* Mean Previous state is same as current state */ - if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) - { - xferrequest = I2C_NO_STARTSTOP; - } + //if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) + //{ + // xferrequest = I2C_NO_STARTSTOP; + //} /* Send Slave Address and set NBYTES to write */ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, xferrequest); @@ -2673,7 +2666,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); + hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED commit 23926a2418 hi2c->XferISR = I2C_Master_ISR_IT; /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ @@ -2688,12 +2681,13 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, xfermode = hi2c->XferOptions; } + // MBED commit 23926a2418 /* If transfer direction not change, do not generate Restart Condition */ /* Mean Previous state is same as current state */ - if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) - { - xferrequest = I2C_NO_STARTSTOP; - } + //if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) + //{ + // xferrequest = I2C_NO_STARTSTOP; + //} /* Send Slave Address and set NBYTES to read */ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, xferrequest); @@ -2983,13 +2977,6 @@ void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) /* I2C events treatment -------------------------------------*/ if (hi2c->XferISR != NULL) - { - hi2c->XferISR(hi2c, itflags, itsources); - uint32_t itflags = READ_REG(hi2c->Instance->ISR); - uint32_t itsources = READ_REG(hi2c->Instance->CR1); - - /* I2C events treatment -------------------------------------*/ - if(hi2c->XferISR != NULL) { hi2c->XferISR(hi2c, itflags, itsources); } @@ -3584,11 +3571,6 @@ static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, ui /* Call I2C Master complete process */ I2C_ITMasterCplt(hi2c, ITFlags); } - else if (((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET)) - { - /* Call I2C Master complete process */ - I2C_ITMasterCplt(hi2c, ITFlags); - } /* Process Unlocked */ __HAL_UNLOCK(hi2c); @@ -4794,79 +4776,6 @@ static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t Interr return HAL_OK; } -/** - * @brief Manage the disabling of Interrupts. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param InterruptRequest Value of @ref I2C_Interrupt_configuration_definition. - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest) -{ - uint32_t tmpisr = 0U; - - if((hi2c->XferISR == I2C_Master_ISR_DMA) || \ - (hi2c->XferISR == I2C_Slave_ISR_DMA)) - { - if((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) - { - /* Enable ERR, STOP, NACK and ADDR interrupts */ - tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; - } - - if((InterruptRequest & I2C_XFER_ERROR_IT) == I2C_XFER_ERROR_IT) - { - /* Enable ERR and NACK interrupts */ - tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI; - } - - if((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) - { - /* Enable STOP interrupts */ - tmpisr |= I2C_IT_STOPI; - } - - if((InterruptRequest & I2C_XFER_RELOAD_IT) == I2C_XFER_RELOAD_IT) - { - /* Enable TC interrupts */ - tmpisr |= I2C_IT_TCI; - } - } - else - { - if((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) - { - /* Enable ERR, STOP, NACK, and ADDR interrupts */ - tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; - } - - if((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) - { - /* Enable ERR, TC, STOP, NACK and RXI interrupts */ - tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI; - } - - if((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) - { - /* Enable ERR, TC, STOP, NACK and TXI interrupts */ - tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI; - } - - if((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) - { - /* Enable STOP interrupts */ - tmpisr |= I2C_IT_STOPI; - } - } - - /* Enable interrupts only at the end */ - /* to avoid the risk of I2C interrupt handle execution before */ - /* all interrupts requested done */ - __HAL_I2C_ENABLE_IT(hi2c, tmpisr); - - return HAL_OK; -} - /** * @brief Manage the disabling of Interrupts. * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.h b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.h index 66f5ded5fb..e8d14e187a 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.h @@ -225,8 +225,6 @@ typedef struct __I2C_HandleTypeDef __IO uint32_t ErrorCode; /*!< I2C Error code */ - __IO uint32_t ErrorCode; /*!< I2C Error code */ - __IO uint32_t AddrEventCount; /*!< I2C Address Event counter */ } I2C_HandleTypeDef; /** @@ -621,73 +619,6 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); /* Private macros ------------------------------------------------------------*/ /** @defgroup I2C_Private_Macro I2C Private Macros - -/* Private macros ------------------------------------------------------------*/ -/** @defgroup I2C_Private_Macro I2C Private Macros - * @{ - */ - -#define IS_I2C_ADDRESSING_MODE(MODE) (((MODE) == I2C_ADDRESSINGMODE_7BIT) || \ - ((MODE) == I2C_ADDRESSINGMODE_10BIT)) - -#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ - ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) - -#define IS_I2C_OWN_ADDRESS2_MASK(MASK) (((MASK) == I2C_OA2_NOMASK) || \ - ((MASK) == I2C_OA2_MASK01) || \ - ((MASK) == I2C_OA2_MASK02) || \ - ((MASK) == I2C_OA2_MASK03) || \ - ((MASK) == I2C_OA2_MASK04) || \ - ((MASK) == I2C_OA2_MASK05) || \ - ((MASK) == I2C_OA2_MASK06) || \ - ((MASK) == I2C_OA2_MASK07)) - -#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ - ((CALL) == I2C_GENERALCALL_ENABLE)) - -#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ - ((STRETCH) == I2C_NOSTRETCH_ENABLE)) - -#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ - ((SIZE) == I2C_MEMADD_SIZE_16BIT)) - -#define IS_TRANSFER_MODE(MODE) (((MODE) == I2C_RELOAD_MODE) || \ - ((MODE) == I2C_AUTOEND_MODE) || \ - ((MODE) == I2C_SOFTEND_MODE)) - -#define IS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == I2C_GENERATE_STOP) || \ - ((REQUEST) == I2C_GENERATE_START_READ) || \ - ((REQUEST) == I2C_GENERATE_START_WRITE) || \ - ((REQUEST) == I2C_NO_STARTSTOP)) - -#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ - ((REQUEST) == I2C_FIRST_AND_NEXT_FRAME) || \ - ((REQUEST) == I2C_NEXT_FRAME) || \ - ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ - ((REQUEST) == I2C_LAST_FRAME)) - -#define I2C_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN))) - -#define I2C_GET_ADDR_MATCH(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) >> 16U) -#define I2C_GET_DIR(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) >> 16U) -#define I2C_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND) -#define I2C_GET_OWN_ADDRESS1(__HANDLE__) ((__HANDLE__)->Instance->OAR1 & I2C_OAR1_OA1) -#define I2C_GET_OWN_ADDRESS2(__HANDLE__) ((__HANDLE__)->Instance->OAR2 & I2C_OAR2_OA2) - -#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x000003FFU) -#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU) - -#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U))) -#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU)))) - -#define I2C_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == I2C_ADDRESSINGMODE_7BIT) ? (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & (~I2C_CR2_RD_WRN)) : \ - (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_ADD10) | (I2C_CR2_START)) & (~I2C_CR2_RD_WRN))) -/** - * @} - */ - -/* Private Functions ---------------------------------------------------------*/ -/** @defgroup I2C_Private_Functions I2C Private Functions * @{ */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c index 9ef6dcd9f1..97cfd49e66 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_spi.c @@ -167,12 +167,13 @@ * @{ */ #define SPI_TIMEOUT_VALUE 10U -#define SPI_DEFAULT_TIMEOUT 100U +#define SPI_DEFAULT_TIMEOUT 100U // MBED commit 64a037cc /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ +// MBED commit 64a037cc static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart); static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi); static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi); @@ -1026,6 +1027,7 @@ HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, u hspi->State = HAL_SPI_STATE_BUSY_TX; hspi->ErrorCode = HAL_SPI_ERROR_NONE; + // MBED commit 64a037cc /* Set the function for IT treatment */ if(hspi->Init.DataSize > SPI_DATASIZE_8BIT ) { @@ -1109,6 +1111,7 @@ HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, ui hspi->State = HAL_SPI_STATE_BUSY_RX; hspi->ErrorCode = HAL_SPI_ERROR_NONE; + // MBED commit 64a037cc /* Set the function for IT treatment */ if(hspi->Init.DataSize > SPI_DATASIZE_8BIT ) { @@ -1216,6 +1219,7 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *p hspi->RxXferSize = Size; hspi->RxXferCount = Size; + // MBED commit 64a037cc /* Set the function for IT treatment */ if(hspi->Init.DataSize > SPI_DATASIZE_8BIT ) { @@ -1861,6 +1865,8 @@ uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi) * @{ */ +// MBED commit 64a037cc + /** * @brief DMA SPI transmit process complete callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains @@ -2210,6 +2216,7 @@ static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(SPI_HandleTypeDef *hspi, uin * @} */ +// MBED commit 64a037cc /** * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. * @param hspi: pointer to a SPI_HandleTypeDef structure that contains From 1be48dc5f6be83ee314666c927f9936e97335c59 Mon Sep 17 00:00:00 2001 From: bcostm Date: Mon, 9 Apr 2018 13:03:35 +0200 Subject: [PATCH 09/46] L0 ST CUBE V1.10.0: change adc sampling time --- targets/TARGET_STM/TARGET_STM32L0/analogin_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/TARGET_STM/TARGET_STM32L0/analogin_device.c b/targets/TARGET_STM/TARGET_STM32L0/analogin_device.c index f1ac6a8764..813e53ab53 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/analogin_device.c +++ b/targets/TARGET_STM/TARGET_STM32L0/analogin_device.c @@ -72,7 +72,7 @@ void analogin_init(analogin_t *obj, PinName pin) obj->handle.Init.OversamplingMode = DISABLE; obj->handle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1; obj->handle.Init.Resolution = ADC_RESOLUTION_12B; - obj->handle.Init.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; + obj->handle.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5; obj->handle.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; obj->handle.Init.ContinuousConvMode = DISABLE; From beafcf30223f5eac3a87a37fe7cde16f9c9f2d09 Mon Sep 17 00:00:00 2001 From: Paul Thompson Date: Mon, 16 Apr 2018 07:23:47 -0700 Subject: [PATCH 10/46] Eliminate complier warning and remove superfluous call to empty() Appears when complied with -O3 optimization level Compile: UARTSerial.cpp ../drivers/UARTSerial.cpp: In member function 'void mbed::UARTSerial::tx_irq()': ../drivers/UARTSerial.cpp:314:31: warning: 'data' may be used uninitialized in this function [-Wmaybe-uninitialized] SerialBase::_base_putc(data); --- drivers/UARTSerial.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/UARTSerial.cpp b/drivers/UARTSerial.cpp index 2c590c1276..c6fd37efe7 100644 --- a/drivers/UARTSerial.cpp +++ b/drivers/UARTSerial.cpp @@ -305,12 +305,11 @@ void UARTSerial::rx_irq(void) void UARTSerial::tx_irq(void) { bool was_full = _txbuf.full(); + char data; /* Write to the peripheral if there is something to write * and if the peripheral is available to write. */ - while (!_txbuf.empty() && SerialBase::writeable()) { - char data; - _txbuf.pop(data); + while (SerialBase::writeable() && _txbuf.pop(data)) { SerialBase::_base_putc(data); } From 753f092ea48423ae5b9cde2313fc8d401b520f03 Mon Sep 17 00:00:00 2001 From: Martin Kojtal Date: Wed, 11 Apr 2018 14:46:33 +0100 Subject: [PATCH 11/46] requirements: add future SHA 14255ca introduced the lines that are reported to be breaking. future module in requirements fixes it Reference: https://pypi.python.org/pypi/future Fixes #6489 --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index f98cd36c92..e38fa31892 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,4 @@ beautifulsoup4>=4 fuzzywuzzy>=0.11 pyelftools>=0.24 jsonschema>=2.6 +future>=0.16.0 From cadab34d4a44c9f2ebc11ad92ba1425266131883 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 4 Apr 2018 14:02:13 -0500 Subject: [PATCH 12/46] Prevent compiling with unsupported compilers --- tools/build_api.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/build_api.py b/tools/build_api.py index 932cfb6531..7077393af9 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -289,6 +289,13 @@ def get_mbed_official_release(version): return mbed_official_release +ARM_COMPILERS = ("ARM", "ARMC6", "uARM") +def target_supports_toolchain(target, toolchain_name): + if toolchain_name in ARM_COMPILERS: + return any(tc in target.supported_toolchains for tc in ARM_COMPILERS) + else: + return toolchain_name in target.supported_toolchains + def prepare_toolchain(src_paths, build_dir, target, toolchain_name, macros=None, clean=False, jobs=1, @@ -322,6 +329,11 @@ def prepare_toolchain(src_paths, build_dir, target, toolchain_name, # If the configuration object was not yet created, create it now config = config or Config(target, src_paths, app_config=app_config) target = config.target + if not target_supports_toolchain(target, toolchain_name): + raise NotSupportedException( + "Target {} is not supported by toolchain {}".format( + target.name, toolchain_name)) + try: cur_tc = TOOLCHAIN_CLASSES[toolchain_name] except KeyError: From 0296bbab628271a51b8504602ff1d91a1afdec3a Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Thu, 5 Apr 2018 10:11:51 -0500 Subject: [PATCH 13/46] Add GCC_ARM support to all fake test targets --- tools/test/config/app_override_libs/targets.json | 3 ++- tools/test/config/compound_inheritance/targets.json | 1 + tools/test/config/double_define/targets.json | 2 ++ tools/test/config/feature_compesition/targets.json | 1 + tools/test/config/feature_recursive_add/targets.json | 1 + tools/test/config/feature_recursive_complex/targets.json | 1 + tools/test/config/feature_remove/targets.json | 1 + tools/test/config/feature_uvisor/targets.json | 1 + tools/test/config/macro_inheritance/targets.json | 1 + tools/test/config/override_labels_libs/targets.json | 1 + tools/test/config/override_labels_libs_more/targets.json | 1 + tools/test/config/override_labels_targets/targets.json | 1 + tools/test/config/override_precidence/targets.json | 1 + tools/test/config/override_undefined/targets.json | 2 ++ tools/test/config/override_undefined_libs/targets.json | 1 + tools/test/config/override_with_labels/targets.json | 1 + tools/test/config/simple_features/targets.json | 1 + tools/test/config/simple_iheritance/targets.json | 2 ++ 18 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tools/test/config/app_override_libs/targets.json b/tools/test/config/app_override_libs/targets.json index 9050d38f75..e2b21623dc 100644 --- a/tools/test/config/app_override_libs/targets.json +++ b/tools/test/config/app_override_libs/targets.json @@ -3,6 +3,7 @@ "core": "Cortex-M0", "extra_labels": [], "features": [], - "default_lib": "std" + "default_lib": "std", + "supported_toolchains": ["GCC_ARM"] } } diff --git a/tools/test/config/compound_inheritance/targets.json b/tools/test/config/compound_inheritance/targets.json index 19ad992c0d..ce17a62c63 100644 --- a/tools/test/config/compound_inheritance/targets.json +++ b/tools/test/config/compound_inheritance/targets.json @@ -1,5 +1,6 @@ { "base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", diff --git a/tools/test/config/double_define/targets.json b/tools/test/config/double_define/targets.json index 2dddbe28ac..b1310a19ce 100644 --- a/tools/test/config/double_define/targets.json +++ b/tools/test/config/double_define/targets.json @@ -1,5 +1,6 @@ { "first_base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", @@ -10,6 +11,7 @@ } }, "second_base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", diff --git a/tools/test/config/feature_compesition/targets.json b/tools/test/config/feature_compesition/targets.json index 9050d38f75..a4909c3530 100644 --- a/tools/test/config/feature_compesition/targets.json +++ b/tools/test/config/feature_compesition/targets.json @@ -1,5 +1,6 @@ { "test_target": { + "supported_toolchains": ["GCC_ARM"], "core": "Cortex-M0", "extra_labels": [], "features": [], diff --git a/tools/test/config/feature_recursive_add/targets.json b/tools/test/config/feature_recursive_add/targets.json index 9050d38f75..a4909c3530 100644 --- a/tools/test/config/feature_recursive_add/targets.json +++ b/tools/test/config/feature_recursive_add/targets.json @@ -1,5 +1,6 @@ { "test_target": { + "supported_toolchains": ["GCC_ARM"], "core": "Cortex-M0", "extra_labels": [], "features": [], diff --git a/tools/test/config/feature_recursive_complex/targets.json b/tools/test/config/feature_recursive_complex/targets.json index 9050d38f75..a4909c3530 100644 --- a/tools/test/config/feature_recursive_complex/targets.json +++ b/tools/test/config/feature_recursive_complex/targets.json @@ -1,5 +1,6 @@ { "test_target": { + "supported_toolchains": ["GCC_ARM"], "core": "Cortex-M0", "extra_labels": [], "features": [], diff --git a/tools/test/config/feature_remove/targets.json b/tools/test/config/feature_remove/targets.json index e1bd55f4ad..160039cbe8 100644 --- a/tools/test/config/feature_remove/targets.json +++ b/tools/test/config/feature_remove/targets.json @@ -1,5 +1,6 @@ { "test_target": { + "supported_toolchains": ["GCC_ARM"], "core": "Cortex-M0", "extra_labels": [], "features": ["IPV4"], diff --git a/tools/test/config/feature_uvisor/targets.json b/tools/test/config/feature_uvisor/targets.json index 9050d38f75..a4909c3530 100644 --- a/tools/test/config/feature_uvisor/targets.json +++ b/tools/test/config/feature_uvisor/targets.json @@ -1,5 +1,6 @@ { "test_target": { + "supported_toolchains": ["GCC_ARM"], "core": "Cortex-M0", "extra_labels": [], "features": [], diff --git a/tools/test/config/macro_inheritance/targets.json b/tools/test/config/macro_inheritance/targets.json index 9050d38f75..a4909c3530 100644 --- a/tools/test/config/macro_inheritance/targets.json +++ b/tools/test/config/macro_inheritance/targets.json @@ -1,5 +1,6 @@ { "test_target": { + "supported_toolchains": ["GCC_ARM"], "core": "Cortex-M0", "extra_labels": [], "features": [], diff --git a/tools/test/config/override_labels_libs/targets.json b/tools/test/config/override_labels_libs/targets.json index d045de8670..18deeb9467 100644 --- a/tools/test/config/override_labels_libs/targets.json +++ b/tools/test/config/override_labels_libs/targets.json @@ -1,5 +1,6 @@ { "base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0" diff --git a/tools/test/config/override_labels_libs_more/targets.json b/tools/test/config/override_labels_libs_more/targets.json index d045de8670..18deeb9467 100644 --- a/tools/test/config/override_labels_libs_more/targets.json +++ b/tools/test/config/override_labels_libs_more/targets.json @@ -1,5 +1,6 @@ { "base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0" diff --git a/tools/test/config/override_labels_targets/targets.json b/tools/test/config/override_labels_targets/targets.json index 1f360cb7e6..ab0329f18c 100644 --- a/tools/test/config/override_labels_targets/targets.json +++ b/tools/test/config/override_labels_targets/targets.json @@ -1,5 +1,6 @@ { "base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", diff --git a/tools/test/config/override_precidence/targets.json b/tools/test/config/override_precidence/targets.json index 1f360cb7e6..ab0329f18c 100644 --- a/tools/test/config/override_precidence/targets.json +++ b/tools/test/config/override_precidence/targets.json @@ -1,5 +1,6 @@ { "base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", diff --git a/tools/test/config/override_undefined/targets.json b/tools/test/config/override_undefined/targets.json index ae1cf7c300..f62e4d5e27 100644 --- a/tools/test/config/override_undefined/targets.json +++ b/tools/test/config/override_undefined/targets.json @@ -1,5 +1,6 @@ { "first_base_target": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", @@ -21,6 +22,7 @@ } }, "second_base_target": { + "supported_toolchains": ["GCC_ARM"], "config": { "base2_1": "v_base2_1_b2", "base2_2": "v_base2_2_b2" diff --git a/tools/test/config/override_undefined_libs/targets.json b/tools/test/config/override_undefined_libs/targets.json index 16c687b6c6..72b743f5ab 100644 --- a/tools/test/config/override_undefined_libs/targets.json +++ b/tools/test/config/override_undefined_libs/targets.json @@ -1,5 +1,6 @@ { "base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0" diff --git a/tools/test/config/override_with_labels/targets.json b/tools/test/config/override_with_labels/targets.json index 3d78e3ef9c..11ffbb6b04 100644 --- a/tools/test/config/override_with_labels/targets.json +++ b/tools/test/config/override_with_labels/targets.json @@ -1,5 +1,6 @@ { "base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0" diff --git a/tools/test/config/simple_features/targets.json b/tools/test/config/simple_features/targets.json index 9050d38f75..a4909c3530 100644 --- a/tools/test/config/simple_features/targets.json +++ b/tools/test/config/simple_features/targets.json @@ -1,5 +1,6 @@ { "test_target": { + "supported_toolchains": ["GCC_ARM"], "core": "Cortex-M0", "extra_labels": [], "features": [], diff --git a/tools/test/config/simple_iheritance/targets.json b/tools/test/config/simple_iheritance/targets.json index 1608366477..8e6dfdd39f 100644 --- a/tools/test/config/simple_iheritance/targets.json +++ b/tools/test/config/simple_iheritance/targets.json @@ -1,5 +1,6 @@ { "first_base": { + "supported_toolchains": ["GCC_ARM"], "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", @@ -21,6 +22,7 @@ } }, "second_base": { + "supported_toolchains": ["GCC_ARM"], "config": { "base2_1": "v_base2_1_b2", "base2_2": "v_base2_2_b2" From f705b4159cd76da4c6096445564135441c40af56 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Mon, 23 Apr 2018 17:56:13 -0500 Subject: [PATCH 14/46] Modifying echo test to be driven more from the device. Previously, the echo test followed a flow like the following: -STEP- -HOST PC- -DEVICE- 0 send _sync 1 echo back _sync 2 send echo_count 3 echo back echo_count 4 send first echo packet 5 echo back echo packet (repeat echo steps) However, as noted by issue #6659, this test would somtimes fail between steps 4 and 5. To ensure each KV pair makes to the correct destination, we usually write the KV back. Step 4 does not wait for this to happen and starts sending echo packets. So the device is acting as the "echo server". This change makes the host PC the "echo server". The idea being that the device will be slower and the host pc should always be able to keep up with it, not the other way around. --- TESTS/host_tests/device_echo.py | 32 ++++++++++++++++++++++++++ TESTS/mbed_drivers/echo/main.cpp | 39 ++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 TESTS/host_tests/device_echo.py diff --git a/TESTS/host_tests/device_echo.py b/TESTS/host_tests/device_echo.py new file mode 100644 index 0000000000..03dadaadd9 --- /dev/null +++ b/TESTS/host_tests/device_echo.py @@ -0,0 +1,32 @@ +""" +mbed SDK +Copyright (c) 2011-2016 ARM Limited + +Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + +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. +""" + + +import uuid +from mbed_host_tests import BaseHostTest + +class Device_Echo(BaseHostTest): + + def _callback_repeat(self, key, value, _): + self.send_kv(key, value) + + def setup(self): + self.register_callback("echo", self._callback_repeat) + self.register_callback("echo_count", self._callback_repeat) + + def teardown(self): + pass diff --git a/TESTS/mbed_drivers/echo/main.cpp b/TESTS/mbed_drivers/echo/main.cpp index 6388299c40..7295ddb4a6 100644 --- a/TESTS/mbed_drivers/echo/main.cpp +++ b/TESTS/mbed_drivers/echo/main.cpp @@ -21,28 +21,49 @@ #include "unity/unity.h" #include "utest/utest.h" +#define PAYLOAD_LENGTH 36 + using namespace utest::v1; +// Fill a buffer with a slice of the ASCII alphabet. +void fill_buffer(char* buffer, unsigned int length, unsigned int index) { + unsigned int start = length * index; + for (int i = 0; i < length - 1; i++) { + buffer[i] = 'a' + ((start + i) % 26); + } + buffer[length - 1] = '\0'; +} + // Echo server (echo payload to host) template void test_case_echo_server_x() { char _key[11] = {}; - char _value[128] = {}; + char _tx_value[PAYLOAD_LENGTH + 1] = {}; + char _rx_value[PAYLOAD_LENGTH + 1] = {}; const int echo_count = N; - const char _key_const[] = "echo_count"; + const char _echo_count_key_const[] = "echo_count"; + const char _echo_key_const[] = "echo"; int expected_key = 1; - greentea_send_kv(_key_const, echo_count); + // Send up the echo count + greentea_send_kv(_echo_count_key_const, echo_count); // Handshake with host do { - greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); - expected_key = strcmp(_key_const, _key); + greentea_parse_kv(_key, _rx_value, sizeof(_key), sizeof(_rx_value)); + // Ensure the key received is "echo_count" and not some old data + expected_key = strcmp(_echo_count_key_const, _key); } while (expected_key); - TEST_ASSERT_EQUAL_INT(echo_count, atoi(_value)); + TEST_ASSERT_EQUAL_INT(echo_count, atoi(_rx_value)); for (int i=0; i < echo_count; ++i) { - greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); - greentea_send_kv(_key, _value); + fill_buffer(_tx_value, PAYLOAD_LENGTH, i); + greentea_send_kv(_echo_key_const, _tx_value); + do { + greentea_parse_kv(_key, _rx_value, sizeof(_key), sizeof(_rx_value)); + // Ensure the key received is "echo" and not some old data + expected_key = strcmp(_echo_key_const, _key); + } while (expected_key); + TEST_ASSERT(strncmp(_tx_value, _rx_value, PAYLOAD_LENGTH) == 0); } } @@ -56,7 +77,7 @@ Case cases[] = { }; utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(30, "echo"); + GREENTEA_SETUP(30, "device_echo"); return greentea_test_setup_handler(number_of_cases); } From 95c98506abd262b62f8c287441760e2020622c58 Mon Sep 17 00:00:00 2001 From: Sam Grove Date: Thu, 19 Apr 2018 17:12:44 -0500 Subject: [PATCH 15/46] Update URL that points at a blank page. Looks like the URL changed where #workflow became workflow.html --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 33855686f2..0288ca11f3 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,7 +3,7 @@ From 4ec0bc693fbe84b0d74f6448c83225a3f8ba756d Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Tue, 24 Apr 2018 10:56:49 +0200 Subject: [PATCH 16/46] STM32 RTC Init minor update --- targets/TARGET_STM/rtc_api.c | 19 ++++++------------- targets/TARGET_STM/rtc_api_hal.h | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/targets/TARGET_STM/rtc_api.c b/targets/TARGET_STM/rtc_api.c index 28bcde11dd..8c091d5835 100644 --- a/targets/TARGET_STM/rtc_api.c +++ b/targets/TARGET_STM/rtc_api.c @@ -53,7 +53,11 @@ void rtc_init(void) __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWR_EnableBkUpAccess(); +#if DEVICE_LOWPOWERTIMER + if ( (rtc_isenabled()) && ((RTC->PRER & RTC_PRER_PREDIV_S) == PREDIV_S_VALUE) ) { +#else /* DEVICE_LOWPOWERTIMER */ if (rtc_isenabled()) { +#endif /* DEVICE_LOWPOWERTIMER */ return; } @@ -107,19 +111,8 @@ void rtc_init(void) RtcHandle.Init.AsynchPrediv = RTC_AUTO_1_SECOND; #else /* TARGET_STM32F1 */ RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; - - /* PREDIV_A : 7-bit asynchronous prescaler */ -#if DEVICE_LOWPOWERTIMER && !MBED_CONF_TARGET_LOWPOWERTIMER_LPTIM - /* PREDIV_A is set to a small value to improve the SubSeconds resolution */ - /* with a 32768Hz clock, PREDIV_A=7 gives a precision of 244us */ - RtcHandle.Init.AsynchPrediv = 7; -#else - /* PREDIV_A is set to the maximum value to improve the consumption */ - RtcHandle.Init.AsynchPrediv = 0x007F; -#endif - /* PREDIV_S : 15-bit synchronous prescaler */ - /* PREDIV_S is set in order to get a 1 Hz clock */ - RtcHandle.Init.SynchPrediv = RTC_CLOCK / (RtcHandle.Init.AsynchPrediv + 1) - 1; + RtcHandle.Init.AsynchPrediv = PREDIV_A_VALUE; + RtcHandle.Init.SynchPrediv = PREDIV_S_VALUE; RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; diff --git a/targets/TARGET_STM/rtc_api_hal.h b/targets/TARGET_STM/rtc_api_hal.h index ff1722a0e8..32dad0386d 100644 --- a/targets/TARGET_STM/rtc_api_hal.h +++ b/targets/TARGET_STM/rtc_api_hal.h @@ -51,6 +51,20 @@ extern "C" { #define RTC_CLOCK LSI_VALUE #endif +/* PREDIV_A : 7-bit asynchronous prescaler */ +/* PREDIV_S : 15-bit synchronous prescaler */ +/* PREDIV_S is set in order to get a 1 Hz clock */ +#if DEVICE_LOWPOWERTIMER && !MBED_CONF_TARGET_LOWPOWERTIMER_LPTIM +/* PREDIV_A is set to a small value to improve the SubSeconds resolution */ +/* with a 32768Hz clock, PREDIV_A=7 gives a precision of 244us */ +#define PREDIV_A_VALUE 7 +#else /* DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM */ +/* PREDIV_A is set to the maximum value to improve the consumption */ +#define PREDIV_A_VALUE 127 +#endif /* DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM */ + +#define PREDIV_S_VALUE RTC_CLOCK / (PREDIV_A_VALUE + 1) - 1 + /** Read RTC time with subsecond precision. * * @return Time is microsecond From 7165f315969a6641bb72afe93d47024ac5e2fb32 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Tue, 24 Apr 2018 14:26:20 -0500 Subject: [PATCH 17/46] LPC546XX: Add check for GPIO IRQ GPIO IRQ is available on pins for Ports 0 & 1. Add a check to return error for other ports. Signed-off-by: Mahesh Mahadevan --- .../TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c index 0b1e7072ae..46cea7a73b 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/gpio_irq_api.c @@ -25,6 +25,8 @@ #include "fsl_pint.h" #include "mbed_error.h" +#define INTERRUPT_PORTS 2 + static uint32_t channel_ids[NUMBER_OF_GPIO_INTS] = {0}; static gpio_irq_handler irq_handler; /* Array of PORT IRQ number. */ @@ -83,6 +85,10 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 obj->pin = pin & 0x1F; obj->port = pin / 32; + if (obj->port >= INTERRUPT_PORTS) { + return -1; + } + /* Connect trigger sources to PINT */ INPUTMUX_Init(INPUTMUX); From 640af767ef4f92a511ade3806c1301b78ce273ac Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Sun, 22 Apr 2018 23:23:02 -0500 Subject: [PATCH 18/46] Update to EFR32 15.4 driver * Updates driver library to v2.3.1 (2018q1) for bugfixes and convenience functions * Provides library in correct format (2-byte wchar_t flag) for compiling with ARMCC (#6695 uncovered by #6577) * Reverts to using a statically-allocated packet buffer since malloc is not thread-safe (and the asserts have been turned on) --- .../TARGET_SL_RAIL/NanostackRfPhyEfr32.cpp | 143 +- .../TARGET_EFR32_1/librail_efr32xg1_release.a | Bin 246836 -> 252434 bytes .../librail_efr32xg1_release.ar | Bin 0 -> 501736 bytes .../librail_efr32xg12_release.a | Bin 248378 -> 254482 bytes .../librail_efr32xg12_release.ar | Bin 0 -> 507738 bytes .../efr32-rf-driver/rail/ble/rail_ble.h | 111 +- .../rail/ieee802154/rail_ieee802154.h | 218 ++- .../TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h | 15 +- .../TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h | 2 +- .../efr32-rf-driver/rail/rail.h | 1436 ++++++++++------- .../rail/rail_assert_error_codes.h | 245 +-- .../efr32-rf-driver/rail/rail_chip_specific.h | 123 +- .../efr32-rf-driver/rail/rail_types.h | 1292 +++++++++------ .../efr32-rf-driver/rail/timing_state.h | 8 +- 14 files changed, 2214 insertions(+), 1379 deletions(-) mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.a create mode 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.ar mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.a create mode 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.ar mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ble/rail_ble.h mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ieee802154/rail_ieee802154.h mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_assert_error_codes.h mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_chip_specific.h mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_types.h mode change 100644 => 100755 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/timing_state.h diff --git a/features/nanostack/FEATURE_NANOSTACK/targets/TARGET_SL_RAIL/NanostackRfPhyEfr32.cpp b/features/nanostack/FEATURE_NANOSTACK/targets/TARGET_SL_RAIL/NanostackRfPhyEfr32.cpp index 8418d2892c..7ada01adaa 100644 --- a/features/nanostack/FEATURE_NANOSTACK/targets/TARGET_SL_RAIL/NanostackRfPhyEfr32.cpp +++ b/features/nanostack/FEATURE_NANOSTACK/targets/TARGET_SL_RAIL/NanostackRfPhyEfr32.cpp @@ -46,6 +46,13 @@ #define RF_QUEUE_SIZE 8 #endif +/* 802.15.4 maximum size of a single packet including PHY byte is 128 bytes */ +#define MAC_PACKET_MAX_LENGTH 128 +/* Offsets of prepended data in packet buffer */ +#define MAC_PACKET_OFFSET_RSSI 0 +#define MAC_PACKET_OFFSET_LQI 1 +/* This driver prepends RSSI and LQI */ +#define MAC_PACKET_INFO_LENGTH 2 /* RFThreadSignal used to signal from interrupts to the adaptor thread */ enum RFThreadSignal { @@ -68,12 +75,12 @@ enum RFThreadSignal { /* Adaptor thread definitions */ static void rf_thread_loop(const void *arg); static osThreadDef(rf_thread_loop, osPriorityRealtime, RF_THREAD_STACK_SIZE); -static osThreadId rf_thread_id; +static osThreadId rf_thread_id = 0; /* Queue for passing messages from interrupt to adaptor thread */ -static volatile void* rx_queue[8]; -static volatile size_t rx_queue_head; -static volatile size_t rx_queue_tail; +static volatile uint8_t rx_queue[RF_QUEUE_SIZE][MAC_PACKET_MAX_LENGTH + MAC_PACKET_INFO_LENGTH]; +static volatile size_t rx_queue_head = 0; +static volatile size_t rx_queue_tail = 0; /* Silicon Labs headers */ extern "C" { @@ -123,7 +130,7 @@ static const RAIL_CsmaConfig_t csma_config = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_ #error "Not a valid target." #endif -#ifdef MBED_CONF_SL_RAIL_HAS_SUBGIG +#if MBED_CONF_SL_RAIL_HAS_SUBGIG static RAIL_ChannelConfigEntryAttr_t entry_868; static RAIL_ChannelConfigEntryAttr_t entry_915; static const RAIL_ChannelConfigEntry_t entry[] = { @@ -151,7 +158,7 @@ static const RAIL_ChannelConfigEntry_t entry[] = { #endif #if MBED_CONF_SL_RAIL_BAND == 868 -#ifndef MBED_CONF_SL_RAIL_HAS_SUBGIG +#if !MBED_CONF_SL_RAIL_HAS_SUBGIG #error "Sub-Gigahertz band is not supported on this target." #endif static const RAIL_ChannelConfig_t channels = { @@ -161,7 +168,7 @@ static const RAIL_ChannelConfig_t channels = { 1 }; #elif MBED_CONF_SL_RAIL_BAND == 915 -#ifndef MBED_CONF_SL_RAIL_HAS_SUBGIG +#if !MBED_CONF_SL_RAIL_HAS_SUBGIG #error "Sub-Gigahertz band is not supported on this target." #endif static const RAIL_ChannelConfig_t channels = { @@ -187,7 +194,7 @@ static const RAIL_TxPowerConfig_t paInit2p4 = { }; #endif -#if defined (MBED_CONF_SL_RAIL_HAS_SUBGIG) +#if MBED_CONF_SL_RAIL_HAS_SUBGIG // Set up the PA for sub-GHz operation static const RAIL_TxPowerConfig_t paInitSubGhz = { .mode = RAIL_TX_POWER_MODE_SUBGIG, @@ -210,9 +217,9 @@ static const RAIL_StateTiming_t timings = { static const RAIL_IEEE802154_Config_t config = { .addresses = NULL, .ackConfig = { - .enable = true, - .ackTimeout = 1200, - .rxTransitions = { + .enable = true, + .ackTimeout = 1200, + .rxTransitions = { .success = RAIL_RF_STATE_RX, .error = RAIL_RF_STATE_RX // ignored }, @@ -270,16 +277,13 @@ static void rf_thread_loop(const void *arg) if (event.value.signals & SL_RX_DONE) { while(rx_queue_tail != rx_queue_head) { uint8_t* packet = (uint8_t*) rx_queue[rx_queue_tail]; - SL_DEBUG_PRINT("rPKT %d\n", packet[2] - 2); + SL_DEBUG_PRINT("rPKT %d\n", packet[MAC_PACKET_INFO_LENGTH] - 2); device_driver.phy_rx_cb( - &packet[3], /* Data payload for Nanostack starts at FCS */ - packet[2] - 2, /* Payload length is part of frame, but need to subtract CRC bytes */ - packet[1], /* LQI in second byte */ - packet[0], /* RSSI in first byte */ + &packet[MAC_PACKET_INFO_LENGTH + 1], /* Data payload for Nanostack starts at FCS */ + packet[MAC_PACKET_INFO_LENGTH] - 2, /* Payload length is part of frame, but need to subtract CRC bytes */ + packet[MAC_PACKET_OFFSET_LQI], /* LQI in second byte */ + packet[MAC_PACKET_OFFSET_RSSI], /* RSSI in first byte */ rf_radio_driver_id); - - free(packet); - rx_queue[rx_queue_tail] = NULL; rx_queue_tail = (rx_queue_tail + 1) % RF_QUEUE_SIZE; } @@ -887,6 +891,12 @@ static void radioEventHandler(RAIL_Handle_t railHandle, if (railHandle != gRailHandle) return; +#ifdef MBED_CONF_RTOS_PRESENT + if(rf_thread_id == 0) { + return; + } +#endif + size_t index = 0; do { if (events & 1ull) { @@ -956,43 +966,20 @@ static void radioEventHandler(RAIL_Handle_t railHandle, /* Only process the packet if it had a correct CRC */ if(rxPacketInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS) { - /* Get RSSI and LQI information about this packet */ - RAIL_RxPacketDetails_t rxPacketDetails; - rxPacketDetails.timeReceived.timePosition = RAIL_PACKET_TIME_DEFAULT; - rxPacketDetails.timeReceived.totalPacketBytes = 0; - RAIL_GetRxPacketDetails(gRailHandle, rxHandle, &rxPacketDetails); + uint8_t header[4]; + RAIL_PeekRxPacket(gRailHandle, rxHandle, header, 4, 0); - /* Allocate a contiguous buffer for this packet's payload */ - uint8_t* packetBuffer = (uint8_t*) malloc(rxPacketInfo.packetBytes + 2); - if(packetBuffer == NULL) { - SL_DEBUG_PRINT("Out of memory\n"); - break; - } - - /* First two bytes are RSSI and LQI, respecitvely */ - packetBuffer[0] = (uint8_t)rxPacketDetails.rssi; - packetBuffer[1] = (uint8_t)rxPacketDetails.lqi; - - /* Copy packet payload from circular FIFO into contiguous memory */ - memcpy(&packetBuffer[2], rxPacketInfo.firstPortionData, rxPacketInfo.firstPortionBytes); - if (rxPacketInfo.firstPortionBytes < rxPacketInfo.packetBytes) { - memcpy(&packetBuffer[2+rxPacketInfo.firstPortionBytes], - rxPacketInfo.lastPortionData, - rxPacketInfo.packetBytes - rxPacketInfo.firstPortionBytes); - } - - /* Release RAIL resources early */ - RAIL_ReleaseRxPacket(gRailHandle, rxHandle); - - /* If this is an ACK, deal with it */ - if( packetBuffer[2] == 5 && - packetBuffer[2+3] == (current_tx_sequence) && + /* If this is an ACK, deal with it early */ + if( (header[0] == 5) && + (header[3] == current_tx_sequence) && waiting_for_ack) { /* Tell the radio to not ACK an ACK */ RAIL_CancelAutoAck(gRailHandle); waiting_for_ack = false; /* Save the pending bit */ - last_ack_pending_bit = (packetBuffer[2+1] & (1 << 4)) != 0; + last_ack_pending_bit = (header[1] & (1 << 4)) != 0; + /* Release packet */ + RAIL_ReleaseRxPacket(gRailHandle, rxHandle); /* Tell the stack we got an ACK */ #ifdef MBED_CONF_RTOS_PRESENT osSignalSet(rf_thread_id, SL_ACK_RECV | (last_ack_pending_bit ? SL_ACK_PEND : 0)); @@ -1004,8 +991,37 @@ static void radioEventHandler(RAIL_Handle_t railHandle, 1, 1); #endif - free(packetBuffer); } else { + /* Get RSSI and LQI information about this packet */ + RAIL_RxPacketDetails_t rxPacketDetails; + rxPacketDetails.timeReceived.timePosition = RAIL_PACKET_TIME_DEFAULT; + rxPacketDetails.timeReceived.totalPacketBytes = 0; + RAIL_GetRxPacketDetails(gRailHandle, rxHandle, &rxPacketDetails); + +#ifdef MBED_CONF_RTOS_PRESENT + /* Drop this packet if we're out of space */ + if (((rx_queue_head + 1) % RF_QUEUE_SIZE) == rx_queue_tail) { + osSignalSet(rf_thread_id, SL_QUEUE_FULL); + RAIL_ReleaseRxPacket(gRailHandle, rxHandle); + break; + } + + /* Copy into queue */ + uint8_t* packetBuffer = (uint8_t*)rx_queue[rx_queue_head]; +#else + /* Packet going temporarily onto stack for bare-metal apps */ + uint8_t packetBuffer[MAC_PACKET_MAX_LENGTH + MAC_PACKET_INFO_LENGTH]; +#endif + /* First two bytes are RSSI and LQI, respecitvely */ + packetBuffer[MAC_PACKET_OFFSET_RSSI] = (uint8_t)rxPacketDetails.rssi; + packetBuffer[MAC_PACKET_OFFSET_LQI] = (uint8_t)rxPacketDetails.lqi; + + /* Copy packet payload from circular FIFO into contiguous memory */ + RAIL_CopyRxPacket(&packetBuffer[MAC_PACKET_INFO_LENGTH], &rxPacketInfo); + + /* Release RAIL resources early */ + RAIL_ReleaseRxPacket(gRailHandle, rxHandle); + /* Figure out whether we want to not ACK this packet */ /* @@ -1015,27 +1031,20 @@ static void radioEventHandler(RAIL_Handle_t railHandle, * [1] => b[0:2] frame type, b[3] = security enabled, b[4] = frame pending, b[5] = ACKreq, b[6] = intrapan * [2] => b[2:3] destmode, b[4:5] version, b[6:7] srcmode */ - if( (packetBuffer[2+1] & (1 << 5)) == 0 ) { + if( (packetBuffer[MAC_PACKET_INFO_LENGTH + 1] & (1 << 5)) == 0 ) { /* Cancel the ACK if the sender did not request one */ RAIL_CancelAutoAck(gRailHandle); } #ifdef MBED_CONF_RTOS_PRESENT - if (((rx_queue_head + 1) % RF_QUEUE_SIZE) != rx_queue_tail) { - rx_queue[rx_queue_head] = (void*)packetBuffer; - rx_queue_head = (rx_queue_head + 1) % RF_QUEUE_SIZE; - osSignalSet(rf_thread_id, SL_RX_DONE); - } else { - free(packetBuffer); - osSignalSet(rf_thread_id, SL_QUEUE_FULL); - } + rx_queue_head = (rx_queue_head + 1) % RF_QUEUE_SIZE; + osSignalSet(rf_thread_id, SL_RX_DONE); #else - SL_DEBUG_PRINT("rPKT %d\n", rxPacket[2] - 2); - device_driver.phy_rx_cb(&rxPacket[3], /* Data payload for Nanostack starts at FCS */ - rxPacket[2] - 2, /* Payload length is part of frame, but need to subtract CRC bytes */ - rxPacket[1], /* LQI in second byte */ - rxPacket[0], /* RSSI in first byte */ + SL_DEBUG_PRINT("rPKT %d\n", packetBuffer[MAC_PACKET_INFO_LENGTH] - 2); + device_driver.phy_rx_cb(&packetBuffer[MAC_PACKET_INFO_LENGTH + 1], /* Data payload for Nanostack starts at FCS */ + packetBuffer[MAC_PACKET_INFO_LENGTH] - 2, /* Payload length is part of frame, but need to subtract CRC bytes */ + packetBuffer[MAC_PACKET_OFFSET_LQI], /* LQI in second byte */ + packetBuffer[MAC_PACKET_OFFSET_RSSI], /* RSSI in first byte */ rf_radio_driver_id); - free(packetBuffer); #endif } } @@ -1265,4 +1274,4 @@ static void radioEventHandler(RAIL_Handle_t railHandle, index += 1; } while (events != 0); -} \ No newline at end of file +} diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.a b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.a old mode 100644 new mode 100755 index 1237f8cf542e699487e10ea8126aca9bf11b4f55..670c0b70ac4872d60e16ad619508b6405dab843b GIT binary patch delta 87378 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 delta 84331 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 C@IChc diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.ar b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.ar new file mode 100755 index 0000000000000000000000000000000000000000..f782a60b35cbdaad725c9146e13dc22bdd5bf7bb GIT binary patch literal 501736 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 XL*iiC)ZiRlI!;Y?00-IDr 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

vz%pXR3*<9o<9@l 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 uaXxXmYq$t3MPSh-Vh3 literal 0 HcmV?d00001 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.a b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.a old mode 100644 new mode 100755 index 6964e54cb588435ab96e26b926a1ed12316e107b..2125481bfc7d6206846d3a2a7bd41bb9080173d8 GIT binary patch literal 254482 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%0Au~AxtiPNyv4L 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

    ^9| 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 literal 0 HcmV?d00001 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ble/rail_ble.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ble/rail_ble.h old mode 100644 new mode 100755 index 8b86cd515f..ebf223b687 --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ble/rail_ble.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ble/rail_ble.h @@ -1,7 +1,7 @@ /***************************************************************************//** * @file rail_ble.h * @brief The BLE specific header file for the RAIL library. - * @copyright Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com + * @copyright Copyright 2016 Silicon Laboratories, Inc. www.silabs.com ******************************************************************************/ #ifndef __RAIL_BLE_H__ @@ -14,48 +14,65 @@ // Get the RAIL specific structures and types #include "rail_types.h" -/** - * @addtogroup BLE - * @ingroup Protocol_Specific - * Accelerator routines for Bluetooth Low Energy (BLE). - * - * The APIs in this module help take care of configuring the radio for BLE - * operation and provide some additional helper routines necessary for - * normal BLE send/receive that aren't available directly in RAIL. To initialize - * the radio you will still have to call RAIL_Init(). However - * RAIL_ConfigChannels(), and RAIL_ConfigRadio() will be taken care of for you. - * - * To implement a standard BLE link layer you will also need to handle tight - * turnaround times and send packets at specific instants. This can all be - * managed through general RAIL functions like RAIL_ScheduleTx(), - * RAIL_ScheduleRx(), and RAIL_SetStateTiming(). See the full RAIL API for more - * useful functions. - * - * A simple example of how to setup your application to be in BLE mode is shown - * below. Note that this will put the radio on the first advertising channel - * with the advertising Access Address. In any full featured BLE application you - * will need to use the RAIL_BLE_ConfigChannelRadioParams() function to change - * the sync word and other parameters as needed based on your connection. - * - * @code{.c} - * - * // Put the radio into receive on the first BLE advertising channel - * int bleAdvertiseEnable(void) - * { - * // Call the BLE initialization function to load the right radio config - * RAIL_BLE_Init(); - * - * // Configure us for the first advertising channel (Physical: 0, Logical: 37) - * // The CRC init value and Access Address come from the BLE specification. - * RAIL_BLE_ConfigChannelRadioParams(0x555555, 0x8E89BED6, 37, false); - * - * // Start receiving on this channel (Physical: 0, Logical: 37) - * RAIL_StartRx(0); - * } - * @endcode - * - * @{ - */ +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup BLE +/// @ingroup Protocol_Specific +/// Accelerator routines for Bluetooth Low Energy (BLE). +/// +/// The APIs in this module help take care of configuring the radio for BLE +/// operation and provide some additional helper routines necessary for +/// normal BLE send/receive that aren't available directly in RAIL. All normal +/// RAIL APIs should be used to setup the application; however, +/// RAIL_ConfigChannels() and RAIL_ConfigRadio() should not be called to setup +/// the PHY. Instead, the RAIL_BLE_Config* APIs should be used to setup the +/// 1Mbps, 2Mbps, or Coded PHY configuration needed by the application. These +/// APIs will configure the hardware and also configure the set of valid BLE +/// channels. +/// +/// To implement a standard BLE link layer you will also need to handle tight +/// turnaround times and send packets at specific instants. This can all be +/// managed through general RAIL functions like RAIL_ScheduleTx(), +/// RAIL_ScheduleRx(), and RAIL_SetStateTiming(). See the full RAIL API for more +/// useful functions. +/// +/// A simple example of how to setup your application to be in BLE mode is shown +/// below. Note that this will put the radio on the first advertising channel +/// with the advertising Access Address. In any full featured BLE application you +/// will need to use the RAIL_BLE_ConfigChannelRadioParams() function to change +/// the sync word and other parameters as needed based on your connection. +/// +/// @code{.c} +/// +/// // RAIL Handle set at init time +/// static RAIL_Handle_t railHandle = NULL; +/// +/// // Put the radio into receive on the first BLE advertising channel +/// int bleAdvertiseEnable(void) +/// { +/// // Call the BLE initialization function to load the right radio config +/// RAIL_BLE_Init(railHandle); +/// +/// // Always choose the Viterbi PHY configuration if available on your chip +/// // for performance reasons. +/// RAIL_BLE_ConfigPhy1MbpsViterbi(railHandle); +/// +/// // Configure us for the first advertising channel (Physical: 0, Logical: 37) +/// // The CRC init value and Access Address come from the BLE specification. +/// RAIL_BLE_ConfigChannelRadioParams(railHandle, +/// 0x555555, +/// 0x8E89BED6, +/// 37, +/// false); +/// +/// // Start receiving on physical channel 0 (logical channel 37) +/// RAIL_StartRx(railHandle, 0, NULL); +/// } +/// @endcode +/// +/// @{ /** * @enum RAIL_BLE_Coding_t @@ -175,7 +192,7 @@ RAIL_Status_t RAIL_BLE_ConfigPhy2Mbps(RAIL_Handle_t railHandle); * Switch to the BLE Coded PHY. * * @param[in] railHandle Handle for RAIL instance. - * @param[in] ble_coding The RAIL_BLE_Coding_t to use + * @param[in] bleCoding The RAIL_BLE_Coding_t to use * @return Status code indicating success of the function call. * * You can use this function to switch back to BLE Coded PHY from the default @@ -188,7 +205,7 @@ RAIL_Status_t RAIL_BLE_ConfigPhy2Mbps(RAIL_Handle_t railHandle); * manual to be sure that it does before trying this. */ RAIL_Status_t RAIL_BLE_ConfigPhyCoded(RAIL_Handle_t railHandle, - RAIL_BLE_Coding_t ble_coding); + RAIL_BLE_Coding_t bleCoding); /** * Helper function to change BLE radio parameters. @@ -215,4 +232,8 @@ RAIL_Status_t RAIL_BLE_ConfigChannelRadioParams(RAIL_Handle_t railHandle, /** @} */ // end of BLE +#ifdef __cplusplus +} +#endif + #endif // __RAIL_BLE_H__ diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ieee802154/rail_ieee802154.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ieee802154/rail_ieee802154.h old mode 100644 new mode 100755 index 47ce594340..7befb7aeea --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ieee802154/rail_ieee802154.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ieee802154/rail_ieee802154.h @@ -1,7 +1,7 @@ /***************************************************************************//** * @file rail_ieee802154.h * @brief The IEEE 802.15.4 specific header file for the RAIL library. - * @copyright Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com + * @copyright Copyright 2016 Silicon Laboratories, Inc. www.silabs.com ******************************************************************************/ #ifndef __RAIL_IEEE802154_H__ @@ -9,67 +9,142 @@ #include "rail_types.h" -/** - * @addtogroup IEEE802_15_4 IEEE 802.15.4 - * @ingroup Protocol_Specific - * @brief IEEE 802.15.4 configuration routines - * - * The functions in this group configure RAIL IEEE 802.15.4 hardware - * acceleration. To configure 802.15.4 functionality, call - * RAIL_IEEE802154_Init(). Make note that this function calls many other RAIL - * functions; the application is advised to not reconfigure any of these - * functions. When using 802.15.4 functionality in the 2.4 GHz band, consider - * using RAIL_IEEE802154_Config2p4GHzRadio() instead of RAIL_ConfigRadio() and - * RAIL_ConfigChannels(). - * - * @code{.c} - * RAIL_IEEE802154_Config_t config = { NULL, {100, 192, 894, RAIL_RF_STATE_RX}, - * RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES, - * false, false }; - * RAIL_IEEE802154_Config2p4GHzRadio(); - * RAIL_IEEE802154_Init(&config); - * @endcode - * - * The application can configure the node's address by using - * RAIL_IEEE802154_SetAddresses(). Inidividual members can be changed with - * RAIL_IEEE802154_SetPanId(), RAIL_IEEE802154_SetShortAddress(), - * RAIL_IEEE802154_SetLongAddress(). RAIL only supports one set of addresses at - * a time. Beacon addresses are supported by default, without additional - * configuration. - * - * @code{.c} - * // PanID OTA value of 0x34 0x12 - * // Short Address OTA byte order of 0x78 0x56 - * // Long address with OTA byte order of 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 - * RAIL_IEEE802154_AddrConfig_t nodeAddress = { - * { 0x1234, 0xFFFF }, - * { 0x5678, 0xFFFF }, - * { { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }, - * { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } - * }; - * - * bool status = RAIL_IEEE802154_SetAddresses(&nodeAddress); - * - * // Alternative methods: - * status = RAIL_IEEE802154_SetPanId(nodeAddress.panId[0], 0); - * status = RAIL_IEEE802154_SetPanId(nodeAddress.panId[1], 1); - * status = RAIL_IEEE802154_SetShortAddress(nodeAddress.shortAddr[0], 0); - * status = RAIL_IEEE802154_SetShortAddress(nodeAddress.shortAddr[1], 1); - * status = RAIL_IEEE802154_SetLongAddress(nodeAddress.longAddr[0], 0); - * status = RAIL_IEEE802154_SetLongAddress(nodeAddress.longAddr[1], 1); - * @endcode - * - * Auto ack is initialized through RAIL_IEEE802154_Init(). It is not advised - * to call RAIL_ConfigAutoAck() while 802.15.4 hardware acceleration is - * enabled. The default IEEE 802.15.4 ack will have a 5 byte length. The frame - * type will be an ack. The frame pending bit will be set based on the - * RAIL_IEEE802154_SetFramePending() function. The sequence number will be set to - * match the packet being acknowledged. All other frame control fields will be - * set to 0, in compliance with IEEE Std 802.15.4-2011 section 5.2.2.3. - * However, the auto ack modification function can be used to control auto - * acking. Documentation for these functions can be found in \ref Auto_Ack. - * @{ - */ +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup IEEE802_15_4 IEEE 802.15.4 +/// @ingroup Protocol_Specific +/// @brief IEEE 802.15.4 configuration routines +/// +/// The functions in this group configure RAIL IEEE 802.15.4 hardware +/// acceleration which includes IEEE 802.15.4 format filtering, address +/// filtering, acking, and filtering based on the frame type. +/// +/// To configure IEEE 802.15.4 functionality, the application must first setup +/// a RAIL instance as normal with RAIL_Init() and other setup functions. +/// Instead of RAIL_ConfigChannels() and RAIL_ConfigRadio(), however, an +/// application may use RAIL_IEEE802154_Config2p4GHzRadio() to setup the +/// official IEEE 2.4GHz 802.15.4 PHY. This configuration is shown below. +/// +/// @code{.c} +/// static RAIL_Handle_t railHandle = NULL; // Initialized somewhere else +/// +/// static const RAIL_IEEE802154_Config_t rail154Config = { +/// .addresses = NULL, +/// .ackConfig = { +/// .enable = true, // Turn on auto ACK for IEEE 802.15.4 +/// .ackTimeout = 864, // 54 symbols * 16 us/symbol = 864 us +/// .rxTransitions = { +/// .success = RAIL_RF_STATE_TX, // Go to Tx to send the ACK +/// .error = RAIL_RF_STATE_RX, // For an always on device stay in Rx +/// }, +/// .txTransitions = { +/// .success = RAIL_RF_STATE_RX, // Go to Rx for receiving the ACK +/// .error = RAIL_RF_STATE_RX, // For an always on device stay in Rx +/// }, +/// }, +/// .timings = { +/// .idleToRx = 100, +/// .idleToTx = 100, +/// .rxToTx = 192, // 12 symbols * 16 us/symbol = 192 us +/// .txToRx = 192, // 12 symbols * 16 us/symbol = 192 us +/// .rxSearchTimeout = 0, // not used +/// .txToRxSearchTimeout = 0, // not used +/// }, +/// .framesMask = RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES, +/// .promiscuousMode = false, // Enable format and address filtering +/// .isPanCoordinator = false, +/// }; +/// +/// void config154(void) +/// { +/// // Configure the radio and channels for 2.4GHz IEEE 802.15.4 +/// RAIL_IEEE802154_Config2p4GHzRadio(railHandle); +/// // Initialize the IEEE 802.15.4 config using the static config above +/// RAIL_IEEE802154_Init(railHandle, &rail154Config); +/// } +/// @endcode +/// +/// To configure address filtering the application can call +/// RAIL_IEEE802154_SetAddresses() with a structure containing all addresses or +/// can call the individual RAIL_IEEE802154_SetPanId(), +/// RAIL_IEEE802154_SetShortAddress(), and RAIL_IEEE802154_SetLongAddress() +/// APIs. RAIL supports \ref RAIL_IEEE802154_MAX_ADDRESSES number of address +/// pairs for situations where you want to receive packets from multiple IEEE +/// 802.15.4 networks at the same time. Broadcast addresses are supported by +/// default without any additional configuration so they do not consume one of +/// these slots. If the application does not require all address pairs be sure +/// to set unused ones to the proper disabled value for each type. These can +/// be found in the \ref RAIL_IEEE802154_AddrConfig_t documentation. Below is +/// an example of setting filtering for one set of addresses. +/// +/// @code{.c} +/// // PanID OTA value of 0x34 0x12 +/// // Short Address OTA byte order of 0x78 0x56 +/// // Long address with OTA byte order of 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 +/// +/// // Setup all address simultaneously +/// RAIL_Status_t setup1(void) +/// { +/// RAIL_IEEE802154_AddrConfig_t nodeAddress = { +/// { 0x1234, 0xFFFF, 0xFFFF }, +/// { 0x5678, 0xFFFF, 0xFFFF }, +/// { { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }, +/// { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, +/// { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } +/// }; +/// return RAIL_IEEE802154_SetAddresses(railHandle, &nodeAddress); +/// } +/// +/// // Alternatively the addresses can be setup individually as follows: +/// RAIL_Status_t setup2(void) +/// { +/// RAIL_Status_t status; +/// const uint8_t longAddress[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }; +/// +/// status = RAIL_IEEE802154_SetPanId(railHandle, 0x1234, 0); +/// if (status != RAIL_STATUS_NO_ERROR) { +/// return status +/// } +/// status = RAIL_IEEE802154_SetShortAddress(railHandle, 0x5678, 0); +/// if (status != RAIL_STATUS_NO_ERROR) { +/// return status +/// } +/// status = RAIL_IEEE802154_SetLongAddress(railHandle, longAddress, 0); +/// if (status != RAIL_STATUS_NO_ERROR) { +/// return status +/// } +/// +/// return RAIL_STATUS_NO_ERROR; +/// } +/// @endcode +/// +/// Address filtering will be enabled except when in promiscuous mode which can +/// be set with RAIL_IEEE802154_SetPromiscuousMode(). The addresses may be +/// changed at runtime but if you are receiving a packet while reconfiguring the +/// address filters you may get undesired behavior so it's safest to do this +/// while not in receive. +/// +/// Auto ACK is controlled by the ackConfig and timings fields passed to +/// RAIL_IEEE802154_Init(). After initialization though they may be controlled +/// using the normal \ref Auto_Ack and \ref State_Transitions APIs. When in IEEE +/// 802.15.4 mode the ACK will have a 5 byte length, the frame type will be set +/// to ack, and the frame pending bit will be set if +/// RAIL_IEEE802154_SetFramePending() is called when the \ref +/// RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND event is triggered. This event +/// must be turned on by the user and will fire whenever a data request is being +/// received so that the stack can determine whether there is pending data. Be +/// aware that the frame pending bit must be set quickly after receiving the +/// event or the ACK may already have been transmitted. Check the return code of +/// RAIL_IEEE802154_SetFramePending() to be sure that the bit was set in time. +/// +/// Transmit and receive operations are all done using the standard RAIL APIs in +/// IEEE 802.15.4 mode. To send packets using the correct CSMA configuration +/// there is a \ref RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA define +/// that can initialize the csmaConfig structure passed to \ref +/// RAIL_StartCcaCsmaTx(). +/// @{ /** * @enum RAIL_IEEE802154_AddressLength_t @@ -176,7 +251,7 @@ typedef struct RAIL_IEEE802154_Config { * Initialize RAIL for IEEE802.15.4 features * * @param[in] railHandle Handle of RAIL instance - * @param[in] config IEEE802154 configuration struct + * @param[in] fifteenFourConfig IEEE802154 configuration struct * @return Status code indicating success of the function call. * * This function calls the following RAIL functions to configure the radio for @@ -196,7 +271,7 @@ typedef struct RAIL_IEEE802154_Config { * - RAIL_EnableAddressFilter() */ RAIL_Status_t RAIL_IEEE802154_Init(RAIL_Handle_t railHandle, - const RAIL_IEEE802154_Config_t *config); + const RAIL_IEEE802154_Config_t *fifteenFourConfig); /** * Configures the radio for 2.4GHz 802.15.4 operation @@ -227,7 +302,7 @@ RAIL_Status_t RAIL_IEEE802154_Config2p4GHzRadio(RAIL_Handle_t railHandle); RAIL_Status_t RAIL_IEEE802154_Deinit(RAIL_Handle_t railHandle); /** - * Return whether IEEE802.15.4 hardware accelertion is currently enabled. + * Return whether IEEE802.15.4 hardware acceleration is currently enabled. * * @param[in] railHandle Handle of RAIL instance * @return True if IEEE802.15.4 hardware acceleration was enabled to start with @@ -258,7 +333,7 @@ RAIL_Status_t RAIL_IEEE802154_SetAddresses(RAIL_Handle_t railHandle, * @param[in] panId The 16-bit PAN ID information. * This will be matched against the destination PAN ID of incoming messages. * The PAN ID is sent little endian over the air meaning panId[7:0] is first in - * the payload followed by panId[15:8]. + * the payload followed by panId[15:8]. Set to 0xFFFF to disable for this index. * @param[in] index Which PAN ID to set. Must be below * RAIL_IEEE802154_MAX_ADDRESSES. * @return Status code indicating success of the function call. @@ -276,7 +351,7 @@ RAIL_Status_t RAIL_IEEE802154_SetPanId(RAIL_Handle_t railHandle, * @param[in] shortAddr 16 bit short address value. This will be matched against the * destination short address of incoming messages. The short address is sent * little endian over the air meaning shortAddr[7:0] is first in the payload - * followed by shortAddr[15:8]. + * followed by shortAddr[15:8]. Set to 0xFFFF to disable for this index. * @param[in] index Which short address to set. Must be below * RAIL_IEEE802154_MAX_ADDRESSES. * @return Status code indicating success of the function call. @@ -294,7 +369,8 @@ RAIL_Status_t RAIL_IEEE802154_SetShortAddress(RAIL_Handle_t railHandle, * @param[in] railHandle Handle of RAIL instance * @param[in] longAddr Pointer to a 8 byte array containing the long address * information. The long address must be in over the air byte order. This will - * be matched against the destination long address of incoming messages. + * be matched against the destination long address of incoming messages. Set to + * 0x00 00 00 00 00 00 00 00 to disable for this index. * @param[in] index Which long address to set. Must be below * RAIL_IEEE802154_MAX_ADDRESSES. * @return Status code indicating success of the function call. @@ -316,7 +392,7 @@ RAIL_Status_t RAIL_IEEE802154_SetLongAddress(RAIL_Handle_t railHandle, * If the device is a PAN Coordinator, then it will accept data and command * frames with no destination address. This function will fail if 802.15.4 * hardware acceleration is not currently enabled. This setting may be changed - * at any time when 802.15.4 hardwarea acceleration is enabled. + * at any time when 802.15.4 hardware acceleration is enabled. */ RAIL_Status_t RAIL_IEEE802154_SetPanCoordinator(RAIL_Handle_t railHandle, bool isPanCoordinator); @@ -404,4 +480,8 @@ RAIL_Status_t RAIL_IEEE802154_GetAddress(RAIL_Handle_t railHandle, /** @} */ // end of IEEE802.15.4 +#ifdef __cplusplus +} +#endif + #endif // __RAIL_IEEE802154_H__ diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h old mode 100644 new mode 100755 index a2130945d0..80b43601ed --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h @@ -3,7 +3,7 @@ * @brief RADIO PA API ******************************************************************************* * @section License - * (C) Copyright 2015 Silicon Labs, http://www.silabs.com + * (C) Copyright 2015 Silicon Labs, www.silabs.com ******************************************************************************* * * Permission is granted to anyone to use this software for any purpose, @@ -81,13 +81,17 @@ extern "C" { * @param[in] paConfig * Pointer to a structure containing the desired PA configuration settings. * + * @param[in] timings + * Pointer to a structure containing the current state transition timings. + * * @return * RAIL_Status_t indicating success * * @warning * The radio should not be transmitting when this function is called! */ -RAIL_Status_t PA_Config(const RAIL_TxPowerConfig_t *paConfig); +RAIL_Status_t PA_Config(const RAIL_TxPowerConfig_t *paConfig, + const StateTimings_t *timings); /** * @brief @@ -131,6 +135,9 @@ uint32_t PA_GetRampTime(void); * * @param[in] ramptime * Desired ramp time in microseconds + + * @param[in] timings + * Pointer to a structure containing the current state transition timings. * * @return * The actual ramp time that was set in microseconds. @@ -138,7 +145,7 @@ uint32_t PA_GetRampTime(void); * @warning * The radio should not be transmitting when this function is called! */ -uint32_t PA_SetRampTime(uint32_t ramptime, StateTimings_t *timings); +uint32_t PA_SetRampTime(uint32_t rampTime, const StateTimings_t *timings); /** * Enable/Disable PA calibration @@ -194,7 +201,7 @@ void PA_SetCTune(uint8_t txPaCtuneValue, uint8_t rxPaCtuneValue); * @warning * The radio should not be transmitting when this function is called! */ -RAIL_TxPowerLevel_t PA_SetPowerLevel(RAIL_TxPowerLevel_t pwrLevel); +RAIL_TxPowerLevel_t PA_SetPowerLevel(RAIL_TxPowerLevel_t powerLevel); /** @} (end addtogroup EFR32xG1x_PA_Advanced) */ /** @} (end addtogroup EFR32xG1x_PA) */ diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h old mode 100644 new mode 100755 index 11bf9e4499..9df4dd3760 --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h @@ -2,7 +2,7 @@ * @file pti.h * @brief This header file contains information for working with the packet * trace APIs. - * @copyright Copyright 2015 Silicon Laboratories, Inc. http://www.silabs.com + * @copyright Copyright 2015 Silicon Laboratories, Inc. www.silabs.com ******************************************************************************/ #ifndef __RADIO_PTI_H diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h old mode 100644 new mode 100755 index d78511b813..9e29adc897 --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h @@ -2,7 +2,7 @@ * @file rail.h * @brief The main header file for the RAIL library. It describes the external * APIs available to a RAIL user - * @copyright Copyright 2015 Silicon Laboratories, Inc. http://www.silabs.com + * @copyright Copyright 2015 Silicon Laboratories, Inc. www.silabs.com *****************************************************************************/ #ifndef __RAIL_H__ @@ -11,10 +11,16 @@ // Get the standard include types #include #include +#include // For memcpy() // Get the RAIL-specific structures and types #include "rail_chip_specific.h" #include "rail_types.h" +#include "rail_assert_error_codes.h" + +#ifdef __cplusplus +extern "C" { +#endif /** * @addtogroup RAIL_API RAIL API @@ -108,7 +114,7 @@ uint16_t RAIL_GetRadioEntropy(RAIL_Handle_t railHandle, * Configures PTI pin locations, serial protocols, and baud rates. * * @param[in] railHandle A RAIL instance handle (currently not used). - * @param[in] config A configuration structure applied to the + * @param[in] ptiConfig A configuration structure applied to the * relevant PTI registers. * @return Status code indicating success of the function call. * @@ -123,7 +129,7 @@ uint16_t RAIL_GetRadioEntropy(RAIL_Handle_t railHandle, * \ref RAIL_EFR32_HANDLE for now. */ RAIL_Status_t RAIL_ConfigPti(RAIL_Handle_t railHandle, - const RAIL_PtiConfig_t *config); + const RAIL_PtiConfig_t *ptiConfig); /** * Gets the currently active PTI configuration. @@ -179,29 +185,52 @@ RAIL_Status_t RAIL_SetPtiProtocol(RAIL_Handle_t railHandle, /** @} */ // end of group PTI /****************************************************************************** - * Radio Configuration + * Antenna Control *****************************************************************************/ /** - * @addtogroup Radio_Configuration Radio Configuration - * @brief Routines for setting up and querying radio configuration information. - * - * These routines allow for runtime flexibility in the radio - * configuration. Some of the parameters, however, are meant to be generated - * from the radio calculator in Simplicity Studio. The basic code to configure - * the radio from this calculator output looks like the example below. - * - * @code{.c} - * // Associate a specific channel config with a particular RAIL instance, and - * // load the settings that correspond to the first usable channel. - * RAIL_ConfigChannels(railHandle, channelConfigs[0]); - * @endcode - * - * For more information about the types of parameters that can be changed in - * the other functions and how to use them, see their individual documentation. - * + * @addtogroup Antenna_Control + * @brief Basic APIs to control the Antenna functionality * @{ */ +/** + * Configures Antenna pin locations + * @param[in] railHandle a RAIL instance handle. + * @param[in] config A configuration structure applied to the relevant Antenna + * Configuration registers. + * @return Status code indicating success of the function call. + * + * Although we do take a RAIL handle for potential future expansion, it is + * currently not used. + * + */ +RAIL_Status_t RAIL_ConfigAntenna(RAIL_Handle_t railHandle, + const RAIL_AntennaConfig_t *config); + +/** @} */ // end of group Antenna_Control + +/****************************************************************************** + * Radio Configuration + *****************************************************************************/ +/// @addtogroup Radio_Configuration Radio Configuration +/// @brief Routines for setting up and querying radio configuration information. +/// +/// These routines allow for runtime flexibility in the radio +/// configuration. Some of the parameters, however, are meant to be generated +/// from the radio calculator in Simplicity Studio. The basic code to configure +/// the radio from this calculator output looks like the example below. +/// +/// @code{.c} +/// // Associate a specific channel config with a particular RAIL instance, and +/// // load the settings that correspond to the first usable channel. +/// RAIL_ConfigChannels(railHandle, channelConfigs[0]); +/// @endcode +/// +/// For more information about the types of parameters that can be changed in +/// the other functions and how to use them, see their individual documentation. +/// +/// @{ + /** * Loads a static radio configuration. * @@ -226,14 +255,15 @@ RAIL_Status_t RAIL_ConfigRadio(RAIL_Handle_t railHandle, * A value of RAIL_SETFIXEDLENGTH_INVALID restores the frame's length back to * that length specified by the default frame type configuration. * @return Length configured; The new frame length configured into the hardware - * for use. 0 if in infinite mode, or RAIL_SETFIXEDLENGTH_INVALID if not in - * fixed length mode or if the frame length has not yet been overridden by a - * valid value. + * for use. 0 if in infinite mode, or RAIL_SETFIXEDLENGTH_INVALID if the frame + * length has not yet been overridden by a valid value. * * Sets the fixed-length configuration for transmit and receive. * Be careful when using this function in receive and transmit as this * function changes the default frame configuration and remains in force until - * it is called again with an input value of RAIL_SETFIXEDLENGTH_INVALID. + * it is called again with an input value of RAIL_SETFIXEDLENGTH_INVALID. This + * function will override any fixed or variable length settings from a radio + * configuration. */ uint16_t RAIL_SetFixedLength(RAIL_Handle_t railHandle, uint16_t length); @@ -255,22 +285,6 @@ uint16_t RAIL_ConfigChannels(RAIL_Handle_t railHandle, const RAIL_ChannelConfig_t *config, RAIL_RadioConfigChangedCallback_t cb); -/** - * Get the active channel config. - * - * @param[in] railHandle A RAIL instance handle. - * @return The active channel config. - */ -const RAIL_ChannelConfig_t *RAIL_GetActiveChannelConfig(RAIL_Handle_t railHandle); - -/** - * Get the active channel config entry. - * - * @param[in] railHandle A RAIL instance handle. - * @return The active channel config entry. - */ -const RAIL_ChannelConfigEntry_t *RAIL_GetActiveChannelConfigEntry(RAIL_Handle_t railHandle); - /** * Checks to see if the channel exists in RAIL. * @@ -360,6 +374,23 @@ RAIL_Status_t RAIL_SetPaCTune(RAIL_Handle_t railHandle, * @{ */ +/** + * Configure the RAIL timer plugin. + * + * @param[in] enable Enables/Disables the RAIL multitimer. + * @return True if the multitimer was successfully enabled/disabled, false + * otherwise. + * + * @note This function must be called before calling \ref RAIL_SetMultiTimer. + * This function must be called to use the timer driver plugin + * with the RAIL single protocol library. + * This function should not be called while the RAIL timer is running. + * Call \ref RAIL_IsTimerRunning before enabling/disabling the multitimer. + * If the multitimer is not needed, do not call this function. + * This will allow the multitimer code to be dead stripped. + */ +bool RAIL_ConfigMultiTimer(bool enable); + /** * Gets the current RAIL time. * @@ -369,7 +400,7 @@ RAIL_Status_t RAIL_SetPaCTune(RAIL_Handle_t railHandle, * Returns the current time in the RAIL timebase (microseconds). It can be * used to compare with packet timestamps or to schedule transmits. */ -uint32_t RAIL_GetTime(void); +RAIL_Time_t RAIL_GetTime(void); /** * Sets the current RAIL time. @@ -379,7 +410,7 @@ uint32_t RAIL_GetTime(void); * * Sets the current time in the RAIL timebase in microseconds. */ -RAIL_Status_t RAIL_SetTime(uint32_t time); +RAIL_Status_t RAIL_SetTime(RAIL_Time_t time); /** * Schedules a timer to expire using the RAIL timebase. @@ -405,7 +436,7 @@ RAIL_Status_t RAIL_SetTime(uint32_t time); * running timer before rescheduling it to minimize such ambiguity. */ RAIL_Status_t RAIL_SetTimer(RAIL_Handle_t railHandle, - uint32_t time, + RAIL_Time_t time, RAIL_TimeMode_t mode, RAIL_TimerCallback_t cb); @@ -420,7 +451,7 @@ RAIL_Status_t RAIL_SetTimer(RAIL_Handle_t railHandle, * past if the timer already expired. The return value is undefined if the * timer was never set. */ -uint32_t RAIL_GetTimer(RAIL_Handle_t railHandle); +RAIL_Time_t RAIL_GetTimer(RAIL_Handle_t railHandle); /** * Stops the currently scheduled RAIL timer. @@ -454,6 +485,89 @@ bool RAIL_IsTimerExpired(RAIL_Handle_t railHandle); */ bool RAIL_IsTimerRunning(RAIL_Handle_t railHandle); +/** + * Starts a multitimer instance. + * + * @note + * It is legal to start an already running timer. If this is done, the timer + * will first be stopped before the new configurations are applied. + * If expirationTime is 0, the callback will be called + * immediately. + * + * @param[in,out] tmr A pointer to the timer instance to start. + * @param[in] expirationTime When the timer is to expire. + * @param[in] expirationMode Select mode of expirationTime. See \ref + * RAIL_TimeMode_t. + * @param[in] callback Function to call on timer expiry. See \ref + * RAIL_MultiTimerCallback_t. NULL is a legal value. + * @param[in] cbArg Extra callback function parameter for user application. + * + * @return + * \ref RAIL_STATUS_NO_ERROR on success.@n + * \ref RAIL_STATUS_INVALID_PARAMETER if tmr has an illegal value or if + * timeout is in the past. + */ +RAIL_Status_t RAIL_SetMultiTimer(RAIL_MultiTimer_t *tmr, + RAIL_Time_t expirationTime, + RAIL_TimeMode_t expirationMode, + RAIL_MultiTimerCallback_t callback, + void *cbArg); + +/** + * Stops the currently scheduled RAIL multi timer. + * + * @param[in,out] tmr A RAIL timer instance handle. + * + * @return + * true if timer was successfully cancelled. + * false if timer was not running. + * + * Cancels the timer. If this function is called before the timer expires, + * the cb callback specified in the earlier RAIL_SetTimer() call will never + * be called. + */ +bool RAIL_CancelMultiTimer(RAIL_MultiTimer_t *tmr); + +/** + * Check if a given timer is running. + * + * @param[in] tmr A pointer to the timer structure to query. + * + * @return + * true if timer is running. + * false if timer is not running. + */ +bool RAIL_IsMultiTimerRunning(RAIL_MultiTimer_t *tmr); + +/** + * Check if a given timer has expired. + * + * @param[in] tmr A pointer to the timer structure to query. + * + * @return + * true if timer is expired. + * false if timer is running. + */ +bool RAIL_IsMultiTimerExpired(RAIL_MultiTimer_t *tmr); + +/** + * Get time left before a given timer instance expires. + * + * @param[in] tmr A pointer to the timer structure to query. + * @param[in] timeMode An indication as to how the function provides the time + * remaining. By choosing \ref + * RAIL_TimeMode_t::RAIL_TIME_ABSOLUTE, the function returns the + * absolute expiration time, and by choosing \ref + * RAIL_TimeMode_t::RAIL_TIME_DELAY, the function returns the + * amount of time remaining before the timer's expiration. + * + * @return + * Time left expressed in RAIL's time units. + * 0 if the soft timer is not running or has already expired. + */ +RAIL_Time_t RAIL_GetMultiTimer(RAIL_MultiTimer_t *tmr, + RAIL_TimeMode_t timeMode); + /** * Initialize RAIL timer synchronization. * @@ -493,7 +607,7 @@ RAIL_Status_t RAIL_Sleep(uint16_t wakeupProcessTime, bool *deepSleepAllowed); * timer using an alternate timer. Otherwise, add elapsedTime to the RAIL * timer. */ -RAIL_Status_t RAIL_Wake(uint32_t elapsedTime); +RAIL_Status_t RAIL_Wake(RAIL_Time_t elapsedTime); /** @} */ // end of group System_Timing @@ -528,177 +642,175 @@ RAIL_Status_t RAIL_ConfigEvents(RAIL_Handle_t railHandle, /****************************************************************************** * Data Management *****************************************************************************/ -/** - * @addtogroup Data_Management Data Management - * @brief Data management functions - * - * These functions allow the application to choose how data is presented to the - * application. RAIL provides data in a packet-based method or in a FIFO-based - * method which gives the application more granularity and responsibility in - * managing transmit and receive data, and allows packet sizes larger than - * the RX or TX FIFO buffers. - * - * The application can configure RAIL data management through - * RAIL_ConfigData(). - * This function allows the application to specify the type of radio data - * (\ref RAIL_TxDataSource_t and \ref RAIL_RxDataSource_t) and the method of - * interacting with data (\ref RAIL_DataMethod_t). By default, RAIL - * configures TX and RX both with packet data source and packet mode. - * - * In packet based data management: - * - Packet lengths are determined from the Radio Configurator configuration - * or after receive packet completion using RAIL_GetRxPacketInfo(). - * - Load transmit data with RAIL_WriteTxFifo(). - * - Received packet data is made available on successful packet completion - * via \ref RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_RX_PACKET_RECEIVED - * which can then use RAIL_GetRxPacketInfo() and RAIL_GetRxPacketDetails() to - * access packet information, and RAIL_PeekRxPacket() to access packet - * data. - * - Filtered, Aborted, or FrameError received packet data is automatically - * dropped without the application needing to worry about consuming it. - * The application can choose to not even be bothered with the events - * related to such packets: \ref RAIL_EVENT_RX_ADDRESS_FILTERED, - * \ref RAIL_EVENT_RX_PACKET_ABORTED, or \ref RAIL_EVENT_RX_FRAME_ERROR. - * - * In FIFO based data management: - * - Packet Lengths are determined from the Radio Configurator configuration - * or by application knowledge of packet payload structure. - * - Load transmit data with RAIL_WriteTxFifo() with reset set to false. - * - Received data can be retrieved prior to packet completion through - * RAIL_ReadRxFifo(), and is never dropped on Filtered, Aborted, or - * FrameError packets. The application should enable and handle these - * events so it can flush any packet data it's already retrieved. - * - After packet completion, remaining packet data for Filtered, Aborted, - * or FrameError packets can be either flushed automatically by RAIL - * or consumed by the application just like a successfully received packet, - * as determined from RAIL_GetRxPacketInfo(). RAIL_GetRxPacketDetails() - * provides packet detailed information only for successfully received - * packets. - * - Set the TX FIFO threshold through RAIL_SetTxFifoThreshold(). The - * \ref RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_TX_FIFO_ALMOST_EMPTY - * will occur telling the application to load more TX packet data, if needed - * lest a \ref RAIL_EVENT_TX_UNDERFLOW event occurs. - * - Set the RX FIFO threshold through RAIL_SetRxFifoThreshold(). The - * \ref RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL - * will occur telling the application to consume some RX packet data lest a - * \ref RAIL_EVENT_RX_FIFO_OVERFLOW event occurs. - * - Get RX FIFO count information through - * RAIL_GetRxPacketInfo(\ref RAIL_RX_PACKET_HANDLE_NEWEST) - * (or RAIL_GetRxFifoBytesAvailable()). - * - Get TX FIFO count information through RAIL_GetTxFifoSpaceAvailable(). - * - Reset RX and/or TX FIFOs with RAIL_ResetFifo(). - * - * When trying to determine an appropriate threshold, the application needs - * to know each FIFO's size. The receive FIFO is internal to RAIL and its - * size is 512 bytes. The receive FIFO is level-based in that the \ref - * RAIL_EVENT_RX_FIFO_ALMOST_FULL event will constantly pend if the threshold - * is exceeded. This normally means that inside this event's callback, the - * application should - * empty enough of the FIFO to go under the threshold. To defer reading the - * FIFO to main context, the application can disable or re-enable the receive - * FIFO threshold event using RAIL_ConfigEvents() with the mask - * \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL. - * - * The transmit FIFO is specified by the application and its actual size is - * the value returned from the most recent call to RAIL_SetTxFifo(), - * The transmit FIFO is edge-based in that it only provides the \ref - * RAIL_EVENT_TX_FIFO_ALMOST_EMPTY event once when the threshold is crossed - * in the emptying direction. - * - * In FIFO mode, the FIFOs can store multiple packets. Depending on the - * traffic, RAIL can receive multiple packets into the receive FIFO before the - * application gets around to reading out the received data from the FIFO. - * RAIL_ReadRxFifo() won't allow reading beyond a packet boundary so - * process packet completion events promptly. Keep in mind that in FIFO mode, - * packet data already read from packets that are subsequently aborted, - * frameerror, or filtered should be flushed. - * - * While RAIL defaults to packet mode, the application can explicitly - * initialize RAIL for packet mode in the following manner: - * @code{.c} - * static const RAIL_DataConfig_t railDataConfig = { - * .txSource = TX_PACKET_DATA, - * .rxSource = RX_PACKET_DATA, - * .txMethod = PACKET_MODE, - * .rxMethod = PACKET_MODE, - * }; - * - * status = RAIL_ConfigData(&railDataConfig); - * - * // Events that can occur in Packet Mode: - * RAIL_EVENT_TX_PACKET_SENT - * RAIL_EVENT_RX_PACKET_RECEIVED - * and optionally (packet data automatically dropped): - * RAIL_EVENT_RX_ADDRESS_FILTERED - * RAIL_EVENT_RX_PACKET_ABORTED - * RAIL_EVENT_RX_FRAME_ERROR - * @endcode - * - * Initializing RAIL for FIFO Mode requires a few more function calls: - * @code{.c} - * static const RAIL_DataConfig_t railDataConfig = { - * .txSource = TX_PACKET_DATA, - * .rxSource = RX_PACKET_DATA, - * .txMethod = FIFO_MODE, - * .rxMethod = FIFO_MODE, - * }; - * - * status = RAIL_ConfigData(&railDataConfig); - * - * // Gets the size of the FIFOs. - * // The transmit and receive FIFOs are the same size - * uint16_t fifoSize = RAIL_GetTxFifoSpaceAvailable(); - * - * // Sets the transmit and receive FIFO thresholds. - * // For this example, set the threshold in the middle of each FIFO - * RAIL_SetRxFifoThreshold(fifoSize / 2); - * RAIL_SetTxFifoThreshold(fifoSize / 2); - * - * // Events that can occur in FIFO mode: - * RAIL_EVENT_TX_FIFO_ALMOST_EMPTY - * RAIL_EVENT_TX_UNDERFLOW - * RAIL_EVENT_TXACK_UNDERFLOW - * RAIL_EVENT_TX_PACKET_SENT - * RAIL_EVENT_RX_FIFO_ALMOST_FULL - * RAIL_EVENT_RX_FIFO_OVERFLOW - * RAIL_EVENT_RX_ADDRESS_FILTERED - * RAIL_EVENT_RX_PACKET_ABORTED - * RAIL_EVENT_RX_FRAME_ERROR - * RAIL_EVENT_RX_PACKET_RECEIVED - * @endcode - * - * On receive, an application can use multiple data sources that - * are only compatible with the FIFO method of data delivery. All that differs - * from the FIFO mode example above is the RAIL_DataConfig_t::rxSource setting. - * IQ data samples are taken at the hardware's oversample rate and the amount - * of data can easily overwhelm the CPU processing time. The sample rate - * depends on the chosen PHY, as determined by the data rate and the decimation - * chain. It is not recommended to use the IQ data source with sample - * rates above 300 k samples/second as the CPU might not be able to keep up - * with the data. Depending on the application and needed CPU bandwidth, slower - * data rates may be required. - * @code{.c} - * // IQ data is provided into the receive FIFO - * static const RAIL_DataConfig_t railDataConfig = { - * .txSource = TX_PACKET_DATA, - * .rxSource = RX_IQDATA_FILTLSB, - * .txMethod = FIFO_MODE, - * .rxMethod = FIFO_MODE, - * }; - * - * // When reading IQ data out of the FIFO, it comes in the following format: - * //------------------------------------ - * // I[LSB] | I[MSB] | Q[LSB] | Q[MSB] | - * //------------------------------------ - * @endcode - * - * @note \ref RAIL_DataConfig_t.txMethod and \ref RAIL_DataConfig_t.rxMethod - * must have the same \ref RAIL_DataMethod_t configuration. - * - * @warning Do not call RAIL_ReadRxFifo() function while in - * \ref RAIL_DataMethod_t::PACKET_MODE. - * @{ - */ +/// @addtogroup Data_Management Data Management +/// @brief Data management functions +/// +/// These functions allow the application to choose how data is presented to the +/// application. RAIL provides data in a packet-based method or in a FIFO-based +/// method which gives the application more granularity and responsibility in +/// managing transmit and receive data, and allows packet sizes larger than +/// the RX or TX FIFO buffers. +/// +/// The application can configure RAIL data management through +/// RAIL_ConfigData(). +/// This function allows the application to specify the type of radio data +/// (\ref RAIL_TxDataSource_t and \ref RAIL_RxDataSource_t) and the method of +/// interacting with data (\ref RAIL_DataMethod_t). By default, RAIL +/// configures TX and RX both with packet data source and packet mode. +/// +/// In packet based data management: +/// - Packet lengths are determined from the Radio Configurator configuration +/// or after receive packet completion using RAIL_GetRxPacketInfo(). +/// - Load transmit data with RAIL_WriteTxFifo(). +/// - Received packet data is made available on successful packet completion +/// via \ref RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_RX_PACKET_RECEIVED +/// which can then use RAIL_GetRxPacketInfo() and RAIL_GetRxPacketDetails() to +/// access packet information, and RAIL_PeekRxPacket() to access packet +/// data. +/// - Filtered, Aborted, or FrameError received packet data is automatically +/// dropped without the application needing to worry about consuming it. +/// The application can choose to not even be bothered with the events +/// related to such packets: \ref RAIL_EVENT_RX_ADDRESS_FILTERED, +/// \ref RAIL_EVENT_RX_PACKET_ABORTED, or \ref RAIL_EVENT_RX_FRAME_ERROR. +/// +/// In FIFO based data management: +/// - Packet Lengths are determined from the Radio Configurator configuration +/// or by application knowledge of packet payload structure. +/// - Load transmit data with RAIL_WriteTxFifo() with reset set to false. +/// - Received data can be retrieved prior to packet completion through +/// RAIL_ReadRxFifo(), and is never dropped on Filtered, Aborted, or +/// FrameError packets. The application should enable and handle these +/// events so it can flush any packet data it's already retrieved. +/// - After packet completion, remaining packet data for Filtered, Aborted, +/// or FrameError packets can be either flushed automatically by RAIL +/// or consumed by the application just like a successfully received packet, +/// as determined from RAIL_GetRxPacketInfo(). RAIL_GetRxPacketDetails() +/// provides packet detailed information only for successfully received +/// packets. +/// - Set the TX FIFO threshold through RAIL_SetTxFifoThreshold(). The +/// \ref RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_TX_FIFO_ALMOST_EMPTY +/// will occur telling the application to load more TX packet data, if needed +/// lest a \ref RAIL_EVENT_TX_UNDERFLOW event occurs. +/// - Set the RX FIFO threshold through RAIL_SetRxFifoThreshold(). The +/// \ref RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL +/// will occur telling the application to consume some RX packet data lest a +/// \ref RAIL_EVENT_RX_FIFO_OVERFLOW event occurs. +/// - Get RX FIFO count information through +/// RAIL_GetRxPacketInfo(\ref RAIL_RX_PACKET_HANDLE_NEWEST) +/// (or RAIL_GetRxFifoBytesAvailable()). +/// - Get TX FIFO count information through RAIL_GetTxFifoSpaceAvailable(). +/// - Reset RX and/or TX FIFOs with RAIL_ResetFifo(). +/// +/// When trying to determine an appropriate threshold, the application needs +/// to know each FIFO's size. The receive FIFO is internal to RAIL and its +/// size is 512 bytes. The receive FIFO is level-based in that the \ref +/// RAIL_EVENT_RX_FIFO_ALMOST_FULL event will constantly pend if the threshold +/// is exceeded. This normally means that inside this event's callback, the +/// application should +/// empty enough of the FIFO to go under the threshold. To defer reading the +/// FIFO to main context, the application can disable or re-enable the receive +/// FIFO threshold event using RAIL_ConfigEvents() with the mask +/// \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL. +/// +/// The transmit FIFO is specified by the application and its actual size is +/// the value returned from the most recent call to RAIL_SetTxFifo(), +/// The transmit FIFO is edge-based in that it only provides the \ref +/// RAIL_EVENT_TX_FIFO_ALMOST_EMPTY event once when the threshold is crossed +/// in the emptying direction. +/// +/// In FIFO mode, the FIFOs can store multiple packets. Depending on the +/// traffic, RAIL can receive multiple packets into the receive FIFO before the +/// application gets around to reading out the received data from the FIFO. +/// RAIL_ReadRxFifo() won't allow reading beyond a packet boundary so +/// process packet completion events promptly. Keep in mind that in FIFO mode, +/// packet data already read from packets that are subsequently aborted, +/// frameerror, or filtered should be flushed. +/// +/// While RAIL defaults to packet mode, the application can explicitly +/// initialize RAIL for packet mode in the following manner: +/// @code{.c} +/// static const RAIL_DataConfig_t railDataConfig = { +/// .txSource = TX_PACKET_DATA, +/// .rxSource = RX_PACKET_DATA, +/// .txMethod = PACKET_MODE, +/// .rxMethod = PACKET_MODE, +/// }; +/// +/// status = RAIL_ConfigData(&railDataConfig); +/// +/// // Events that can occur in Packet Mode: +/// RAIL_EVENT_TX_PACKET_SENT +/// RAIL_EVENT_RX_PACKET_RECEIVED +/// and optionally (packet data automatically dropped): +/// RAIL_EVENT_RX_ADDRESS_FILTERED +/// RAIL_EVENT_RX_PACKET_ABORTED +/// RAIL_EVENT_RX_FRAME_ERROR +/// @endcode +/// +/// Initializing RAIL for FIFO Mode requires a few more function calls: +/// @code{.c} +/// static const RAIL_DataConfig_t railDataConfig = { +/// .txSource = TX_PACKET_DATA, +/// .rxSource = RX_PACKET_DATA, +/// .txMethod = FIFO_MODE, +/// .rxMethod = FIFO_MODE, +/// }; +/// +/// status = RAIL_ConfigData(&railDataConfig); +/// +/// // Gets the size of the FIFOs. +/// // The transmit and receive FIFOs are the same size +/// uint16_t fifoSize = RAIL_GetTxFifoSpaceAvailable(); +/// +/// // Sets the transmit and receive FIFO thresholds. +/// // For this example, set the threshold in the middle of each FIFO +/// RAIL_SetRxFifoThreshold(fifoSize / 2); +/// RAIL_SetTxFifoThreshold(fifoSize / 2); +/// +/// // Events that can occur in FIFO mode: +/// RAIL_EVENT_TX_FIFO_ALMOST_EMPTY +/// RAIL_EVENT_TX_UNDERFLOW +/// RAIL_EVENT_TXACK_UNDERFLOW +/// RAIL_EVENT_TX_PACKET_SENT +/// RAIL_EVENT_RX_FIFO_ALMOST_FULL +/// RAIL_EVENT_RX_FIFO_OVERFLOW +/// RAIL_EVENT_RX_ADDRESS_FILTERED +/// RAIL_EVENT_RX_PACKET_ABORTED +/// RAIL_EVENT_RX_FRAME_ERROR +/// RAIL_EVENT_RX_PACKET_RECEIVED +/// @endcode +/// +/// On receive, an application can use multiple data sources that +/// are only compatible with the FIFO method of data delivery. All that differs +/// from the FIFO mode example above is the RAIL_DataConfig_t::rxSource setting. +/// IQ data samples are taken at the hardware's oversample rate and the amount +/// of data can easily overwhelm the CPU processing time. The sample rate +/// depends on the chosen PHY, as determined by the data rate and the decimation +/// chain. It is not recommended to use the IQ data source with sample +/// rates above 300 k samples/second as the CPU might not be able to keep up +/// with the data. Depending on the application and needed CPU bandwidth, slower +/// data rates may be required. +/// @code{.c} +/// // IQ data is provided into the receive FIFO +/// static const RAIL_DataConfig_t railDataConfig = { +/// .txSource = TX_PACKET_DATA, +/// .rxSource = RX_IQDATA_FILTLSB, +/// .txMethod = FIFO_MODE, +/// .rxMethod = FIFO_MODE, +/// }; +/// +/// // When reading IQ data out of the FIFO, it comes in the following format: +/// //------------------------------------ +/// // I[LSB] | I[MSB] | Q[LSB] | Q[MSB] | +/// //------------------------------------ +/// @endcode +/// +/// @note \ref RAIL_DataConfig_t.txMethod and \ref RAIL_DataConfig_t.rxMethod +/// must have the same \ref RAIL_DataMethod_t configuration. +/// +/// @warning Do not call RAIL_ReadRxFifo() function while in +/// \ref RAIL_DataMethod_t::PACKET_MODE. +/// @{ /** * RAIL data management configuration @@ -792,7 +904,7 @@ uint16_t RAIL_WriteTxFifo(RAIL_Handle_t railHandle, * Set the address of the TX FIFO, a circular buffer used for TX data * * @param[in] railHandle A RAIL instance handle. - * @param[in,out] txBufPtr Pointer to a read-write memory location in RAM + * @param[in,out] addr Pointer to a read-write memory location in RAM * used as the TX FIFO. This memory must persist until the next call to * this function. * @param[in] initLength Number of initial bytes already in the TX FIFO. @@ -836,7 +948,7 @@ uint16_t RAIL_WriteTxFifo(RAIL_Handle_t railHandle, * automatically. */ uint16_t RAIL_SetTxFifo(RAIL_Handle_t railHandle, - uint8_t *txBufPtr, + uint8_t *addr, uint16_t initLength, uint16_t size); @@ -860,6 +972,18 @@ uint16_t RAIL_SetTxFifo(RAIL_Handle_t railHandle, * Because this function does not have a critical section, either use it * only in one context or make sure function calls are protected to prevent * buffer corruption. + * + * @note When reading data from an arriving packet that is not yet complete + * keep in mind its data is highly suspect because it has not yet passed + * any CRC integrity checking. Also note the packet could be aborted, + * cancelled, or fail momentarily, invalidating its data in Packet mode. + * Furthermore, there is a small chance towards the end of packet reception + * that the RX FIFO could include not only packet data received so far, + * but also some raw radio-appended info detail bytes that RAIL's + * packet-completion processing will subsequently deal with. It's up to the + * application to know its packet format well enough to avoid reading this + * info as it will corrupt the packet's details and possibly corrupt the + * RX FIFO buffer. */ uint16_t RAIL_ReadRxFifo(RAIL_Handle_t railHandle, uint8_t *dataPtr, @@ -891,12 +1015,12 @@ uint16_t RAIL_SetTxFifoThreshold(RAIL_Handle_t railHandle, * * This function configures the threshold for the receive FIFO. When the count * of the receive FIFO is greater than the configured threshold, - * \ref RAIL_Config_t::eventsCallback will fire with \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL set. - * A value of 0xFFFF is invalid and will not change the current configuration. - * Depending on the size of the receive FIFO hardware, the maximum value can - * vary. If the rxThreshold value exceeds the capability of the hardware, the - * RX threshold will be configured so that it fires only when the FIFO is one - * byte away from being full. + * \ref RAIL_Config_t::eventsCallback will fire with + * \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL set. A value of 0xFFFF is invalid and + * will not change the current configuration. Depending on the size of the + * receive FIFO hardware, the maximum value can vary. If the rxThreshold value + * exceeds the capability of the hardware, the RX threshold will be configured + * so that it fires only when the FIFO is one byte away from being full. */ uint16_t RAIL_SetRxFifoThreshold(RAIL_Handle_t railHandle, uint16_t rxThreshold); @@ -945,7 +1069,9 @@ void RAIL_ResetFifo(RAIL_Handle_t railHandle, bool txFifo, bool rxFifo); * @note The number of bytes returned may not just reflect the current * packet's data but could also include raw appended info bytes added * after successful packet reception and bytes from subsequently received - * packets. + * packets. It is up to the app to never try to consume more than the + * packet's actual data when using the value returned here in a subsequent + * call to RAIL_ReadRxFifo(), otherwise the Rx buffer will be corrupted. */ uint16_t RAIL_GetRxFifoBytesAvailable(RAIL_Handle_t railHandle); @@ -1023,7 +1149,11 @@ RAIL_Status_t RAIL_SetStateTiming(RAIL_Handle_t railHandle, * idle before returning. * @return void. * - * This function is used to remove the radio from TX and RX states. + * This function is used to remove the radio from TX and RX states. How these + * states are left is defined by the mode parameter. + * + * In multiprotocol, this API will also cause the radio to be yielded so that + * other tasks can be run. See \ref rail_radio_scheduler_yield for more details. */ void RAIL_Idle(RAIL_Handle_t railHandle, RAIL_IdleMode_t mode, @@ -1058,133 +1188,131 @@ RAIL_RadioState_t RAIL_GetRadioState(RAIL_Handle_t railHandle); * @{ */ -/** - * @addtogroup PA Power Amplifier (PA) - * @brief APIs for interacting with one of the on chip PAs. - * - * These APIs let you configure the on chip PA to get the appropriate output - * power. - * - * There a few types of functions that are found here - * 1) Configuration functions: These functions set and get configuration - * for the PA. In this case, "configuration" refers to a) indicating - * which PA to use, b) the voltage supplied by your board to the PA, - * and c) the ramp time over which to ramp the PA up to its full - * power. - * 2) Power-setting functions: These functions consume the actual - * values written to the PA registers, and write them appropriately. - * These values are referred to as "(raw) power levels". The range of - * acceptable values for these functions depends on which PA is - * currently active. The higher the power level set, the higher - * the dBm power actually output by the chip. However, the mapping - * between dBm and these power levels can vary greatly between - * modules/boards. - * 3) Conversion functions: These functions do the work of converting - * between the "power levels" discussed previously and the actual - * dBm values output by the chip. Continue reading for more details - * on how to handle unit conversion. - * - * The accuracy of the chip output power in dBm will vary from application to - * to application. For some protocols or channels the protocol itself or - * legal limitations will require applications to know exactly what power - * they're transmitting at, in dBm. Other applications will not have - * these restrictions, and users will simply find some power level(s) - * that fit their criteria for the trade-off between radio range and - * power savings, regardless of what dBm power that maps to. - * - * In order to provide a solution that fits all these applications, - * Silicon Labs has provided a great deal of flexibility in - * \ref RAIL_ConvertRawToDbm and \ref RAIL_ConvertDbmToRaw, the two functions - * that do the conversion between the dBm power and the raw power levels. - * Those levels of customizability are outlined below - * 1) No customizability needed: for a given dBm value, the result - * of RAIL_ConvertDbmToRaw provides an appropriate - * raw power level that, when written to the registers via - * RAIL_SetPowerLevel, causes the chip to actually output at that - * dBm power. In this case, no action is needed by the user, - * the WEAK versions of the conversion functions can be used, - * and the default include paths in pa_conversions_efr32.h can - * be used. - * 2) The mapping of power level to dBm is not good, but the - * level of precision is sufficient: In pa_conversions_efr32.c - * the WEAK versions of the conversion functions work by using - * 8-segment piecewise linear curves to convert between dBm - * and power levels for PA's with hundreds of power levels - * and simple mapping tables for use with PA's with only a few - * levels. If this method is sufficiently precise, but the mapping - * between power levels and dBm is wrong, Silicon Labs recommends - * copying pa_curves_efr32.h into a new file, updating the segments - * to form a better fit (_DCDC_CURVES or _VBAT_CURVES defines), and - * then adding the RAIL_PA_CURVES define to your build with the path - * to the new file. - * 3) A different level of precision is needed and the fit is bad: - * If the piecewise-linear line segment fit is not appropriate for - * your solution, the functions in pa_conversions_efr32.c can be - * totally rewritten, as long as RAIL_ConvertDbmToRaw and - * RAIL_ConvertRawToDbm have the same signatures. It is completely - * acceptable to re-write these in a way that makes the - * pa_curves_efr32.h and pa_curve_types_efr32.h files referenced in - * pa_conversions_efr32.h unnecessary. Those files are needed solely - * for the conversion methods that Silicon Labs provides. - * 4) dBm values are not necessary: If your application does not require - * dBm values at all, Silicon Labs recommends overwriting - * RAIL_ConvertDbmToRaw and RAIL_ConvertRawToDbm with smaller functions - * (i.e. return 0 or whatever was input). These functions are called - * from within the RAIL library, so they can never be deadstripped, - * but making them as small as possible is the best way to reduce code - * size. From there, you can simply call RAIL_SetTxPower, without - * converting from a dBm value. If you never want the library to coerce the - * power based on channels, RAIL_ConvertRawToDbm should be overwritten - * to always return 0 and RAIL_ConvertDbmToRaw should be overwritten to - * always return 255. - * - * The following is example code on how to initialize your PA - * @code{.c} - * - * #include "pa_conversions_efr32.h" - * - * // Helper macro to declare all the curve structures used by the Silicon Labs-provided - * // conversion functions - * RAIL_DECLARE_TX_POWER_VBAT_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp); - * - * // Put the variables declared above into the appropriate structure - * RAIL_TxPowerCurvesConfig_t txPowerCurvesConfig = { curves24Hp, curvesSg, curves24Lp, piecewiseSegments }; - * - * // In the Silicon Labs implementation, the user is required to save those curves into - * // to be referenced when the conversion functions are called - * RAIL_InitTxPowerCurves(&txPowerCurvesConfig); - * - * // Declare the structure used to configure the PA - * RAIL_TxPowerConfig_t txPowerConfig = { RAIL_TX_POWER_MODE_2P4_HP, 3300, 10 }; - * - * // And then init the PA. Here, it is assumed that 'railHandle' is a valid RAIL_Handle_t - * // that has already been initialized. - * RAIL_ConfigTxPower(railHandle, &txPowerConfig); - * - * // Pick a dBm power to use: 100 deci-dBm = 10 dBm. See docs on RAIL_TxPower_t - * RAIL_TxPower_t power = 100; - * - * // Get the config written by RAIL_ConfigTxPower to confirm what was actually set - * RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); - * - * // RAIL_ConvertDbmToRaw will be the weak version provided by Silicon Labs - * // by default, or the customer version, if overwritten. - * RAIL_TxPowerLevel_t powerLevel = RAIL_ConvertDbmToRaw(railHandle, - * txPowerConfig.mode, - * power); - * - * // Write the result of the conversion to the PA power registers in terms - * // of raw power levels - * RAIL_SetTxPower(railHandle, powerLevel); - * @endcode - * - * @note: all the lines following "RAIL_TxPower_t power = 100;" can be - * replaced with the provided utility function, \ref RAIL_SetTxPowerDbm. - * However, the full example here was provided for clarity. See the - * documentation on \ref RAIL_SetTxPowerDbm for more details. - * - * @{ - */ +/// @addtogroup PA Power Amplifier (PA) +/// @brief APIs for interacting with one of the on chip PAs. +/// +/// These APIs let you configure the on chip PA to get the appropriate output +/// power. +/// +/// There a few types of functions that are found here +/// 1) Configuration functions: These functions set and get configuration +/// for the PA. In this case, "configuration" refers to a) indicating +/// which PA to use, b) the voltage supplied by your board to the PA, +/// and c) the ramp time over which to ramp the PA up to its full +/// power. +/// 2) Power-setting functions: These functions consume the actual +/// values written to the PA registers, and write them appropriately. +/// These values are referred to as "(raw) power levels". The range of +/// acceptable values for these functions depends on which PA is +/// currently active. The higher the power level set, the higher +/// the dBm power actually output by the chip. However, the mapping +/// between dBm and these power levels can vary greatly between +/// modules/boards. +/// 3) Conversion functions: These functions do the work of converting +/// between the "power levels" discussed previously and the actual +/// dBm values output by the chip. Continue reading for more details +/// on how to handle unit conversion. +/// +/// The accuracy of the chip output power in dBm will vary from application to +/// to application. For some protocols or channels the protocol itself or +/// legal limitations will require applications to know exactly what power +/// they're transmitting at, in dBm. Other applications will not have +/// these restrictions, and users will simply find some power level(s) +/// that fit their criteria for the trade-off between radio range and +/// power savings, regardless of what dBm power that maps to. +/// +/// In order to provide a solution that fits all these applications, +/// Silicon Labs has provided a great deal of flexibility in +/// \ref RAIL_ConvertRawToDbm and \ref RAIL_ConvertDbmToRaw, the two functions +/// that do the conversion between the dBm power and the raw power levels. +/// Those levels of customizability are outlined below +/// 1) No customizability needed: for a given dBm value, the result +/// of RAIL_ConvertDbmToRaw provides an appropriate +/// raw power level that, when written to the registers via +/// RAIL_SetPowerLevel, causes the chip to actually output at that +/// dBm power. In this case, no action is needed by the user, +/// the WEAK versions of the conversion functions can be used, +/// and the default include paths in pa_conversions_efr32.h can +/// be used. +/// 2) The mapping of power level to dBm is not good, but the +/// level of precision is sufficient: In pa_conversions_efr32.c +/// the WEAK versions of the conversion functions work by using +/// 8-segment piecewise linear curves to convert between dBm +/// and power levels for PA's with hundreds of power levels +/// and simple mapping tables for use with PA's with only a few +/// levels. If this method is sufficiently precise, but the mapping +/// between power levels and dBm is wrong, Silicon Labs recommends +/// copying pa_curves_efr32.h into a new file, updating the segments +/// to form a better fit (_DCDC_CURVES or _VBAT_CURVES defines), and +/// then adding the RAIL_PA_CURVES define to your build with the path +/// to the new file. +/// 3) A different level of precision is needed and the fit is bad: +/// If the piecewise-linear line segment fit is not appropriate for +/// your solution, the functions in pa_conversions_efr32.c can be +/// totally rewritten, as long as RAIL_ConvertDbmToRaw and +/// RAIL_ConvertRawToDbm have the same signatures. It is completely +/// acceptable to re-write these in a way that makes the +/// pa_curves_efr32.h and pa_curve_types_efr32.h files referenced in +/// pa_conversions_efr32.h unnecessary. Those files are needed solely +/// for the conversion methods that Silicon Labs provides. +/// 4) dBm values are not necessary: If your application does not require +/// dBm values at all, Silicon Labs recommends overwriting +/// RAIL_ConvertDbmToRaw and RAIL_ConvertRawToDbm with smaller functions +/// (i.e. return 0 or whatever was input). These functions are called +/// from within the RAIL library, so they can never be deadstripped, +/// but making them as small as possible is the best way to reduce code +/// size. From there, you can simply call RAIL_SetTxPower, without +/// converting from a dBm value. If you never want the library to coerce the +/// power based on channels, RAIL_ConvertRawToDbm should be overwritten +/// to always return 0 and RAIL_ConvertDbmToRaw should be overwritten to +/// always return 255. +/// +/// The following is example code on how to initialize your PA +/// @code{.c} +/// +/// #include "pa_conversions_efr32.h" +/// +/// // Helper macro to declare all the curve structures used by the Silicon Labs-provided +/// // conversion functions +/// RAIL_DECLARE_TX_POWER_VBAT_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp); +/// +/// // Put the variables declared above into the appropriate structure +/// RAIL_TxPowerCurvesConfig_t txPowerCurvesConfig = { curves24Hp, curvesSg, curves24Lp, piecewiseSegments }; +/// +/// // In the Silicon Labs implementation, the user is required to save those curves into +/// // to be referenced when the conversion functions are called +/// RAIL_InitTxPowerCurves(&txPowerCurvesConfig); +/// +/// // Declare the structure used to configure the PA +/// RAIL_TxPowerConfig_t txPowerConfig = { RAIL_TX_POWER_MODE_2P4_HP, 3300, 10 }; +/// +/// // And then init the PA. Here, it is assumed that 'railHandle' is a valid RAIL_Handle_t +/// // that has already been initialized. +/// RAIL_ConfigTxPower(railHandle, &txPowerConfig); +/// +/// // Pick a dBm power to use: 100 deci-dBm = 10 dBm. See docs on RAIL_TxPower_t +/// RAIL_TxPower_t power = 100; +/// +/// // Get the config written by RAIL_ConfigTxPower to confirm what was actually set +/// RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); +/// +/// // RAIL_ConvertDbmToRaw will be the weak version provided by Silicon Labs +/// // by default, or the customer version, if overwritten. +/// RAIL_TxPowerLevel_t powerLevel = RAIL_ConvertDbmToRaw(railHandle, +/// txPowerConfig.mode, +/// power); +/// +/// // Write the result of the conversion to the PA power registers in terms +/// // of raw power levels +/// RAIL_SetTxPower(railHandle, powerLevel); +/// @endcode +/// +/// @note: all the lines following "RAIL_TxPower_t power = 100;" can be +/// replaced with the provided utility function, \ref RAIL_SetTxPowerDbm. +/// However, the full example here was provided for clarity. See the +/// documentation on \ref RAIL_SetTxPowerDbm for more details. +/// +/// @{ /** * Initialize TxPower Settings @@ -1339,59 +1467,57 @@ RAIL_TxPowerLevel_t RAIL_ConvertDbmToRaw(RAIL_Handle_t railHandle, /** @} */ // end of group PA -/** - * Sets the TX power in terms of deci-dBm instead of raw power level. - * - * @param[in] railHandle A RAIL instance handle. - * @param[in] power Desired deci-dBm power to be set. - * @return RAIL Status variable indicate whether setting the - * power was successful. - * - * This is a utility function crafted for user convenience. Normally, to set TX - * power in dBm, the user would have to do the following: - * - * @code{.c} - * RAIL_TxPower_t power = 100; // 100 deci-dBm, 10 dBm - * RAIL_TxPowerConfig_t txPowerConfig; - * RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); - * // RAIL_ConvertDbmToRaw will be the weak version provided by Silicon Labs - * // by default, or the customer version, if overwritten. - * RAIL_TxPowerLevel_t powerLevel = RAIL_ConvertDbmToRaw(railHandle, - * txPowerConfig.mode, - * power); - * RAIL_SetTxPower(railHandle, powerLevel); - * @endcode - * - * This function wraps all those calls in a single function with power passed in - * as a parameter. - */ +/// Sets the TX power in terms of deci-dBm instead of raw power level. +/// +/// @param[in] railHandle A RAIL instance handle. +/// @param[in] power Desired deci-dBm power to be set. +/// @return RAIL Status variable indicate whether setting the +/// power was successful. +/// +/// This is a utility function crafted for user convenience. Normally, to set TX +/// power in dBm, the user would have to do the following: +/// +/// @code{.c} +/// RAIL_TxPower_t power = 100; // 100 deci-dBm, 10 dBm +/// RAIL_TxPowerConfig_t txPowerConfig; +/// RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); +/// // RAIL_ConvertDbmToRaw will be the weak version provided by Silicon Labs +/// // by default, or the customer version, if overwritten. +/// RAIL_TxPowerLevel_t powerLevel = RAIL_ConvertDbmToRaw(railHandle, +/// txPowerConfig.mode, +/// power); +/// RAIL_SetTxPower(railHandle, powerLevel); +/// @endcode +/// +/// This function wraps all those calls in a single function with power passed in +/// as a parameter. +/// RAIL_Status_t RAIL_SetTxPowerDbm(RAIL_Handle_t railHandle, RAIL_TxPower_t power); -/** - * Gets the TX power in terms of deci-dBm instead of raw power level. - * - * @param[in] railHandle A RAIL instance handle. - * @return The current output power in deci-dBm - * - * This is a utility function crafted for user convenience. Normally, to get TX - * power in dBm, the user would have to do the following: - * - * @code{.c} - * RAIL_TxPowerLevel_t powerLevel = RAIL_GetTxPower(railHandle); - * RAIL_TxPowerConfig_t txPowerConfig; - * RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); - * // RAIL_ConvertRawToDbm will be the weak version provided by Silicon Labs - * // by default, or the customer version, if overwritten. - * RAIL_TxPower_t power = RAIL_ConvertRawToDbm(railHandle, - * txPowerConfig.mode, - * power); - * return power; - * @endcode - * - * This function wraps all those calls in a single function with power returned - * as the result. - */ +/// Gets the TX power in terms of deci-dBm instead of raw power level. +/// +/// @param[in] railHandle A RAIL instance handle. +/// @return The current output power in deci-dBm +/// +/// This is a utility function crafted for user convenience. Normally, to get TX +/// power in dBm, the user would have to do the following: +/// +/// @code{.c} +/// RAIL_TxPowerLevel_t powerLevel = RAIL_GetTxPower(railHandle); +/// RAIL_TxPowerConfig_t txPowerConfig; +/// RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); +/// // RAIL_ConvertRawToDbm will be the weak version provided by Silicon Labs +/// // by default, or the customer version, if overwritten. +/// RAIL_TxPower_t power = RAIL_ConvertRawToDbm(railHandle, +/// txPowerConfig.mode, +/// power); +/// return power; +/// @endcode +/// +/// This function wraps all those calls in a single function with power returned +/// as the result. +/// RAIL_TxPower_t RAIL_GetTxPowerDbm(RAIL_Handle_t railHandle); /** @@ -1708,11 +1834,53 @@ RAIL_Status_t RAIL_ScheduleRx(RAIL_Handle_t railHandle, * if packetHandle was one of the sentinel values, returns the actual * packet handle for that packet, otherwise returns packetHandle. * It may return \ref RAIL_RX_PACKET_HANDLE_INVALID to indicate an error. + * + * @note When getting info about an arriving packet that is not yet complete + * (i.e. pPacketInfo->packetStatus == \ref RAIL_RX_PACKET_RECEIVING), keep + * in mind its data is highly suspect because it has not yet passed any CRC + * integrity checking. Also note the packet could be aborted, cancelled, or + * fail momentarily, invalidating its data in Packet mode. Furthermore, there + * is a small chance towards the end of packet reception that the filled-in + * RAIL_RxPacketInfo_t could include not only packet data received so far, + * but also some raw radio-appended info detail bytes that RAIL's + * packet-completion processing will subsequently deal with. It's up to the + * application to know its packet format well enough to avoid confusing such + * info as packet data. */ RAIL_RxPacketHandle_t RAIL_GetRxPacketInfo(RAIL_Handle_t railHandle, RAIL_RxPacketHandle_t packetHandle, RAIL_RxPacketInfo_t *pPacketInfo); +/** + * Convenience helper function to copy a full packet to a user-specified + * contiguous buffer. + * + * @param[out] pDest An application-provided pointer to a buffer of at + * least pPacketInfo->packetBytes in size to store the packet data + * contiguously. This buffer must never overlay RAIL's Rx FIFO buffer. + * Exactly pPacketInfo->packetBytes of packet data will be written into it. + * @param[out] pPacketInfo + * \ref RAIL_RxPacketInfo_t for the requested packet. + * @return void. + * + * @note This helper is intended to be expedient -- it does not check the + * validity of its arguments, so don't pass either as NULL, and don't + * pass a pDest pointer to a buffer that's too small for the packet's data. + * @note If only a portion of the packet is needed, use RAIL_PeekRxPacket() + * instead. + */ +static inline +void RAIL_CopyRxPacket(uint8_t *pDest, + const RAIL_RxPacketInfo_t *pPacketInfo) +{ + memcpy(pDest, pPacketInfo->firstPortionData, pPacketInfo->firstPortionBytes); + if (pPacketInfo->lastPortionData != NULL) { + memcpy(pDest + pPacketInfo->firstPortionBytes, + pPacketInfo->lastPortionData, + pPacketInfo->packetBytes - pPacketInfo->firstPortionBytes); + } +} + /** * Get detailed information about a ready packet received (one whose * \ref RAIL_RxPacketStatus_t is among the RAIL_RX_PACKET_READY_ set). @@ -1780,8 +1948,10 @@ RAIL_RxPacketHandle_t RAIL_HoldRxPacket(RAIL_Handle_t railHandle); * @return Number of packet bytes copied. * * @note Peek does not permit peeking beyond the requested packet's - * available packet data, nor peeking into already-consumed data read by - * RAIL_ReadRxFifo(). len and offset are relative to the remaining data + * available packet data (though there is a small chance it might + * for a \ref RAIL_RX_PACKET_HANDLE_NEWEST packet at the very end of + * still being received). Nor can one peek into already-consumed data read + * by RAIL_ReadRxFifo(). len and offset are relative to the remaining data * available in the packet, if any was already consumed by RAIL_ReadRxFifo(). */ uint16_t RAIL_PeekRxPacket(RAIL_Handle_t railHandle, @@ -1869,7 +2039,7 @@ int16_t RAIL_GetRssi(RAIL_Handle_t railHandle, bool wait); */ RAIL_Status_t RAIL_StartAverageRssi(RAIL_Handle_t railHandle, uint16_t channel, - uint32_t averagingTimeUs, + RAIL_Time_t averagingTimeUs, const RAIL_SchedulerInfo_t *schedulerInfo); /** @@ -2061,135 +2231,132 @@ RAIL_Status_t RAIL_EnableAddressFilterAddress(RAIL_Handle_t railHandle, /****************************************************************************** * Auto Acking *****************************************************************************/ -/** - * @addtogroup Auto_Ack Auto ACK - * @brief APIs for configuring auto ACK functionality - * - * These APIs are used to configure the radio for auto acknowledgment - * features. Auto ACK inherently changes how the underlying state machine - * behaves so users should not modify RAIL_SetRxTransitions() and - * RAIL_SetTxTransitions() while using auto ACK features. - * - * @code{.c} - * // Go to RX after ACK operation - * RAIL_AutoAckConfig_t autoAckConfig = { - * .enable = true, - * .ackTimeout = 1000, - * // "error" param ignored - * .rxTransitions = { RAIL_RF_STATE_RX, RAIL_RF_STATE_RX}, - * // "error" param ignored - * .txTransitions = { RAIL_RF_STATE_RX, RAIL_RF_STATE_RX} - * }; - * - * RAIL_Status_t status = RAIL_ConfigAutoAck(railHandle, &autoAckConfig); - * - * uint8_t ackData[] = {0x05, 0x02, 0x10, 0x00}; - * - * RAIL_Status_t status = RAIL_WriteAutoAckFifo(ackData, sizeof(ackData)); - * @endcode - * - * The acknowledgment transmits based on the frame format configured via - * the Radio Configurator. For example, if the frame format is using a variable - * length scheme, the ACK will be sent according to that scheme. If a 10-byte - * packet is loaded into the ACK, but the variable length field of the ACK - * payload specifies a length of 5, only 5 bytes will transmit for the ACK. - * The converse is also true, if the frame length is configured to be a fixed - * 10-byte packet but only 5 bytes are loaded into the ACK buffer, a TX - * underflow occurs during the ACK transmit. - * - * Unlike in non-ACK mode, ACK mode will always return to a single - * state after all ACK sequences complete, regardless of whether - * the ACK was successfully received/sent or not. Read the documentation - * of RAIL_ConfigAutoAck for more detail on how that is configured. To - * not auto acknowledge a series of packets after transmit - * or receive, call RAIL_PauseTxAutoAck(true) or RAIL_PauseRxAutoAck(true). - * When auto acking is paused, after receiving or transmitting (also - * regardless of success) a packet, the radio transitions to the same single - * state it always defaults to while acking. To return to - * normal state transition logic outside of acking, you must call - * RAIL_ConfigAutoAck with the "enable" field false, and specify the - * desired transitions in the rxTransitions and txTransitions fields. - * To simply get out of a paused state and resume auto acking, call - * RAIL_PauseTxAutoAck(false) or RAIL_PauseRxAutoAck(false). - * - * Applications can cancel the transmission of an ACK with - * RAIL_CancelAutoAck(). Conversely, applications can control if a transmit - * operation should wait for an ACK after transmitting by using - * the \ref RAIL_TX_OPTION_WAIT_FOR_ACK bit. - * - * If the ACK payload is dynamic, the application must call - * RAIL_WriteAutoAckFifo() with the appropriate ACK payload after the - * application processes the receive. RAIL can auto ACK from the normal - * transmit buffer if RAIL_UseTxFifoForAutoAck() is called before the radio - * transmits the ACK. Ensure the transmit buffer contains data loaded by - * RAIL_WriteTxFifo(). - * - * Standard-based protocols that contain auto ACK functionality are normally - * configured in the protocol-specific configuration function. For example, - * RAIL_IEEE802154_Init() provides auto ACK configuration parameters in \ref - * RAIL_IEEE802154_Config_t and should only be configured through that - * function. It is not advisable to call both RAIL_IEEE802154_Init() and - * RAIL_ConfigAutoAck(). However, ACK modification functions are still valid to - * use with protocol-specific ACKs. To cancel a IEEE 802.15.4 ACK transmit, use - * RAIL_CancelAutoAck(). - * - * @{ - */ +/// @addtogroup Auto_Ack Auto ACK +/// @brief APIs for configuring auto ACK functionality +/// +/// These APIs are used to configure the radio for auto acknowledgment +/// features. Auto ACK inherently changes how the underlying state machine +/// behaves so users should not modify RAIL_SetRxTransitions() and +/// RAIL_SetTxTransitions() while using auto ACK features. +/// +/// @code{.c} +/// // Go to RX after ACK operation +/// RAIL_AutoAckConfig_t autoAckConfig = { +/// .enable = true, +/// .ackTimeout = 1000, +/// // "error" param ignored +/// .rxTransitions = { RAIL_RF_STATE_RX, RAIL_RF_STATE_RX}, +/// // "error" param ignored +/// .txTransitions = { RAIL_RF_STATE_RX, RAIL_RF_STATE_RX} +/// }; +/// +/// RAIL_Status_t status = RAIL_ConfigAutoAck(railHandle, &autoAckConfig); +/// +/// uint8_t ackData[] = {0x05, 0x02, 0x10, 0x00}; +/// +/// RAIL_Status_t status = RAIL_WriteAutoAckFifo(ackData, sizeof(ackData)); +/// @endcode +/// +/// The acknowledgment transmits based on the frame format configured via +/// the Radio Configurator. For example, if the frame format is using a variable +/// length scheme, the ACK will be sent according to that scheme. If a 10-byte +/// packet is loaded into the ACK, but the variable length field of the ACK +/// payload specifies a length of 5, only 5 bytes will transmit for the ACK. +/// The converse is also true, if the frame length is configured to be a fixed +/// 10-byte packet but only 5 bytes are loaded into the ACK buffer, a TX +/// underflow occurs during the ACK transmit. +/// +/// Unlike in non-ACK mode, ACK mode will always return to a single +/// state after all ACK sequences complete, regardless of whether +/// the ACK was successfully received/sent or not. Read the documentation +/// of RAIL_ConfigAutoAck for more detail on how that is configured. To +/// not auto acknowledge a series of packets after transmit +/// or receive, call RAIL_PauseTxAutoAck(true) or RAIL_PauseRxAutoAck(true). +/// When auto acking is paused, after receiving or transmitting (also +/// regardless of success) a packet, the radio transitions to the same single +/// state it always defaults to while acking. To return to +/// normal state transition logic outside of acking, you must call +/// RAIL_ConfigAutoAck with the "enable" field false, and specify the +/// desired transitions in the rxTransitions and txTransitions fields. +/// To simply get out of a paused state and resume auto acking, call +/// RAIL_PauseTxAutoAck(false) or RAIL_PauseRxAutoAck(false). +/// +/// Applications can cancel the transmission of an ACK with +/// RAIL_CancelAutoAck(). Conversely, applications can control if a transmit +/// operation should wait for an ACK after transmitting by using +/// the \ref RAIL_TX_OPTION_WAIT_FOR_ACK bit. +/// +/// If the ACK payload is dynamic, the application must call +/// RAIL_WriteAutoAckFifo() with the appropriate ACK payload after the +/// application processes the receive. RAIL can auto ACK from the normal +/// transmit buffer if RAIL_UseTxFifoForAutoAck() is called before the radio +/// transmits the ACK. Ensure the transmit buffer contains data loaded by +/// RAIL_WriteTxFifo(). +/// +/// Standard-based protocols that contain auto ACK functionality are normally +/// configured in the protocol-specific configuration function. For example, +/// RAIL_IEEE802154_Init() provides auto ACK configuration parameters in \ref +/// RAIL_IEEE802154_Config_t and should only be configured through that +/// function. It is not advisable to call both RAIL_IEEE802154_Init() and +/// RAIL_ConfigAutoAck(). However, ACK modification functions are still valid to +/// use with protocol-specific ACKs. To cancel a IEEE 802.15.4 ACK transmit, use +/// RAIL_CancelAutoAck(). +/// +/// @{ -/** - * Configures and enable auto acknowledgment. - * - * @param[in] railHandle A RAIL instance handle. - * @param[in] config Auto ACK configuration structure. - * @return Status code indicating success of the function call. - * - * Configures the RAIL state machine to for hardware-accelerated auto - * acknowledgment. ACK timing parameters are defined in the configuration - * structure. - * - * While auto acking is enabled, do not call the following RAIL functions: - * - RAIL_SetRxTransitions() - * - RAIL_SetTxTransitions() - * - * Note, that if you are enabling auto ACK (i.e. "enable" field is true) - * The "error" fields of rxTransitions and txTransitions are ignored. - * After all ACK sequences, (success or fail) the state machine will return - * the radio to the "success" state. If you need information about the - * actual success of the ACK sequence, you can use RAIL events such as - * \ref RAIL_EVENT_TXACK_PACKET_SENT to make sure an ACK was sent, or - * \ref RAIL_EVENT_RX_ACK_TIMEOUT to make sure that an ACK was received - * within the specified timeout. - * - * If you wish to set a certain turnaround time (i.e. txToRx and rxToTx - * in \ref RAIL_StateTiming_t), we recommend that you make txToRx lower than - * desired, in order to ensure you get to RX in time to receive the ACK. - * Silicon Labs recommends setting 10us lower than desired: - * - * @code{.c} - * void setAutoAckStateTimings() - * { - * RAIL_StateTiming_t timings; - * - * // User is already in auto ACK and wants a turnaround of 192us - * timings.rxToTx = 192; - * timings.txToRx = 192 - 10; - * - * // Set other fields of timings... - * timings.idleToRx = 100; - * timings.idleToTx = 100; - * timings.rxSearchTimeout = 0; - * timings.txToRxSearchTimeout = 0; - * - * RAIL_SetStateTiming(railHandle, &timings); - * } - * @endcode - * - * As opposed to an explicit "Disable" API, simply set the "enable" - * field of the RAIL_AutoAckConfig_t to false. Then, auto ACK will be - * disabled and state transitions will be returned to the values set - * in \ref RAIL_AutoAckConfig_t. During this disable, the "ackTimeout" field - * isn't used. - */ +/// Configures and enable auto acknowledgment. +/// +/// @param[in] railHandle A RAIL instance handle. +/// @param[in] config Auto ACK configuration structure. +/// @return Status code indicating success of the function call. +/// +/// Configures the RAIL state machine to for hardware-accelerated auto +/// acknowledgment. ACK timing parameters are defined in the configuration +/// structure. +/// +/// While auto acking is enabled, do not call the following RAIL functions: +/// - RAIL_SetRxTransitions() +/// - RAIL_SetTxTransitions() +/// +/// Note, that if you are enabling auto ACK (i.e. "enable" field is true) +/// The "error" fields of rxTransitions and txTransitions are ignored. +/// After all ACK sequences, (success or fail) the state machine will return +/// the radio to the "success" state. If you need information about the +/// actual success of the ACK sequence, you can use RAIL events such as +/// \ref RAIL_EVENT_TXACK_PACKET_SENT to make sure an ACK was sent, or +/// \ref RAIL_EVENT_RX_ACK_TIMEOUT to make sure that an ACK was received +/// within the specified timeout. +/// +/// If you wish to set a certain turnaround time (i.e. txToRx and rxToTx +/// in \ref RAIL_StateTiming_t), we recommend that you make txToRx lower than +/// desired, in order to ensure you get to RX in time to receive the ACK. +/// Silicon Labs recommends setting 10us lower than desired: +/// +/// @code{.c} +/// void setAutoAckStateTimings() +/// { +/// RAIL_StateTiming_t timings; +/// +/// // User is already in auto ACK and wants a turnaround of 192us +/// timings.rxToTx = 192; +/// timings.txToRx = 192 - 10; +/// +/// // Set other fields of timings... +/// timings.idleToRx = 100; +/// timings.idleToTx = 100; +/// timings.rxSearchTimeout = 0; +/// timings.txToRxSearchTimeout = 0; +/// +/// RAIL_SetStateTiming(railHandle, &timings); +/// } +/// @endcode +/// +/// As opposed to an explicit "Disable" API, simply set the "enable" +/// field of the RAIL_AutoAckConfig_t to false. Then, auto ACK will be +/// disabled and state transitions will be returned to the values set +/// in \ref RAIL_AutoAckConfig_t. During this disable, the "ackTimeout" field +/// isn't used. +/// RAIL_Status_t RAIL_ConfigAutoAck(RAIL_Handle_t railHandle, const RAIL_AutoAckConfig_t *config); @@ -2205,15 +2372,15 @@ bool RAIL_IsAutoAckEnabled(RAIL_Handle_t railHandle); * Loads the auto ACK buffer with ACK data. * * @param[in] railHandle A RAIL instance handle. - * @param[in] dataPtr A pointer to ACK data to transmit. - * @param[in] dataLength Number of bytes of ACK data. + * @param[in] ackData A pointer to ACK data to transmit. + * @param[in] ackDataLen Number of bytes of ACK data. * @return Status code indicating success of the function call. * * If the ACK buffer is available for updates, load the ACK buffer with data. */ RAIL_Status_t RAIL_WriteAutoAckFifo(RAIL_Handle_t railHandle, - const uint8_t *dataPtr, - uint8_t dataLength); + const uint8_t *ackData, + uint8_t ackDataLen); /** * Pauses/resumes RX auto ACK functionality. @@ -2312,19 +2479,55 @@ bool RAIL_IsAutoAckWaitingForAck(RAIL_Handle_t railHandle); /****************************************************************************** * Calibration *****************************************************************************/ -/** - * @addtogroup Calibration - * @brief APIs for calibrating the radio - * @{ - * - * These APIs can be used to calibrate the radio. The RAIL library - * determines which calibrations are necessary. Calibrations can - * be enabled/disabled with the RAIL_CalMask_t parameter. - * - * Some calibrations produce values that can be saved and reapplied to - * save repetition of the calibration process. RAIL_CalValues_t is the - * structure to communicate this value between RAIL and the application. - */ +/// @addtogroup Calibration +/// @brief APIs for calibrating the radio +/// @{ +/// +/// These APIs can be used to calibrate the radio. The RAIL library +/// determines which calibrations are necessary. Calibrations can +/// be enabled/disabled with the RAIL_CalMask_t parameter. +/// +/// Some calibrations produce values that can be saved and reapplied to +/// save repetition of the calibration process. +/// +/// Calibrations can either be run with \ref RAIL_Calibrate, or with the +/// individual chip-specific calibration routines. An example for running code +/// with \ref RAIL_Calibrate looks like: +/// +/// @code{.c} +/// static RAIL_CalValues_t calValues = RAIL_CALVALUES_UNINIT; +/// +/// void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events) { +/// // Omitting other event handlers +/// if (events & RAIL_EVENT_CAL_NEEDED) { +/// // Run all pending calibrations, and save the results +/// RAIL_Calibrate(railHandle, &calValues, RAIL_CAL_ALL_PENDING); +/// } +/// } +/// @endcode +/// +/// Alternatively, if the image rejection calibration for your chip can be +/// determined ahead of time, such as by running the calibration on a separate +/// firmware image on each chip, then the following calibration process will +/// result in smaller code. +/// +/// @code{.c} +/// static uint32_t imageRejection = IRCAL_VALUE; +/// +/// void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events) { +/// // Omitting other event handlers +/// if (events & RAIL_EVENT_CAL_NEEDED) { +/// RAIL_CalMask_t pendingCals = RAIL_GetPendingCal(railHandle); +/// // Disable the radio if we have to do an offline calibration +/// if (pendingCals & RAIL_CAL_TEMP_VC0) { +/// RAIL_CalibrateTemp(railHandle); +/// } +/// if (pendingCals & RAIL_CAL_ONETIME_IRCAL) { +/// RAIL_ApplyIrCalibration(railHandle, imageRejection); +/// } +/// } +/// } +/// @endcode /** * Initialize RAIL Calibration @@ -2344,33 +2547,40 @@ RAIL_Status_t RAIL_ConfigCal(RAIL_Handle_t railHandle, * Starts the calibration process. * * @param[in] railHandle A RAIL instance handle. - * @param[in,out] calValues Calibration values to apply. If the calibration - * value is \ref RAIL_CAL_INVALID_VALUE, that value will be updated to a - * valid value. If the calValues pointer is NULL, the specified - * calibration will still occur, but the valid calibration value will - * not be returned. + * @param[in,out] calValues A structure of calibration values to apply. + * If a valid calibration values structure is provided and the structure + * contains valid calibration values, those values will be applied to the + * hardware, and the RAIL library will cache those values for use again later. + * If a valid calibration values structure is provided and the structure + * contains a calibration value of \ref RAIL_CAL_INVALID_VALUE for the + * desired calibration, the desired calibration will run, the calibration + * values structure will be updated with a valid calibration value, and the + * RAIL library will cache that value for use again later. + * If a NULL pointer is provided, the desired calibration will run, + * and the RAIL library will cache that value for use again later; however, + * the valid calibration value will not be returned to the application. * @param[in] calForce A mask to force specific calibration(s) to execute. * To run all pending calibrations, use the value \ref RAIL_CAL_ALL_PENDING. * Only the calibrations specified will run, even if not enabled during * initialization. * @return Status code indicating success of the function call. * - * This function begins the calibration process while determining which - * calibrations should be performed. The possible list of calibration options - * is configured with the RAIL_CalMask_t parameter. - * - * If the calibration was performed previously and the application saves off - * the calibration value, it can be passed into the function and applied to the - * chip. If the calibration value provided is \ref RAIL_CAL_INVALID_VALUE, - * the calibration is performed, and the calibration output updates the - * structure passed in. If a NULL pointer is passed, all calibrations - * requested/required are performed, and the results are not returned. + * If calibrations were performed previously and the application saves the + * calibration values (i.e. call this function with a calibration values + * structure containing calibration values of \ref RAIL_CAL_INVALID_VALUE + * before a reset), the application can later bypass the time it would normally + * take to recalibrate hardware by reusing previous calibration values (i.e. + * call this function with a calibration values structure containing valid + * calibration values after a reset). * * If multiple protocols are used, this function will return * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is * not active. The caller must attempt to re-call this function later, in that * case. * + * @note Instead of this function, consider using the individual chip-specific + * functions. Using the individual functions will allow for better + * dead-stripping if not all calibrations are run. * @note Some calibrations should only be executed when the radio is IDLE. See * chip-specific documentation for more details. */ @@ -2436,13 +2646,20 @@ void RAIL_EnablePaCal(bool enable); * @note After RF energy has been sensed, the RF Sense is automatically * disabled. RAIL_StartRfSense() must be called again to reactivate it. * + * @note Packet reception is not guaranteed to work correctly once RF Sense is + * enabled. To be safe, an application should turn this on only after idling + * the radio to stop receive and turn it off before attempting to restart + * receive. Since EM4 sleep causes the chip to come up through the reset + * vector any wake from EM4 must also shut off RF Sense to ensure proper + * receive functionality. + * * @warning RF Sense functionality is only guaranteed from 0 to 85 degrees * Celsius. RF Sense should be disabled outside of this temperature range. */ -uint32_t RAIL_StartRfSense(RAIL_Handle_t railHandle, - RAIL_RfSenseBand_t band, - uint32_t senseTime, - RAIL_RfSense_CallbackPtr_t cb); +RAIL_Time_t RAIL_StartRfSense(RAIL_Handle_t railHandle, + RAIL_RfSenseBand_t band, + RAIL_Time_t senseTime, + RAIL_RfSense_CallbackPtr_t cb); /** * Checks if the RF was sensed. @@ -2477,11 +2694,11 @@ bool RAIL_IsRfSensed(RAIL_Handle_t railHandle); * receive operation has completed. It must be used in multiprotocol RAIL since * the scheduler assumes that any transmit or receive operation that is started * by you can go on infinitely based on state transitions and your protocol. - * RAIL will not allow a new transmit or scheduled receive until this is called - * and will not run lower priority tasks from other instances. You may also - * simply call the \ref RAIL_Idle() API to terminate the operation too. In - * single protocol RAIL this API does nothing but may be called to keep your - * code multiprotocol ready if desired. + * RAIL will not allow a lower priority tasks to run until this is called so it + * can negatively impact performance of those protocols if this is omitted or + * delayed. It is also possible to simply call the \ref RAIL_Idle() API to + * to both terminate the operation and idle the radio. In single protocol RAIL + * this API does nothing. * * See \ref rail_radio_scheduler_yield for more details. */ @@ -2493,8 +2710,8 @@ void RAIL_YieldRadio(RAIL_Handle_t railHandle); * @param[in] railHandle A RAIL instance handle. * @return \ref RAIL_SchedulerStatus_t status. * - * This function should be checked after the \ref RAIL_EVENT_SCHEDULER_STATUS - * event occurs. + * This function can only be called from callback context after the + * \ref RAIL_EVENT_SCHEDULER_STATUS event occurs. */ RAIL_SchedulerStatus_t RAIL_GetSchedulerStatus(RAIL_Handle_t railHandle); @@ -2571,7 +2788,7 @@ uint32_t RAIL_GetTune(RAIL_Handle_t railHandle); * * Retrieves the measured frequency offset used during the previous * received packet, which includes the current radio frequency offset - * (see \ref RAIL_SetFreqOffset()). If the chip has not been in RX, + * (see \ref RAIL_SetFreqOffset()). If the chip has not been in RX, * it returns the nominal radio frequency offset. */ RAIL_FrequencyOffset_t RAIL_GetRxFreqOffset(RAIL_Handle_t railHandle); @@ -2623,6 +2840,60 @@ RAIL_Status_t RAIL_StartTxStream(RAIL_Handle_t railHandle, */ RAIL_Status_t RAIL_StopTxStream(RAIL_Handle_t railHandle); +/** + * Configures the verification of radio memory contents. + * + * @param[in] railHandle A RAIL instance handle. + * @param[in,out] configVerify A configuration structure made available to + * RAIL in order to perform radio state verification. This structure must be + * allocated in application global read-write memory. RAIL may modify + * fields within or referenced by this structure during its operation. + * @param[in] radioConfig A ptr to a radioConfig that is to be used as a + * white list for verifying memory contents. + * @param[in] cb A callback that notifies the application of a mismatch in + * expected vs actual memory contents. A NULL parameter may be passed in + * if a callback is not provided by the application. + * @return \ref RAIL_STATUS_NO_ERROR if setup of the verification feature + * successfully occurred. + * \ref RAIL_STATUS_INVALID_PARAMETER is returned if the provided railHandle + * or configVerify structures are invalid. + */ +RAIL_Status_t RAIL_ConfigVerification(RAIL_Handle_t railHandle, + RAIL_VerifyConfig_t *configVerify, + const uint32_t *radioConfig, + RAIL_VerifyCallbackPtr_t cb); + +/** + * Verifies radio memory contents. + * + * @param[in,out] configVerify A configuration structure made available to + * RAIL in order to perform radio state verification. This structure must be + * allocated in application global read-write memory. RAIL may modify + * fields within or referenced by this structure during its operation. + * @param[in] durationUs The duration (in microseconds) for how long memory + * verification should occur before returning to the application. A value of + * RAIL_VERIFY_DURATION_MAX indicates that all memory contents should be + * verified before returning to the application. + * @param[in] restart This flag only has meaning if a previous call of this + * function returned \ref RAIL_STATUS_SUSPENDED. By restarting (true), the + * verification process starts over from the beginning, or by resuming + * where verification left off after being suspended (false), verification + * can proceed towards completion. + * @return \ref RAIL_STATUS_NO_ERROR if the contents of all applicable + * memory locations have been verified. + * \ref RAIL_STATUS_SUSPENDED is returned if the provided test duration + * expired but the time was not sufficient to verify all memory contents. + * By calling \ref RAIL_Verify again, further verification will commence. + * \ref RAIL_STATUS_INVALID_PARAMETER is returned if the provided + * verifyConfig structure pointer is not configured for use by the active + * RAIL handle. + * \ref RAIL_STATUS_INVALID_STATE is returned if any of the verified + * memory contents are different from their reference values. + */ +RAIL_Status_t RAIL_Verify(RAIL_VerifyConfig_t *configVerify, + uint32_t durationUs, + bool restart); + /** @} */ // end of group Diagnostic #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -2700,10 +2971,15 @@ RAIL_Status_t RAIL_OverrideDebugFrequency(RAIL_Handle_t railHandle, * the RAIL error that is indicated by the failing assertion. * @return void. */ -void RAILCb_AssertFailed(RAIL_Handle_t railHandle, uint32_t errorCode); +void RAILCb_AssertFailed(RAIL_Handle_t railHandle, + RAIL_AssertErrorCodes_t errorCode); /** @} */ // end of group Assertions /** @} */ // end of group RAIL_API +#ifdef __cplusplus +} +#endif + #endif // __RAIL_H__ diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_assert_error_codes.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_assert_error_codes.h old mode 100644 new mode 100755 index f286c7447c..609ec53e9a --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_assert_error_codes.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_assert_error_codes.h @@ -1,11 +1,12 @@ /***************************************************************************//** * @file rail_assert_error_codes.h * @brief Definition of error codes that occur in rail for use in - RAILCb_AssertFailed. This file is purely informational and optional - - it need not be included even if rail_assert libraries are included. - - * @copyright Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com + * RAILCb_AssertFailed. This file is purely informational and optional - + * it need not be included even if rail_assert libraries are included. + * @copyright Copyright 2017 Silicon Laboratories, Inc. www.silabs.com ******************************************************************************/ +#ifndef __RAIL_ASSERT_ERROR_CODES_H__ +#define __RAIL_ASSERT_ERROR_CODES_H__ #include "rail_types.h" @@ -14,132 +15,132 @@ * @{ */ -#ifndef _RAIL_ASSERT_ERROR_CODES_ - -#define _RAIL_ASSERT_ERROR_CODES_ - /** * Enumeration of all possible error codes from RAIL_ASSERT */ -RAIL_ENUM(RAIL_AssertErrorCodes_t) +RAIL_ENUM_GENERIC(RAIL_AssertErrorCodes_t, uint32_t) { - RAIL_ASSERT_FAILED_APPENDED_INFO_MISSING, - RAIL_ASSERT_FAILED_RX_FIFO_BYTES, - RAIL_ASSERT_FAILED_RX_FIFO_ZERO_BYTES_READ, - RAIL_ASSERT_FAILED_ILLEGAL_RXLEN_ENTRY_STATUS, - RAIL_ASSERT_FAILED_BAD_PACKET_LENGTH, - RAIL_ASSERT_FAILED_SYNTH_DIVCTRL_ENUM_CONVERSION_ERROR, //5 - RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RX_FIFO, - RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RXLEN_FIFO, - RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TX_FIFO, - RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TXACK_FIFO, - RAIL_ASSERT_FAILED_PBUFFER_NOT_DEFINED, //10 - RAIL_ASSERT_FAILED_INSUFFICIENT_BYTES_IN_RX_PACKET, - RAIL_ASSERT_FAILED_CLOCK_PRESCALER, - RAIL_ASSERT_FAILED_RTCC_POST_WAKEUP, - RAIL_ASSERT_FAILED_SYNTH_VCO_FREQUENCY, - RAIL_ASSERT_FAILED_RAC_STATE, //15 - RAIL_ASSERT_FAILED_RETIME_LIMIT, - RAIL_ASSERT_FAILED_NESTED_SEQUENCER_LOCK, - RAIL_ASSERT_FAILED_RSSI_AVERAGE_DONE, - RAIL_ASSERT_FAILED_DFL_BITS_SIZE, - RAIL_ASSERT_FAILED_PROTIMER_RANDOM_SEED, //20 - RAIL_ASSERT_FAILED_EFR32XG1_REGISTER_SIZE, - RAIL_ASSERT_FAILED_PROTIMER_CHANNEL, - RAIL_ASSERT_FAILED_TIMER_REQUIRES_WRAP, - RAIL_ASSERT_FAILED_BASECNTTOP, - RAIL_ASSERT_FAILED_DEPRECATED_LBTRETRY, //25 - RAIL_ASSERT_FAILED_RTCC_SYNC_MISSED, - RAIL_ASSERT_FAILED_CLOCK_SOURCE_NOT_READY, - RAIL_ASSERT_FAILED_TIMINGS_INVALID, - RAIL_ASSERT_NULL_HANDLE, - RAIL_ASSERT_FAILED_TMRDRV_SCHED_TIMER_NOT_RUNNING, //30 - RAIL_ASSERT_FAILED_NO_ACTIVE_CONFIG, - RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SWITCH, - RAIL_ASSERT_FAILED_RFINIT, - RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SCHEDRX, - RAIL_ASSERT_FAILED_INVALID_HANDLE_SCHEDTX, //35 - RAIL_ASSERT_FAILED_INACTIVE_HANDLE_SCHEDTX, - RAIL_ASSERT_FAILED_CONFIG_INDEX_INVALID, - RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SINGLEPROTOCOL, - RAIL_ASSERT_DEPRECATED_FUNCTION, - RAIL_ASSERT_MULTIPROTOCOL_NO_EVENT, //40 - RAIL_ASSERT_FAILED_INVALID_INTERRUPT_ENABLED, - RAIL_ASSERT_CONVERSION_CURVES_NOT_INITIALIZED, + RAIL_ASSERT_FAILED_APPENDED_INFO_MISSING = 0, + RAIL_ASSERT_FAILED_RX_FIFO_BYTES = 1, + RAIL_ASSERT_FAILED_RX_FIFO_ZERO_BYTES_READ = 2, + RAIL_ASSERT_FAILED_ILLEGAL_RXLEN_ENTRY_STATUS = 3, + RAIL_ASSERT_FAILED_BAD_PACKET_LENGTH = 4, + RAIL_ASSERT_FAILED_SYNTH_DIVCTRL_ENUM_CONVERSION_ERROR = 5, + RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RX_FIFO = 6, + RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RXLEN_FIFO = 7, + RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TX_FIFO = 8, + RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TXACK_FIFO = 9, + RAIL_ASSERT_FAILED_PBUFFER_NOT_DEFINED = 10, + RAIL_ASSERT_FAILED_INSUFFICIENT_BYTES_IN_RX_PACKET = 11, + RAIL_ASSERT_FAILED_CLOCK_PRESCALER = 12, + RAIL_ASSERT_FAILED_RTCC_POST_WAKEUP = 13, + RAIL_ASSERT_FAILED_SYNTH_VCO_FREQUENCY = 14, + RAIL_ASSERT_FAILED_RAC_STATE = 15, + RAIL_ASSERT_FAILED_RETIME_LIMIT = 16, + RAIL_ASSERT_FAILED_NESTED_SEQUENCER_LOCK = 17, + RAIL_ASSERT_FAILED_RSSI_AVERAGE_DONE = 18, + RAIL_ASSERT_FAILED_DFL_BITS_SIZE = 19, + RAIL_ASSERT_FAILED_PROTIMER_RANDOM_SEED = 20, + RAIL_ASSERT_FAILED_EFR32XG1_REGISTER_SIZE = 21, + RAIL_ASSERT_FAILED_PROTIMER_CHANNEL = 22, + RAIL_ASSERT_FAILED_TIMER_REQUIRES_WRAP = 23, + RAIL_ASSERT_FAILED_BASECNTTOP = 24, + RAIL_ASSERT_FAILED_DEPRECATED_LBTRETRY = 25, + RAIL_ASSERT_FAILED_RTCC_SYNC_MISSED = 26, + RAIL_ASSERT_FAILED_CLOCK_SOURCE_NOT_READY = 27, + RAIL_ASSERT_FAILED_TIMINGS_INVALID = 28, + RAIL_ASSERT_NULL_HANDLE = 29, + RAIL_ASSERT_FAILED_SCHED_TIMER_NOT_RUNNING = 30, + RAIL_ASSERT_FAILED_NO_ACTIVE_CONFIG = 31, + RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SWITCH = 32, + RAIL_ASSERT_FAILED_RFINIT = 33, + RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SCHEDRX = 34, + RAIL_ASSERT_FAILED_INVALID_HANDLE_SCHEDTX = 35, + RAIL_ASSERT_FAILED_INACTIVE_HANDLE_SCHEDTX = 36, + RAIL_ASSERT_FAILED_CONFIG_INDEX_INVALID = 37, + RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SINGLEPROTOCOL = 38, + RAIL_ASSERT_DEPRECATED_FUNCTION = 39, + RAIL_ASSERT_MULTIPROTOCOL_NO_EVENT = 40, + RAIL_ASSERT_FAILED_INVALID_INTERRUPT_ENABLED = 41, + RAIL_ASSERT_CONVERSION_CURVES_NOT_INITIALIZED = 42, + RAIL_ASSERT_DIVISION_BY_ZERO = 43, + RAIL_ASSERT_CANT_USE_HARDWARE = 44, }; -/** - * Use this define to create an array of error messages that map to the codes - * in \ref RAIL_AssertErrorCodes_t. You can use these to print slightly more - * detailed error strings related to a particular assert error code if desired. - * For example, you could implement your assert failed callback as follows to - * make use of this. - * - * @code{.c} - * void RAILCb_AssertFailed(RAIL_Handle_t railHandle, uint32_t errorCode) - * { - * static const char* railErrorMessages[] = RAIL_ASSERT_ERROR_MESSAGES; - * const char *errorMessage = "Unknown"; - * - * // If this error code is within the range of known error messages then use - * // the appropriate error message. - * if (errorCode < (sizeof(railErrorMessages) / sizeof(char*))) { - * errorMessage = railErrorMessages[errorCode]; - * } - * printf(errorMessage); - * - * // Reset the chip since an assert is a fatal error - * NVIC_SystemReset(); - * } - * @endcode - */ -#define RAIL_ASSERT_ERROR_MESSAGES { \ - "Appended info missing from Rx packet", \ - "Payload bytes missing from Rx packet", \ - "Error reading back packet payload", \ - "Receive fifo entry has invalid status", \ - "Receive fifo entry bad packet length", \ - "Unable to configure radio for IR calibration", \ - "Reached unexpected state while handling Rx fifo events", \ - "Reached unexpected state while handling RXLEN fifo events", \ - "Reached unexpected state while handling Tx fifo events", \ - "Reached unexpected state while handling Tx ACK fifo events", \ - "No memory to store receive packet", \ - "Packet length longer than the receive FIFO size", \ - "Invalid radio clock prescaler", \ - "Error synchronizing the RAIL timebase after sleep", \ - "VCO frequency outside supported range", \ - "Radio active while changing channels", \ - "Unable to configure DCDC retiming", \ - "Nested attempt to lock the sequencer", \ - "RSSI averaging enabled without a valid callback", \ - "Invalid dynamic frame length setting provided (dflBits)", \ - "Unable to seed radio pseudo random number generator", \ - "Timeout exceeds EFR32XG1 register size", \ - "Invalid timer channel specified", \ - "Timer value larger than RAIL timebase", \ - "LBT config exceeds EFR32XG1 register size", \ - "Deprecated CSMA/LBT retry callback unexpectedly called", \ - "Could not synchronize RAIL timebase with the RTC", \ - "Clock source not ready", \ - "Attempted to set RAIL timings to invalid value", \ - "NULL was supplied as a RAIL_Handle_t argument", \ - "Scheduled timer not running", \ - "No active config to switch from", \ - "No active handle after switch", \ - "RfInit failed to configure active state", \ - "No active handle for scheduled rx", \ - "Invalid handle for scheduled tx", \ - "Inactive handle for scheduled tx", \ - "Invalid config index to switch to", \ - "No active handle for single protocol", \ - "This function is deprecated and must not be called", \ - "Multiprotocol task started with no event to run", \ - "Invalid interrupt enabled", \ - "Power conversion functions called before curves were initialized", \ +/// Use this define to create an array of error messages that map to the codes +/// in \ref RAIL_AssertErrorCodes_t. You can use these to print slightly more +/// detailed error strings related to a particular assert error code if desired. +/// For example, you could implement your assert failed callback as follows to +/// make use of this. +/// +/// @code{.c} +/// void RAILCb_AssertFailed(RAIL_Handle_t railHandle, uint32_t errorCode) +/// { +/// static const char* railErrorMessages[] = RAIL_ASSERT_ERROR_MESSAGES; +/// const char *errorMessage = "Unknown"; +/// +/// // If this error code is within the range of known error messages then use +/// // the appropriate error message. +/// if (errorCode < (sizeof(railErrorMessages) / sizeof(char*))) { +/// errorMessage = railErrorMessages[errorCode]; +/// } +/// printf(errorMessage); +/// +/// // Reset the chip since an assert is a fatal error +/// NVIC_SystemReset(); +/// } +/// @endcode +/// +#define RAIL_ASSERT_ERROR_MESSAGES { \ + /* 0*/ "Appended info missing from Rx packet", \ + /* 1*/ "Payload bytes missing from Rx packet", \ + /* 2*/ "Error reading back packet payload", \ + /* 3*/ "Receive fifo entry has invalid status", \ + /* 4*/ "Receive fifo entry bad packet length", \ + /* 5*/ "Unable to configure radio for IR calibration", \ + /* 6*/ "Reached unexpected state while handling Rx fifo events", \ + /* 7*/ "Reached unexpected state while handling RXLEN fifo events", \ + /* 8*/ "Reached unexpected state while handling Tx fifo events", \ + /* 9*/ "Reached unexpected state while handling Tx ACK fifo events", \ + /*10*/ "No memory to store receive packet", \ + /*11*/ "Packet length longer than the receive FIFO size", \ + /*12*/ "Invalid radio clock prescaler", \ + /*13*/ "Error synchronizing the RAIL timebase after sleep", \ + /*14*/ "VCO frequency outside supported range", \ + /*15*/ "Radio active while changing channels", \ + /*16*/ "Unable to configure DCDC retiming", \ + /*17*/ "Nested attempt to lock the sequencer", \ + /*18*/ "RSSI averaging enabled without a valid callback", \ + /*19*/ "Invalid dynamic frame length setting provided (dflBits)", \ + /*20*/ "Unable to seed radio pseudo random number generator", \ + /*21*/ "Timeout exceeds EFR32XG1 register size", \ + /*22*/ "Invalid timer channel specified", \ + /*23*/ "Timer value larger than RAIL timebase", \ + /*24*/ "LBT config exceeds EFR32XG1 register size", \ + /*25*/ "Deprecated CSMA/LBT retry callback unexpectedly called", \ + /*26*/ "Could not synchronize RAIL timebase with the RTC", \ + /*27*/ "Clock source not ready", \ + /*28*/ "Attempted to set RAIL timings to invalid value", \ + /*29*/ "NULL was supplied as a RAIL_Handle_t argument", \ + /*30*/ "Scheduled timer not running", \ + /*31*/ "No active config to switch from", \ + /*32*/ "No active handle after switch", \ + /*33*/ "RfInit failed to configure active state", \ + /*34*/ "No active handle for scheduled rx", \ + /*35*/ "Invalid handle for scheduled tx", \ + /*36*/ "Inactive handle for scheduled tx", \ + /*37*/ "Invalid config index to switch to", \ + /*38*/ "No active handle for single protocol", \ + /*39*/ "This function is deprecated and must not be called", \ + /*40*/ "Multiprotocol task started with no event to run", \ + /*41*/ "Invalid interrupt enabled", \ + /*42*/ "Power conversion functions called before curves were initialized", \ + /*43*/ "Division by zero", \ + /*44*/ "Function cannot be called without access to the hardware", \ } -#endif /** * @} */ + +#endif // __RAIL_ASSERT_ERROR_CODES_H__ diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_chip_specific.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_chip_specific.h old mode 100644 new mode 100755 index 2c6eacf903..ad06ceebb6 --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_chip_specific.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_chip_specific.h @@ -2,7 +2,7 @@ * @file rail_chip_specific.h * @brief This file contains the type definitions for EFR32 chip specific * aspects of RAIL. - * @copyright Copyright 2015 Silicon Laboratories, Inc. http://www.silabs.com + * @copyright Copyright 2015 Silicon Laboratories, Inc. www.silabs.com ******************************************************************************/ #ifndef __RAIL_CHIP_SPECIFIC_H_ @@ -17,6 +17,10 @@ #include "rail_types.h" +#ifdef __cplusplus +extern "C" { +#endif + // ----------------------------------------------------------------------------- // Multiprotocol // ----------------------------------------------------------------------------- @@ -62,9 +66,9 @@ */ /** EFR32 specific temperature calibration bit */ -#define RAIL_CAL_TEMP_VCO (0x00000001) +#define RAIL_CAL_TEMP_VCO (0x00000001U) /** EFR32 specific IR calibration bit */ -#define RAIL_CAL_ONETIME_IRCAL (0x00010000) +#define RAIL_CAL_ONETIME_IRCAL (0x00010000U) /** Mask to run temperature dependent calibrations */ #define RAIL_CAL_TEMP (RAIL_CAL_TEMP_VCO) @@ -77,9 +81,74 @@ /** Mask to run all possible calibrations for this chip */ #define RAIL_CAL_ALL (RAIL_CAL_TEMP | RAIL_CAL_ONETIME) /** Mask to run all pending calibrations */ -#define RAIL_CAL_ALL_PENDING (0x00000000) +#define RAIL_CAL_ALL_PENDING (0x00000000U) /** Invalid calibration value */ -#define RAIL_CAL_INVALID_VALUE (0xFFFFFFFF) +#define RAIL_CAL_INVALID_VALUE (0xFFFFFFFFU) + +/** + * Applies a given image rejection calibration value. + * + * @param[in] railHandle A RAIL instance handle. + * @param[in] imageRejection The image rejection value to apply. + * @return Status code indicating success of the function call. + * + * Take an image rejection calibration value and apply it. This value should be + * determined from a previous run of \ref RAIL_CalibrateIr on the same + * physical device with the same radio configuration. The imageRejection value + * will also be stored to the \ref RAIL_ChannelConfigEntry_t::attr, if possible. + * + * If multiple protocols are used, this function will return + * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is + * not active. The caller must attempt to re-call this function later, in that + * case. + */ +RAIL_Status_t RAIL_ApplyIrCalibration(RAIL_Handle_t railHandle, + uint32_t imageRejection); + +/** + * Run the image rejection calibration + * + * @param[in] railHandle A RAIL instance handle. + * @param[out] imageRejection The result of the image rejection calibration. + * @return Status code indicating success of the function call. + * + * Run the image rejection calibration, and apply the resulting value. If the + * imageRejection parameter is non-NULL, then also store the value at that + * location. The imageRejection value will also be stored to the + * \ref RAIL_ChannelConfigEntry_t::attr, if possible. This is a long-running + * calibration that adds significant code space when run, and can be run with a + * separate firmware image on each device in order to save code space in the + * final image. + * + * If multiple protocols are used, this function will return + * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is + * not active. The caller must attempt to re-call this function later, in that + * case. + */ +RAIL_Status_t RAIL_CalibrateIr(RAIL_Handle_t railHandle, + uint32_t *imageRejection); + +/** + * Run the temperature calibration + * + * @param[in] railHandle A RAIL instance handle. + * @return Status code indicating success of the function call. + * + * Run the temperature calibration, which needs to recalibrate the synth if + * the temperature crosses 0C or the temperature delta since the last + * calibration exceeds 70C while sitting in receive. RAIL will run VCO + * calibration automatically upon entering receive state so the application can + * omit this calibration if the stack will re-enter receive with enough + * frequency to not hit this temperature delta. If the application does not + * calibrate for temperature, it's possible to miss receive packets due to + * drift in the carrier frequency. + * + * If multiple protocols are used, this function will return + * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is + * not active. In that case the calibration will be automatically performed the + * next time the radio enters receive. + */ +RAIL_Status_t RAIL_CalibrateTemp(RAIL_Handle_t railHandle); /** * @struct RAIL_CalValues_t @@ -311,4 +380,48 @@ typedef struct RAIL_PtiConfig { /** @} */ // end of group PTI_EFR32 +// ----------------------------------------------------------------------------- +// Antenna Control +// ----------------------------------------------------------------------------- +/** + * @addtogroup Antenna_Control_EFR32 EFR32 + * @{ + * @brief EFR32 Antenna Control functionality + * @ingroup Antenna + * + * These enums and structures are used with RAIL Antenna Control API. EFR32 supports + * up to two antennas and with configurable pin locations. + */ + +/** + * @struct RAIL_AntennaConfig_t + * @brief Configuration for Antenna switch pins. + */ +typedef struct RAIL_AntennaConfig { + /** MODEM_ROUTEPEN fields */ + /** Antenna 0 Pin Enable */ + bool ant0PinEn; + /** Antenna 1 Pin Enable */ + bool ant1PinEn; + /** MODEM_ROUTELOC1 fields */ + /** Antenna 0 location for pin/port */ + uint8_t ant0Loc; + /** Antenna 0 output GPIO port */ + GPIO_Port_TypeDef ant0Port; + /** Antenna 0 output GPIO pin */ + uint8_t ant0Pin; + /** Antenna 1 location for pin/port */ + uint8_t ant1Loc; + /** Antenna 1 output GPIO port */ + GPIO_Port_TypeDef ant1Port; + /** Antenna 1 output GPIO pin */ + uint8_t ant1Pin; +} RAIL_AntennaConfig_t; + +/** @} */ // end of group Antenna_Control_EFR32 + +#ifdef __cplusplus +} +#endif + #endif diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_types.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_types.h old mode 100644 new mode 100755 index 692070c3d4..d9958b758e --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_types.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_types.h @@ -2,7 +2,7 @@ * @file rail_types.h * @brief This file contains the type definitions for RAIL structures, enums, * and other types. - * @copyright Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com + * @copyright Copyright 2017 Silicon Laboratories, Inc. www.silabs.com *****************************************************************************/ #ifndef __RAIL_TYPES_H__ @@ -13,6 +13,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + #ifdef DOXYGEN_SHOULD_SKIP_THIS /// The RAIL library does not use enums because the ARM EABI leaves their /// size ambiguous. This ambiguity causes problems if the application is built @@ -47,6 +51,12 @@ * @{ */ +/** + * @typedef RAIL_Time_t + * @brief Time in microseconds + */ +typedef uint32_t RAIL_Time_t; + /** * @def RAIL_SCHEDULER_STATE_UINT32_BUFFER_SIZE * @brief The size in 32-bit words of RAIL_SchedulerStateBuffer_t to store @@ -98,7 +108,7 @@ typedef struct RAIL_SchedulerInfo { * the current time for relative transmits. If we cannot start by this time * the operation will be considered a failure. */ - uint32_t slipTime; + RAIL_Time_t slipTime; /** * The transaction time in us for this operation. Since transaction times may * not be known exactly you will likely want to use a minimum or expected @@ -106,7 +116,7 @@ typedef struct RAIL_SchedulerInfo { * for overlaps between low priority and high priority tasks and attempt to * find a schedule where all tasks get to run. */ - uint32_t transactionTime; + RAIL_Time_t transactionTime; } RAIL_SchedulerInfo_t; /** @@ -164,8 +174,8 @@ RAIL_ENUM(RAIL_SchedulerStatus_t) { RAIL_SCHEDULER_STATUS_TX_STREAM_FAIL, /** * RSSI averaging failed. If this scheduler status occurs - * RAIL_GetAverageRssi will return \ref RAIL_RSSI_INVALID until - * a RAIL_StartAverageRssi completes successfully. + * RAIL_GetAverageRssi() will return \ref RAIL_RSSI_INVALID until + * a RAIL_StartAverageRssi() completes successfully. */ RAIL_SCHEDULER_STATUS_AVERAGE_RSSI_FAIL, /** @@ -191,9 +201,6 @@ RAIL_ENUM(RAIL_SchedulerStatus_t) { * indicated due to interrupt latency. */ RAIL_ENUM_GENERIC(RAIL_Events_t, uint64_t) { - /** Value representing no events */ - RAIL_EVENTS_NONE = 0, - // RX Event Bit Shifts /** Shift position of \ref RAIL_EVENT_RSSI_AVERAGE_DONE bit */ @@ -204,6 +211,8 @@ RAIL_ENUM_GENERIC(RAIL_Events_t, uint64_t) { RAIL_EVENT_RX_FIFO_ALMOST_FULL_SHIFT, /** Shift position of \ref RAIL_EVENT_RX_PACKET_RECEIVED bit */ RAIL_EVENT_RX_PACKET_RECEIVED_SHIFT, + /** Shift position of \ref RAIL_EVENT_RX_PREAMBLE_LOST bit */ + RAIL_EVENT_RX_PREAMBLE_LOST_SHIFT, /** Shift position of \ref RAIL_EVENT_RX_PREAMBLE_DETECT bit */ RAIL_EVENT_RX_PREAMBLE_DETECT_SHIFT, /** Shift position of \ref RAIL_EVENT_RX_SYNC1_DETECT bit */ @@ -273,192 +282,357 @@ RAIL_ENUM_GENERIC(RAIL_Events_t, uint64_t) { /** Shift position of \ref RAIL_EVENT_CAL_NEEDED bit */ RAIL_EVENT_CAL_NEEDED_SHIFT, - - // RX Event Bitmasks - - /** - * Occurs when the AGC averaged RSSI is done. - * It occurs in response to RAIL_StartAverageRssi() to indicate that the - * hardware has completed averaging. Call \ref RAIL_GetAverageRssi to get the - * result. - */ - RAIL_EVENT_RSSI_AVERAGE_DONE - = (1ull << RAIL_EVENT_RSSI_AVERAGE_DONE_SHIFT), - /** - * Notifies the application when searching for an ACK has timed - * out. This event occurs whenever the timeout for searching for an - * ACK is exceeded. - */ - RAIL_EVENT_RX_ACK_TIMEOUT - = (1ull << RAIL_EVENT_RX_ACK_TIMEOUT_SHIFT), - /** - * Occurs when the receive FIFO exceeds the configured threshold - * value. Call \ref RAIL_GetRxFifoBytesAvailable to get the number of bytes - * available. - */ - RAIL_EVENT_RX_FIFO_ALMOST_FULL - = (1ull << RAIL_EVENT_RX_FIFO_ALMOST_FULL_SHIFT), - /** - * Occurs whenever a packet is received. - * Call RAIL_GetRxPacketInfo() to get basic packet information along - * with a handle to this packet for subsequent use with - * RAIL_PeekRxPacket(), RAIL_GetRxPacketDetails(), - * RAIL_HoldRxPacket(), and RAIL_ReleaseRxPacket() as needed. - * - * If \ref RAIL_RX_OPTION_IGNORE_CRC_ERRORS is set, this event also occurs - * for packets with CRC errors. - */ - RAIL_EVENT_RX_PACKET_RECEIVED - = (1ull << RAIL_EVENT_RX_PACKET_RECEIVED_SHIFT), - /** Event for preamble detection */ - RAIL_EVENT_RX_PREAMBLE_DETECT - = (1ull << RAIL_EVENT_RX_PREAMBLE_DETECT_SHIFT), - /** Event for detection of the first sync word */ - RAIL_EVENT_RX_SYNC1_DETECT - = (1ull << RAIL_EVENT_RX_SYNC1_DETECT_SHIFT), - /** Event for detection of the second sync word */ - RAIL_EVENT_RX_SYNC2_DETECT - = (1ull << RAIL_EVENT_RX_SYNC2_DETECT_SHIFT), - /** Event for detection of frame errors - * - * For efr32xg1x parts, frame errors include violations of variable length - * minimum/maximum limits, frame coding errors, and CRC errors. If \ref - * RAIL_RX_OPTION_IGNORE_CRC_ERRORS is set, \ref RAIL_EVENT_RX_FRAME_ERROR - * will not occur for CRC errors. - */ - RAIL_EVENT_RX_FRAME_ERROR - = (1ull << RAIL_EVENT_RX_FRAME_ERROR_SHIFT), - /** Occurs when RX buffer is full */ - RAIL_EVENT_RX_FIFO_OVERFLOW - = (1ull << RAIL_EVENT_RX_FIFO_OVERFLOW_SHIFT), - /** Occurs when a packet is address filtered */ - RAIL_EVENT_RX_ADDRESS_FILTERED - = (1ull << RAIL_EVENT_RX_ADDRESS_FILTERED_SHIFT), - /** Occurs when an RX event times out */ - RAIL_EVENT_RX_TIMEOUT - = (1ull << RAIL_EVENT_RX_TIMEOUT_SHIFT), - /** Occurs when the scheduled RX window ends */ - RAIL_EVENT_RX_SCHEDULED_RX_END - = (1ull << RAIL_EVENT_RX_SCHEDULED_RX_END_SHIFT), - /** An event for an aborted packet. It is triggered when a more specific - * reason isn't known for why the packet was aborted (e.g. - * \ref RAIL_EVENT_RX_ADDRESS_FILTERED). */ - RAIL_EVENT_RX_PACKET_ABORTED - = (1ull << RAIL_EVENT_RX_PACKET_ABORTED_SHIFT), - /** - * Occurs when the packet has passed any configured address and frame - * filtering options. - */ - RAIL_EVENT_RX_FILTER_PASSED - = (1ull << RAIL_EVENT_RX_FILTER_PASSED_SHIFT), - /** Occurs when modem timing is lost */ - RAIL_EVENT_RX_TIMING_LOST - = (1ull << RAIL_EVENT_RX_TIMING_LOST_SHIFT), - /** Occurs when modem timing is detected */ - RAIL_EVENT_RX_TIMING_DETECT - = (1ull << RAIL_EVENT_RX_TIMING_DETECT_SHIFT), - /** - * Indicates a Data Request is being received when using IEEE 802.15.4 - * functionality. This occurs when the command byte of an incoming frame is - * for a data request, which requests an ACK. This callback is called before - * the packet is fully received to allow the node to have more time to decide - * whether to set the frame pending in the outgoing ACK. This event only ever - * occurs if the RAIL IEEE 802.15.4 functionality is enabled. - * - * Call \ref RAIL_IEEE802154_GetAddress to get the source address of the - * packet. - */ - RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND - = (1ull << RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND_SHIFT), - - // TX Event Bitmasks - - /** - * Occurs when the transmit FIFO falls under the configured - * threshold value. It only occurs if a rising edge occurs across this - * threshold. This event does not occur on initailization or after resetting - * the transmit FIFO with RAIL_ResetFifo(). - * Call \ref RAIL_GetTxFifoSpaceAvailable to get the number of bytes - * available in the transmit FIFO at the time of the callback dispatch. - */ - RAIL_EVENT_TX_FIFO_ALMOST_EMPTY - = (1ull << RAIL_EVENT_TX_FIFO_ALMOST_EMPTY_SHIFT), - /** - * Interrupt level event to signify when the packet was sent. - * Call RAIL_GetTxPacketDetails() to get information about the packet - * that was transmitted. - * @note that this structure is only valid during the timeframe of the - * \ref RAIL_Config_t::eventsCallback. - */ - RAIL_EVENT_TX_PACKET_SENT - = (1ull << RAIL_EVENT_TX_PACKET_SENT_SHIFT), - /** - * An interrupt level event to signify when the packet was sent. - * Call RAIL_GetTxPacketDetails() to get information about the packet - * that was transmitted. - * @note This structure is only valid during the timeframe of the - * \ref RAIL_Config_t::eventsCallback. - */ - RAIL_EVENT_TXACK_PACKET_SENT - = (1ull << RAIL_EVENT_TXACK_PACKET_SENT_SHIFT), - /** Occurs when a TX is aborted by the user */ - RAIL_EVENT_TX_ABORTED - = (1ull << RAIL_EVENT_TX_ABORTED_SHIFT), - /** Occurs when a TX ACK is aborted by the user */ - RAIL_EVENT_TXACK_ABORTED - = (1ull << RAIL_EVENT_TXACK_ABORTED_SHIFT), - /** Occurs when a TX is blocked by something like PTA or RHO */ - RAIL_EVENT_TX_BLOCKED - = (1ull << RAIL_EVENT_TX_BLOCKED_SHIFT), - /** Occurs when a TX ACK is blocked by something like PTA or RHO */ - RAIL_EVENT_TXACK_BLOCKED - = (1ull << RAIL_EVENT_TXACK_BLOCKED_SHIFT), - /** Occurs when the TX buffer underflows */ - RAIL_EVENT_TX_UNDERFLOW - = (1ull << RAIL_EVENT_TX_UNDERFLOW_SHIFT), - /** Occurs when the buffer used for TX acking underflows */ - RAIL_EVENT_TXACK_UNDERFLOW - = (1ull << RAIL_EVENT_TXACK_UNDERFLOW_SHIFT), - /** Occurs when CCA/CSMA/LBT succeeds */ - RAIL_EVENT_TX_CHANNEL_CLEAR - = (1ull << RAIL_EVENT_TX_CHANNEL_CLEAR_SHIFT), - /** Occurs when CCA/CSMA/LBT fails */ - RAIL_EVENT_TX_CHANNEL_BUSY - = (1ull << RAIL_EVENT_TX_CHANNEL_BUSY_SHIFT), - /** Occurs when a CCA check is being retried */ - RAIL_EVENT_TX_CCA_RETRY - = (1ull << RAIL_EVENT_TX_CCA_RETRY_SHIFT), - /** Occurs when a clear channel assessment (CCA) is begun */ - RAIL_EVENT_TX_START_CCA - = (1ull << RAIL_EVENT_TX_START_CCA_SHIFT), - - // Scheduler Event Bitmasks - - /** Event for when the scheduler switches away from this configuration */ - RAIL_EVENT_CONFIG_UNSCHEDULED - = (1ull << RAIL_EVENT_CONFIG_UNSCHEDULED_SHIFT), - /** Event for when the scheduler switches to this configuration */ - RAIL_EVENT_CONFIG_SCHEDULED - = (1ull << RAIL_EVENT_CONFIG_SCHEDULED_SHIFT), - /** Event for when the status of the scheduler changes */ - RAIL_EVENT_SCHEDULER_STATUS - = (1ull << RAIL_EVENT_SCHEDULER_STATUS_SHIFT), - - // Other Event Bitmasks - - /** - * Notifies the application that a calibration is needed. - * It occurs whenever the RAIL library detects that a - * calibration is needed. An application determines a valid - * window to call \ref RAIL_Calibrate(). - */ - RAIL_EVENT_CAL_NEEDED - = (1ull << RAIL_EVENT_CAL_NEEDED_SHIFT), - - /** Value representing all possible events */ - RAIL_EVENTS_ALL = 0xFFFFFFFFFFFFFFFFULL }; +// RAIL_Event_t bitmasks + +/** Value representing no events */ +#define RAIL_EVENTS_NONE 0ULL + +/** + * Occurs when the hardware-averaged RSSI is done. It only occurs in response to + * RAIL_StartAverageRssi() to indicate that the hardware has completed + * averaging. Call RAIL_GetAverageRssi() to get the result. + */ +#define RAIL_EVENT_RSSI_AVERAGE_DONE (1ULL << RAIL_EVENT_RSSI_AVERAGE_DONE_SHIFT) + +/** + * Notifies the application when searching for an ack packet has timed out. + * This event occurs whenever the timeout for searching for an ack packet is + * exceeded. This will only occur after calling RAIL_ConfigAutoAck() and + * transmitting a packet. + */ +#define RAIL_EVENT_RX_ACK_TIMEOUT (1ULL << RAIL_EVENT_RX_ACK_TIMEOUT_SHIFT) + +/** + * Occurs when the receive FIFO exceeds the configured threshold value. Call + * RAIL_GetRxFifoBytesAvailable() to get the number of bytes available. When + * using this event, the threshold should be set via RAIL_SetRxFifoThreshold(). + */ +#define RAIL_EVENT_RX_FIFO_ALMOST_FULL (1ULL << RAIL_EVENT_RX_FIFO_ALMOST_FULL_SHIFT) + +/** + * Occurs whenever a packet is received. Call RAIL_GetRxPacketInfo() to get + * basic packet information along with a handle to this packet for subsequent + * use with RAIL_PeekRxPacket(), RAIL_GetRxPacketDetails(), RAIL_HoldRxPacket(), + * and RAIL_ReleaseRxPacket() as needed. + * + * If \ref RAIL_RX_OPTION_IGNORE_CRC_ERRORS is set, this event also occurs + * for packets with CRC errors. + */ +#define RAIL_EVENT_RX_PACKET_RECEIVED (1ULL << RAIL_EVENT_RX_PACKET_RECEIVED_SHIFT) + +/** + * Occurs when the radio has lost a preamble. This event can occur multiple + * times while searching for a packet, and is generally used for diagnostic + * purposes. This event can only occur after a + * \ref RAIL_EVENT_RX_PREAMBLE_DETECT event has already occurred. + */ +#define RAIL_EVENT_RX_PREAMBLE_LOST (1ULL << RAIL_EVENT_RX_PREAMBLE_LOST_SHIFT) + +/** + * Occurs when the radio has detected a preamble. This event can occur multiple + * times while searching for a packet, and is generally used for diagnostic + * purposes. This event can only occur after a \ref RAIL_EVENT_RX_TIMING_DETECT + * event has already occurred. + */ +#define RAIL_EVENT_RX_PREAMBLE_DETECT (1ULL << RAIL_EVENT_RX_PREAMBLE_DETECT_SHIFT) + +/** + * Occurs when the first sync word is detected. After this event occurs, one of + * the events in the \ref RAIL_EVENTS_RX_COMPLETION mask will occur. + */ +#define RAIL_EVENT_RX_SYNC1_DETECT (1ULL << RAIL_EVENT_RX_SYNC1_DETECT_SHIFT) + +/** + * Occurs when the second sync word is detected. After this event occurs, one of + * the events in the \ref RAIL_EVENTS_RX_COMPLETION mask will occur. + */ +#define RAIL_EVENT_RX_SYNC2_DETECT (1ULL << RAIL_EVENT_RX_SYNC2_DETECT_SHIFT) + +/** + * Occurs when a packet being received has a frame error. + * + * For efr32xg1x parts, frame errors include violations of variable length + * minimum/maximum limits and CRC errors. If + * \ref RAIL_RX_OPTION_IGNORE_CRC_ERRORS is set, \ref RAIL_EVENT_RX_FRAME_ERROR + * will not occur for CRC errors. + */ +#define RAIL_EVENT_RX_FRAME_ERROR (1ULL << RAIL_EVENT_RX_FRAME_ERROR_SHIFT) + +/** + * Occurs when RX buffer is full. This will cause the radio to stop receiving + * packets until the packet causing the overflow is processed. + * */ +#define RAIL_EVENT_RX_FIFO_OVERFLOW (1ULL << RAIL_EVENT_RX_FIFO_OVERFLOW_SHIFT) + +/** + * Occurs when a packet's address does not match the filtering settings. After + * this event, the packet will not be received, and no other events should occur + * for the packet. This event can only occur after calling + * RAIL_EnableAddressFilter(). + */ +#define RAIL_EVENT_RX_ADDRESS_FILTERED (1ULL << RAIL_EVENT_RX_ADDRESS_FILTERED_SHIFT) + +/** + * Occurs when an RX event times out. This event can only occur if the + * RAIL_StateTiming_t::rxSearchTimeout passed to RAIL_SetStateTiming() is + * nonzero. + */ +#define RAIL_EVENT_RX_TIMEOUT (1ULL << RAIL_EVENT_RX_TIMEOUT_SHIFT) + +/** + * Occurs when the scheduled RX window ends. This event only occurs in response + * to a scheduled receive timeout after calling RAIL_ScheduleRx(). If + * RAIL_ScheduleRxConfig_t::rxTransitionEndSchedule was passed as false, then + * this event will occur unless the receive is aborted (due to a call to + * RAIL_Idle() or a scheduler pre-emption, for instance). If + * RAIL_ScheduleRxConfig_t::rxTransitionEndSchedule was passed as true, then + * any of the \ref RAIL_EVENTS_RX_COMPLETION events occurring will also cause + * this event to not occur, since the scheduled reeive will end with the + * transition at the end of the packet. + */ +#define RAIL_EVENT_RX_SCHEDULED_RX_END (1ULL << RAIL_EVENT_RX_SCHEDULED_RX_END_SHIFT) + +/** + * Occurs when a packet is aborted, but a more specific reason (such as + * \ref RAIL_EVENT_RX_ADDRESS_FILTERED) isn't known. + */ +#define RAIL_EVENT_RX_PACKET_ABORTED (1ULL << RAIL_EVENT_RX_PACKET_ABORTED_SHIFT) + +/** + * Occurs when the packet has passed any configured address and frame + * filtering options. This event will only occur between the start of the + * packet, indicated by \ref RAIL_EVENT_RX_SYNC1_DETECT or + * \ref RAIL_EVENT_RX_SYNC2_DETECT, and one of the events in the + * \ref RAIL_EVENTS_RX_COMPLETION mask. This event will always occur before or + * concurrently with \ref RAIL_EVENT_RX_PACKET_RECEIVED. If IEEE 802.15.4 frame + * and address filtering are enabled, this event will occur immediately after + * destination address filtering. + */ +#define RAIL_EVENT_RX_FILTER_PASSED (1ULL << RAIL_EVENT_RX_FILTER_PASSED_SHIFT) + +/** + * Occurs when the modem timing is lost. This event can occur multiple times + * while searching for a packet, and is generally used for diagnostic purposes. + * This event can only occur after a \ref RAIL_EVENT_RX_TIMING_DETECT event has + * already occurred. + */ +#define RAIL_EVENT_RX_TIMING_LOST (1ULL << RAIL_EVENT_RX_TIMING_LOST_SHIFT) + +/** + * Occurs when the modem timing is detected. This event can occur multiple times + * while searching for a packet, and is generally used for diagnostic purposes. + */ +#define RAIL_EVENT_RX_TIMING_DETECT (1ULL << RAIL_EVENT_RX_TIMING_DETECT_SHIFT) + +/** + * Indicates a Data Request is being received when using IEEE 802.15.4 + * functionality. This occurs when the command byte of an incoming frame is + * for a data request, which requests an ACK. This callback is called before + * the packet is fully received to allow the node to have more time to decide + * whether to set the frame pending in the outgoing ACK. This event only ever + * occurs if the RAIL IEEE 802.15.4 functionality is enabled, but will never + * occur if promiscuous mode is enabled via + * RAIL_IEEE802154_SetPromiscuousMode(). + * + * Call RAIL_IEEE802154_GetAddress() to get the source address of the packet. + */ +#define RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND (1ULL << RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND_SHIFT) + +/** + * This mask indicates all of the events that determine the end of a received + * packet. After a packet has begun to be received, which is indicated by a + * \ref RAIL_EVENT_RX_SYNC1_DETECT or a \ref RAIL_EVENT_RX_SYNC2_DETECT, + * exactly one of the following events will occur. When one of these events + * occurs a state transition will take place, based on the parameter passed to + * RAIL_SetRxTransitions(). The RAIL_StateTransitions_t::success transition + * will be followed only if the \ref RAIL_EVENT_RX_PACKET_RECEIVED event occurs. + * Any of the other events will trigger the RAIL_StateTransitions_t::error + * transition. + */ +#define RAIL_EVENTS_RX_COMPLETION (RAIL_EVENT_RX_PACKET_RECEIVED \ + | RAIL_EVENT_RX_PACKET_ABORTED \ + | RAIL_EVENT_RX_FRAME_ERROR \ + | RAIL_EVENT_RX_FIFO_OVERFLOW \ + | RAIL_EVENT_RX_ADDRESS_FILTERED) + +// TX Event Bitmasks + +/** + * Occurs when the number of bytes in the transmit FIFO was above the + * configured threshold, and falls to a value at or below the threshold value. + * This event does not occur on initailization or after resetting the transmit + * FIFO with RAIL_ResetFifo(). Call RAIL_GetTxFifoSpaceAvailable() to get the + * number of bytes available in the transmit FIFO at the time of the callback + * dispatch. When using this event, the threshold should be set via + * RAIL_SetTxFifoThreshold(). + */ +#define RAIL_EVENT_TX_FIFO_ALMOST_EMPTY (1ULL << RAIL_EVENT_TX_FIFO_ALMOST_EMPTY_SHIFT) + +/** + * Occurs when a packet was sent. Call RAIL_GetTxPacketDetails() to get + * information about the packet that was transmitted. + * @note RAIL_GetTxPacketDetails() is only valid to call during the timeframe + * of the RAIL_Config_t::eventsCallback. + */ +#define RAIL_EVENT_TX_PACKET_SENT (1ULL << RAIL_EVENT_TX_PACKET_SENT_SHIFT) + +/** + * Occurs when an ack packet was sent. Call RAIL_GetTxPacketDetails() to get + * information about the packet that was transmitted. This event can only occur + * after calling RAIL_ConfigAutoAck(). + * @note RAIL_GetTxPacketDetails() is only valid to call during the timeframe + * of the RAIL_Config_t::eventsCallback. + */ +#define RAIL_EVENT_TXACK_PACKET_SENT (1ULL << RAIL_EVENT_TXACK_PACKET_SENT_SHIFT) + +/** + * Occurs when a transmit is aborted by the user. This can occur due to calling + * RAIL_Idle() or due to a scheduler pre-emption. + */ +#define RAIL_EVENT_TX_ABORTED (1ULL << RAIL_EVENT_TX_ABORTED_SHIFT) + +/** + * Occurs when an ack transmit is aborted by the user. This event can only + * occur after calling RAIL_ConfigAutoAck(). This can occur due to calling + * RAIL_Idle() or due to a scheduler pre-emption. + */ +#define RAIL_EVENT_TXACK_ABORTED (1ULL << RAIL_EVENT_TXACK_ABORTED_SHIFT) + +/** + * Occurs when a transmit is blocked from occurring due to having called + * RAIL_EnableTxHoldOff(). + */ +#define RAIL_EVENT_TX_BLOCKED (1ULL << RAIL_EVENT_TX_BLOCKED_SHIFT) + +/** + * Occurs when an ack transmit is blocked from occurring due to having called + * RAIL_EnableTxHoldOff(). This event can only occur after calling + * RAIL_ConfigAutoAck(). + */ +#define RAIL_EVENT_TXACK_BLOCKED (1ULL << RAIL_EVENT_TXACK_BLOCKED_SHIFT) + +/** + * Occurs when the transmit buffer underflows. This can happen due to the + * transmitted packet specifying an unintended length based on the current + * radio configuration, or due to RAIL_WriteTxFifo() calls not keeping up with + * the transmit rate, if the entire packet isn't loaded at once. + */ +#define RAIL_EVENT_TX_UNDERFLOW (1ULL << RAIL_EVENT_TX_UNDERFLOW_SHIFT) + +/** + * Occurs when the ack transmit buffer underflows. This can happen due to the + * transmitted packet specifying an unintended length based on the current + * radio configuration, or due to RAIL_WriteAutoAckFifo() not being called at + * all before an ack transmit. This event can only occur after calling + * RAIL_ConfigAutoAck(). + */ +#define RAIL_EVENT_TXACK_UNDERFLOW (1ULL << RAIL_EVENT_TXACK_UNDERFLOW_SHIFT) + +/** + * Occurs when Carrier Sense Mulitple Access (CSMA) or Listen Before Talk (LBT) + * succeeds. This event can only happen after calling RAIL_StartCcaCsmaTx() or + * RAIL_StartCsmaLbtTx(). + */ +#define RAIL_EVENT_TX_CHANNEL_CLEAR (1ULL << RAIL_EVENT_TX_CHANNEL_CLEAR_SHIFT) + +/** + * Occurs when Carrier Sense Mulitple Access (CSMA) or Listen Before Talk (LBT) + * fails. This event can only happen after calling RAIL_StartCcaCsmaTx() or + * RAIL_StartCsmaLbtTx(). + */ +#define RAIL_EVENT_TX_CHANNEL_BUSY (1ULL << RAIL_EVENT_TX_CHANNEL_BUSY_SHIFT) + +/** + * Occurs during CSMA or LBT when an individual Clear Channel Assessment (CCA) + * check failed, but there are more tries needed before the overall operation + * completes. This event can occur multiple times based on the configuration + * of the ongoing CSMA or LBT tranmission. This event can only happen after + * calling RAIL_StartCcaCsmaTx() or RAIL_StartCsmaLbtTx(). + * + */ +#define RAIL_EVENT_TX_CCA_RETRY (1ULL << RAIL_EVENT_TX_CCA_RETRY_SHIFT) + +/** + * Occurs when a Clear Channel Assessment (CCA) check begins. This event can + * occur multiple times based on the configuration of the ongoing CSMA or LBT + * transmission. This event can only happen after calling RAIL_StartCcaCsmaTx() + * or RAIL_StartCsmaLbtTx(). + */ +#define RAIL_EVENT_TX_START_CCA (1ULL << RAIL_EVENT_TX_START_CCA_SHIFT) + +/** + * This mask indicates all of the events that determine the end of a transmitted + * packet. After a packet has begun to be transmitted, which is indicated by + * a \ref RAIL_STATUS_NO_ERROR return value from one of the transmit functions, + * exactly one of the following events will occur. When one of these events + * occurs a state transition will take place based on the parameter + * passed to RAIL_SetTxTransitions(). The RAIL_StateTransitions_t::success + * transition will be followed only if the \ref RAIL_EVENT_TX_PACKET_SENT + * event occurs. Any of the other events will trigger the + * RAIL_StateTransitions_t::error transition. + */ +#define RAIL_EVENTS_TX_COMPLETION (RAIL_EVENT_TX_PACKET_SENT \ + | RAIL_EVENT_TX_ABORTED \ + | RAIL_EVENT_TX_BLOCKED \ + | RAIL_EVENT_TX_UNDERFLOW \ + | RAIL_EVENT_TX_CHANNEL_BUSY) + +/** + * This mask indicates all of the events that determine the end of a transmitted + * ack packet. After an ack packet has begun to be transmitted, which occurs + * after an ack-requesting receive, exactly one of the following events will + * occur. When one of these events occurs a state transition will take place + * based on the RAIL_AutoAckConfig_t::rxTransitions passed to + * RAIL_ConfigAutoAck(). The receive transitions are used because the + * transmitted ack packet is considered a part of the ack-requesting received + * packet. The RAIL_StateTransitions_t::success transition will be followed + * only if the \ref RAIL_EVENT_TXACK_PACKET_SENT event occurs. Any of the other + * events will trigger the RAIL_StateTransitions_t::error transition. + */ +#define RAIL_EVENTS_TXACK_COMPLETION (RAIL_EVENT_TXACK_PACKET_SENT \ + | RAIL_EVENT_TXACK_ABORTED \ + | RAIL_EVENT_TXACK_BLOCKED \ + | RAIL_EVENT_TXACK_UNDERFLOW) + +// Scheduler Event Bitmasks + +/** + * Occurs when the scheduler switches away from this configuration. This event + * can occur often in dynamic multiprotocol scenarios, and can give the + * current stack an opportunity to release hardware resources. + */ +#define RAIL_EVENT_CONFIG_UNSCHEDULED (1ULL << RAIL_EVENT_CONFIG_UNSCHEDULED_SHIFT) + +/** + * Occurs when the scheduler switches to this configuration. This event can + * occur often in dynamic multiprotocol scenarios, and can be used to influence + * the stack's operation. + */ +#define RAIL_EVENT_CONFIG_SCHEDULED (1ULL << RAIL_EVENT_CONFIG_SCHEDULED_SHIFT) + +/** + * Occurs when the scheduler has a status to report. The exact status can be + * found with RAIL_GetSchedulerStatus(). See \ref RAIL_SchedulerStatus_t for + * more details. + * @note RAIL_GetSchedulerStatus() is only valid to call during the timeframe + * of the RAIL_Config_t::eventsCallback. + */ +#define RAIL_EVENT_SCHEDULER_STATUS (1ULL << RAIL_EVENT_SCHEDULER_STATUS_SHIFT) + +// Other Event Bitmasks + +/** + * Occurs when the application needs to run a calibration. + * The RAIL library detects when a calibration is needed. The application + * determines a valid window to call RAIL_Calibrate(). + */ +#define RAIL_EVENT_CAL_NEEDED (1ULL << RAIL_EVENT_CAL_NEEDED_SHIFT) + +/** Value representing all possible events */ +#define RAIL_EVENTS_ALL 0xFFFFFFFFFFFFFFFFULL + /** @} */ // end of group Events /** @@ -531,7 +705,9 @@ RAIL_ENUM(RAIL_Status_t) { RAIL_STATUS_INVALID_STATE, /**< Call to RAIL function threw an error because it was called during an invalid radio state */ - RAIL_STATUS_INVALID_CALL, /**< The function is called in an invalid order */ + RAIL_STATUS_INVALID_CALL, /**< RAIL function is called in an invalid order */ + RAIL_STATUS_SUSPENDED, /**< RAIL function did not finish in the allotted + time */ }; /** @@ -539,7 +715,7 @@ RAIL_ENUM(RAIL_Status_t) { * @brief The size, in 32-bit words, of RAIL_StateBuffer_t to store RAIL * internal state. */ -#define RAIL_STATE_UINT32_BUFFER_SIZE 54 +#define RAIL_STATE_UINT32_BUFFER_SIZE 70 /** * @typedef RAIL_StateBuffer_t @@ -691,213 +867,212 @@ typedef struct RAIL_ChannelConfigEntry { channel set. */ } RAIL_ChannelConfigEntry_t; -/** - * @struct RAIL_ChannelConfig_t - * @brief Channel configuration structure, which defines the channel meaning - * when a channel number is passed into a RAIL function, e.g., RAIL_StartTx() - * and RAIL_StartRx(). - * - * A RAIL_ChannelConfig_t structure defines the channel scheme that an - * application uses when registered in RAIL_ConfigChannels(). - * - * A few examples of different channel configurations: - * @code{.c} - * // 21 channels starting at 2.45GHz with channel spacing of 1MHz - * // ... generated by Simplicity Studio (i.e. rail_config.c) ... - * const uint32_t generated[] = { ... }; - * RAIL_ChannelConfigEntryAttr_t generated_entryAttr = { ... }; - * const RAIL_ChannelConfigEntry_t generated_channels[] = { - * { - * .phyConfigDeltaAdd = NULL, // Add this to default config for this entry - * .baseFrequency = 2450000000, - * .channelSpacing = 1000000, - * .physicalChannelOffset = 0, - * .channelNumberStart = 0, - * .channelNumberEnd = 20, - * .maxPower = RAIL_TX_POWER_MAX, - * .attr = &generated_entryAttr - * }, - * }; - * const RAIL_ChannelConfig_t generated_channelConfig = { - * .phyConfigBase = generated, // Default radio config for all entries - * .phyConfigDeltaSubtract = NULL, // Subtract this to restore default config - * .configs = generated_channels, - * .length = 1 // There are this many channel config entries - * }; - * const RAIL_ChannelConfig_t *channelConfigs[] = { - * &generated_channelConfig, - * NULL - * }; - * // ... in main code ... - * // Associate a specific channel config with a particular rail instance. - * RAIL_ConfigChannels(railHandle, channelConfigs[0]); - * - * // 4 nonlinear channels - * // ... in rail_config.c ... - * const uint32_t generated[] = { ... }; - * RAIL_ChannelConfigEntryAttr_t generated_entryAttr = { ... }; - * const RAIL_ChannelConfigEntry_t generated_channels[] = { - * { - * .phyConfigDeltaAdd = NULL, // Add this to default config for this entry - * .baseFrequency = 910123456, - * .channelSpacing = 0, - * .physicalChannelOffset = 0, - * .channelNumberStart = 0, - * .channelNumberEnd = 0, - * .maxPower = RAIL_TX_POWER_MAX, - * .attr = &generated_entryAttr - * }, - * { - * .phyConfigDeltaAdd = NULL, - * .baseFrequency = 911654789, - * .channelSpacing = 0, - * .physicalChannelOffset = 0, // Since ch spacing = 0, offset can be 0 - * .channelNumberStart = 1, - * .channelNumberEnd = 1, - * .maxPower = RAIL_TX_POWER_MAX, - * .attr = &generated_entryAttr - * }, - * { - * .phyConfigDeltaAdd = NULL, - * .baseFrequency = 912321456, - * .channelSpacing = 100000, - * .physicalChannelOffset = 2, // Since ch spacing != 0, offset = 2 - * .channelNumberStart = 2, // We want ch 2 = baseFrequency - * .channelNumberEnd = 2, - * .maxPower = RAIL_TX_POWER_MAX, - * .attr = &generated_entryAttr - * }, - * { - * .phyConfigDeltaAdd = NULL, - * .baseFrequency = 913147852, - * .channelSpacing = 0, - * .physicalChannelOffset = 0, - * .channelNumberStart = 3, - * .channelNumberEnd = 3, - * .maxPower = RAIL_TX_POWER_MAX, - * .attr = &generated_entryAttr - * }, - * }; - * const RAIL_ChannelConfig_t generated_channelConfig = { - * .phyConfigBase = generated, // Default radio config for all entries - * .phyConfigDeltaSubtract = NULL, // Subtract this to restore default config - * .configs = generated_channels, - * .length = 4 // There are this many channel config entries - * }; - * const RAIL_ChannelConfig_t *channelConfigs[] = { - * &generated_channelConfig, - * NULL - * }; - * // ... in main code ... - * // Associate a specific channel config with a particular rail instance. - * RAIL_ConfigChannels(railHandle, channelConfigs[0]); - * - * // Multiple radio configurations - * // ... in rail_config.c ... - * const uint32_t generated0[] = { ... }; - * RAIL_ChannelConfigEntryAttr_t generated0_entryAttr = { ... }; - * const RAIL_ChannelConfigEntry_t generated0_channels[] = { - * { - * .phyConfigDeltaAdd = NULL, // Add this to default config for this entry - * .baseFrequency = 2450000000, - * .channelSpacing = 1000000, - * .physicalChannelOffset = 0, - * .channelNumberStart = 0, - * .channelNumberEnd = 20, - * .maxPower = RAIL_TX_POWER_MAX, - * .attr = &generated0_entryAttr - * }, - * }; - * const RAIL_ChannelConfig_t generated0_channelConfig = { - * .phyConfigBase = generated0, // Default radio config for all entries - * .phyConfigDeltaSubtract = NULL, // Subtract this to restore default config - * .configs = generated0_channels, - * .length = 1 // There are this many channel config entries - * }; - * const uint32_t generated1[] = { ... }; - * RAIL_ChannelConfigEntryAttr_t generated1_entryAttr = { ... }; - * const RAIL_ChannelConfigEntry_t generated1_channels[] = { - * { - * .phyConfigDeltaAdd = NULL, - * .baseFrequency = 2450000000, - * .channelSpacing = 1000000, - * .physicalChannelOffset = 0, - * .channelNumberStart = 0, - * .channelNumberEnd = 20, - * .maxPower = -100, // Use this entry when TX power <= -10dBm - * .attr = &generated1_entryAttr - * }, - * { - * .phyConfigDeltaAdd = NULL, - * .baseFrequency = 2450000000, - * .channelSpacing = 1000000, - * .physicalChannelOffset = 0, - * .channelNumberStart = 0, - * .channelNumberEnd = 20, - * .maxPower = 15, // Use this entry when TX power > -10dBm - * // and TX power <= 1.5dBm - * .attr = &generated1_entryAttr - * }, - * { - * .phyConfigDeltaAdd = NULL, - * .baseFrequency = 2450000000, - * .channelSpacing = 1000000, - * .physicalChannelOffset = 0, - * .channelNumberStart = 0, - * .channelNumberEnd = 20, - * .maxPower = RAIL_TX_POWER_MAX, // Use this entry when TX power > 1.5dBm - * .attr = &generated1_entryAttr - * }, - * }; - * const RAIL_ChannelConfig_t generated1_channelConfig = { - * .phyConfigBase = generated1, - * .phyConfigDeltaSubtract = NULL, - * .configs = generated1_channels, - * .length = 3 - * }; - * const uint32_t generated2[] = { ... }; - * RAIL_ChannelConfigEntryAttr_t generated2_entryAttr = { ... }; - * const RAIL_ChannelConfigEntry_t generated2_channels[] = { - * { - * .phyConfigDeltaAdd = NULL, - * .baseFrequency = 2450000000, - * .channelSpacing = 1000000, - * .physicalChannelOffset = 0, - * .channelNumberStart = 0, - * .channelNumberEnd = 20, - * .maxPower = RAIL_TX_POWER_MAX, - * .attr = &generated2_entryAttr - * }, - * }; - * const RAIL_ChannelConfig_t generated2_channelConfig = { - * .phyConfigBase = generated2, - * .phyConfigDeltaSubtract = NULL, - * .configs = generated2_channels, - * .length = 1 - * }; - * const RAIL_ChannelConfig_t *channelConfigs[] = { - * &generated0_channelConfig, - * &generated1_channelConfig, - * &generated2_channelConfig, - * NULL - * }; - * // ... in main code ... - * // Create a unique RAIL handle for each unique channel config. - * railHandle0 = RAIL_Init(&railCfg0, &RAILCb_RfReady0); - * railHandle1 = RAIL_Init(&railCfg1, &RAILCb_RfReady1); - * railHandle2 = RAIL_Init(&railCfg2, &RAILCb_RfReady2); - * // Associate each channel config with its corresponding RAIL handle. - * RAIL_ConfigChannels(railHandle0, channelConfigs[0]); - * RAIL_ConfigChannels(railHandle1, channelConfigs[1]); - * RAIL_ConfigChannels(railHandle2, channelConfigs[2]); - * // Use a RAIL handle and channel to access the desired channel config entry. - * RAIL_SetTxPowerDbm(railHandle1, 100); // set 10.0 dBm TX power - * RAIL_StartRx(railHandle1, 0, &schedInfo); // RX using generated1_channels[2] - * RAIL_SetTxPowerDbm(railHandle1, 0); // set 0 dBm TX power - * RAIL_StartRx(railHandle1, 0, &schedInfo); // RX using generated1_channels[1] - * RAIL_StartRx(railHandle2, 0, &schedInfo); // RX using generated2_channels[0] - * @endcode - */ +/// @struct RAIL_ChannelConfig_t +/// @brief Channel configuration structure, which defines the channel meaning +/// when a channel number is passed into a RAIL function, e.g., RAIL_StartTx() +/// and RAIL_StartRx(). +/// +/// A RAIL_ChannelConfig_t structure defines the channel scheme that an +/// application uses when registered in RAIL_ConfigChannels(). +/// +/// A few examples of different channel configurations: +/// @code{.c} +/// // 21 channels starting at 2.45GHz with channel spacing of 1MHz +/// // ... generated by Simplicity Studio (i.e. rail_config.c) ... +/// const uint32_t generated[] = { ... }; +/// RAIL_ChannelConfigEntryAttr_t generated_entryAttr = { ... }; +/// const RAIL_ChannelConfigEntry_t generated_channels[] = { +/// { +/// .phyConfigDeltaAdd = NULL, // Add this to default config for this entry +/// .baseFrequency = 2450000000, +/// .channelSpacing = 1000000, +/// .physicalChannelOffset = 0, +/// .channelNumberStart = 0, +/// .channelNumberEnd = 20, +/// .maxPower = RAIL_TX_POWER_MAX, +/// .attr = &generated_entryAttr +/// }, +/// }; +/// const RAIL_ChannelConfig_t generated_channelConfig = { +/// .phyConfigBase = generated, // Default radio config for all entries +/// .phyConfigDeltaSubtract = NULL, // Subtract this to restore default config +/// .configs = generated_channels, +/// .length = 1 // There are this many channel config entries +/// }; +/// const RAIL_ChannelConfig_t *channelConfigs[] = { +/// &generated_channelConfig, +/// NULL +/// }; +/// // ... in main code ... +/// // Associate a specific channel config with a particular rail instance. +/// RAIL_ConfigChannels(railHandle, channelConfigs[0]); +/// +/// // 4 nonlinear channels +/// // ... in rail_config.c ... +/// const uint32_t generated[] = { ... }; +/// RAIL_ChannelConfigEntryAttr_t generated_entryAttr = { ... }; +/// const RAIL_ChannelConfigEntry_t generated_channels[] = { +/// { +/// .phyConfigDeltaAdd = NULL, // Add this to default config for this entry +/// .baseFrequency = 910123456, +/// .channelSpacing = 0, +/// .physicalChannelOffset = 0, +/// .channelNumberStart = 0, +/// .channelNumberEnd = 0, +/// .maxPower = RAIL_TX_POWER_MAX, +/// .attr = &generated_entryAttr +/// }, +/// { +/// .phyConfigDeltaAdd = NULL, +/// .baseFrequency = 911654789, +/// .channelSpacing = 0, +/// .physicalChannelOffset = 0, // Since ch spacing = 0, offset can be 0 +/// .channelNumberStart = 1, +/// .channelNumberEnd = 1, +/// .maxPower = RAIL_TX_POWER_MAX, +/// .attr = &generated_entryAttr +/// }, +/// { +/// .phyConfigDeltaAdd = NULL, +/// .baseFrequency = 912321456, +/// .channelSpacing = 100000, +/// .physicalChannelOffset = 2, // Since ch spacing != 0, offset = 2 +/// .channelNumberStart = 2, // We want ch 2 = baseFrequency +/// .channelNumberEnd = 2, +/// .maxPower = RAIL_TX_POWER_MAX, +/// .attr = &generated_entryAttr +/// }, +/// { +/// .phyConfigDeltaAdd = NULL, +/// .baseFrequency = 913147852, +/// .channelSpacing = 0, +/// .physicalChannelOffset = 0, +/// .channelNumberStart = 3, +/// .channelNumberEnd = 3, +/// .maxPower = RAIL_TX_POWER_MAX, +/// .attr = &generated_entryAttr +/// }, +/// }; +/// const RAIL_ChannelConfig_t generated_channelConfig = { +/// .phyConfigBase = generated, // Default radio config for all entries +/// .phyConfigDeltaSubtract = NULL, // Subtract this to restore default config +/// .configs = generated_channels, +/// .length = 4 // There are this many channel config entries +/// }; +/// const RAIL_ChannelConfig_t *channelConfigs[] = { +/// &generated_channelConfig, +/// NULL +/// }; +/// // ... in main code ... +/// // Associate a specific channel config with a particular rail instance. +/// RAIL_ConfigChannels(railHandle, channelConfigs[0]); +/// +/// // Multiple radio configurations +/// // ... in rail_config.c ... +/// const uint32_t generated0[] = { ... }; +/// RAIL_ChannelConfigEntryAttr_t generated0_entryAttr = { ... }; +/// const RAIL_ChannelConfigEntry_t generated0_channels[] = { +/// { +/// .phyConfigDeltaAdd = NULL, // Add this to default config for this entry +/// .baseFrequency = 2450000000, +/// .channelSpacing = 1000000, +/// .physicalChannelOffset = 0, +/// .channelNumberStart = 0, +/// .channelNumberEnd = 20, +/// .maxPower = RAIL_TX_POWER_MAX, +/// .attr = &generated0_entryAttr +/// }, +/// }; +/// const RAIL_ChannelConfig_t generated0_channelConfig = { +/// .phyConfigBase = generated0, // Default radio config for all entries +/// .phyConfigDeltaSubtract = NULL, // Subtract this to restore default config +/// .configs = generated0_channels, +/// .length = 1 // There are this many channel config entries +/// }; +/// const uint32_t generated1[] = { ... }; +/// RAIL_ChannelConfigEntryAttr_t generated1_entryAttr = { ... }; +/// const RAIL_ChannelConfigEntry_t generated1_channels[] = { +/// { +/// .phyConfigDeltaAdd = NULL, +/// .baseFrequency = 2450000000, +/// .channelSpacing = 1000000, +/// .physicalChannelOffset = 0, +/// .channelNumberStart = 0, +/// .channelNumberEnd = 20, +/// .maxPower = -100, // Use this entry when TX power <= -10dBm +/// .attr = &generated1_entryAttr +/// }, +/// { +/// .phyConfigDeltaAdd = NULL, +/// .baseFrequency = 2450000000, +/// .channelSpacing = 1000000, +/// .physicalChannelOffset = 0, +/// .channelNumberStart = 0, +/// .channelNumberEnd = 20, +/// .maxPower = 15, // Use this entry when TX power > -10dBm +/// // and TX power <= 1.5dBm +/// .attr = &generated1_entryAttr +/// }, +/// { +/// .phyConfigDeltaAdd = NULL, +/// .baseFrequency = 2450000000, +/// .channelSpacing = 1000000, +/// .physicalChannelOffset = 0, +/// .channelNumberStart = 0, +/// .channelNumberEnd = 20, +/// .maxPower = RAIL_TX_POWER_MAX, // Use this entry when TX power > 1.5dBm +/// .attr = &generated1_entryAttr +/// }, +/// }; +/// const RAIL_ChannelConfig_t generated1_channelConfig = { +/// .phyConfigBase = generated1, +/// .phyConfigDeltaSubtract = NULL, +/// .configs = generated1_channels, +/// .length = 3 +/// }; +/// const uint32_t generated2[] = { ... }; +/// RAIL_ChannelConfigEntryAttr_t generated2_entryAttr = { ... }; +/// const RAIL_ChannelConfigEntry_t generated2_channels[] = { +/// { +/// .phyConfigDeltaAdd = NULL, +/// .baseFrequency = 2450000000, +/// .channelSpacing = 1000000, +/// .physicalChannelOffset = 0, +/// .channelNumberStart = 0, +/// .channelNumberEnd = 20, +/// .maxPower = RAIL_TX_POWER_MAX, +/// .attr = &generated2_entryAttr +/// }, +/// }; +/// const RAIL_ChannelConfig_t generated2_channelConfig = { +/// .phyConfigBase = generated2, +/// .phyConfigDeltaSubtract = NULL, +/// .configs = generated2_channels, +/// .length = 1 +/// }; +/// const RAIL_ChannelConfig_t *channelConfigs[] = { +/// &generated0_channelConfig, +/// &generated1_channelConfig, +/// &generated2_channelConfig, +/// NULL +/// }; +/// // ... in main code ... +/// // Create a unique RAIL handle for each unique channel config. +/// railHandle0 = RAIL_Init(&railCfg0, &RAILCb_RfReady0); +/// railHandle1 = RAIL_Init(&railCfg1, &RAILCb_RfReady1); +/// railHandle2 = RAIL_Init(&railCfg2, &RAILCb_RfReady2); +/// // Associate each channel config with its corresponding RAIL handle. +/// RAIL_ConfigChannels(railHandle0, channelConfigs[0]); +/// RAIL_ConfigChannels(railHandle1, channelConfigs[1]); +/// RAIL_ConfigChannels(railHandle2, channelConfigs[2]); +/// // Use a RAIL handle and channel to access the desired channel config entry. +/// RAIL_SetTxPowerDbm(railHandle1, 100); // set 10.0 dBm TX power +/// RAIL_StartRx(railHandle1, 0, &schedInfo); // RX using generated1_channels[2] +/// RAIL_SetTxPowerDbm(railHandle1, 0); // set 0 dBm TX power +/// RAIL_StartRx(railHandle1, 0, &schedInfo); // RX using generated1_channels[1] +/// RAIL_StartRx(railHandle2, 0, &schedInfo); // RX using generated2_channels[0] +/// @endcode + typedef struct RAIL_ChannelConfig { const uint32_t *phyConfigBase; /**< Base radio config for the corresponding channel config entries. */ @@ -996,6 +1171,39 @@ RAIL_ENUM(RAIL_TimeMode_t) { RAIL_TIME_DISABLED }; +/// Forward declaration of RAIL_MultiTimer +struct RAIL_MultiTimer; + +/** + * @typedef RAIL_MultiTimerCallback_t + * @brief Callback fired when timer expires + * + * @param[in] tmr pointer to expired timer + * @param[in] expectedTimeOfEvent Absolute time event fired + * @param[in] cbArg User supplied callback argument + */ +typedef void (*RAIL_MultiTimerCallback_t)(struct RAIL_MultiTimer *tmr, + RAIL_Time_t expectedTimeOfEvent, + void *cbArg); + +/** + * @struct RAIL_MultiTimer_t + * @brief RAIL timer state structure + * + * This structure is filled out and maintained internally only. + * The user/application should not alter any elements of this structure. + */ +typedef struct RAIL_MultiTimer { + RAIL_Time_t absOffset; /**< absolute time before next event */ + RAIL_Time_t relPeriodic; /**< relative, periodic time between events; 0 = timer is oneshot */ + RAIL_MultiTimerCallback_t callback; /**< user callback */ + void *cbArg; /**< user callback argument */ + struct RAIL_MultiTimer *next; /**< pointer to next soft timer structure */ + uint8_t priority; /**< priority of callback; 0 = highest priority; 255 = lowest */ + bool isRunning; /**< soft timer currently running? */ + bool doCallback; /**< callback needs to run? */ +} RAIL_MultiTimer_t; + /** * @enum RAIL_SleepConfig_t * @brief The config @@ -1071,7 +1279,7 @@ typedef struct RAIL_PacketTimeStamp { /** * Timestamp of the packet in the RAIL timebase. */ - uint32_t packetTime; + RAIL_Time_t packetTime; /** * A value specifying the total length in bytes of the packet for * use when calculating the packetTime requested by the timePosition @@ -1189,10 +1397,12 @@ typedef struct RAIL_StateTransitions { * @struct RAIL_StateTiming_t * @brief Timing configuration structure for the RAIL State Machine. * - * Configures the timings of the radio state transitions for - * common situations. All of the listed timings are in µs. - * Timing values cannot exceed 13 ms. - * Transitions to IDLE always happen as fast as possible. + * Configures the timings of the radio state transitions for common situations. + * All of the listed timings are in us. Timing values cannot exceed 13 ms. A + * value of 0 for the transition time means that the specified transition + * should happen as fast as possible, even if the timing cannot be as + * consistent. Any other timing value will be limited, so that the time can be + * hit consistently. Transitions to IDLE always happen as fast as possible. */ typedef struct RAIL_StateTiming { uint16_t idleToRx; /**< Transition time from IDLE to RX */ @@ -1253,41 +1463,60 @@ RAIL_ENUM(RAIL_IdleMode_t) { * @brief Transmit options, in reality a bitmask. */ RAIL_ENUM_GENERIC(RAIL_TxOptions_t, uint32_t) { - /** Value representing no options enabled. */ - RAIL_TX_OPTIONS_NONE = 0, - /** Default is all options disabled. */ - RAIL_TX_OPTIONS_DEFAULT = RAIL_TX_OPTIONS_NONE, - /** Shift position of \ref RAIL_TX_OPTION_WAIT_FOR_ACK bit */ RAIL_TX_OPTION_WAIT_FOR_ACK_SHIFT = 0, /** Shift position of \ref RAIL_TX_OPTION_REMOVE_CRC bit */ RAIL_TX_OPTION_REMOVE_CRC_SHIFT, /** Shift position of \ref RAIL_TX_OPTION_SYNC_WORD_ID bit */ RAIL_TX_OPTION_SYNC_WORD_ID_SHIFT, - - /** - * Option to configure whether or not the TX'ing node will listen for an ACK. - * If this is false, the isAck flag in RAIL_RxPacketDetails_t of a received - * packet will always be false. - */ - RAIL_TX_OPTION_WAIT_FOR_ACK = (1ul << RAIL_TX_OPTION_WAIT_FOR_ACK_SHIFT), - /** - * Option to remove crc bytes from tx packets. If you want to be able to - * receive packets with this option set as true, you'll need to set - * the IGNORE_CRC_ERRORS option on the receive side. - */ - RAIL_TX_OPTION_REMOVE_CRC = (1ul << RAIL_TX_OPTION_REMOVE_CRC_SHIFT), - /** - * Option to select which sync word to send (0 or 1). Note that this does - * not set the actual sync words, it just picks which of the two will be - * sent with the packet. - */ - RAIL_TX_OPTION_SYNC_WORD_ID = (1ul << RAIL_TX_OPTION_SYNC_WORD_ID_SHIFT), - - /** Value representing all possible options */ - RAIL_TX_OPTIONS_ALL = 0xFFFFFFFFul + /** Shift position of \ref RAIL_TX_OPTION_ANTENNA0 bit */ + RAIL_TX_OPTION_ANTENNA0_SHIFT, + /** Shift position of \ref RAIL_TX_OPTION_ANTENNA1 bit */ + RAIL_TX_OPTION_ANTENNA1_SHIFT, }; +/** Value representing no options enabled. */ +#define RAIL_TX_OPTIONS_NONE 0UL +/** Default is all options disabled. */ +#define RAIL_TX_OPTIONS_DEFAULT RAIL_TX_OPTIONS_NONE +/** + * Option to configure whether or not the TX'ing node will listen for an ACK. + * If this is false, the isAck flag in RAIL_RxPacketDetails_t of a received + * packet will always be false. + */ +#define RAIL_TX_OPTION_WAIT_FOR_ACK (1UL << RAIL_TX_OPTION_WAIT_FOR_ACK_SHIFT) +/** + * Option to remove crc bytes from tx packets. If you want to be able to + * receive packets with this option set as true, you'll need to set + * the IGNORE_CRC_ERRORS option on the receive side. + */ +#define RAIL_TX_OPTION_REMOVE_CRC (1UL << RAIL_TX_OPTION_REMOVE_CRC_SHIFT) +/** + * Option to select which sync word to send (0 or 1). Note that this does + * not set the actual sync words, it just picks which of the two will be + * sent with the packet. + */ +#define RAIL_TX_OPTION_SYNC_WORD_ID (1UL << RAIL_TX_OPTION_SYNC_WORD_ID_SHIFT) +/** + * Option to select antenna 0 for transmission. If not antenna selection + * option is set or if both antenna options are set, then the TX will + * take place in either antenna depending on the last RX or TX + * configuration. This option is only valid on platforms that support + * antenna selection. + */ +#define RAIL_TX_OPTION_ANTENNA0 (1UL << RAIL_TX_OPTION_ANTENNA0_SHIFT) +/** + * Option to select antenna 1 for transmission. If not antenna selection + * option is set or if both antenna options are set, then the TX will + * take place in either antenna depending on the last RX or TX + * configuration. This option is only valid on platforms that support + * antenna selection. + */ +#define RAIL_TX_OPTION_ANTENNA1 (1UL << RAIL_TX_OPTION_ANTENNA1_SHIFT) + +/** Value representing all possible options */ +#define RAIL_TX_OPTIONS_ALL 0xFFFFFFFFUL + /** * @struct RAIL_TxPacketDetails_t * @brief Detailed information requested and about the packet that was just @@ -1336,7 +1565,7 @@ typedef struct RAIL_ScheduleTxConfig { * The time when to transmit this packet. The exact interpretation of * this value depends on the mode specified below. */ - uint32_t when; + RAIL_Time_t when; /** * The type of delay. See the \ref RAIL_TimeMode_t documentation for * more information. Be sure to use \ref RAIL_TIME_ABSOLUTE delays for @@ -1398,7 +1627,7 @@ typedef struct RAIL_CsmaConfig { * If the transmission doesn't start before this timeout expires, the * transmission will fail. A value 0 means no timeout is imposed. */ - uint32_t csmaTimeout; + RAIL_Time_t csmaTimeout; } RAIL_CsmaConfig_t; /** @@ -1478,7 +1707,7 @@ typedef struct RAIL_LbtConfig { * unbounded requirement that if the channel is busy, the next try must wait * for the channel to clear. A value 0 means no timeout is imposed. */ - uint32_t lbtTimeout; + RAIL_Time_t lbtTimeout; } RAIL_LbtConfig_t; /** @@ -1512,11 +1741,6 @@ typedef struct RAIL_LbtConfig { * @brief Receive options, in reality a bitmask. */ RAIL_ENUM_GENERIC(RAIL_RxOptions_t, uint32_t) { - /** Value representing no options enabled. */ - RAIL_RX_OPTIONS_NONE = 0, - /** Default is all options disabled. */ - RAIL_RX_OPTIONS_DEFAULT = RAIL_RX_OPTIONS_NONE, - /** Shift position of \ref RAIL_RX_OPTION_STORE_CRC bit */ RAIL_RX_OPTION_STORE_CRC_SHIFT = 0, /** Shift position of \ref RAIL_RX_OPTION_IGNORE_CRC_ERRORS bit */ @@ -1527,46 +1751,80 @@ RAIL_ENUM_GENERIC(RAIL_RxOptions_t, uint32_t) { RAIL_RX_OPTION_TRACK_ABORTED_FRAMES_SHIFT, /** Shift position of \ref RAIL_RX_OPTION_REMOVE_APPENDED_INFO bit */ RAIL_RX_OPTION_REMOVE_APPENDED_INFO_SHIFT, - - /** - * Option to configure whether the CRC portion of the packet is included in - * the packet payload exposed to the app on packet reception. - * Defaults to false. - */ - RAIL_RX_OPTION_STORE_CRC - = (1ul << RAIL_RX_OPTION_STORE_CRC_SHIFT), - /** - * Option to configure whether CRC errors will be ignored - * if this is set, RX will still be successful, even if - * the CRC does not pass the check. Defaults to false. - */ - RAIL_RX_OPTION_IGNORE_CRC_ERRORS - = (1ul << RAIL_RX_OPTION_IGNORE_CRC_ERRORS_SHIFT), - /** - * Option to configure which out of SYNC0 and SYNC1 - * will be sent as the sync word during transmit. - * Defaults to false (SYNC0). - */ - RAIL_RX_OPTION_ENABLE_DUALSYNC - = (1ul << RAIL_RX_OPTION_ENABLE_DUALSYNC_SHIFT), - /** - * Option to configure whether frames which are aborted during reception - * should continue to be tracked. Setting this option allows viewing Packet - * Trace information for frames which get discarded. Defaults to false. - */ - RAIL_RX_OPTION_TRACK_ABORTED_FRAMES - = (1ul << RAIL_RX_OPTION_TRACK_ABORTED_FRAMES_SHIFT), - /** - * Option to configure whether appended info is included after received - * frames. Default is false. - */ - RAIL_RX_OPTION_REMOVE_APPENDED_INFO - = (1ul << RAIL_RX_OPTION_REMOVE_APPENDED_INFO_SHIFT), - - /** Value representing all possible options */ - RAIL_RX_OPTIONS_ALL = 0xFFFFFFFFul + /** Shift position of \ref RAIL_RX_OPTION_ANTENNA0 bit */ + RAIL_RX_OPTION_ANTENNA0_SHIFT, + /** Shift position of \ref RAIL_RX_OPTION_ANTENNA1 bit */ + RAIL_RX_OPTION_ANTENNA1_SHIFT, }; +/** Value representing no options enabled. */ +#define RAIL_RX_OPTIONS_NONE 0 +/** Default is all options disabled. */ +#define RAIL_RX_OPTIONS_DEFAULT RAIL_RX_OPTIONS_NONE + +/** + * Option to configure whether the CRC portion of the packet is included in + * the packet payload exposed to the app on packet reception. + * Defaults to false. + */ +#define RAIL_RX_OPTION_STORE_CRC (1UL << RAIL_RX_OPTION_STORE_CRC_SHIFT) +/** + * Option to configure whether CRC errors will be ignored + * if this is set, RX will still be successful, even if + * the CRC does not pass the check. Defaults to false. + */ +#define RAIL_RX_OPTION_IGNORE_CRC_ERRORS (1UL << RAIL_RX_OPTION_IGNORE_CRC_ERRORS_SHIFT) + +/** + * Option to control which sync words will be accepted. Setting it to + * 0 (default) will cause the receiver to listen for SYNC0 only, 1 causes + * the receiver to listen for either SYNC0 or SYNC1. RX appended info will + * contain which sync word was detected. Note, this only affects which + * sync word(s) are received, but not what each of the sync words actually are. + * This feature may not be available on some combinations of chips, phys, and + * protocols. Consult the data sheet or support team for more details. + */ +#define RAIL_RX_OPTION_ENABLE_DUALSYNC (1UL << RAIL_RX_OPTION_ENABLE_DUALSYNC_SHIFT) + +/** + * Option to configure whether frames which are aborted during reception + * should continue to be tracked. Setting this option allows viewing Packet + * Trace information for frames which get discarded. Defaults to false. + */ +#define RAIL_RX_OPTION_TRACK_ABORTED_FRAMES (1UL << RAIL_RX_OPTION_TRACK_ABORTED_FRAMES_SHIFT) + +/** + * Option to configure whether appended info is included after received + * frames. Default is false. + */ +#define RAIL_RX_OPTION_REMOVE_APPENDED_INFO (1UL << RAIL_RX_OPTION_REMOVE_APPENDED_INFO_SHIFT) + +/** + * Option to select the use of antenna 0 when doing RX. If no antenna option + * is selected, the RX may take place on either antenna depending on the last + * RX or TX configuration. Defaults to false. + * This option is only valid on platforms that support antenna selection. + */ +#define RAIL_RX_OPTION_ANTENNA0 (1UL << RAIL_RX_OPTION_ANTENNA0_SHIFT) + +/** + * Option to select the use of antenna 1 when doing RX. If no antenna option + * is selected, the RX may take place on either antenna depending on the last + * RX or TX configuration. Defaults to false. + * This option is only valid on platforms that support antenna selection. + */ +#define RAIL_RX_OPTION_ANTENNA1 (1UL << RAIL_RX_OPTION_ANTENNA1_SHIFT) + +/** + * Option to automatically choose an antenna. If both antenna 0 and + * antenna 1 options are set the chip will switch between antennas and + * will automatically choose one. + */ +#define RAIL_RX_OPTION_ANTENNA_AUTO (RAIL_RX_OPTION_ANTENNA0 | RAIL_RX_OPTION_ANTENNA1) + +/** Value representing all possible options */ +#define RAIL_RX_OPTIONS_ALL 0xFFFFFFFFUL + /** The value returned by RAIL for an invalid RSSI, in dBm */ #define RAIL_RSSI_INVALID_DBM (-128) /** The value returned by RAIL for an invalid RSSI: in quarter dBm */ @@ -1585,7 +1843,7 @@ typedef struct RAIL_ScheduleRxConfig { * The time to start receive. See startMode for more information about they * types of start times that you can specify. */ - uint32_t start; + RAIL_Time_t start; /** * How to interpret the time value specified in the start parameter. See the * \ref RAIL_TimeMode_t documentation for more information. Use @@ -1598,7 +1856,7 @@ typedef struct RAIL_ScheduleRxConfig { * The time to end receive. See endMode for more information about the types * of end times you can specify. */ - uint32_t end; + RAIL_Time_t end; /** * How to interpret the time value specified in the end parameter. See the * \ref RAIL_TimeMode_t documentation for more information. Note that, in @@ -1684,8 +1942,9 @@ typedef const void *RAIL_RxPacketHandle_t; * @note Because the RX FIFO buffer is circular, a packet might start * near the end of the buffer and wrap around to the beginning of * the buffer to finish, hence the distinction between the first - * and last portions. Packets that fit without wrapping only have - * a first portion (firstPortionBytes == packetBytes). + * and last portions. Packets that fit without wrapping only have + * a first portion (firstPortionBytes == packetBytes and lastPortionData + * will be NULL). */ typedef struct RAIL_RxPacketInfo { RAIL_RxPacketStatus_t packetStatus; /**< Packet status of this packet. */ @@ -1696,8 +1955,8 @@ typedef struct RAIL_RxPacketInfo { data containing firstPortionBytes number of bytes. */ uint8_t *lastPortionData; /**< Pointer to last portion of - packet (if any). The number of - bytes in this portion is + packet, if any; NULL otherwise. The + number of bytes in this portion is packetBytes - firstPortionBytes. */ } RAIL_RxPacketInfo_t; @@ -1747,6 +2006,12 @@ typedef struct RAIL_RxPacketDetails { * this ability, and the subPhy is set to 0 in those cases. */ uint8_t subPhyId; + /** + * For configurations where the device has multiple antennas, indicates + * which antenna received the packets. For hardware configurations + * with only one antenna, this will be set to the default of 0. + */ + uint8_t antennaId; } RAIL_RxPacketDetails_t; /** @@ -1940,6 +2205,59 @@ RAIL_ENUM(RAIL_StreamMode_t) { RAIL_STREAM_PN9_STREAM = 1, /**< PN9 byte sequence */ }; +/** + * @def RAIL_VERIFY_DURATION_MAX + * @brief This radio state verification duration indicates to RAIL that + * all memory contents should be verified by RAIL before returning to the + * application. + */ +#define RAIL_VERIFY_DURATION_MAX 0xFFFFFFFFUL + +/** + * A pointer to a verification callback function. This will be called by the + * radio state verification feature built into RAIL when a verified memory + * value is different from its reference value. + * + * @param[in] address The address of the data in question. + * @param[in] expectedValue The expected value of the data in question. + * @param[in] actualValue The actual value of the data in question. + * @return bool True indicates a data value difference is acceptable, and False + * indicates a data value difference in unacceptable. + * + * @note This callback will be issued when an address' value is different from + * its reference value and either of the following conditions are met: + * 1) The default radio config provided by the radio configurator is used + * for verification purposes (i.e. a custom radio config is not supplied + * as an input to \ref RAIL_ConfigVerification()), and the radio + * configurator has flagged the address under question as being verifiable. + * 2) A custom radio config is provided to the verification API (i.e. + * a custom radio config is supplied as an input to \ref + * RAIL_ConfigVerification()). When providing a custom radio config for + * verification purposes, all addresses in that config will be verified, + * regardless of whether or not the addresses are flagged as verifiable. + */ +typedef bool (*RAIL_VerifyCallbackPtr_t)(uint32_t address, + uint32_t expectedValue, + uint32_t actualValue); + +/** + * @struct RAIL_VerifyConfig_t + * @brief The configuration array provided to RAIL for use by the radio state + * verification feature. This structure will be populated with appropriate + * values by calling \ref RAIL_ConfigVerification(). The application should + * not set or alter any of these structure elements. + */ +typedef struct RAIL_VerifyConfig { + /** Internal verification tracking information */ + RAIL_Handle_t correspondingHandle; + /** Internal verification tracking information */ + uint32_t nextIndexToVerify; + /** Internal verification tracking information */ + const uint32_t *override; + /** Internal verification tracking information */ + RAIL_VerifyCallbackPtr_t cb; +} RAIL_VerifyConfig_t; + #ifndef DOXYGEN_SHOULD_SKIP_THIS typedef struct RAIL_DirectModeConfig { @@ -1983,4 +2301,8 @@ typedef struct RAIL_DirectModeConfig { * end of RAIL_API */ +#ifdef __cplusplus +} +#endif + #endif // __RAIL_TYPES_H__ diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/timing_state.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/timing_state.h old mode 100644 new mode 100755 index 4b5fda137f..8fc3c81a8e --- a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/timing_state.h +++ b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/timing_state.h @@ -4,7 +4,7 @@ * @version INTERNAL ******************************************************************************* * @section License - * (C) Copyright 2017 Silicon Labs, http://silabs.com + * (C) Copyright 2017 Silicon Labs, www.silabs.com ******************************************************************************/ #ifndef __TIMING_STATE_H #define __TIMING_STATE_H @@ -34,6 +34,12 @@ typedef struct StateTimings { // delay for RX only calculates how long we need to stay in RX to get SYNC, // which does not need to be precise. (And hard to measure.) int32_t rxDoneDelayNs; +#endif +#if _SILICON_LABS_32B_SERIES_1_CONFIG >= 2 + // The viterbi phy needs extra time to power up the receive path during + // TX2RX in order to receive low RSSI packets. This flag indicates to + // turn on that extra time + bool viterbiPhy; #endif int32_t txChainDelayNs; uint16_t rxSearch; From a9101c2586fb8235fece6d3260a43df7e5bcfff8 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 23 Apr 2018 08:21:20 -0500 Subject: [PATCH 19/46] Revert file permissions to non-executable --- .../rail/TARGET_EFR32_1/librail_efr32xg1_release.a | Bin .../rail/TARGET_EFR32_1/librail_efr32xg1_release.ar | Bin .../TARGET_EFR32_12/librail_efr32xg12_release.a | Bin .../TARGET_EFR32_12/librail_efr32xg12_release.ar | Bin .../efr32-rf-driver/rail/ble/rail_ble.h | 0 .../rail/ieee802154/rail_ieee802154.h | 0 .../TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h | 0 .../TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h | 0 .../TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h | 0 .../efr32-rf-driver/rail/rail_assert_error_codes.h | 0 .../efr32-rf-driver/rail/rail_chip_specific.h | 0 .../efr32-rf-driver/rail/rail_types.h | 0 .../efr32-rf-driver/rail/timing_state.h | 0 13 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.a mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.ar mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.a mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.ar mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ble/rail_ble.h mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ieee802154/rail_ieee802154.h mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_assert_error_codes.h mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_chip_specific.h mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_types.h mode change 100755 => 100644 targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/timing_state.h diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.a b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.a old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.ar b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_1/librail_efr32xg1_release.ar old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.a b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.a old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.ar b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/TARGET_EFR32_12/librail_efr32xg12_release.ar old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ble/rail_ble.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ble/rail_ble.h old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ieee802154/rail_ieee802154.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/ieee802154/rail_ieee802154.h old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pa.h old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/pti.h old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail.h old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_assert_error_codes.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_assert_error_codes.h old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_chip_specific.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_chip_specific.h old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_types.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/rail_types.h old mode 100755 new mode 100644 diff --git a/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/timing_state.h b/targets/TARGET_Silicon_Labs/TARGET_SL_RAIL/efr32-rf-driver/rail/timing_state.h old mode 100755 new mode 100644 From 60781c860e2fc81addc8059fb8c66d82d56cbcb5 Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Tue, 17 Apr 2018 10:42:59 -0500 Subject: [PATCH 20/46] Update doxygen options rules to not strip code comments --- doxygen_options.json | 1 + 1 file changed, 1 insertion(+) diff --git a/doxygen_options.json b/doxygen_options.json index 4d0530b0e9..fc5ba91bbc 100644 --- a/doxygen_options.json +++ b/doxygen_options.json @@ -9,5 +9,6 @@ "PREDEFINED": "DOXYGEN_ONLY DEVICE_ANALOGIN DEVICE_ANALOGOUT DEVICE_CAN DEVICE_ETHERNET DEVICE_EMAC DEVICE_FLASH DEVICE_I2C DEVICE_I2CSLAVE DEVICE_I2C_ASYNCH DEVICE_INTERRUPTIN DEVICE_ITM DEVICE_LOWPOWERTIMER DEVICE_PORTIN DEVICE_PORTINOUT DEVICE_PORTOUT DEVICE_PWMOUT DEVICE_RTC DEVICE_TRNG DEVICE_SERIAL DEVICE_SERIAL_ASYNCH DEVICE_SERIAL_FC DEVICE_SLEEP DEVICE_SPI DEVICE_SPI_ASYNCH DEVICE_SPISLAVE DEVICE_STORAGE \"MBED_DEPRECATED_SINCE(f, g)=\" \"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=\" \"MBED_DEPRECATED(s)=\"", "EXPAND_AS_DEFINED": "", "SKIP_FUNCTION_MACROS": "NO", + "STRIP_CODE_COMMENTS": "NO", "EXCLUDE_PATTERNS": "*/tools/* */targets/* */features/mbedtls/* */features/storage/* */features/unsupported/* */BUILD/* */rtos/TARGET_CORTEX/rtx*/* */cmsis/* */features/FEATURE_COMMON_PAL/* */features/FEATURE_LWIP/* */features/FEATURE_UVISOR/* */features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/* */features/nanostack/FEATURE_NANOSTACK/coap-service/* */ble/generic/* */ble/pal/*" } From bec428ec1b7521bfa49cc0167f28b0dccc12d6a8 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 25 Apr 2018 15:33:40 +0300 Subject: [PATCH 21/46] Clarify mesh configuration values. Most of the help fields were correct. Just add field specifying acceptable ranges. --- .../mbed_lib.json | 2 +- .../mbed-mesh-api/mbed_lib.json | 30 +++++++++---------- .../sal-stack-nanostack/mbed_lib.json | 5 +++- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/mbed_lib.json b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/mbed_lib.json index 408bb7627f..091fa46ae6 100644 --- a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/mbed_lib.json +++ b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/mbed_lib.json @@ -6,7 +6,7 @@ "value": false }, "event_loop_thread_stack_size": { - "help": "Define event-loop thread stack size.", + "help": "Define event-loop thread stack size. [bytes]", "value": 6144 }, "critical-section-usable-from-interrupt": { diff --git a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json index 5ccb713378..a209ef14a9 100644 --- a/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json +++ b/features/nanostack/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json @@ -2,15 +2,15 @@ "name": "mbed-mesh-api", "config": { "heap-size": { - "help": "Nanostack's heap size (bytes: 0-65534)", + "help": "Nanostack's heap size [bytes: 0-65534]", "value": 32500 }, "use-malloc-for-heap": { - "help": "Use `malloc()` for reserving the internal heap.", + "help": "Use `malloc()` for reserving the Nanostack's internal heap.", "value": false }, "6lowpan-nd-channel-mask": { - "help": "Channel mask, bit mask of channels to use.", + "help": "Channel mask, bit-mask of channels to use. [0-0x07fff800]", "value": "0x7fff800" }, "6lowpan-nd-channel-page": { @@ -18,11 +18,11 @@ "value": 0 }, "6lowpan-nd-channel": { - "help": "RF channel to use when `channel_mask` is not defined (0-26).", + "help": "RF channel to use when `channel_mask` is not defined. [0-26].", "value": 0 }, "6lowpan-nd-panid-filter": { - "help": "Beacon PAN ID filter, 0xffff means no filtering.", + "help": "Beacon PAN ID filter, 0xffff means no filtering. [0-0xffff]", "value": "0xffff" }, "6lowpan-nd-security-mode": { @@ -34,7 +34,7 @@ "value": 1 }, "6lowpan-nd-psk-key": { - "help": "Pre-shared network key.", + "help": "Pre-shared network key. Byte array of 16 bytes. In form of: {0x00, 0x11, ... 0xff}", "value": "{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf}" }, "6lowpan-nd-sec-level": { @@ -54,7 +54,7 @@ "value": true }, "thread-config-channel-mask": { - "help": "Channel mask, 0x7ffff800 scans all channels.", + "help": "Channel bit mask, 0x7ffff800 scans all channels. [0-0x07fff800]", "value": "0x7fff800" }, "thread-config-channel-page": { @@ -62,15 +62,15 @@ "value": 0 }, "thread-config-channel": { - "help": "RF channel to use. (11-26)", + "help": "RF channel to use. [11-26]", "value": 22 }, "thread-config-panid": { - "help": "Network identifier (0-0xFFFF)", + "help": "Network identifier [0-0xFFFF]", "value": "0x0700" }, "thread-config-network-name": { - "help": "Network name (max 16 characters)", + "help": "Network name [string, max 16 characters]", "value": "\"Thread Network\"" }, "thread-config-commissioning-dataset-timestamp": { @@ -78,19 +78,19 @@ "value": "0x10000" }, "thread-config-extended-panid": { - "help": "Extended PAN ID.", + "help": "Extended PAN ID. [8 byte array]", "value": "{0xf1, 0xb5, 0xa1, 0xb2,0xc4, 0xd5, 0xa1, 0xbd }" }, "thread-master-key": { - "help": "Network master key.", + "help": "Network master key. [16 byte array]", "value": "{0x10, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}" }, "thread-config-ml-prefix": { - "help": "Mesh Local prefix.", + "help": "Mesh Local prefix. [8 byte array]", "value": "{0xfd, 0x0, 0x0d, 0xb8, 0x0, 0x0, 0x0, 0x0}" }, "thread-config-pskc": { - "help": "Pre-Shared Key for the Commissioner.", + "help": "Pre-Shared Key for the Commissioner. [16 byte array]", "value": "{0xc8, 0xa6, 0x2e, 0xae, 0xf3, 0x68, 0xf3, 0x46, 0xa9, 0x9e, 0x57, 0x85, 0x98, 0x9d, 0x1c, 0xd0}" }, "thread-device-type": { @@ -98,7 +98,7 @@ "value": "MESH_DEVICE_TYPE_THREAD_ROUTER" }, "thread-security-policy": { - "help": "Commissioning security policy bits (0-0xFF)", + "help": "Commissioning security policy bits [0-0xFF]", "value": 255 } } diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/mbed_lib.json b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/mbed_lib.json index ba94bfbc7d..4def941f3a 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/mbed_lib.json +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/mbed_lib.json @@ -1,7 +1,10 @@ { "name": "nanostack", "config": { - "configuration": "nanostack_full" + "configuration": { + "help": "Build time configuration. Refer to Handbook for valid values. Default: full stack", + "value": "nanostack_full" + } }, "macros": ["NS_USE_EXTERNAL_MBED_TLS"] } From 1d3b504d9827599ab9c39dc0a6fc7e0ac19dfd16 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Tue, 24 Apr 2018 11:24:23 -0500 Subject: [PATCH 22/46] LPC546XX: Set the pin function to Digital mode We cannot rely on the default value as a pin could be use for Analog purposes in which this bit is cleared Signed-off-by: Mahesh Mahadevan --- targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/pinmap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/pinmap.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/pinmap.c index 6a3b87d644..5d03ca0f50 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/pinmap.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/pinmap.c @@ -29,6 +29,9 @@ void pin_function(PinName pin, int function) CLOCK_EnableClock(gpio_clocks[port_number]); CLOCK_EnableClock(kCLOCK_Iocon); + /* Set the DIGIMODE bit */ + IOCON->PIO[port_number][pin_number] |= IOCON_PIO_DIGIMODE_MASK; + reg = IOCON->PIO[port_number][pin_number]; reg = (reg & ~0x7) | (function & 0x7); IOCON->PIO[port_number][pin_number] = reg; From 7f11ac0b9522ee4bf92aa05f58f18070a2518923 Mon Sep 17 00:00:00 2001 From: Keyur Hariya Date: Mon, 23 Apr 2018 15:43:46 -0500 Subject: [PATCH 23/46] Add type cast --- targets/TARGET_Maxim/TARGET_MAX32620C/analogin_api.c | 3 +-- targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c | 2 +- targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c | 3 +-- targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c | 2 +- targets/TARGET_Maxim/TARGET_MAX32630/analogin_api.c | 3 +-- targets/TARGET_Maxim/TARGET_MAX32630/i2c_api.c | 2 +- 6 files changed, 6 insertions(+), 9 deletions(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/analogin_api.c b/targets/TARGET_Maxim/TARGET_MAX32620C/analogin_api.c index 9079b2a638..7c4971b139 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/analogin_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/analogin_api.c @@ -50,7 +50,7 @@ void analogin_init(analogin_t *obj, PinName pin) // Set the object pointer and channel encoding obj->adc = MXC_ADC; - obj->channel = pinmap_find_function(pin, PinMap_ADC); + obj->channel = (mxc_adc_chsel_t)pinmap_find_function(pin, PinMap_ADC); if (!initialized) { MBED_ASSERT(ADC_Init() == E_NO_ERROR); @@ -93,4 +93,3 @@ uint16_t analogin_read_u16(analogin_t *obj) return result; } - diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c b/targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c index 49a2706eb7..4faf56cdf7 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/i2c_api.c @@ -78,7 +78,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) //****************************************************************************** void i2c_frequency(i2c_t *obj, int hz) { - I2CM_Init(obj->i2c, &obj->sys_cfg, hz); + I2CM_Init(obj->i2c, &obj->sys_cfg, (i2cm_speed_t)hz); } //****************************************************************************** diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c index 560d535314..844d35c7bf 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c @@ -50,7 +50,7 @@ void analogin_init(analogin_t *obj, PinName pin) // Set the object pointer and channel encoding obj->adc = MXC_ADC; - obj->channel = pinmap_find_function(pin, PinMap_ADC); + obj->channel = (mxc_adc_chsel_t)pinmap_find_function(pin, PinMap_ADC); if (!initialized) { MBED_ASSERT(ADC_Init() == E_NO_ERROR); @@ -93,4 +93,3 @@ uint16_t analogin_read_u16(analogin_t *obj) return result; } - diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c index a068a23efe..c8d3359340 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32625/i2c_api.c @@ -79,7 +79,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) //****************************************************************************** void i2c_frequency(i2c_t *obj, int hz) { - I2CM_SetFrequency(obj->i2c, hz); + I2CM_SetFrequency(obj->i2c, (i2cm_speed_t)hz); } //****************************************************************************** diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/analogin_api.c b/targets/TARGET_Maxim/TARGET_MAX32630/analogin_api.c index 560d535314..844d35c7bf 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32630/analogin_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32630/analogin_api.c @@ -50,7 +50,7 @@ void analogin_init(analogin_t *obj, PinName pin) // Set the object pointer and channel encoding obj->adc = MXC_ADC; - obj->channel = pinmap_find_function(pin, PinMap_ADC); + obj->channel = (mxc_adc_chsel_t)pinmap_find_function(pin, PinMap_ADC); if (!initialized) { MBED_ASSERT(ADC_Init() == E_NO_ERROR); @@ -93,4 +93,3 @@ uint16_t analogin_read_u16(analogin_t *obj) return result; } - diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/i2c_api.c b/targets/TARGET_Maxim/TARGET_MAX32630/i2c_api.c index edd351fb79..cf2ab623df 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32630/i2c_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32630/i2c_api.c @@ -78,7 +78,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) //****************************************************************************** void i2c_frequency(i2c_t *obj, int hz) { - I2CM_Init(obj->i2c, &obj->sys_cfg, hz); + I2CM_Init(obj->i2c, &obj->sys_cfg, (i2cm_speed_t)hz); } //****************************************************************************** From 4edbde80b9fd280404efeb2c09e330e0652c5acb Mon Sep 17 00:00:00 2001 From: Keyur Hariya Date: Mon, 23 Apr 2018 15:45:05 -0500 Subject: [PATCH 24/46] Fix the return type to allow returning error --- targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.c | 2 +- targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.h | 2 +- targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c | 2 +- targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.c b/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.c index d0d26c1c01..c16343eee5 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.c @@ -179,7 +179,7 @@ int LP_ConfigGPIOWakeUpDetect(const gpio_cfg_t *gpio, unsigned int act_high, lp_ return result; } -uint8_t LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio) +int LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio) { uint8_t gpioWokeUp = 0; diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.h b/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.h index 55487f5a8e..521996c7ec 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.h +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/lp.h @@ -138,7 +138,7 @@ int LP_ClearGPIOWakeUpDetect(const gpio_cfg_t *gpio); * nonzero = at least one of the gpio passed in triggered a wake up * the bit set represents which pin is the wake up source */ -uint8_t LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio); +int LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio); /** * @brief Wake on USB plug or unplug diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c index fd1a0889e3..ce8944d478 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.c @@ -178,7 +178,7 @@ int LP_ConfigGPIOWakeUpDetect(const gpio_cfg_t *gpio, unsigned int act_high, lp_ return result; } -uint8_t LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio) +int LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio) { uint8_t gpioWokeUp = 0; diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h index 1c1e73846e..4a5017fdea 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h +++ b/targets/TARGET_Maxim/TARGET_MAX32625/mxc/lp.h @@ -138,7 +138,7 @@ int LP_ClearGPIOWakeUpDetect(const gpio_cfg_t *gpio); * nonzero = at least one of the gpio passed in triggered a wake up * the bit set represents which pin is the wake up source */ -uint8_t LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio); +int LP_IsGPIOWakeUpSource(const gpio_cfg_t *gpio); /** * @brief Wake on USB plug or unplug From 974864adba6c2bc4c43b1b2f8b97e175bd026e2c Mon Sep 17 00:00:00 2001 From: Keyur Hariya Date: Mon, 23 Apr 2018 15:46:18 -0500 Subject: [PATCH 25/46] Add the missing input parameter --- .../TARGET_MAX32620C/mxc/mxc_sys.h | 12 +++---- .../TARGET_MAX32630/mxc/mxc_sys.h | 34 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/mxc_sys.h b/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/mxc_sys.h index 753fcce180..e96de2a442 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/mxc_sys.h +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/mxc_sys.h @@ -125,7 +125,7 @@ uint32_t SYS_CPU_GetFreq(void); * @returns E_NO_ERROR if everything is successful */ int SYS_ADC_Init(void); - + /** * @brief System level initialization for AES module. * @returns E_NO_ERROR if everything is successful @@ -240,13 +240,13 @@ int SYS_SPIX_Init(const sys_cfg_spix_t *sys_cfg, uint32_t baud); * @brief System level shutdown for SPIX module * @returns E_NO_ERROR if everything is successful */ -int SYS_SPIX_Shutdown(); +int SYS_SPIX_Shutdown(void); /** * @brief Get the frequency of the SPIX module source clock * @returns frequency in Hz */ -uint32_t SYS_SPIX_GetFreq(); +uint32_t SYS_SPIX_GetFreq(void); /** * @brief System level initialization for SPIS module. @@ -259,13 +259,13 @@ int SYS_SPIS_Init(const sys_cfg_spix_t *sys_cfg); * @brief System level shutdown for SPIS module * @returns E_NO_ERROR if everything is successful */ -int SYS_SPIS_Shutdown(); +int SYS_SPIS_Shutdown(void); /** * @brief Get the frequency of the SPIS module source clock * @returns frequency in Hz */ -uint32_t SYS_SPIS_GetFreq(); +uint32_t SYS_SPIS_GetFreq(void); /** * @brief System level initialization for OWM module. @@ -436,7 +436,7 @@ uint32_t SYS_SRAM_GetSize(void); * @returns size of Flash in bytes */ uint32_t SYS_FLASH_GetSize(void); - + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_sys.h b/targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_sys.h index 05babf66c9..9bab2aabcc 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_sys.h +++ b/targets/TARGET_Maxim/TARGET_MAX32630/mxc/mxc_sys.h @@ -92,50 +92,50 @@ typedef struct { */ typedef sys_cfg_t sys_cfg_uart_t; -/** +/** * Structure type for I2CM System Configuration. * @ingroup i2cm */ typedef sys_cfg_t sys_cfg_i2cm_t; -/** - * Structure type for I2CS System Configuration. +/** + * Structure type for I2CS System Configuration. * @ingroup i2cs */ typedef sys_cfg_t sys_cfg_i2cs_t; -/** - * Structure type for SPIM System Configuration. +/** + * Structure type for SPIM System Configuration. * @ingroup spim */ typedef sys_cfg_t sys_cfg_spim_t; -/** - * Structure type for SPIX System Configuration. - * @ingroup spix +/** + * Structure type for SPIX System Configuration. + * @ingroup spix */ typedef sys_cfg_t sys_cfg_spix_t; -/** - * Structure type for OWM System Configuration. +/** + * Structure type for OWM System Configuration. * @ingroup owm */ typedef sys_cfg_t sys_cfg_owm_t; -/** - * Structure type for Timer System Configuration. +/** + * Structure type for Timer System Configuration. * @ingroup timer */ typedef gpio_cfg_t sys_cfg_tmr_t; -/** +/** * Structure type for Pulse Train System Configuration. * @ingroup pulsetrain */ typedef gpio_cfg_t sys_cfg_pt_t; /** - * Structure type for Pulse Train Clock Scale Configuration. + * Structure type for Pulse Train Clock Scale Configuration. * @ingroup clkman * @ingroup pulsetrain */ @@ -168,7 +168,7 @@ uint32_t SYS_CPU_GetFreq(void); * @ingroup adc */ int SYS_ADC_Init(void); - + /** * @brief System level initialization for the AES module. * @return #E_NO_ERROR if everything is successful @@ -299,14 +299,14 @@ int SYS_SPIX_Init(const sys_cfg_spix_t *sys_cfg, uint32_t baud); * @return #E_NO_ERROR if everything is successful * @ingroup spix */ -int SYS_SPIX_Shutdown(); +int SYS_SPIX_Shutdown(void); /** * @brief Get the frequency of the SPIX module source clock * @return frequency in Hz * @ingroup spix */ -uint32_t SYS_SPIX_GetFreq(); +uint32_t SYS_SPIX_GetFreq(void); /** * @brief System level initialization for OWM module. From 74ae87eeeb200793fba082b69d5e7f7f5cc39e9f Mon Sep 17 00:00:00 2001 From: Keyur Hariya Date: Mon, 23 Apr 2018 15:52:44 -0500 Subject: [PATCH 26/46] Remove the redundant input parameter --- targets/TARGET_Maxim/TARGET_MAX32620C/mxc/spis.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/spis.c b/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/spis.c index 6d2317107d..ae85aaf5ee 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/spis.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/mxc/spis.c @@ -46,9 +46,9 @@ #include "spis.h" /** - * @ingroup spis + * @ingroup spis * @{ - */ + */ /* **** Definitions **** */ #define SPIS_FIFO_BUFFER 6 @@ -119,7 +119,7 @@ int SPIS_Shutdown(mxc_spis_regs_t *spis) } // Clear system level configurations - if ((err = SYS_SPIS_Shutdown(spis)) != E_NO_ERROR) { + if ((err = SYS_SPIS_Shutdown()) != E_NO_ERROR) { return err; } @@ -162,7 +162,7 @@ int SPIS_Trans(mxc_spis_regs_t *spis, spis_req_t *req) // Start the transaction, keep calling the handler until complete spis->intfl = (MXC_F_SPIS_INTFL_SS_DEASSERTED | MXC_F_SPIS_INTFL_TX_UNDERFLOW); - while(SPIS_TransHandler(spis, req, spis_num) & (MXC_F_SPIS_INTEN_RX_FIFO_AF | + while(SPIS_TransHandler(spis, req, spis_num) & (MXC_F_SPIS_INTEN_RX_FIFO_AF | MXC_F_SPIS_INTEN_TX_FIFO_AE)) { if((req->tx_data != NULL) && (spis->intfl & MXC_F_SPIS_INTFL_TX_UNDERFLOW)) { @@ -174,7 +174,7 @@ int SPIS_Trans(mxc_spis_regs_t *spis, spis_req_t *req) } if((req->deass) && (spis->intfl & MXC_F_SPIS_INTFL_SS_DEASSERTED)) { - if(((req->rx_data != NULL) && ((req->read_num + SPIS_NumReadAvail(spis)) < req->len)) || + if(((req->rx_data != NULL) && ((req->read_num + SPIS_NumReadAvail(spis)) < req->len)) || ((req->tx_data != NULL) && (req->write_num < req->len))) { return E_COMM_ERR; @@ -306,7 +306,7 @@ void SPIS_Handler(mxc_spis_regs_t *spis) if((flags & MXC_F_SPIS_INTFL_SS_DEASSERTED) && (req != NULL) && (req->deass)) { - if(((req->rx_data != NULL) && ((req->read_num + SPIS_NumReadAvail(spis)) < req->len)) || + if(((req->rx_data != NULL) && ((req->read_num + SPIS_NumReadAvail(spis)) < req->len)) || ((req->tx_data != NULL) && (req->write_num < req->len))) { // Unlock this SPIS From c87b8a6d37c532f21a23cd1cd0ddb66e00a776c9 Mon Sep 17 00:00:00 2001 From: Keyur Hariya Date: Mon, 23 Apr 2018 15:53:20 -0500 Subject: [PATCH 27/46] Fix the initialization of a structure --- targets/TARGET_Maxim/TARGET_MAX32620C/rtc_api.c | 4 +++- targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c | 4 +++- targets/TARGET_Maxim/TARGET_MAX32630/rtc_api.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/rtc_api.c b/targets/TARGET_Maxim/TARGET_MAX32620C/rtc_api.c index ff39b3673e..38ce17209c 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/rtc_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/rtc_api.c @@ -35,6 +35,7 @@ #include "lp_ticker_api.h" #include "rtc.h" #include "lp.h" +#include // LOG2 for 32-bit powers of 2 #define LOG2_1(n) (((n) >= (1 << 1)) ? 1 : 0) @@ -65,7 +66,8 @@ static void init_rtc(void) * if it is already running. */ if (!RTC_IsActive()) { - rtc_cfg_t cfg = { 0 }; + rtc_cfg_t cfg; + memset(&cfg, 0, sizeof(rtc_cfg_t)); cfg.prescaler = LP_TIMER_PRESCALE; cfg.snoozeMode = RTC_SNOOZE_DISABLE; diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c index ff39b3673e..38ce17209c 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32625/rtc_api.c @@ -35,6 +35,7 @@ #include "lp_ticker_api.h" #include "rtc.h" #include "lp.h" +#include // LOG2 for 32-bit powers of 2 #define LOG2_1(n) (((n) >= (1 << 1)) ? 1 : 0) @@ -65,7 +66,8 @@ static void init_rtc(void) * if it is already running. */ if (!RTC_IsActive()) { - rtc_cfg_t cfg = { 0 }; + rtc_cfg_t cfg; + memset(&cfg, 0, sizeof(rtc_cfg_t)); cfg.prescaler = LP_TIMER_PRESCALE; cfg.snoozeMode = RTC_SNOOZE_DISABLE; diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/rtc_api.c b/targets/TARGET_Maxim/TARGET_MAX32630/rtc_api.c index b8cc9d092e..5c1d3274a6 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32630/rtc_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32630/rtc_api.c @@ -35,6 +35,7 @@ #include "lp_ticker_api.h" #include "rtc.h" #include "lp.h" +#include // LOG2 for 32-bit powers of 2 #define LOG2_1(n) (((n) >= (1 << 1)) ? 1 : 0) @@ -65,7 +66,8 @@ static void init_rtc(void) * if it is already running. */ if (!RTC_IsActive()) { - rtc_cfg_t cfg = {0}; + rtc_cfg_t cfg; + memset(&cfg, 0, sizeof(rtc_cfg_t)); cfg.prescaler = LP_TIMER_PRESCALE; cfg.snoozeMode = RTC_SNOOZE_DISABLE; From 8febfd99f2ab1b7b9b00fb27c86a52f581b039d7 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Mon, 16 Apr 2018 16:10:57 +0800 Subject: [PATCH 28/46] Fix build tool with ARMC6/ARMv8M 1. Add linking time preprocessor macro __DOMAIN_NS for non-secure build 2. For output .hex format, combine multiple .hex files (for multiple load regions) into one This can help for Greentea test. 3. Fix 'None' build_dir with cmse_lib.o on Greentea test --- tools/toolchains/arm.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index 9bb21ece5f..a555defb94 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -233,6 +233,11 @@ class ARM(mbedToolchain): cmd_pre = self.ld + args cmd = self.hook.get_cmdline_linker(cmd_pre) + # Create Secure library + if self.target.core == "Cortex-M23" or self.target.core == "Cortex-M33": + secure_file = join(dirname(output), "cmse_lib.o") + cmd.extend(["--import_cmse_lib_out=%s" % secure_file]) + if self.RESPONSE_FILES: cmd_linker = cmd[0] link_files = self.get_link_file(cmd[1:]) @@ -252,7 +257,8 @@ class ARM(mbedToolchain): @hook_tool def binary(self, resources, elf, bin): _, fmt = splitext(bin) - bin_arg = {".bin": "--bin", ".hex": "--i32"}[fmt] + # On .hex format, combine multiple .hex files (for multiple load regions) into one + bin_arg = {".bin": "--bin", ".hex": "--i32combined"}[fmt] cmd = [self.elf2bin, bin_arg, '-o', bin, elf] cmd = self.hook.get_cmdline_binary(cmd) @@ -357,13 +363,12 @@ class ARMC6(ARM_STD): if target.core == "Cortex-M23" or target.core == "Cortex-M33": self.flags['common'].append("-mcmse") - - # Create Secure library - if target.core == "Cortex-M23" or self.target.core == "Cortex-M33": - build_dir = kwargs['build_dir'] - secure_file = join(build_dir, "cmse_lib.o") - self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file] - + + # Add linking time preprocessor macro __DOMAIN_NS + if target.core == "Cortex-M23-NS" or self.target.core == "Cortex-M33-NS": + define_string = self.make_ld_define("__DOMAIN_NS", 1) + self.flags["ld"].append(define_string) + asm_cpu = { "Cortex-M0+": "Cortex-M0", "Cortex-M4F": "Cortex-M4.fp", From 3b76d9d94d2936a037244c787708c62993e2843c Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Tue, 17 Apr 2018 11:58:02 -0500 Subject: [PATCH 29/46] Correct exporting with cortex-M23 and M33 --- tools/test_api.py | 5 +++-- tools/toolchains/arm.py | 14 +++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tools/test_api.py b/tools/test_api.py index aab28a4db2..a485fb99bb 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -2077,8 +2077,9 @@ def find_tests(base_dir, target_name, toolchain_name, app_config=None): commons = [] # Prepare the toolchain - toolchain = prepare_toolchain([base_dir], None, target_name, toolchain_name, - silent=True, app_config=app_config) + toolchain = prepare_toolchain( + [base_dir], base_dir, target_name, toolchain_name, silent=True, + app_config=app_config) # Scan the directory for paths to probe for 'TESTS' folders base_resources = scan_resources([base_dir], toolchain) diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index a555defb94..72b277d340 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -233,11 +233,6 @@ class ARM(mbedToolchain): cmd_pre = self.ld + args cmd = self.hook.get_cmdline_linker(cmd_pre) - # Create Secure library - if self.target.core == "Cortex-M23" or self.target.core == "Cortex-M33": - secure_file = join(dirname(output), "cmse_lib.o") - cmd.extend(["--import_cmse_lib_out=%s" % secure_file]) - if self.RESPONSE_FILES: cmd_linker = cmd[0] link_files = self.get_link_file(cmd[1:]) @@ -363,12 +358,17 @@ class ARMC6(ARM_STD): if target.core == "Cortex-M23" or target.core == "Cortex-M33": self.flags['common'].append("-mcmse") - + + # Create Secure library + if target.core == "Cortex-M23" or self.target.core == "Cortex-M33": + build_dir = kwargs['build_dir'] + secure_file = join(build_dir, "cmse_lib.o") + self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file] # Add linking time preprocessor macro __DOMAIN_NS if target.core == "Cortex-M23-NS" or self.target.core == "Cortex-M33-NS": define_string = self.make_ld_define("__DOMAIN_NS", 1) self.flags["ld"].append(define_string) - + asm_cpu = { "Cortex-M0+": "Cortex-M0", "Cortex-M4F": "Cortex-M4.fp", From f9a78afd8ce57040c08ff4519e58846b24fbc275 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Tue, 24 Apr 2018 10:07:16 -0500 Subject: [PATCH 30/46] Correct test finding behavior Scan resources ignores the build dir so we can't set it to something dumb like the directory we want to scan --- tools/test_api.py | 5 ++--- tools/toolchains/arm.py | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/test_api.py b/tools/test_api.py index a485fb99bb..aab28a4db2 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -2077,9 +2077,8 @@ def find_tests(base_dir, target_name, toolchain_name, app_config=None): commons = [] # Prepare the toolchain - toolchain = prepare_toolchain( - [base_dir], base_dir, target_name, toolchain_name, silent=True, - app_config=app_config) + toolchain = prepare_toolchain([base_dir], None, target_name, toolchain_name, + silent=True, app_config=app_config) # Scan the directory for paths to probe for 'TESTS' folders base_resources = scan_resources([base_dir], toolchain) diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index 72b277d340..cb0cd7b5fe 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -360,7 +360,8 @@ class ARMC6(ARM_STD): self.flags['common'].append("-mcmse") # Create Secure library - if target.core == "Cortex-M23" or self.target.core == "Cortex-M33": + if ((target.core == "Cortex-M23" or self.target.core == "Cortex-M33") and + kwargs.get('build_dir', False)): build_dir = kwargs['build_dir'] secure_file = join(build_dir, "cmse_lib.o") self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file] From 962fc545784d0ef6f084a0c71d32a7914903f4eb Mon Sep 17 00:00:00 2001 From: Marcus Chang Date: Thu, 26 Apr 2018 09:33:43 -0700 Subject: [PATCH 31/46] Re-enable flash clock test for NRF52 but with higher tolerance The flash clock test is disabled for the NRF52 series. This change re-enables the test but with a higher tolerance to accommodate the high jitter on the current ticker implementation. --- TESTS/mbed_hal/flash/functional_tests/main.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/TESTS/mbed_hal/flash/functional_tests/main.cpp b/TESTS/mbed_hal/flash/functional_tests/main.cpp index 4b28510c68..8ca81ecb8b 100644 --- a/TESTS/mbed_hal/flash/functional_tests/main.cpp +++ b/TESTS/mbed_hal/flash/functional_tests/main.cpp @@ -28,7 +28,13 @@ using namespace utest::v1; #define TEST_CYCLES 10000000 + +#ifdef TARGET_NRF52 +/* The increased tolerance is to account for the imprecise timers on the NRF52. */ +#define ALLOWED_DRIFT_PPM (1000000/50000) //5.0% +#else #define ALLOWED_DRIFT_PPM (1000000/5000) //0.5% +#endif /* return values to be checked are documented at: @@ -279,9 +285,7 @@ Case cases[] = { Case("Flash - erase sector", flash_erase_sector_test), Case("Flash - program page", flash_program_page_test), Case("Flash - buffer alignment test", flash_buffer_alignment_test), -#ifndef MCU_NRF52 Case("Flash - clock and cache test", flash_clock_and_cache_test), -#endif }; utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { From a2910f8925abdb8373a8c07e2dc4204dd58a5c2c Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Tue, 1 May 2018 14:48:12 -0500 Subject: [PATCH 32/46] KW41Z: Update SDK TPM driver Certain instances of the TPM are missing some registers, updated TPM driver handles this variation. This issue was discovered when running the PWMOUT tests using the ci-test-shield Signed-off-by: Mahesh Mahadevan --- .../TARGET_KW41Z/device/MKW41Z4_features.h | 21 ++++++++++++++++--- .../TARGET_KW41Z/drivers/fsl_tpm.c | 14 +++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/MKW41Z4_features.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/MKW41Z4_features.h index 50aa128734..2daa41fba9 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/MKW41Z4_features.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/MKW41Z4_features.h @@ -1680,14 +1680,29 @@ #define FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER (1) /* @brief Has external trigger selection. */ #define FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION (1) -/* @brief Has TPM_COMBINE. */ +/* @brief Has TPM_COMBINE register. */ #define FSL_FEATURE_TPM_HAS_COMBINE (1) +/* @brief Whether COMBINE register has effect. */ +#define FSL_FEATURE_TPM_COMBINE_HAS_EFFECTn(x) \ + ((x) == TPM0 ? (0) : \ + ((x) == TPM1 ? (1) : \ + ((x) == TPM2 ? (1) : (-1)))) /* @brief Has TPM_POL. */ #define FSL_FEATURE_TPM_HAS_POL (1) -/* @brief Has TPM_FILTER. */ +/* @brief Has TPM_FILTER register. */ #define FSL_FEATURE_TPM_HAS_FILTER (1) -/* @brief Has TPM_QDCTRL. */ +/* @brief Whether FILTER register has effect. */ +#define FSL_FEATURE_TPM_FILTER_HAS_EFFECTn(x) \ + ((x) == TPM0 ? (0) : \ + ((x) == TPM1 ? (1) : \ + ((x) == TPM2 ? (1) : (-1)))) +/* @brief Has TPM_QDCTRL register. */ #define FSL_FEATURE_TPM_HAS_QDCTRL (1) +/* @brief Whether QDCTRL register has effect. */ +#define FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(x) \ + ((x) == TPM0 ? (0) : \ + ((x) == TPM1 ? (1) : \ + ((x) == TPM2 ? (1) : (-1)))) /* TRNG0 module features */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_tpm.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_tpm.c index 0571adbf63..e97fd48c1a 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_tpm.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_tpm.c @@ -162,6 +162,12 @@ status_t TPM_SetupPwm(TPM_Type *base, assert(pwmFreq_Hz); assert(numOfChnls); assert(srcClock_Hz); +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + if(mode == kTPM_CombinedPwm) + { + assert(FSL_FEATURE_TPM_COMBINE_HAS_EFFECTn(base)); + } +#endif uint32_t mod; uint32_t tpmClock = (srcClock_Hz / (1U << (base->SC & TPM_SC_PS_MASK))); @@ -169,8 +175,12 @@ status_t TPM_SetupPwm(TPM_Type *base, uint8_t i; #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL - /* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/ - base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + /* The TPM's QDCTRL register required to be effective */ + if( FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base) ) + { + /* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/ + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } #endif switch (mode) From 01ffbce4738b26077ad95c7a7dfa8326e6e47d22 Mon Sep 17 00:00:00 2001 From: deepikabhavnani Date: Tue, 1 May 2018 13:56:47 -0500 Subject: [PATCH 33/46] Moved stats test to platform folder --- TESTS/{mbed_drivers/stats => mbed_platform/stats_heap}/main.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename TESTS/{mbed_drivers/stats => mbed_platform/stats_heap}/main.cpp (100%) diff --git a/TESTS/mbed_drivers/stats/main.cpp b/TESTS/mbed_platform/stats_heap/main.cpp similarity index 100% rename from TESTS/mbed_drivers/stats/main.cpp rename to TESTS/mbed_platform/stats_heap/main.cpp From ff6f0592bb9b80691368aea2b2b76a8d126f61a3 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Tue, 1 May 2018 12:22:04 -0500 Subject: [PATCH 34/46] KL82Z: Fix clock selection for PWMOUT driver This was verified using the ci-test shield Signed-off-by: Mahesh Mahadevan --- .../TARGET_MCUXpresso_MCUS/TARGET_KL82Z/pwmout_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/pwmout_api.c index 405446e694..40ed83c4cb 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/pwmout_api.c @@ -36,9 +36,9 @@ void pwmout_init(pwmout_t* obj, PinName pin) uint32_t pwm_base_clock; - /* Set the TPM clock source to be IRC 48M */ + /* Set the TPM clock source to be MCG FLL clock */ CLOCK_SetTpmClock(1U); - pwm_base_clock = CLOCK_GetFreq(kCLOCK_McgIrc48MClk); + pwm_base_clock = CLOCK_GetFreq(kCLOCK_PllFllSelClk); float clkval = (float)pwm_base_clock / 1000000.0f; uint32_t clkdiv = 0; while (clkval > 1) { From f1cf7cc176931ca26571dda5f2b882ace840a425 Mon Sep 17 00:00:00 2001 From: Brendan McDonnell Date: Mon, 30 Apr 2018 17:49:37 -0400 Subject: [PATCH 35/46] use separate variable to resolve compiler warning --- .../lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c index 5b3b326435..4d21c32406 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c @@ -557,7 +557,7 @@ static err_t lpc_low_level_output(struct netif *netif, struct pbuf *p) u8_t *dst; u32_t idx, notdmasafe = 0; struct pbuf *np; - s32_t dn; + s32_t count, dn; /* Zero-copy TX buffers may be fragmented across mutliple payload chains. Determine the number of descriptors needed for the @@ -611,7 +611,7 @@ static err_t lpc_low_level_output(struct netif *netif, struct pbuf *p) /* Wait until enough descriptors are available for the transfer. */ /* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */ #if NO_SYS == 0 - for (idx = 0; idx < dn; idx++) { + for (count = 0; count < dn; count++) { osSemaphoreAcquire(lpc_enetif->xTXDCountSem.id, osWaitForever); } MBED_ASSERT(dn <= lpc_tx_ready(netif)); From 05c07b174419207cb636d3d7714664c4424a4561 Mon Sep 17 00:00:00 2001 From: Brendan McDonnell Date: Wed, 2 May 2018 11:16:58 -0400 Subject: [PATCH 36/46] reduce variable scope --- .../lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c index 4d21c32406..c79083c943 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/TARGET_LPCTarget/lpc17_emac.c @@ -557,7 +557,7 @@ static err_t lpc_low_level_output(struct netif *netif, struct pbuf *p) u8_t *dst; u32_t idx, notdmasafe = 0; struct pbuf *np; - s32_t count, dn; + s32_t dn; /* Zero-copy TX buffers may be fragmented across mutliple payload chains. Determine the number of descriptors needed for the @@ -611,7 +611,7 @@ static err_t lpc_low_level_output(struct netif *netif, struct pbuf *p) /* Wait until enough descriptors are available for the transfer. */ /* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */ #if NO_SYS == 0 - for (count = 0; count < dn; count++) { + for (s32_t count = 0; count < dn; count++) { osSemaphoreAcquire(lpc_enetif->xTXDCountSem.id, osWaitForever); } MBED_ASSERT(dn <= lpc_tx_ready(netif)); From bd9eff93f87b8f0a1ddc1eb503b1c2a3d704b171 Mon Sep 17 00:00:00 2001 From: Keyur Hariya Date: Mon, 30 Apr 2018 15:27:07 -0500 Subject: [PATCH 37/46] Add support for open drain leds --- targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c | 7 +++++++ targets/targets.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c index 2b5bb5e41b..c59a879a2b 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32625/gpio_api.c @@ -67,6 +67,13 @@ void gpio_init(gpio_t *obj, PinName name) void gpio_mode(gpio_t *obj, PinMode mode) { +#ifdef OPEN_DRAIN_LEDS + if ((obj->name == LED1) || (obj->name == LED2) || + (obj->name == LED3) || (obj->name == LED4)) { + mode = OpenDrain; + } +#endif + obj->mode = mode; pin_mode(obj->name, mode); } diff --git a/targets/targets.json b/targets/targets.json index 9ee12f7f14..2116c87d8b 100755 --- a/targets/targets.json +++ b/targets/targets.json @@ -2791,7 +2791,7 @@ "MAX32625MBED": { "inherits": ["Target"], "core": "Cortex-M4F", - "macros": ["__SYSTEM_HFX=96000000","TARGET=MAX32625","TARGET_REV=0x4132"], + "macros": ["__SYSTEM_HFX=96000000","TARGET=MAX32625","TARGET_REV=0x4132", "OPEN_DRAIN_LEDS"], "extra_labels": ["Maxim", "MAX32625"], "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], "device_has": ["ANALOGIN", "I2C", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "STDIO_MESSAGES"], From 420df0c793ea4d757de323c7be952d5d65a434b7 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 30 Apr 2018 03:42:53 -0500 Subject: [PATCH 38/46] littlefs: Fixed issue with trailing dots in file paths Paths such as the following were causing issues: /tea/hottea/. /tea/hottea/.. Unfortunately the existing structure for path lookup didn't make it very easy to introduce proper handling in this case without duplicating the entire skip logic for paths. So the lfs_dir_find function had to be restructured a bit. One odd side-effect of this is that now lfs_dir_find includes the initial fetch operation. This kinda breaks the fetch -> op pattern of the dir functions, but does come with a nice code size reduction. --- features/filesystem/littlefs/littlefs/lfs.c | 100 ++++++------------ .../littlefs/littlefs/tests/test_paths.sh | 16 +++ 2 files changed, 46 insertions(+), 70 deletions(-) diff --git a/features/filesystem/littlefs/littlefs/lfs.c b/features/filesystem/littlefs/littlefs/lfs.c index 0ae983d573..f12e9ccf92 100644 --- a/features/filesystem/littlefs/littlefs/lfs.c +++ b/features/filesystem/littlefs/littlefs/lfs.c @@ -783,26 +783,19 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry, const char **path) { const char *pathname = *path; size_t pathlen; + entry->d.type = LFS_TYPE_DIR; + entry->d.elen = sizeof(entry->d) - 4; + entry->d.alen = 0; + entry->d.nlen = 0; + entry->d.u.dir[0] = lfs->root[0]; + entry->d.u.dir[1] = lfs->root[1]; while (true) { - nextname: +nextname: // skip slashes pathname += strspn(pathname, "/"); pathlen = strcspn(pathname, "/"); - // special case for root dir - if (pathname[0] == '\0') { - *entry = (lfs_entry_t){ - .d.type = LFS_TYPE_DIR, - .d.elen = sizeof(entry->d) - 4, - .d.alen = 0, - .d.nlen = 0, - .d.u.dir[0] = lfs->root[0], - .d.u.dir[1] = lfs->root[1], - }; - return 0; - } - // skip '.' and root '..' if ((pathlen == 1 && memcmp(pathname, ".", 1) == 0) || (pathlen == 2 && memcmp(pathname, "..", 2) == 0)) { @@ -834,10 +827,25 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, suffix += sufflen; } + // found path + if (pathname[0] == '\0') { + return 0; + } + // update what we've found *path = pathname; - // find path + // continue on if we hit a directory + if (entry->d.type != LFS_TYPE_DIR) { + return LFS_ERR_NOTDIR; + } + + int err = lfs_dir_fetch(lfs, dir, entry->d.u.dir); + if (err) { + return err; + } + + // find entry matching name while (true) { int err = lfs_dir_next(lfs, dir, entry); if (err) { @@ -873,21 +881,8 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, entry->d.type &= ~0x80; } + // to next name pathname += pathlen; - pathname += strspn(pathname, "/"); - if (pathname[0] == '\0') { - return 0; - } - - // continue on if we hit a directory - if (entry->d.type != LFS_TYPE_DIR) { - return LFS_ERR_NOTDIR; - } - - int err = lfs_dir_fetch(lfs, dir, entry->d.u.dir); - if (err) { - return err; - } } } @@ -904,13 +899,8 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { // fetch parent directory lfs_dir_t cwd; - int err = lfs_dir_fetch(lfs, &cwd, lfs->root); - if (err) { - return err; - } - lfs_entry_t entry; - err = lfs_dir_find(lfs, &cwd, &entry, &path); + int err = lfs_dir_find(lfs, &cwd, &entry, &path); if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) { return err ? err : LFS_ERR_EXIST; } @@ -954,13 +944,8 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) { dir->pair[0] = lfs->root[0]; dir->pair[1] = lfs->root[1]; - int err = lfs_dir_fetch(lfs, dir, dir->pair); - if (err) { - return err; - } - lfs_entry_t entry; - err = lfs_dir_find(lfs, dir, &entry, &path); + int err = lfs_dir_find(lfs, dir, &entry, &path); if (err) { return err; } else if (entry.d.type != LFS_TYPE_DIR) { @@ -1302,13 +1287,8 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, // allocate entry for file if it doesn't exist lfs_dir_t cwd; - int err = lfs_dir_fetch(lfs, &cwd, lfs->root); - if (err) { - return err; - } - lfs_entry_t entry; - err = lfs_dir_find(lfs, &cwd, &entry, &path); + int err = lfs_dir_find(lfs, &cwd, &entry, &path); if (err && (err != LFS_ERR_NOENT || strchr(path, '/') != NULL)) { return err; } @@ -1814,13 +1794,8 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) { /// General fs operations /// int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { lfs_dir_t cwd; - int err = lfs_dir_fetch(lfs, &cwd, lfs->root); - if (err) { - return err; - } - lfs_entry_t entry; - err = lfs_dir_find(lfs, &cwd, &entry, &path); + int err = lfs_dir_find(lfs, &cwd, &entry, &path); if (err) { return err; } @@ -1855,13 +1830,8 @@ int lfs_remove(lfs_t *lfs, const char *path) { } lfs_dir_t cwd; - int err = lfs_dir_fetch(lfs, &cwd, lfs->root); - if (err) { - return err; - } - lfs_entry_t entry; - err = lfs_dir_find(lfs, &cwd, &entry, &path); + int err = lfs_dir_find(lfs, &cwd, &entry, &path); if (err) { return err; } @@ -1916,24 +1886,14 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { // find old entry lfs_dir_t oldcwd; - int err = lfs_dir_fetch(lfs, &oldcwd, lfs->root); - if (err) { - return err; - } - lfs_entry_t oldentry; - err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath); + int err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath); if (err) { return err; } // allocate new entry lfs_dir_t newcwd; - err = lfs_dir_fetch(lfs, &newcwd, lfs->root); - if (err) { - return err; - } - lfs_entry_t preventry; err = lfs_dir_find(lfs, &newcwd, &preventry, &newpath); if (err && (err != LFS_ERR_NOENT || strchr(newpath, '/') != NULL)) { diff --git a/features/filesystem/littlefs/littlefs/tests/test_paths.sh b/features/filesystem/littlefs/littlefs/tests/test_paths.sh index f277e451f9..79c4e66571 100755 --- a/features/filesystem/littlefs/littlefs/tests/test_paths.sh +++ b/features/filesystem/littlefs/littlefs/tests/test_paths.sh @@ -90,6 +90,22 @@ tests/test.py << TEST lfs_unmount(&lfs) => 0; TEST +echo "--- Trailing dot path tests ---" +tests/test.py << TEST + lfs_mount(&lfs, &cfg) => 0; + lfs_stat(&lfs, "tea/hottea/", &info) => 0; + strcmp(info.name, "hottea") => 0; + lfs_stat(&lfs, "tea/hottea/.", &info) => 0; + strcmp(info.name, "hottea") => 0; + lfs_stat(&lfs, "tea/hottea/./.", &info) => 0; + strcmp(info.name, "hottea") => 0; + lfs_stat(&lfs, "tea/hottea/..", &info) => 0; + strcmp(info.name, "tea") => 0; + lfs_stat(&lfs, "tea/hottea/../.", &info) => 0; + strcmp(info.name, "tea") => 0; + lfs_unmount(&lfs) => 0; +TEST + echo "--- Root dot dot path tests ---" tests/test.py << TEST lfs_mount(&lfs, &cfg) => 0; From c5fa459f47a504341891cb82868376f6d4f45d3a Mon Sep 17 00:00:00 2001 From: ccli8 Date: Fri, 27 Apr 2018 14:19:12 +0800 Subject: [PATCH 39/46] Fix compile error with MBED_MEM_TRACING_ENABLED and ARMC6 --- platform/mbed_retarget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mbed_retarget.cpp b/platform/mbed_retarget.cpp index 740636f932..d7de8bfa00 100644 --- a/platform/mbed_retarget.cpp +++ b/platform/mbed_retarget.cpp @@ -1339,7 +1339,7 @@ extern "C" void __cxa_guard_abort(int *guard_object_p) #endif -#if defined(MBED_MEM_TRACING_ENABLED) && (defined(__CC_ARM) || defined(__ICCARM__)) +#if defined(MBED_MEM_TRACING_ENABLED) && (defined(__CC_ARM) || defined(__ICCARM__) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) // If the memory tracing is enabled, the wrappers in mbed_alloc_wrappers.cpp // provide the implementation for these. Note: this needs to use the wrappers From 30a978ac04f6c10754d48b5342fc5a7e51f5951f Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 25 Apr 2018 11:53:53 +0300 Subject: [PATCH 40/46] Lora: Fix max tx power check In LoRa TX power value 0 means the maximum allowed TX power and values >0 are limiting the allowed TX power to lower. tx_config was incorrectly checking the power level and causing the maximum TX power to be always used. Lora gateway can request node to use lower TX power with LinkAdrReq MAC command. --- features/lorawan/lorastack/phy/LoRaPHY.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index d57257e003..eb81fe576c 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -888,9 +888,7 @@ bool LoRaPHY::tx_config(tx_config_params_t* tx_conf, int8_t* tx_power, band_t *bands = (band_t *)phy_params.bands.table; // limit TX power if set to too much - if (tx_conf->tx_power > bands[band_idx].max_tx_pwr) { - tx_conf->tx_power = bands[band_idx].max_tx_pwr; - } + tx_conf->tx_power = MAX(tx_conf->tx_power, bands[band_idx].max_tx_pwr); uint8_t bandwidth = get_bandwidth(tx_conf->datarate); int8_t phy_tx_power = 0; From 716d6462852916e1108738e29dec9be4c83d909b Mon Sep 17 00:00:00 2001 From: Jammu Kekkonen Date: Thu, 26 Apr 2018 16:19:43 +0300 Subject: [PATCH 41/46] Add bootloader support for NUCLEO_F411RE target --- .../TARGET_NUCLEO_F411RE/system_clock.c | 15 --------------- .../device/TOOLCHAIN_ARM_STD/stm32f411re.sct | 15 ++++++++++++--- .../device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld | 12 ++++++++++-- .../device/TOOLCHAIN_IAR/stm32f411xe.icf | 9 ++++++--- targets/targets.json | 3 ++- 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/system_clock.c index 7be2a9fd72..0e303c6dec 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/system_clock.c @@ -32,13 +32,6 @@ #include "stm32f4xx.h" #include "mbed_assert.h" -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ - - // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) @@ -88,14 +81,6 @@ void SystemInit(void) #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ - - /* Configure the Vector Table location add offset address ------------------*/ -#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 - } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct index c018724bf7..b8e8b03e12 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct @@ -1,3 +1,4 @@ +#! armcc -E ; Scatter-Loading Description File ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copyright (c) 2014, STMicroelectronics @@ -27,10 +28,18 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; STM32F411RE: 512 KB FLASH (0x80000) + 128 KB SRAM (0x20000) -LR_IROM1 0x08000000 0x80000 { ; load region size_region +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif - ER_IROM1 0x08000000 0x80000 { ; load address = execution address +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x80000 +#endif + +; STM32F411RE: 512 KB FLASH (0x80000) + 128 KB SRAM (0x20000) +LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region + + ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld index c028371d60..86b7d86bb7 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld @@ -1,7 +1,15 @@ +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 512K +#endif + /* Linker script to configure memory regions. */ MEMORY -{ - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +{ + FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE RAM (rwx) : ORIGIN = 0x20000198, LENGTH = 128k - 0x198 } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_IAR/stm32f411xe.icf b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_IAR/stm32f411xe.icf index f481cdbf14..264cd0e8ce 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_IAR/stm32f411xe.icf +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_IAR/stm32f411xe.icf @@ -1,7 +1,10 @@ +if (!isdefinedsymbol(MBED_APP_START)) { define symbol MBED_APP_START = 0x08000000; } +if (!isdefinedsymbol(MBED_APP_SIZE)) { define symbol MBED_APP_SIZE = 0x80000; } + /* [ROM = 512kb = 0x80000] */ -define symbol __intvec_start__ = 0x08000000; -define symbol __region_ROM_start__ = 0x08000000; -define symbol __region_ROM_end__ = 0x0807FFFF; +define symbol __intvec_start__ = MBED_APP_START; +define symbol __region_ROM_start__ = MBED_APP_START; +define symbol __region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; /* [RAM = 128kb = 0x20000] Vector table dynamic copy: 102 vectors = 408 bytes (0x198) to be reserved in RAM */ define symbol __NVIC_start__ = 0x20000000; diff --git a/targets/targets.json b/targets/targets.json index 2116c87d8b..dd3d219c1b 100755 --- a/targets/targets.json +++ b/targets/targets.json @@ -1105,7 +1105,8 @@ "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], "device_has_add": ["LOWPOWERTIMER", "SERIAL_ASYNCH", "SERIAL_FC", "FLASH"], "release_versions": ["2", "5"], - "device_name": "STM32F411RE" + "device_name": "STM32F411RE", + "bootloader_supported": true }, "NUCLEO_F412ZG": { "inherits": ["FAMILY_STM32"], From 4edec3d2e220f53a821fd09decab418ce62b319a Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 23 Apr 2018 15:23:00 -0500 Subject: [PATCH 42/46] Remove ASM include paths for ARM compiler --- tools/export/uvision/uvision.tmpl | 2 +- tools/toolchains/arm.py | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/export/uvision/uvision.tmpl b/tools/export/uvision/uvision.tmpl index 49c708c3bb..f49c79659d 100644 --- a/tools/export/uvision/uvision.tmpl +++ b/tools/export/uvision/uvision.tmpl @@ -394,7 +394,7 @@ {{asm_flags}} - {{include_paths}} + diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index cb0cd7b5fe..4a61982e40 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -135,17 +135,18 @@ class ARM(mbedToolchain): def get_config_option(self, config_header): return ['--preinclude=' + config_header] - def get_compile_options(self, defines, includes, for_asm=False): + def get_compile_options(self, defines, includes, for_asm=False): opts = ['-D%s' % d for d in defines] + if for_asm: + return opts if self.RESPONSE_FILES: opts += ['--via', self.get_inc_file(includes)] else: opts += ["-I%s" % i for i in includes] - if not for_asm: - config_header = self.get_config_header() - if config_header is not None: - opts = opts + self.get_config_option(config_header) + config_header = self.get_config_header() + if config_header is not None: + opts = opts + self.get_config_option(config_header) return opts @hook_tool @@ -156,7 +157,10 @@ class ARM(mbedToolchain): tempfile = join(dir, basename(object) + '.E.s') # Build preprocess assemble command - cmd_pre = self.asm + self.get_compile_options(self.get_symbols(True), includes) + ["-E", "-o", tempfile, source] + cmd_pre = self.asm + cmd_pre.extend(self.get_compile_options( + self.get_symbols(True), includes, True)) + cmd_pre.extend(["-E", "-o", tempfile, source]) # Build main assemble command cmd = self.asm + ["-o", object, tempfile] From 54c6e65d37b43c38e6afda10f7d499206a26f0fc Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 23 Apr 2018 15:23:35 -0500 Subject: [PATCH 43/46] Use rel path for the ONLY arm asm include statement --- .../TARGET_CM3DS_MPS2/device/TOOLCHAIN_ARM_STD/startup_MPS2.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/TOOLCHAIN_ARM_STD/startup_MPS2.S b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/TOOLCHAIN_ARM_STD/startup_MPS2.S index 8399347cf7..de0211858a 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/TOOLCHAIN_ARM_STD/startup_MPS2.S +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/TOOLCHAIN_ARM_STD/startup_MPS2.S @@ -22,7 +22,7 @@ * */ -#include "memory_zones.h" +#include "../memory_zones.h" __initial_sp EQU ZBT_SSRAM23_START + ZBT_SSRAM23_SIZE ; Top of ZBT SSRAM2 and 3, used for data From f38f1269b1e5787daf31f892070d6353a0dc904f Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 30 Apr 2018 09:29:41 -0500 Subject: [PATCH 44/46] Cleanup extraneous spaces on empty lines --- tools/toolchains/arm.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index 4a61982e40..1497a3e1b9 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -71,7 +71,7 @@ class ARM(mbedToolchain): ARM_BIN = join(TOOLCHAIN_PATHS['ARM'], "bin") ARM_INC = join(TOOLCHAIN_PATHS['ARM'], "include") - + main_cc = join(ARM_BIN, "armcc") self.flags['common'] += ["--cpu=%s" % cpu] @@ -155,7 +155,7 @@ class ARM(mbedToolchain): dir = join(dirname(object), '.temp') mkdir(dir) tempfile = join(dir, basename(object) + '.E.s') - + # Build preprocess assemble command cmd_pre = self.asm cmd_pre.extend(self.get_compile_options( @@ -168,7 +168,7 @@ class ARM(mbedToolchain): # Call cmdline hook cmd_pre = self.hook.get_cmdline_assembler(cmd_pre) cmd = self.hook.get_cmdline_assembler(cmd) - + # Return command array, don't execute return [cmd_pre, cmd] @@ -176,9 +176,9 @@ class ARM(mbedToolchain): def compile(self, cc, source, object, includes): # Build compile command cmd = cc + self.get_compile_options(self.get_symbols(), includes) - + cmd.extend(self.get_dep_option(object)) - + cmd.extend(["-o", object, source]) # Call cmdline hook From 5a320b837fe17d92d39d6280f279b3cfbabb9f8c Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Mon, 30 Apr 2018 09:34:32 -0500 Subject: [PATCH 45/46] Extend a local version of the asm cmd list I was extending an object-local one instead of a call-local one --- tools/toolchains/arm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index 1497a3e1b9..8b1533ee05 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -157,7 +157,7 @@ class ARM(mbedToolchain): tempfile = join(dir, basename(object) + '.E.s') # Build preprocess assemble command - cmd_pre = self.asm + cmd_pre = copy(self.asm) cmd_pre.extend(self.get_compile_options( self.get_symbols(True), includes, True)) cmd_pre.extend(["-E", "-o", tempfile, source]) From 09132ce8ce8e4f0fac7d7147bb09cb99e90aeb1d Mon Sep 17 00:00:00 2001 From: adbridge Date: Fri, 4 May 2018 12:22:31 +0100 Subject: [PATCH 46/46] Update Mbed version block for patch release --- mbed.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mbed.h b/mbed.h index cf7c145f21..c7d6db5a4d 100644 --- a/mbed.h +++ b/mbed.h @@ -16,13 +16,13 @@ #ifndef MBED_H #define MBED_H -#define MBED_LIBRARY_VERSION 161 +#define MBED_LIBRARY_VERSION 162 #if MBED_CONF_RTOS_PRESENT // RTOS present, this is valid only for mbed OS 5 #define MBED_MAJOR_VERSION 5 #define MBED_MINOR_VERSION 8 -#define MBED_PATCH_VERSION 3 +#define MBED_PATCH_VERSION 4 #else // mbed 2