From 31a2a101a67904d5636e6a37549c0add4becaeaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deimantas=20Auk=C5=A1tkalnis?= Date: Fri, 18 Sep 2020 16:25:55 +0300 Subject: [PATCH] added bluenrg peripherial, soc and hal drivers --- CMakeLists.txt | 32 + drivers/CMakeLists.txt | 1 + drivers/inc/BlueNRG1_adc.h | 252 +++ drivers/inc/BlueNRG1_conf.h | 68 + drivers/inc/BlueNRG1_dma.h | 348 ++++ drivers/inc/BlueNRG1_flash.h | 172 ++ drivers/inc/BlueNRG1_gpio.h | 455 +++++ drivers/inc/BlueNRG1_i2c.h | 397 ++++ drivers/inc/BlueNRG1_mft.h | 248 +++ drivers/inc/BlueNRG1_pka.h | 179 ++ drivers/inc/BlueNRG1_radio.h | 281 +++ drivers/inc/BlueNRG1_rng.h | 99 + drivers/inc/BlueNRG1_rtc.h | 242 +++ drivers/inc/BlueNRG1_spi.h | 397 ++++ drivers/inc/BlueNRG1_sysCtrl.h | 186 ++ drivers/inc/BlueNRG1_timer.h | 378 ++++ drivers/inc/BlueNRG1_uart.h | 355 ++++ drivers/inc/BlueNRG1_wdg.h | 127 ++ drivers/inc/misc.h | 135 ++ drivers/src/BlueNRG1_adc.c | 778 +++++++ drivers/src/BlueNRG1_dma.c | 513 +++++ drivers/src/BlueNRG1_flash.c | 374 ++++ drivers/src/BlueNRG1_gpio.c | 547 +++++ drivers/src/BlueNRG1_i2c.c | 742 +++++++ drivers/src/BlueNRG1_mft.c | 461 +++++ drivers/src/BlueNRG1_pka.c | 366 ++++ drivers/src/BlueNRG1_radio.c | 947 +++++++++ drivers/src/BlueNRG1_rng.c | 137 ++ drivers/src/BlueNRG1_rtc.c | 419 ++++ drivers/src/BlueNRG1_spi.c | 709 +++++++ drivers/src/BlueNRG1_sysCtrl.c | 284 +++ drivers/src/BlueNRG1_timer.c | 824 ++++++++ drivers/src/BlueNRG1_uart.c | 727 +++++++ drivers/src/BlueNRG1_wdg.c | 225 +++ drivers/src/misc.c | 157 ++ hal/inc/asm.h | 78 + hal/inc/clock.h | 68 + hal/inc/compiler.h | 304 +++ hal/inc/crash_handler.h | 145 ++ hal/inc/fifo.h | 45 + hal/inc/gp_timer.h | 89 + hal/inc/hal_radio.h | 56 + hal/inc/hal_types.h | 73 + hal/inc/miscutil.h | 99 + hal/inc/osal.h | 78 + hal/inc/radio_ota.h | 78 + hal/inc/sleep.h | 281 +++ hal/inc/vtimer.h | 278 +++ hal/src/clock.c | 84 + hal/src/context_switch.s | 109 + hal/src/fifo.c | 175 ++ hal/src/gp_timer.c | 57 + hal/src/hal_radio.c | 323 +++ hal/src/miscutil.c | 130 ++ hal/src/radio_ota.c | 64 + hal/src/sleep.c | 752 +++++++ hal/src/vtimer.c | 756 +++++++ soc/inc/BlueNRG1.h | 3411 +++++++++++++++++++++++++++++++ soc/inc/BlueNRG2.h | 3478 ++++++++++++++++++++++++++++++++ soc/inc/bluenrg_x_device.h | 99 + soc/inc/system_bluenrg.h | 296 +++ soc/inc/system_bluenrg1.h | 88 + soc/inc/system_bluenrg2.h | 88 + soc/src/system_bluenrg1.c | 989 +++++++++ zephyr/module.yml | 2 + 65 files changed, 25135 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 drivers/CMakeLists.txt create mode 100644 drivers/inc/BlueNRG1_adc.h create mode 100644 drivers/inc/BlueNRG1_conf.h create mode 100644 drivers/inc/BlueNRG1_dma.h create mode 100644 drivers/inc/BlueNRG1_flash.h create mode 100644 drivers/inc/BlueNRG1_gpio.h create mode 100644 drivers/inc/BlueNRG1_i2c.h create mode 100644 drivers/inc/BlueNRG1_mft.h create mode 100644 drivers/inc/BlueNRG1_pka.h create mode 100644 drivers/inc/BlueNRG1_radio.h create mode 100644 drivers/inc/BlueNRG1_rng.h create mode 100644 drivers/inc/BlueNRG1_rtc.h create mode 100644 drivers/inc/BlueNRG1_spi.h create mode 100644 drivers/inc/BlueNRG1_sysCtrl.h create mode 100644 drivers/inc/BlueNRG1_timer.h create mode 100644 drivers/inc/BlueNRG1_uart.h create mode 100644 drivers/inc/BlueNRG1_wdg.h create mode 100644 drivers/inc/misc.h create mode 100644 drivers/src/BlueNRG1_adc.c create mode 100644 drivers/src/BlueNRG1_dma.c create mode 100644 drivers/src/BlueNRG1_flash.c create mode 100644 drivers/src/BlueNRG1_gpio.c create mode 100644 drivers/src/BlueNRG1_i2c.c create mode 100644 drivers/src/BlueNRG1_mft.c create mode 100644 drivers/src/BlueNRG1_pka.c create mode 100644 drivers/src/BlueNRG1_radio.c create mode 100644 drivers/src/BlueNRG1_rng.c create mode 100644 drivers/src/BlueNRG1_rtc.c create mode 100644 drivers/src/BlueNRG1_spi.c create mode 100644 drivers/src/BlueNRG1_sysCtrl.c create mode 100644 drivers/src/BlueNRG1_timer.c create mode 100644 drivers/src/BlueNRG1_uart.c create mode 100644 drivers/src/BlueNRG1_wdg.c create mode 100644 drivers/src/misc.c create mode 100644 hal/inc/asm.h create mode 100644 hal/inc/clock.h create mode 100644 hal/inc/compiler.h create mode 100644 hal/inc/crash_handler.h create mode 100644 hal/inc/fifo.h create mode 100644 hal/inc/gp_timer.h create mode 100644 hal/inc/hal_radio.h create mode 100644 hal/inc/hal_types.h create mode 100644 hal/inc/miscutil.h create mode 100644 hal/inc/osal.h create mode 100644 hal/inc/radio_ota.h create mode 100644 hal/inc/sleep.h create mode 100644 hal/inc/vtimer.h create mode 100644 hal/src/clock.c create mode 100644 hal/src/context_switch.s create mode 100644 hal/src/fifo.c create mode 100644 hal/src/gp_timer.c create mode 100644 hal/src/hal_radio.c create mode 100644 hal/src/miscutil.c create mode 100644 hal/src/radio_ota.c create mode 100644 hal/src/sleep.c create mode 100644 hal/src/vtimer.c create mode 100644 soc/inc/BlueNRG1.h create mode 100644 soc/inc/BlueNRG2.h create mode 100644 soc/inc/bluenrg_x_device.h create mode 100644 soc/inc/system_bluenrg.h create mode 100644 soc/inc/system_bluenrg1.h create mode 100644 soc/inc/system_bluenrg2.h create mode 100644 soc/src/system_bluenrg1.c create mode 100644 zephyr/module.yml diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8b371b1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,32 @@ +if(CONFIG_HAS_BLUENRG_HAL) +zephyr_library_sources(soc/system_bluenrg1.c) +zephyr_library_sources(drivers/src/BlueNRG1_sysCtrl.c) +zephyr_sources(soc/context_switch.s) + + +zephyr_include_directories(soc) +zephyr_include_directories(drivers) +zephyr_include_directories(drivers/include) +zephyr_include_directories(drivers/src) + +zephyr_library_sources(soc/clock.c) +zephyr_library_sources(soc/fifo.c) +zephyr_library_sources(soc/gp_timer.c) +zephyr_library_sources(soc/hal_radio.c) +zephyr_library_sources(soc/miscutil.c) +zephyr_library_sources(soc/osal.c) + + +zephyr_library_sources(drivers/src/misc.c) +zephyr_library_sources(drivers/src/BlueNRG1_adc.c) +zephyr_library_sources(drivers/src/BlueNRG1_dma.c) +zephyr_library_sources(drivers/src/BlueNRG1_flash.c) +zephyr_library_sources(drivers/src/BlueNRG1_gpio.c) +zephyr_library_sources(drivers/src/BlueNRG1_i2c.c) +zephyr_library_sources(drivers/src/BlueNRG1_pka.c) +zephyr_library_sources(drivers/src/BlueNRG1_rng.c) +zephyr_library_sources(drivers/src/BlueNRG1_rtc.c) +zephyr_library_sources(drivers/src/BlueNRG1_spi.c) +zephyr_library_sources(drivers/src/BlueNRG1_uart.c) +zephyr_library_sources(drivers/src/BlueNRG1_wdg.c) +endif() \ No newline at end of file diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt new file mode 100644 index 0000000..f6b6d78 --- /dev/null +++ b/drivers/CMakeLists.txt @@ -0,0 +1 @@ +zephyr_include_directories(drivers/include) diff --git a/drivers/inc/BlueNRG1_adc.h b/drivers/inc/BlueNRG1_adc.h new file mode 100644 index 0000000..c8ebe2d --- /dev/null +++ b/drivers/inc/BlueNRG1_adc.h @@ -0,0 +1,252 @@ +/** + ****************************************************************************** + * @file BlueNRG1_adc.h +* @author RF Application Team +* @version V2.6.0 +* @date 30-January-2019 + * @brief This file contains all the functions prototypes for the ADC firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_ADC_H +#define BLUENRG1_ADC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup ADC_Peripheral ADC Peripheral + * @{ + */ + +/** @defgroup ADC_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Structure definition of ADC initialization + */ +typedef struct { + uint8_t ADC_OSR; /*!< Specifies the decimation rate. + This parameter can be a value of @ref ADC_OSR */ + + uint8_t ADC_Input; /*!< Specifies the input used for the conversion. + This parameter can be a value of @ref ADC_Input */ + + uint8_t ADC_ConversionMode; /*!< Specifies the conversion mode. + This parameter can be a value of @ref ADC_ConversionMode */ + + uint8_t ADC_Attenuation; /*!< Specifies the attenuation. + This parameter can be a value of @ref ADC_Attenuation */ + + uint8_t ADC_ReferenceVoltage; /*!< Specifies the ADC reference voltage. + This parameter can be a value of @ref ADC_ReferenceVoltage */ +} ADC_InitType; + +/** + * @} + */ + + + +/** @defgroup ADC_Exported_Constants Exported Constants + * @{ + */ + + +/** @defgroup ADC_Decimation_Rate_Definitions Decimation Rate Definitions + * @{ + */ +#define ADC_OSR_200 ((uint8_t)0x00) /* Recommended value for DC signals */ +#define ADC_OSR_100 ((uint8_t)0x01) +#define ADC_OSR_64 ((uint8_t)0x02) +#define ADC_OSR_32 ((uint8_t)0x03) + +#define IS_ADC_OSR(OSR) (((OSR) == ADC_OSR_200) || \ + ((OSR) == ADC_OSR_100) || \ + ((OSR) == ADC_OSR_64) || \ + ((OSR) == ADC_OSR_32)) +/** + * @} + */ + + +/** @defgroup ADC_Input_Definitions Input Definitions + * @{ + */ +#define ADC_Input_None ((uint8_t)0x00) +#define ADC_Input_AdcPin2 ((uint8_t)0x01) /* Single ended input from ADC2 pin */ +#define ADC_Input_AdcPin1 ((uint8_t)0x02) /* Single ended input from ADC1 pin */ +#define ADC_Input_AdcPin12 ((uint8_t)0x03) /* Differential input */ +#define ADC_Input_TempSensor ((uint8_t)0x04) /* Temperature sensor */ +#define ADC_Input_BattSensor ((uint8_t)0x05) /* Internal battery detector */ +#define ADC_Input_Internal0V60V6 ((uint8_t)0x06) /* Test input */ +#define ADC_Input_Internal1V20V0 ((uint8_t)0x07) /* Test input */ +#define ADC_Input_Microphone ((uint8_t)0x0F) /* Microphone mode */ + +#define IS_ADC_INPUT(INPUT) (((INPUT) == ADC_Input_None) || \ + ((INPUT) == ADC_Input_AdcPin1) || \ + ((INPUT) == ADC_Input_AdcPin2) || \ + ((INPUT) == ADC_Input_AdcPin12) || \ + ((INPUT) == ADC_Input_TempSensor) || \ + ((INPUT) == ADC_Input_BattSensor) || \ + ((INPUT) == ADC_Input_Internal0V60V6) || \ + ((INPUT) == ADC_Input_Internal1V20V0) || \ + ((INPUT) == ADC_Input_Microphone)) + +/** + * @} + */ + + +/** @defgroup ADC_Conversion_Mode_Definitions Conversion Mode Definitions + * @{ + */ +#define ADC_ConversionMode_Single ((uint8_t)0x00) + +/* The user must discards the first 10 converted samples in continuous mode if the SKIP bit is 0. + * The user must discards the first 3 converted samples in continuous mode if the SKIP bit is 1. */ +#define ADC_ConversionMode_Continuous ((uint8_t)0x08) + +#define IS_ADC_CONVERSIONMODE(CONVERSIONMODE) (((CONVERSIONMODE) == ADC_ConversionMode_Single) || \ + ((CONVERSIONMODE) == ADC_ConversionMode_Continuous)) +/** + * @} + */ + + + +/** @defgroup ADC_Attenuation_Definitions Attenuation Definitions + * @{ + */ +#define ADC_Attenuation_0dB ((uint8_t)0x00) +#define ADC_Attenuation_6dB02 ((uint8_t)0x01) +#define ADC_Attenuation_9dB54 ((uint8_t)0x02) + +#define IS_ADC_ATTENUATION(ATTENUATION) (((ATTENUATION) == ADC_Attenuation_0dB) || \ + ((ATTENUATION) == ADC_Attenuation_6dB02) || \ + ((ATTENUATION) == ADC_Attenuation_9dB54)) +/** + * @} + */ + + +/** @defgroup ADC_Reference_Voltage_Definitions Reference Voltage Definitions + * @{ + */ + +#define ADC_ReferenceVoltage_0V6 ((uint8_t)0x02) /* Optimal setting */ +#define ADC_ReferenceVoltage_0V0 ((uint8_t)0x00) /* Default value: not recommended */ + +#define IS_ADC_REFERENCEVOLTAGE(REFERENCEVOLTAGE) (((REFERENCEVOLTAGE) == ADC_ReferenceVoltage_0V6) || \ + ((REFERENCEVOLTAGE) == ADC_ReferenceVoltage_0V0)) +/** + * @} + */ + + +/** @defgroup ADC_Mic_Frequency_Definitions Mic Frequency Definitions + * @{ + */ +#define ADC_MIC_800KHZ ((uint8_t)0x00) /*!< Enable the 800 kHz through IO0 for external MEMS microphone */ +#define ADC_MIC_1600KHZ ((uint8_t)0x01) /*!< Enable the 1.6 MHz through IO0 for external MEMS microphone */ + +#define IS_ADC_MIC_FREQ_SEL(FREQ) (((FREQ) == ADC_MIC_800KHZ) || ((FREQ) == ADC_MIC_1600KHZ)) + +/** + * @} + */ + +/** @defgroup ADC_Flags_Definitions Flags Definitions + * @{ + */ + +#define ADC_FLAG_CAL ((uint8_t)0x01) /*!< End of Calibration flag */ +#define ADC_FLAG_BUSY ((uint8_t)0x02) /*!< Busy flag */ +#define ADC_FLAG_EOC ((uint8_t)0x04) /*!< End of Conversion flag */ +#define ADC_FLAG_WDG ((uint8_t)0x08) /*!< Value within set threshold */ + +#define IS_ADC_GET_FLAG(FLAG) (((FLAG) & 0x0F) != 0) + +/** + * @} + */ + +/** + * @} + */ + + +/** @defgroup ADC_Exported_Functions Exported Functions + * @{ + */ +void ADC_Init(ADC_InitType* ADC_InitStruct); +void ADC_DeInit(void); +void ADC_StructInit(ADC_InitType* ADC_InitStruct); +void ADC_Cmd(FunctionalState NewState); +void ADC_DmaCmd(FunctionalState NewState); +void ADC_Filter(FunctionalState NewState); +void ADC_SelectInput(uint8_t AdcInput); +void ADC_Calibration(FunctionalState NewState); +void ADC_AutoOffsetUpdate(FunctionalState NewState); +void ADC_SetOffset(uint16_t Offset); +uint16_t ADC_GetOffset(void); +void ADC_ThresholdCheck(FunctionalState NewState); +void ADC_ThresholdConfig(uint32_t ThresholdLow, uint32_t ThresholdHigh); +void ADC_ConversionMode(uint8_t ConvertionMode); +void ADC_SelectFrequencyMic(uint8_t Frequency); +float ADC_GetConvertedData(uint8_t DataType, uint8_t Vref); +uint8_t ADC_GetFlags(void); +FlagStatus ADC_GetFlagStatus(uint8_t ADC_Flag); +ITStatus ADC_GetITStatus(uint8_t ADC_Flag); +void ADC_ITConfig(uint8_t ADC_Flag, FunctionalState NewState); + +float ADC_ConvertDifferentialVoltage(int16_t raw_value, uint8_t attenuation); +float ADC_ConvertSingleEndedVoltage(int16_t raw_value, uint8_t channel, uint8_t vRef, uint8_t attenuation); +float ADC_ConvertBatterySensor(int16_t raw_value, uint8_t vRef); +float ADC_ConvertTemperatureSensor(int16_t raw_value, uint8_t vRef, uint8_t attenuation); + +uint16_t ADC_GetRawData(void); + +float ADC_CompensateOutputValue(float value); +uint8_t ADC_SwCalibration(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*BLUENRG1_ADC_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_conf.h b/drivers/inc/BlueNRG1_conf.h new file mode 100644 index 0000000..67342fd --- /dev/null +++ b/drivers/inc/BlueNRG1_conf.h @@ -0,0 +1,68 @@ +/** + ****************************************************************************** + * @file UART/Interrupt/BlueNRG1_conf.h + * @author MEMS Application Team + * @version V1.0.0 + * @date September-2014 + * @brief Library configuration file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2014 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BlueNRG1_CONF_H +#define BlueNRG1_CONF_H + +/* Includes ------------------------------------------------------------------*/ +/* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */ + +#include "BlueNRG1_flash.h" +#include "BlueNRG1_gpio.h" +/*#include "BlueNRG1_i2c.h"*/ +#include "BlueNRG1_wdg.h" +#include "BlueNRG1_spi.h" +#include "BlueNRG1_uart.h" +/*#include "BlueNRG1_mft.h"*/ +/*#include "BlueNRG1_rtc.h"*/ +#include "BlueNRG1_pka.h" +#include "BlueNRG1_rng.h" +#include "BlueNRG1_dma.h" +#include "BlueNRG1_sysCtrl.h" +#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Uncomment the line below to expanse the "assert_param" macro in the + Standard Peripheral Library drivers code */ +/* #define USE_FULL_ASSERT 1 */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT + +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function which reports + * the name of the source file and the source line number of the call + * that failed. If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0) +#endif /* USE_FULL_ASSERT */ + +#endif /* BlueNRG1_CONF_H */ + +/******************* (C) COPYRIGHT 2014 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_dma.h b/drivers/inc/BlueNRG1_dma.h new file mode 100644 index 0000000..be56d0c --- /dev/null +++ b/drivers/inc/BlueNRG1_dma.h @@ -0,0 +1,348 @@ +/** + ****************************************************************************** + * @file BlueNRG1_dma.h + * @author VMA Application Team + * @version V2.0.0 + * @date 21-March-2016 + * @brief This file contains all the functions prototypes for the DMA firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_DMA_H +#define BLUENRG1_DMA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup DMA_Peripheral DMA Peripheral + * @{ + */ + +/** @defgroup DMA_Exported_Types Exported Types + * @{ + */ + +/** + * @brief DMA Init structure definition + */ +typedef struct +{ + uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */ + + uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */ + + uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination. + This parameter can be a value of @ref DMA_data_transfer_direction */ + + uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel. + The data unit is equal to the configuration set in DMA_PeripheralDataSize + or DMA_MemoryDataSize members depending in the transfer direction. */ + + uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not. + This parameter can be a value of @ref DMA_peripheral_incremented_mode */ + + uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not. + This parameter can be a value of @ref DMA_memory_incremented_mode */ + + uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. + This parameter can be a value of @ref DMA_peripheral_data_size */ + + uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. + This parameter can be a value of @ref DMA_memory_data_size */ + + uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx. + This parameter can be a value of @ref DMA_circular_normal_mode. + @note: The circular buffer mode cannot be used if the memory-to-memory + data transfer is configured on the selected Channel */ + + uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx. + This parameter can be a value of @ref DMA_priority_level */ + + uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer. + This parameter can be a value of @ref DMA_memory_to_memory */ +}DMA_InitType; + +/** + * @} + */ + +/** @defgroup DMA_Exported_Constants Exported Constants + * @{ + */ + + +/** @defgroup DMA_Data_Transfer_Direction_Definitions Data Transfer Direction Definitions + * @{ + */ + +#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010) +#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000) +#define IS_DMA_DIR(DIR) (((DIR) == DMA_DIR_PeripheralDST) || \ + ((DIR) == DMA_DIR_PeripheralSRC)) +/** + * @} + */ + +/** @defgroup DMA_Peripheral_Incremented_Mode_Definitions Peripheral Incremented Mode Definitions + * @{ + */ + +#define DMA_PeripheralInc_Enable ((uint32_t)0x00000040) +#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000) +#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PeripheralInc_Enable) || \ + ((STATE) == DMA_PeripheralInc_Disable)) +/** + * @} + */ + +/** @defgroup DMA_Memory_Incremented_Mode_Definitions Memory Incremented Mode Definitions + * @{ + */ + +#define DMA_MemoryInc_Enable ((uint32_t)0x00000080) +#define DMA_MemoryInc_Disable ((uint32_t)0x00000000) +#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MemoryInc_Enable) || \ + ((STATE) == DMA_MemoryInc_Disable)) +/** + * @} + */ + +/** @defgroup DMA_Peripheral_Data_Size_Definitions Peripheral Data Size Definitions + * @{ + */ + +#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) +#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100) +#define DMA_PeripheralDataSize_Word ((uint32_t)0x00000200) +#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PeripheralDataSize_Byte) || \ + ((SIZE) == DMA_PeripheralDataSize_HalfWord) || \ + ((SIZE) == DMA_PeripheralDataSize_Word)) +/** + * @} + */ + +/** @defgroup DMA_Memory_Data_Size_Definitions Memory Data Size Definitions + * @{ + */ + +#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) +#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400) +#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800) +#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MemoryDataSize_Byte) || \ + ((SIZE) == DMA_MemoryDataSize_HalfWord) || \ + ((SIZE) == DMA_MemoryDataSize_Word)) +/** + * @} + */ + +/** @defgroup DMA_Circular_Normal_Mode_Definitions Circular Normal Mode Definitions + * @{ + */ + +#define DMA_Mode_Circular ((uint32_t)0x00000020) +#define DMA_Mode_Normal ((uint32_t)0x00000000) +#define IS_DMA_MODE(MODE) (((MODE) == DMA_Mode_Circular) || ((MODE) == DMA_Mode_Normal)) +/** + * @} + */ + +/** @defgroup DMA_Priority_Level_Definitions Priority Level Definitions + * @{ + */ + +#define DMA_Priority_VeryHigh ((uint32_t)0x00003000) +#define DMA_Priority_High ((uint32_t)0x00002000) +#define DMA_Priority_Medium ((uint32_t)0x00001000) +#define DMA_Priority_Low ((uint32_t)0x00000000) +#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_Priority_VeryHigh) || \ + ((PRIORITY) == DMA_Priority_High) || \ + ((PRIORITY) == DMA_Priority_Medium) || \ + ((PRIORITY) == DMA_Priority_Low)) +/** + * @} + */ + +/** @defgroup DMA_Memory_To_Memory_Definitions Memory To Memory Definitions + * @{ + */ + +#define DMA_M2M_Enable ((uint32_t)0x00004000) +#define DMA_M2M_Disable ((uint32_t)0x00000000) +#define IS_DMA_M2M_STATE(STATE) (((STATE) == DMA_M2M_Enable) || ((STATE) == DMA_M2M_Disable)) + +/** + * @} + */ + +/** @defgroup DMA_Flag_Mask_Definitions Flag Mask Definitions + * @{ + */ + +#define DMA_FLAG_TC ((uint32_t)0x00000002) +#define DMA_FLAG_HT ((uint32_t)0x00000004) +#define DMA_FLAG_TE ((uint32_t)0x00000008) +#define IS_DMA_CONFIG_FLAG(FLAG) (((FLAG) & 0x0E) != 0) + +/** + * @} + */ + + +/** @defgroup DMA_Interrupts_Channel_Definitions Interrupts Channel Definitions + * @{ + */ + +#define DMA_FLAG_GL0 ((uint32_t)0x00000001) +#define DMA_FLAG_TC0 ((uint32_t)0x00000002) +#define DMA_FLAG_HT0 ((uint32_t)0x00000004) +#define DMA_FLAG_TE0 ((uint32_t)0x00000008) +#define DMA_FLAG_GL1 ((uint32_t)0x00000010) +#define DMA_FLAG_TC1 ((uint32_t)0x00000020) +#define DMA_FLAG_HT1 ((uint32_t)0x00000040) +#define DMA_FLAG_TE1 ((uint32_t)0x00000080) +#define DMA_FLAG_GL2 ((uint32_t)0x00000100) +#define DMA_FLAG_TC2 ((uint32_t)0x00000200) +#define DMA_FLAG_HT2 ((uint32_t)0x00000400) +#define DMA_FLAG_TE2 ((uint32_t)0x00000800) +#define DMA_FLAG_GL3 ((uint32_t)0x00001000) +#define DMA_FLAG_TC3 ((uint32_t)0x00002000) +#define DMA_FLAG_HT3 ((uint32_t)0x00004000) +#define DMA_FLAG_TE3 ((uint32_t)0x00008000) +#define DMA_FLAG_GL4 ((uint32_t)0x00010000) +#define DMA_FLAG_TC4 ((uint32_t)0x00020000) +#define DMA_FLAG_HT4 ((uint32_t)0x00040000) +#define DMA_FLAG_TE4 ((uint32_t)0x00080000) +#define DMA_FLAG_GL5 ((uint32_t)0x00100000) +#define DMA_FLAG_TC5 ((uint32_t)0x00200000) +#define DMA_FLAG_HT5 ((uint32_t)0x00400000) +#define DMA_FLAG_TE5 ((uint32_t)0x00800000) +#define DMA_FLAG_GL6 ((uint32_t)0x01000000) +#define DMA_FLAG_TC6 ((uint32_t)0x02000000) +#define DMA_FLAG_HT6 ((uint32_t)0x04000000) +#define DMA_FLAG_TE6 ((uint32_t)0x08000000) +#define DMA_FLAG_GL7 ((uint32_t)0x10000000) +#define DMA_FLAG_TC7 ((uint32_t)0x20000000) +#define DMA_FLAG_HT7 ((uint32_t)0x40000000) +#define DMA_FLAG_TE7 ((uint32_t)0x80000000) + + +#define IS_DMA_CH_FLAG(FLAG) ((FLAG) != 0x00) + + + +/** + * @} + */ + + + +/** @defgroup DMA_Interrupts_Channel_Definitions Interrupts Channel Definitions + * @{ + */ + +#define DMA_ADC_CHANNEL0 ((uint8_t)0x01) +#define DMA_ADC_CHANNEL1 ((uint8_t)0x02) +#define DMA_ADC_CHANNEL2 ((uint8_t)0x04) +#define DMA_ADC_CHANNEL3 ((uint8_t)0x08) +#define DMA_ADC_CHANNEL4 ((uint8_t)0x10) +#define DMA_ADC_CHANNEL5 ((uint8_t)0x20) +#define DMA_ADC_CHANNEL6 ((uint8_t)0x40) +#define DMA_ADC_CHANNEL7 ((uint8_t)0x80) + + +#define IS_DMA_ADC_CH(SEL) (((SEL) == DMA_ADC_CHANNEL0) || \ + ((SEL) == DMA_ADC_CHANNEL1) || \ + ((SEL) == DMA_ADC_CHANNEL2) || \ + ((SEL) == DMA_ADC_CHANNEL3) || \ + ((SEL) == DMA_ADC_CHANNEL4) || \ + ((SEL) == DMA_ADC_CHANNEL5) || \ + ((SEL) == DMA_ADC_CHANNEL6) || \ + ((SEL) == DMA_ADC_CHANNEL7)) + + + +/** + * @} + */ + + + +/** @defgroup DMA_Buffer_Size_Definitions Buffer Size Definitions + * @{ + */ + +#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000)) + +/** + * @} + */ + +/** + * @} + */ + + +/** @defgroup DMA_Exported_Functions Exported Functions + * @{ + */ + +/* Function used to set the DMA configuration to the default reset state *****/ +void DMA_DeInit(DMA_CH_Type* DMAy_Channelx); + +/* Initialization and Configuration functions *********************************/ +void DMA_Init(DMA_CH_Type* DMAy_Channelx, DMA_InitType* DMA_InitStruct); +void DMA_StructInit(DMA_InitType* DMA_InitStruct); +void DMA_Cmd(DMA_CH_Type* DMAy_Channelx, FunctionalState NewState); +void DMA_SelectAdcChannel(uint8_t DMA_AdcChannel, FunctionalState NewState); + +/* Data Counter functions *****************************************************/ +void DMA_SetCurrDataCounter(DMA_CH_Type* DMAy_Channelx, uint16_t DataNumber); +uint16_t DMA_GetCurrDataCounter(DMA_CH_Type* DMAy_Channelx); + +/* Interrupts and flags management functions **********************************/ +FlagStatus DMA_GetFlagStatus(uint32_t DMA_Flag); +void DMA_FlagConfig(DMA_CH_Type* DMAy_Channelx, uint32_t DMA_Flag, FunctionalState NewState); +void DMA_ClearFlag(uint32_t DMA_Flag); + + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*BLUENRG1_DMA_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_flash.h b/drivers/inc/BlueNRG1_flash.h new file mode 100644 index 0000000..4ab7cde --- /dev/null +++ b/drivers/inc/BlueNRG1_flash.h @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + * @file BlueNRG1_flash.h + * @author VMA Application Team + * @version V2.1.1 + * @date 31-January-2017 + * @brief This file contains all the functions prototypes for the FLASH + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_FLASH_H +#define BLUENRG1_FLASH_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup FLASH_Peripheral FLASH Peripheral + * @{ + */ + +/** @defgroup FLASH_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Flash status enumeration + */ + +#define Flash_CMDDONE 0x01 /* Flash command done */ +#define Flash_CMDSTART 0x02 /* Flash command start */ +#define Flash_CMDERR 0x04 /* Flash command error */ +#define Flash_ILLCMD 0x08 /* Flash illegal command written */ +#define Flash_READOK 0x10 /* Flash mass read was OK */ +#define Flash_FLNREADY 0x20 /* Flash not ready (sleep) */ + +#define IS_FLASH_FLAG(FLAG) ( ((FLAG) == Flash_CMDDONE) || \ + ((FLAG) == Flash_CMDSTART) || \ + ((FLAG) == Flash_CMDERR) || \ + ((FLAG) == Flash_ILLCMD) || \ + ((FLAG) == Flash_READOK) || \ + ((FLAG) == Flash_FLNREADY) ) +/** + * @} + */ + +/** @defgroup FLASH_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup FLASH_Size_Definitions Size Definitions + * @{ + */ + +#define FLASH_START (_MEMORY_FLASH_BEGIN_) +#define FLASH_END (_MEMORY_FLASH_END_) + +#define IS_FLASH_ADDRESS(ADDR) ( ((ADDR) >= FLASH_START) && ((ADDR) <= FLASH_END) ) + +#define N_BYTES_WORD (4) +#define N_ROWS (8) +#define N_BYTES_PAGE (_MEMORY_BYTES_PER_PAGE_) +#define N_PAGES (_MEMORY_FLASH_SIZE_/N_BYTES_PAGE) +#define N_WORDS_ROW (N_BYTES_PAGE / N_ROWS / N_BYTES_WORD) +#define N_WORDS_PAGE (N_BYTES_PAGE / N_BYTES_WORD) + +#define IS_PAGE_NUMBER(PAGE) ( (PAGE)
© COPYRIGHT 2016 STMicroelectronics
+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_GPIO_H +#define BLUENRG1_GPIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup GPIO_Peripheral GPIO Peripheral + * @{ + */ + + +/** @defgroup GPIO_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Structure definition of GPIO initialization + */ +typedef struct +{ + uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_Pins_Definition */ + + uint8_t GPIO_Mode; /*!< Specifies the operating mode for the selected pin. + This parameter can be a value of @ref GPIO_Mode_Definition */ + + FunctionalState GPIO_HighPwr; /*!< Specifies the GPIO strength for the selected pin. + This parameter can be any value of @ref FunctionalState */ + + FunctionalState GPIO_Pull; /*!< Specifies the GPIO pull down state for the selected pin. + This parameter can be a value of @ref FunctionalState */ +} GPIO_InitType; + + + +/** + * @brief Structure definition of GPIO EXTernal Interrupt initialization + */ +typedef struct +{ + uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_Pins_Definition */ + + uint32_t GPIO_IrqSense; /*!< Specifies the GPIO interrupt sense to be configured. + This parameter can be any value of @ref GPIO_IRQ_Sense_Definition */ + + uint32_t GPIO_Event; /*!< Specifies the GPIO level sense to be configured. + This parameter can be any value of @ref GPIO_Event_Definition */ + +} GPIO_EXTIConfigType; + + +/** + * @brief Bit_SET and Bit_RESET enumeration + */ +typedef enum +{ + Bit_RESET = 0, /*!< Specifies the GPIO reset state */ + Bit_SET /*!< Specifies the GPIO set state */ +} BitAction; + +/** This macro checks if ACTION is a valid bit action */ +#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) + +/** + * @} + */ + + +/** @defgroup GPIO_Exported_Constants Exported Constants + * @{ + */ + + + +/** @defgroup GPIO_Mode_Definition Mode Definition + * @{ + */ + +#define GPIO_Input ((uint8_t)0) /*!< GPIO input selected */ +#define Serial1_Mode ((uint8_t)1) /*!< Serial1 mode selected */ +#define Serial0_Mode ((uint8_t)4) /*!< Serial0 mode selected */ +#define Serial2_Mode ((uint8_t)5) /*!< Serial2 mode selected */ +#define GPIO_Output ((uint8_t)6) /*!< GPIO output mode selected */ + +/* This macro checks if MODE is a valid mode value for GPIO, please refer to the DATASHEET GPIO mode table */ +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Input) || \ + ((MODE) == GPIO_Output) || \ + ((MODE) == Serial1_Mode) || \ + ((MODE) == Serial0_Mode) || \ + ((MODE) == Serial2_Mode)) + +/** + * @} + */ + + + +/** @defgroup GPIO_Pins_Definition GPIO Pins Definition + * @{ + */ +#define GPIO_Pin_0 ((uint32_t)0x00000001) /*!< Pin 0 selected */ +#define GPIO_Pin_1 ((uint32_t)0x00000002) /*!< Pin 1 selected */ +#define GPIO_Pin_2 ((uint32_t)0x00000004) /*!< Pin 2 selected */ +#define GPIO_Pin_3 ((uint32_t)0x00000008) /*!< Pin 3 selected */ +#define GPIO_Pin_4 ((uint32_t)0x00000010) /*!< Pin 4 selected */ +#define GPIO_Pin_5 ((uint32_t)0x00000020) /*!< Pin 5 selected */ +#define GPIO_Pin_6 ((uint32_t)0x00000040) /*!< Pin 6 selected */ +#define GPIO_Pin_7 ((uint32_t)0x00000080) /*!< Pin 7 selected */ +#define GPIO_Pin_8 ((uint32_t)0x00000100) /*!< Pin 8 selected */ +#define GPIO_Pin_9 ((uint32_t)0x00000200) /*!< Pin 9 selected */ +#define GPIO_Pin_10 ((uint32_t)0x00000400) /*!< Pin 10 selected */ +#define GPIO_Pin_11 ((uint32_t)0x00000800) /*!< Pin 11 selected */ +#define GPIO_Pin_12 ((uint32_t)0x00001000) /*!< Pin 12 selected */ +#define GPIO_Pin_13 ((uint32_t)0x00002000) /*!< Pin 13 selected */ +#define GPIO_Pin_14 ((uint32_t)0x00004000) /*!< Pin 14 selected */ + +#define GPIO_Pin_15 ((uint32_t)0x00008000) /*!< Pin 15 selected */ +#define GPIO_Pin_16 ((uint32_t)0x00010000) /*!< Pin 16 selected */ +#define GPIO_Pin_17 ((uint32_t)0x00020000) /*!< Pin 17 selected */ +#define GPIO_Pin_18 ((uint32_t)0x00040000) /*!< Pin 18 selected */ +#define GPIO_Pin_19 ((uint32_t)0x00080000) /*!< Pin 19 selected */ +#define GPIO_Pin_20 ((uint32_t)0x00100000) /*!< Pin 20 selected */ +#define GPIO_Pin_21 ((uint32_t)0x00200000) /*!< Pin 21 selected */ +#define GPIO_Pin_22 ((uint32_t)0x00400000) /*!< Pin 22 selected */ +#define GPIO_Pin_23 ((uint32_t)0x00800000) /*!< Pin 23 selected */ +#define GPIO_Pin_24 ((uint32_t)0x01000000) /*!< Pin 24 selected */ +#define GPIO_Pin_25 ((uint32_t)0x02000000) /*!< Pin 25 selected */ +#define GPIO_Pin_All ((uint32_t)0x03FFFFFF) /*!< All pins selected */ + +/* Number of total available GPIO pins */ +#define GPIO_PIN_COUNT (26) + +#define IS_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || ((PIN) == GPIO_Pin_1) || \ + ((PIN) == GPIO_Pin_2) || ((PIN) == GPIO_Pin_3) || \ + ((PIN) == GPIO_Pin_4) || ((PIN) == GPIO_Pin_5) || \ + ((PIN) == GPIO_Pin_6) || ((PIN) == GPIO_Pin_7) || \ + ((PIN) == GPIO_Pin_8) || ((PIN) == GPIO_Pin_9) || \ + ((PIN) == GPIO_Pin_10) || ((PIN) == GPIO_Pin_11) || \ + ((PIN) == GPIO_Pin_12) || ((PIN) == GPIO_Pin_13) || \ + ((PIN) == GPIO_Pin_14) || ((PIN) == GPIO_Pin_15) || \ + ((PIN) == GPIO_Pin_16) || ((PIN) == GPIO_Pin_17) || \ + ((PIN) == GPIO_Pin_18) || ((PIN) == GPIO_Pin_19) || \ + ((PIN) == GPIO_Pin_20) || ((PIN) == GPIO_Pin_21) || \ + ((PIN) == GPIO_Pin_22) || ((PIN) == GPIO_Pin_23) || \ + ((PIN) == GPIO_Pin_24) || ((PIN) == GPIO_Pin_25)) + + +/* This macro checks if PIN is a valid pin combination value */ +#define IS_GPIO_PINS(PIN) (((PIN) & GPIO_Pin_All) != 0) + + +/** + * @} + */ + + +/** @defgroup GPIO_IRQ_Sense_Definition IRQ Sense Definition + * @{ + */ + +#define GPIO_IrqSense_Edge (0) /*!< Edge detection */ +#define GPIO_IrqSense_Level (1) /*!< Level detection */ + +/** This macro checks if IS is a valid interrupt sense value */ +#define IS_GPIO_IRQSENSE(IS) (((IS) == GPIO_IrqSense_Edge) || ((IS) == GPIO_IrqSense_Level)) + +/** + * @} + */ + + +/** @defgroup GPIO_Event_Definition Event Definition + * @{ + */ +#define GPIO_Event_Low (0) /*!< Low level or falling edge detection */ +#define GPIO_Event_High (1) /*!< High level or rising edge detection */ +#define GPIO_Event_Both (2) /*!< Both edges detection */ + +/** This macro checks if EV is a valid GPIO_Event value */ +#define IS_GPIO_EVENT(EV) (((EV) == GPIO_Event_Low) || \ + ((EV) == GPIO_Event_High) || \ + ((EV) == GPIO_Event_Both)) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup GPIO_Exported_Macros Exported Macros +* @{ +*/ + +/* + * GPIO Configuration + */ + +/* GPIO Input Signal */ +#define GPIO_InitInputPinx(PIN_NAME) GPIO_Init(&(GPIO_InitType){(PIN_NAME), GPIO_Input, DISABLE, DISABLE}); + +/* GPIO Output Signal */ +#define GPIO_InitOutputPinx(PIN_NAME) GPIO_Init(&(GPIO_InitType){(PIN_NAME), GPIO_Output, DISABLE, DISABLE}); + + +/* + * UART Port Configuration + */ + +/* UART RX Signal */ +#define GPIO_InitUartRxPin4() GPIO_Init(&(GPIO_InitType){GPIO_Pin_4, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitUartRxPin11() GPIO_Init(&(GPIO_InitType){GPIO_Pin_11, Serial1_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitUartRxPin24() GPIO_Init(&(GPIO_InitType){GPIO_Pin_24, Serial1_Mode, DISABLE, DISABLE}); +#endif + +/* UART TX Signal */ +#define GPIO_InitUartTxPin5() GPIO_Init(&(GPIO_InitType){GPIO_Pin_5, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitUartTxPin8() GPIO_Init(&(GPIO_InitType){GPIO_Pin_8, Serial1_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitUartTxPin23() GPIO_Init(&(GPIO_InitType){GPIO_Pin_23, Serial1_Mode, DISABLE, DISABLE}); +#endif + +/* UART CTS Signal */ +#define GPIO_InitUartCtsPin0() GPIO_Init(&(GPIO_InitType){GPIO_Pin_0, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitUartCtsPin7() GPIO_Init(&(GPIO_InitType){GPIO_Pin_7, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitUartCtsPin13() GPIO_Init(&(GPIO_InitType){GPIO_Pin_13, Serial1_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitUartCtsPin19() GPIO_Init(&(GPIO_InitType){GPIO_Pin_19, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitUartCtsPin20() GPIO_Init(&(GPIO_InitType){GPIO_Pin_20, Serial1_Mode, DISABLE, DISABLE}); +#endif + +/* UART RTS Signal */ +#define GPIO_InitUartRtsPin1() GPIO_Init(&(GPIO_InitType){GPIO_Pin_1, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitUartRtsPin6() GPIO_Init(&(GPIO_InitType){GPIO_Pin_6, Serial1_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitUartRtsPin18() GPIO_Init(&(GPIO_InitType){GPIO_Pin_18, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitUartRtsPin25() GPIO_Init(&(GPIO_InitType){GPIO_Pin_25, Serial1_Mode, DISABLE, DISABLE}); +#endif + + +/* + * SPI Port Configuration + */ + +/* SPI Clock Signal */ +#define GPIO_InitSpiClkPin0() GPIO_Init(&(GPIO_InitType){GPIO_Pin_0, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiClkPin8() GPIO_Init(&(GPIO_InitType){GPIO_Pin_8, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiClkPin14() GPIO_Init(&(GPIO_InitType){GPIO_Pin_14, Serial0_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitSpiClkPin25() GPIO_Init(&(GPIO_InitType){GPIO_Pin_25, Serial0_Mode, DISABLE, DISABLE}); +#endif + +/* SPI CS Signal */ +#define GPIO_InitSpiCs1Pin1() GPIO_Init(&(GPIO_InitType){GPIO_Pin_1, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiCs1Pin11() GPIO_Init(&(GPIO_InitType){GPIO_Pin_11, Serial0_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitSpiCs1Pin15() GPIO_Init(&(GPIO_InitType){GPIO_Pin_15, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiCs2Pin18() GPIO_Init(&(GPIO_InitType){GPIO_Pin_18, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiCs2Pin20() GPIO_Init(&(GPIO_InitType){GPIO_Pin_20, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiCs3Pin19() GPIO_Init(&(GPIO_InitType){GPIO_Pin_19, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiCs1Pin21() GPIO_Init(&(GPIO_InitType){GPIO_Pin_21, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiCs3Pin22() GPIO_Init(&(GPIO_InitType){GPIO_Pin_22, Serial1_Mode, DISABLE, DISABLE}); +#endif + + +/* SPI OUT Signal */ +#define GPIO_InitSpiOutPin2() GPIO_Init(&(GPIO_InitType){GPIO_Pin_2, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiOutPin10() GPIO_Init(&(GPIO_InitType){GPIO_Pin_10, Serial0_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitSpiOutPin17() GPIO_Init(&(GPIO_InitType){GPIO_Pin_17, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiOutPin23() GPIO_Init(&(GPIO_InitType){GPIO_Pin_23, Serial0_Mode, DISABLE, DISABLE}); +#endif + + +/* SPI IN Signal */ +#define GPIO_InitSpiInPin9() GPIO_Init(&(GPIO_InitType){GPIO_Pin_9, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiInPin3() GPIO_Init(&(GPIO_InitType){GPIO_Pin_3, Serial0_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitSpiInPin16() GPIO_Init(&(GPIO_InitType){GPIO_Pin_16, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitSpiInPin24() GPIO_Init(&(GPIO_InitType){GPIO_Pin_24, Serial0_Mode, DISABLE, DISABLE}); +#endif + + +/* + * I2C1 Port Configuration + */ + +/* I2C1 Clock Signal */ +#define GPIO_InitI2c1ClkPin12() GPIO_Init(&(GPIO_InitType){GPIO_Pin_12, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitI2c1ClkPin14() GPIO_Init(&(GPIO_InitType){GPIO_Pin_14, Serial1_Mode, DISABLE, DISABLE}); + +/* I2C1 Data Signal */ +#define GPIO_InitI2c1DataPin13() GPIO_Init(&(GPIO_InitType){GPIO_Pin_13, Serial0_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitI2c1DataPin15() GPIO_Init(&(GPIO_InitType){GPIO_Pin_15, Serial1_Mode, DISABLE, DISABLE}); +#endif + +/* + * I2C2 Port Configuration + */ + +/* I2C2 Clock Signal */ +#define GPIO_InitI2c2ClkPin4() GPIO_Init(&(GPIO_InitType){GPIO_Pin_4, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitI2c2ClkPin6() GPIO_Init(&(GPIO_InitType){GPIO_Pin_6, Serial0_Mode, DISABLE, DISABLE}); + +/* I2C2 Data Signal */ +#define GPIO_InitI2c2DataPin5() GPIO_Init(&(GPIO_InitType){GPIO_Pin_5, Serial0_Mode, DISABLE, DISABLE}); +#define GPIO_InitI2c2DataPin7() GPIO_Init(&(GPIO_InitType){GPIO_Pin_7, Serial0_Mode, DISABLE, DISABLE}); + + +/* + * PWM Configuration + */ + +/* PWM0 Signal */ +#define GPIO_InitPwm0Pin2() GPIO_Init(&(GPIO_InitType){GPIO_Pin_2, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitPwm0Pin4() GPIO_Init(&(GPIO_InitType){GPIO_Pin_4, Serial2_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitPwm0Pin16() GPIO_Init(&(GPIO_InitType){GPIO_Pin_16, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitPwm0Pin22() GPIO_Init(&(GPIO_InitType){GPIO_Pin_22, Serial1_Mode, DISABLE, DISABLE}); +#endif + +/* PWM1 Signal */ +#define GPIO_InitPwm1Pin3() GPIO_Init(&(GPIO_InitType){GPIO_Pin_3, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitPwm1Pin5() GPIO_Init(&(GPIO_InitType){GPIO_Pin_5, Serial2_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitPwm1Pin17() GPIO_Init(&(GPIO_InitType){GPIO_Pin_17, Serial1_Mode, DISABLE, DISABLE}); +#define GPIO_InitPwm1Pin21() GPIO_Init(&(GPIO_InitType){GPIO_Pin_21, Serial1_Mode, DISABLE, DISABLE}); +#endif + + +/* + * PDM Configuration + */ + +/* PDM Data Signal */ +#define GPIO_InitPdmDataPin1() GPIO_Init(&(GPIO_InitType){GPIO_Pin_1, Serial2_Mode, DISABLE, DISABLE}); +#define GPIO_InitPdmDataPin6() GPIO_Init(&(GPIO_InitType){GPIO_Pin_6, Serial2_Mode, DISABLE, DISABLE}); +#define GPIO_InitPdmDataPin8() GPIO_Init(&(GPIO_InitType){GPIO_Pin_8, Serial2_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitPdmDataPin24() GPIO_Init(&(GPIO_InitType){GPIO_Pin_24, Serial2_Mode, DISABLE, DISABLE}); +#endif + +/* PDM Clock Signal */ +#define GPIO_InitPdmClockPin2() GPIO_Init(&(GPIO_InitType){GPIO_Pin_2, Serial2_Mode, DISABLE, DISABLE}); +#define GPIO_InitPdmClockPin7() GPIO_Init(&(GPIO_InitType){GPIO_Pin_7, Serial2_Mode, DISABLE, DISABLE}); + +#ifdef BLUENRG2_DEVICE +#define GPIO_InitPdmClockPin23() GPIO_Init(&(GPIO_InitType){GPIO_Pin_23, Serial2_Mode, DISABLE, DISABLE}); +#define GPIO_InitPdmClockPin25() GPIO_Init(&(GPIO_InitType){GPIO_Pin_25, Serial2_Mode, DISABLE, DISABLE}); +#endif + + +/** + * @} + */ + + +/** @defgroup GPIO_Exported_Functions Exported Functions + * @{ + */ + +/* Initialization */ +void GPIO_DeInit(void); /*!< GPIO deinitialization. */ +void GPIO_Init(GPIO_InitType* GPIO_InitStruct); /*!< GPIO initialization. */ +void GPIO_StructInit(GPIO_InitType* GPIO_InitStruct); /*!< Initialization of the GPIO_InitType Structure. */ +void GPIO_InitLowPowerModes(GPIO_InitType* GPIO_InitStruct); /*!< GPIO9, GPIO10, GPIO11 initialization during low power modes for BlueNRG-2. */ +void GPIO_WriteBitsLowPowerModes(uint32_t GPIO_Pins, BitAction BitVal); /*!< Set the output state of the GIO9, GIO10, GIO11 during low power modes. BlueNRG-2 only. */ +void GPIO_ToggleBitsLowPowerModes(uint32_t GPIO_Pins); /*!< Toggle the output state of the GIO9, GIO10, GIO11 during low power modes. BlueNRG-2 only. */ + +/* Data read */ +BitAction GPIO_ReadBit(uint32_t GPIO_Pins); /*!< Read GPIO pin logic state. */ + +/* Data write */ +void GPIO_WriteBit(uint32_t GPIO_Pins, BitAction BitVal); /*!< Write new GPIO pin logic state. */ + +/* Bit operations */ +void GPIO_SetBits(uint32_t GPIO_Pins); /*!< Set selected GPIO pin. */ +void GPIO_ResetBits(uint32_t GPIO_Pins); /*!< Reset selected GPIO pin. */ +void GPIO_ToggleBits(uint32_t GPIO_Pins); /*!< Toggle selected GPIO pin. */ + +/* GPIO interrupts */ +void GPIO_EXTIStructInit(GPIO_EXTIConfigType* GPIO_EXTIInitStruct); /*!< Initialization of the GPIO_EXTIInit Structure. */ +void GPIO_EXTIConfig(GPIO_EXTIConfigType* EXTIConfig); /*!< Selects the GPIO pin used as EXTI Line. */ +void GPIO_EXTICmd(uint32_t GPIO_Pins, FunctionalState NewState); /*!< Enables or disables interrupts on specified pins. */ +void GPIO_ClearITPendingBit(uint32_t GPIO_Pins); /*!< Clears the GPIOx interrupt pending bits. */ +FlagStatus GPIO_GetITPendingBit(uint32_t GPIO_Pin); /*!< Checks whether the specified enabled GPIO interrupt is active. */ +ITStatus GPIO_GetITStatusBit(uint32_t GPIO_Pin); /*!< Checks whether the specified GPIO interrupt is active. */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_GPIO_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_i2c.h b/drivers/inc/BlueNRG1_i2c.h new file mode 100644 index 0000000..6e7cef7 --- /dev/null +++ b/drivers/inc/BlueNRG1_i2c.h @@ -0,0 +1,397 @@ +/** + ****************************************************************************** + * @file BlueNRG1_i2c.h + * @author VMA Application Team + * @version V2.1.0 + * @date 21-March-2016 + * @brief This file contains all the functions prototypes for the I2C firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_I2C_H +#define BLUENRG1_I2C_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup I2C_Peripheral I2C Peripheral + * @{ + */ + +/** @defgroup I2C_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Structure definition of I2C initialization + */ +typedef struct +{ + uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. + This parameter must be set max to 400 Kb/s */ + + uint8_t I2C_OperatingMode; /*!< Specifies the I2C frequency. + This parameter can be a value of @ref I2C_operating_mode */ + + uint8_t I2C_Filtering; /*!< Specifies the I2C filtering. + This parameter can be a value of @ref I2C_filtering */ + + uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address. */ + + + FunctionalState I2C_ExtendAddress; /*!< Specifies if 7-bit or 10-bit address is used. + This parameter can be a value of @ref FunctionalState */ +} I2C_InitType; + + + +/** + * @brief Structure definition of I2C transaction initialization + */ +typedef struct { + uint16_t Operation; /*!< Specifies the transaction operation: read or write. + This parameter can be a value of @ref I2C_operation */ + + uint16_t Address; /*!< Slave address. */ + + uint16_t StartByte; /*!< Enables or disables the start byte. + This parameter can be a value of @ref I2C_start_byte */ + + uint16_t AddressType; /*!< Specifies the address type. + This parameter can be a value of @ref I2C_address_type */ + + uint16_t StopCondition; /*!< Enables or disables the stop condition. + This parameter can be a value of @ref I2C_stop_condition */ + + uint16_t Length; /*!< Specifies the length of the transaction (number of bytes). + This parameter can be a value of @ref I2C_stop_condition */ +} I2C_TransactionType; + + +/** + * @brief I2C operation status enumeration + */ +typedef enum { + I2C_NOP = 0, /*! = 1) && ((SPEED) <= 400000)) + +/** + * @} + */ + + +/** @defgroup I2C_DMA_Requests_Definition DMA Requests Definition + * @{ + */ + +#define I2C_DMAReq_Tx ((uint16_t)0x0200) +#define I2C_DMAReq_Rx ((uint16_t)0x0400) +#define IS_I2C_DMAREQ(DMAREQ) (((DMAREQ) & 0x0600) != 0) + +/** + * @} + */ + +/** @defgroup I2C_Burst_Size Burst Size + * @{ + */ + +/** This macro checks if the burst size is a valid value */ +#define IS_I2C_BURSTSIZE(SIZE) (((SIZE) >= 1) && ((SIZE) <= 7)) + +/** + * @} + */ + +/** @defgroup I2C_Hold_Time Hold Time + * @{ + */ + +/** This macro checks if the hold time is a valid value */ +#define IS_I2C_HOLDTIME(TIME) ((TIME) <= 0x1FF) + +/** + * @} + */ + + +/** @defgroup I2C_Setup_Time Setup Time + * @{ + */ + +/** This macro checks if the setup time is a valid value */ +#define IS_I2C_SETUPTIME(TIME) ((TIME) <= 0x1FF) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions Exported Functions + * @{ + */ +void I2C_DeInit(I2C_Type* I2Cx); +void I2C_Init(I2C_Type* I2Cx, I2C_InitType* I2C_InitStruct); +void I2C_StructInit(I2C_InitType* I2C_InitStruct); +void I2C_Cmd(I2C_Type* I2Cx, FunctionalState NewState); +void I2C_BeginTransaction(I2C_Type* I2Cx, I2C_TransactionType* tr); +void I2C_GeneralCallCmd(I2C_Type* I2Cx, FunctionalState NewState); +void I2C_FillTxFIFO(I2C_Type* I2Cx, uint8_t Data); +uint8_t I2C_ReceiveData(I2C_Type* I2Cx); +void I2C_FlushTx(I2C_Type* I2Cx); +void I2C_FlushRx(I2C_Type* I2Cx); +void I2C_SetTxThreshold(I2C_Type* I2Cx, uint16_t TxThres); +void I2C_SetRxThreshold(I2C_Type* I2Cx, uint16_t RxThres); +void I2C_GenerateStopCondition(I2C_Type* I2Cx); +void I2C_SetHoldTime(I2C_Type* I2Cx, uint16_t I2C_HoldTime); +void I2C_SetHoldTimeStartCondition(I2C_Type* I2Cx, uint16_t I2C_HoldTime); +void I2C_SetSetupTimeStartCondition(I2C_Type* I2Cx, uint16_t I2C_SetupTime); +I2C_OpStatus I2C_WaitFlushRx(I2C_Type* I2Cx); +I2C_OpStatus I2C_WaitFlushTx(I2C_Type* I2Cx); + +void I2C_ITConfig(I2C_Type* I2Cx, uint32_t I2C_IT, FunctionalState NewState); +ITStatus I2C_GetITStatus(I2C_Type* I2Cx, uint32_t I2C_IT); +void I2C_ClearITPendingBit(I2C_Type* I2Cx, uint32_t I2C_IT); +ITStatus I2C_GetITPendingBit(I2C_Type* I2Cx, uint32_t I2C_IT); +I2C_OpStatus I2C_GetStatus(I2C_Type* I2Cx); +void I2C_DMACmd(I2C_Type* I2Cx, uint16_t I2C_DMAReq, FunctionalState NewState); +void I2C_DMATxBurstMode(I2C_Type* I2Cx, FunctionalState NewState); +void I2C_DMATxBurstSize(I2C_Type* I2Cx, uint8_t I2C_BurstSize); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*BLUENRG1_I2C_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_mft.h b/drivers/inc/BlueNRG1_mft.h new file mode 100644 index 0000000..ae2595d --- /dev/null +++ b/drivers/inc/BlueNRG1_mft.h @@ -0,0 +1,248 @@ +/** + ****************************************************************************** + * @file BlueNRG1_mft.h + * @author VMA Application Team + * @version V2.1.0 + * @date 16-Feb-2018 + * @brief This file contains all the functions prototypes for the MFT + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_MFT_H +#define BLUENRG1_MFT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup MFT_Peripheral MFT Peripheral + * @{ + */ + +/** @defgroup MFT_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Structure definition of MFT initialization + */ + typedef struct +{ + uint8_t MFT_Mode; /*!< Specifies the MFT mode. + This value can be a value of @ref MFT_Mode_Definition */ + + uint8_t MFT_Clock1; /*!< Specifies the MFT clock selection, for counter A. + This value can be a value of @ref MFT_Clock_Selector_Definition */ + + uint8_t MFT_Clock2; /*!< Specifies the MFT clock selection, for counter B. + This value can be a value of @ref MFT_Clock_Selector_Definition */ + + uint8_t MFT_Prescaler; /*!< Specifies the MFT prescaler only for MFT_PRESCALED_CLK */ + + uint16_t MFT_CRA; /*!< Specifies the MFT CRA init value. */ + + uint16_t MFT_CRB; /*!< Specifies the MFT CRB init value. */ + +} MFT_InitType; + + +/** + * @} + */ + +/** @defgroup MFT_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup MFT_Peripheral_Name_Definitions Peripheral Name Definitions + * @{ + */ + +/** This macro checks if PERIPH is a valid MFT peripheral */ +#define IS_MFT(PERIPH) (((PERIPH) == MFT1) || ((PERIPH) == MFT2)) + +/** + * @} + */ + +/** @defgroup MFT_Mode_Definitions Mode Definitions + * @{ + */ + +#define MFT_MODE_1 ((uint8_t)0x00) /*!< Mode 1 */ +#define MFT_MODE_1a ((uint8_t)0x80) /*!< Mode 1a */ +#define MFT_MODE_2 ((uint8_t)0x01) /*!< Mode 2 */ +#define MFT_MODE_3 ((uint8_t)0x02) /*!< Mode 3 */ +#define MFT_MODE_4 ((uint8_t)0x03) /*!< Mode 4 */ + +#define IS_MFT_MODE(MODE) (((MODE) == MFT_MODE_1) || \ + ((MODE) == MFT_MODE_1a) || \ + ((MODE) == MFT_MODE_2) || \ + ((MODE) == MFT_MODE_3) || \ + ((MODE) == MFT_MODE_4)) + +/** + * @} + */ + +/** @defgroup MFT_Interrupt_Definitions Interrupt Definitions + * @{ + */ + +#define MFT_IT_TNA ((uint32_t)0x1) /*!< interrupt TnAPND */ +#define MFT_IT_TNB ((uint32_t)0x2) /*!< interrupt TnBPND */ +#define MFT_IT_TNC ((uint32_t)0x4) /*!< interrupt TnCPND */ +#define MFT_IT_TND ((uint32_t)0x8) /*!< interrupt TnDPND */ + +#define IS_MFT_INTERRUPT(IT) ((((IT) & (~0xF)) == 0x00) && ((IT) != 0x00)) + +/** + * @} + */ + +/** @defgroup MFT_Clock_Selector_Definitions Clock Selector Definitions + * @{ + */ + +#define MFT_NO_CLK ((uint8_t)0x00) /*!< Noclock, timer1 stopped */ +#define MFT_PRESCALED_CLK ((uint8_t)0x01) /*!< System clock with configurable prescaler */ +#define MFT_EXTERNAL_EVENT ((uint8_t)0x02) /*!< External event on TnB (mode 1 and 3 only) */ +#define MFT_PULSE_ACCUMULATE ((uint8_t)0x03) /*!< Pulse accumulate (mode 1 and 3 only) */ +#define MFT_LOW_SPEED_CLK ((uint8_t)0x04) /*!< 16 MHz clock without prescaler (only when the system clock is 32 MHz). */ + +#define IS_MFT_CLOCK_SEL(MODE) (((MODE) == MFT_NO_CLK) || \ + ((MODE) == MFT_PRESCALED_CLK) || \ + ((MODE) == MFT_EXTERNAL_EVENT) || \ + ((MODE) == MFT_PULSE_ACCUMULATE) || \ + ((MODE) == MFT_LOW_SPEED_CLK)) + +/** + * @} + */ + + +/** @defgroup MFT_Pin_Trigger_Definitions Pin Trigger Definitions + * @{ + */ + +#define MFT_FALLING ((uint32_t)0x0) /* on rising edge */ +#define MFT_RISING ((uint32_t)0x1) /* on falling edge */ + +#define IS_MFT_Tn_EDGE(REG) (((REG) == MFT_FALLING) || ((REG) == MFT_RISING) ) + +/** + * @} + */ + +/** @defgroup MFT_Mode1a_Trigger_Definitions Mode1a Trigger Definitions + * @{ + */ + +#define MFT_TnB_TRIGGER ((uint32_t)0x0) /* trigger on TnB edge */ +#define MFT_SOFTWARE_TRIGGER ((uint32_t)0x1) /* trigger software */ + +#define IS_MFT_PULSETRAIN_TRIGGER(MODE) (((MODE) == MFT_TnB_TRIGGER) || ((MODE) == MFT_SOFTWARE_TRIGGER)) + + /** + * @} + */ + +/** @defgroup MFT_Pin_Definitions Pin Definitions + * @{ + */ + +#define MFT_TnA 0 /* select internal pin TnA */ +#define MFT_TnB 1 /* select internal pin TnB */ + +#define IS_MFT_TnX(VALUE) (((VALUE) == MFT_TnA) || ((VALUE) == MFT_TnB)) + +/** +* @} +*/ + + + +/** @defgroup MFT_TIMERx_Definitions TIMERx Definitions + * @{ + */ + +#define MFT1_TIMERA ((uint32_t)0x0) /* Timer MFT1 and input TnA */ +#define MFT1_TIMERB ((uint32_t)0x1) /* Timer MFT1 and input TnB */ +#define MFT2_TIMERA ((uint32_t)0x2) /* Timer MFT2 and input TnA */ +#define MFT2_TIMERB ((uint32_t)0x3) /* Timer MFT2 and input TnB */ + +#define IS_MFT_TIMER(VALUE) ((VALUE) <= 3) + +#define IS_MFT_INPUT_IO(VALUE) ((VALUE) < 15) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup MFT_Exported_Functions Exported Functions + * @{ + */ + +void MFT_DeInit(MFT_Type* MFTx); +void MFT_Init(MFT_Type* MFTx, MFT_InitType* MFT_InitStruct); +void MFT_Cmd(MFT_Type* MFTx, FunctionalState NewState); +void MFT_StructInit(MFT_InitType* MFT_InitStruct); +void MFT_TnEDGES(MFT_Type* MFTx, uint32_t MFT_TnA_edge, uint32_t MFT_TnB_edge); +void MFT_PulseTrainTriggerSelect(MFT_Type* MFTx, uint32_t MFT_Trigger); +void MFT_PulseTrainSoftwareTrigger(MFT_Type* MFTx); +uint8_t MFT_PulseTrainEventTriggerStatus(MFT_Type* MFTx); +void MFT_TnXEN(MFT_Type* MFTx, uint8_t TnX, FunctionalState NewState); +void MFT_SelectCapturePin( uint32_t MFT_TimerType, uint8_t MFT_Pin); +void MFT_SetCounter(MFT_Type* MFTx, uint16_t MFT_Cnt1, uint16_t MFT_Cnt2); +void MFT_SetCounter1(MFT_Type* MFTx, uint16_t MFT_Cnt); +uint16_t MFT_GetCounter1(MFT_Type* MFTx); +void MFT_SetCounter2(MFT_Type* MFTx, uint16_t MFT_Cnt); +uint16_t MFT_GetCounter2(MFT_Type* MFTx); +void MFT_EnableIT(MFT_Type* MFTx, uint8_t MFT_IrqSource, FunctionalState NewState); +void MFT_ClearIT(MFT_Type* MFTx, uint8_t MFT_IrqSource); +ITStatus MFT_StatusIT(MFT_Type* MFTx, uint8_t MFT_IrqSource); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*BLUENRG1_MFT_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_pka.h b/drivers/inc/BlueNRG1_pka.h new file mode 100644 index 0000000..6e846cf --- /dev/null +++ b/drivers/inc/BlueNRG1_pka.h @@ -0,0 +1,179 @@ +/** + ****************************************************************************** + * @file BlueNRG1_pka.h + * @author VMA Application Team + * @version V1.0.0 + * @date 27-February-2017 + * @brief This file contains all the functions prototypes for the PKA + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_PKA_H +#define BLUENRG1_PKA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup PKA_Peripheral PKA Peripheral + * @{ + */ + +/** @defgroup PKA_Exported_Types Exported Types + * @{ + */ + +#define PKA_DATA_SK 0x01 /* PKA select data for K value */ +#define PKA_DATA_PCX 0x02 /* PKA select data for Point X coordinate value */ +#define PKA_DATA_PCY 0x03 /* PKA select data for Point Y coordinate value */ + +#define IS_PKA_CMD(CMD) ( ((CMD) == PKA_DATA_SK) || \ + ((CMD) == PKA_DATA_PCX) || \ + ((CMD) == PKA_DATA_PCY) ) + + +/** + * @brief PKA status enumeration + */ + +#define PKA_PROCEND 0x01 /* PKA process end */ +#define PKA_RAMERR 0x04 /* PKA RAM error */ +#define PKA_ADDERR 0x08 /* PKA address invalid */ + +#define IS_PKA_FLAG(FLAG) ( ((FLAG) == PKA_PROCEND) || \ + ((FLAG) == PKA_RAMERR) || \ + ((FLAG) == PKA_ADDERR) ) + +/** + * @} + */ + +/** @defgroup PKA_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup PKA_Size_Definitions Size Definitions + * @{ + */ + +#define PKA_RAM_BASE (PKA_BASE + 0x00000400) + +#define PKA_RAM_START (PKA_RAM_BASE) +#define PKA_RAM_END (PKA_RAM_BASE + 0x00001000) + +#define PKA_RAM_ECC_ADDR_KP_ERROR (PKA_RAM_BASE) +#define PKA_RAM_ECC_ADDR_K (PKA_RAM_BASE + 0x6C) +#define PKA_RAM_ECC_ADDR_PX (PKA_RAM_BASE + 0x90) +#define PKA_RAM_ECC_ADDR_PY (PKA_RAM_BASE + 0xB4) + + + +/* The initial Point X coordinate of the curve in hex format: + * 6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296 + */ +#define INITIAL_START_POINT_X_W1 0xd898c296 +#define INITIAL_START_POINT_X_W2 0xf4a13945 +#define INITIAL_START_POINT_X_W3 0x2deb33a0 +#define INITIAL_START_POINT_X_W4 0x77037d81 +#define INITIAL_START_POINT_X_W5 0x63a440f2 +#define INITIAL_START_POINT_X_W6 0xf8bce6e5 +#define INITIAL_START_POINT_X_W7 0xe12c4247 +#define INITIAL_START_POINT_X_W8 0x6b17d1f2 + +/* The initial Point Y coordinate of the curve in hex format: + * 4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5 + */ +#define INITIAL_START_POINT_Y_W1 0x37bf51f5 +#define INITIAL_START_POINT_Y_W2 0xcbb64068 +#define INITIAL_START_POINT_Y_W3 0x6b315ece +#define INITIAL_START_POINT_Y_W4 0x2bce3357 +#define INITIAL_START_POINT_Y_W5 0x7c0f9e16 +#define INITIAL_START_POINT_Y_W6 0x8ee7eb4a +#define INITIAL_START_POINT_Y_W7 0xfe1a7f9b +#define INITIAL_START_POINT_Y_W8 0x4fe342e2 + + +/** + * @} + */ + + +/** @defgroup PKA_Commands_Definitions Commands Definitions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup PKA_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup PKA_Exported_Functions Exported Functions + * @{ + */ + + +ErrorStatus PKA_SetData(uint8_t dataType, uint32_t* srcData); +ErrorStatus PKA_GetData(uint8_t dataType, uint8_t* dataTarget); + +void PKA_Reset(void); +void PKA_StartProcessing(void); +void PKA_WaitProcess(void); +FlagStatus PKA_GetProcessStatus(void); +ErrorStatus PKA_VerifyProcess(void); + +void PKA_ClearITPendingBit(uint8_t PkaFlag); +FlagStatus PKA_GetFlagStatus(uint8_t PkaFlag); +void PKA_ITConfig(uint8_t PkaFlag, FunctionalState NewState); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_PKA_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_radio.h b/drivers/inc/BlueNRG1_radio.h new file mode 100644 index 0000000..fd6f93c --- /dev/null +++ b/drivers/inc/BlueNRG1_radio.h @@ -0,0 +1,281 @@ +/** + ****************************************************************************** + * @file BlueNRG1_radio.h + * @author RF Application Team + * @date Jan-2020 + * @brief This file contains all the functions prototypes for the radio firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2020 STMicroelectronics

+ ****************************************************************************** + */ + + /* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_RADIO_H +#define BLUENRG1_RADIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + + +/** @addtogroup Radio_Peripheral Radio Peripheral + * @{ + */ + +/** @defgroup Radio_Exported_Constants Exported Constants +* @{ + */ + +#define HEADER_LENGTH 2 +#if defined(BLUENRG2_DEVICE) +#define MAX_PACKET_LENGTH (255+HEADER_LENGTH) // 255 (-4 if encryption) +#else +#define MAX_PACKET_LENGTH (38+HEADER_LENGTH) // 31 in data channel, 38 in adv. channel (-4 if encryption) +#endif +#define MIC_FIELD_LENGTH 4 +#define RECEIVE_BUFFER_LENGTH 45 +#define MAX_OUTPUT_RF_POWER 15 +#define SUCCESS_0 0 +#define INVALID_PARAMETER_C0 0xC0 +#define WAKEUP_NOTSET_C2 0xC2 +#define RADIO_BUSY_C4 0xC4 +#define COMMAND_DISALLOWED 0xC5 +#define NULL_0 0 +#define BLUE_IDLE_0 0 +#define TIMESTAMP_POSITION_ACCESSADDRESS 0x40 +#define TIMESTAMP_POSITION_LASTBIT 0x80 /*C0*/ +#define HOT_ANA_CONFIG_TABLE_LENGTH 64 + +#define STATEMACHINE_COUNT 8 + +/** @defgroup Radio_Interrupt_Status_Bits Interrupt Status bits + * @{ + */ + +#define IRQ_RCV_OK (1UL<<31) /* The packet is received, and the CRC is valid. */ +#define IRQ_CRC_ERR (1UL<<30) /* The packet is received with CRC error or timeout error. */ +#define IRQ_RCV_TRIG (1UL<<29) +#define IRQ_CMD (1UL<<28) +#define IRQ_MD (1UL<<27) +#define IRQ_TIMEOUT (1UL<<26) /* No packet received within the defined RX time window. */ +#define IRQ_RCV_FAIL (1UL<<25) +#define IRQ_DONE (1UL<<24) /* Requested action (TX or RX) has been executed. */ +#define IRQ_ERR_ENC (1UL<<23) /* A packet is received, but there is an error in the MIC field. */ +#define IRQ_TX_OK (1UL<<22) /* The packet has been sent successfully. */ +#define BIT_TX_SKIP (1UL<<20) +#define IRQ_CONFIG_ERR (1UL<<19) +#define BIT_TX_MODE (1UL<<18) /* The packet has been sent successfully. */ +#define BIT_TIME_OVERRUN (1UL<<17) +#define BIT_ACT2_ERROR (1UL<<16) +#define IRQ_WAKEUP_2 (1UL<<15) +#define BIT_AES_READY (1UL<<12) + +/** + * @} + */ + + +/** @defgroup Radio_ActionTag_BitMask ActionTag BitMask +* @{ +*/ + +/* This bit activates the radio frequency PLL calibration. + * 0: Radio frequency calibration disabled. + * 1: Radio frequency calibration enabled. + * User should set this bit only if TIMER_WAKEUP is set to 1. +*/ +#define PLL_TRIG 0x01 + +/* This bit determines if the action is an RX action or a TX action. + * 1: TX + * 0: RX +*/ +#define TXRX 0x02 + +/* The bit determines if the action (RX or TX) is going to be executed based on the back-to-back time or based on the WakeupTime. + * 0: Based on the back-to-back time (default 150 µs). + * 1: Based on the WakeupTime. +*/ +#define TIMER_WAKEUP 0x04 + +/* This bit activates automatic channel increment. The API RADIO_SetChannel sets the value of the increment. + * 0: No increment + * 1: Automatic increment +*/ +#define INC_CHAN 0x10 + +/* It determines if the WakeupTime field of the ActionPacket is considered as absolute time or relative time to the current. + * 0: Absolute + * 1: Relative +*/ +#define RELATIVE 0x20 + +/* This bit sets where the position of time stamp is taken, the beginning of the packet or the end of it. RX only. + * 0: End of the Packet + * 1: Beginning of the packet + */ +#define TIMESTAMP_POSITION 0x80 + +/** + * @} + */ + + +/** +* @} +*/ + +/** @defgroup Radio_Exported_Types Exported Types +* @{ +*/ + +typedef enum { + STATE_MACHINE_0 = 0, + STATE_MACHINE_1, + STATE_MACHINE_2, + STATE_MACHINE_3, + STATE_MACHINE_4, + STATE_MACHINE_5, + STATE_MACHINE_6, + STATE_MACHINE_7, +} StateMachine_t; + +typedef struct +{ + volatile uint16_t next; + volatile uint16_t datptr; + volatile uint8_t rcvlen[3]; + volatile uint8_t timeout[3]; + volatile uint8_t byte10; + volatile uint8_t byte11; +} BlueTransStruct; + + +typedef struct ActionPacket ActionPacket; + +typedef struct { + uint32_t *hot_ana_config_table; /**< Set to NULL */ +} config_table_t; + + +typedef struct { + uint32_t back2backTime; + uint8_t forceRadiotoStop; + uint32_t rssiLevel[2]; + int32_t hot_ana_config_table_a[HOT_ANA_CONFIG_TABLE_LENGTH>>2]; + config_table_t hardware_config; + // uint8_t tone_start_stop_flag; + ActionPacket* current_action_packet; +}RadioGlobalParameters_t; + +extern RadioGlobalParameters_t globalParameters; + + +struct ActionPacket +{ + uint8_t StateMachineNo ; /* This parameter indicates the state machine number for this action. From 0 to 7. */ + uint8_t ActionTag; /* The configuration of the current action. + * Action Tag: PLL_TRIG, TXRX, TIMER_WAKEUP, INC_CHAN, TIMESTAMP_POSITION, RELATIVE */ + uint32_t WakeupTime; /* Contains the wakeup time in microsecond if it is relative. + * It should not be more than 24 bits if it is absolute. + * It only applies if TIMER_WAKEUP flag is set in ActionTag. */ + uint32_t ReceiveWindowLength; /* Sets RX window size in microsecond. Applicable only for RX actions. */ + uint8_t *data; /* Pointer to the array with the data to send (header, length and data field), for TX. + * Pointer to the array where the data received are copied, for RX. + * In case of RX, the array must have the max size MAX_PACKET_LENGTH. */ + uint32_t status; /* The Status Register with the information on the action. */ + uint32_t timestamp_receive; /* This field contains the timestamp when a packet is received. + * Intended to be used in the dataRoutine() callback routine. RX only. */ + int32_t rssi; /* The rssi of the packet was received with. RX only. */ + BlueTransStruct trans_packet; /* This is a linked list, which is going to be used by Hardware. + * User does not need to do anything. */ + ActionPacket *next_true; /* Pointer to next ActionPacket if condRoutine() returns TRUE */ + ActionPacket *next_false; /* Pointer to next ActionPacket if condRoutine() returns FALSE */ + uint8_t (*condRoutine)(ActionPacket*); /* User callback that decide the next ActionPacket to use. + * It is time critical. Routine must end within 45 us. */ + uint8_t (*dataRoutine)(ActionPacket*, ActionPacket*); /* User callback for managing data. */ + uint8_t trans_config; /* This is for configuring the device for TX or RX. User does not need to do anything. */ +}; + +/** +* @} +*/ + + +/** @defgroup Radio_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup Radio_Private_Functions Private Functions +* @{ +*/ + +/** + * @} + */ + + +/** @defgroup Radio_Exported_Functions Exported Functions + * @{ + */ + +void RADIO_Init(uint32_t* hot_table, FunctionalState whitening); +uint8_t RADIO_GetStatus(uint32_t *time); +void RADIO_SetChannelMap(uint8_t StateMachineNo,uint8_t *chan_remap); +void RADIO_SetChannel(uint8_t StateMachineNo, uint8_t channel,uint8_t channel_increment); +void RADIO_SetTxAttributes(uint8_t StateMachineNo, uint32_t NetworkID, uint32_t crc_init); +void RADIO_SetBackToBackTime(uint32_t back_to_back_time); +void RADIO_SetTxPower(uint8_t PowerLevel); +void RADIO_IRQHandler(void); +uint8_t RADIO_StopActivity(void); +void RADIO_SetReservedArea(ActionPacket *p); +uint8_t RADIO_MakeActionPacketPending(ActionPacket *p); +void RADIO_CrystalCheck(void); +void RADIO_StartTone(uint8_t RF_channel, uint8_t powerLevel); +void RADIO_StopTone(void); +void RADIO_SetEncryptionCount(uint8_t StateMachineNo, uint8_t *count_tx, uint8_t *count_rcv); +void RADIO_SetEncryptionAttributes(uint8_t StateMachineNo, uint8_t *enc_iv, uint8_t *enc_key); +void RADIO_SetEncryptFlags(uint8_t StateMachineNo, FunctionalState EncryptFlagTx, FunctionalState EncryptFlagRcv); +void RADIO_EncryptPlainData(uint8_t *Key, uint8_t *plainData, uint8_t *cypherData); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*BLUENRG1_RADIO_H */ + +/******************* (C) COPYRIGHT 2020 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_rng.h b/drivers/inc/BlueNRG1_rng.h new file mode 100644 index 0000000..c62215e --- /dev/null +++ b/drivers/inc/BlueNRG1_rng.h @@ -0,0 +1,99 @@ +/** + ****************************************************************************** + * @file BlueNRG1_RNG.h + * @author VMA Application Team + * @version V2.0.0 + * @date 21-March-2016 + * @brief This file contains all the functions prototypes for the RNG + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_RNG_H +#define BLUENRG1_RNG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup RNG_Peripheral RNG Peripheral + * @{ + */ + +/** @defgroup RNG_Exported_Types Exported Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup RNG_Exported_Constants Exported Constants + * @{ + */ + +/** + * @} + */ + + +/** @defgroup RNG_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup RNG_Exported_Functions Exported Functions + * @{ + */ + +void RNG_Cmd(FunctionalState NewState); +FlagStatus RNG_GetFlagStatus(void); + +/** +* @brief Get the RNG value. +* @param None +* @retval RNG value +*/ +#define RNG_GetValue() READ_REG(RNG->VAL) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_RNG_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_rtc.h b/drivers/inc/BlueNRG1_rtc.h new file mode 100644 index 0000000..1222eb0 --- /dev/null +++ b/drivers/inc/BlueNRG1_rtc.h @@ -0,0 +1,242 @@ +/** + ****************************************************************************** + * @file BlueNRG1_rtc.h + * @author VMA Application Team + * @version V2.0.0 + * @date 21-March-2016 + * @brief This file contains all the functions prototypes for the RTC + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_RTC_H +#define BLUENRG1_RTC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup RTC_Peripheral RTC Peripheral + * @{ + */ + +/** @defgroup RTC_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Structure definition of RTC initialization + */ +typedef struct +{ + uint8_t RTC_operatingMode; /*!< Specifies the operating mode. + This parameter can be a value of @ref RTC_Timer_OperatingMode */ + + uint32_t RTC_TLR1; /*!< Load TLR1 register. + 32 bit value to load */ + + uint32_t RTC_TLR2; /*!< Load TLR2 register. + 32 bit value to load */ + + uint32_t RTC_PATTERN_SIZE; /*!< Define the pattern size to use. + 7 bit pattern, 0x0 size of 1 and 0x7F size of 128 */ + + uint32_t RTC_PATTERN1; /*!< Define the pattern, '0' relaod TLR1 and '1' reload TLR2. + First 32 bit pattern */ + + uint32_t RTC_PATTERN2; /*!< Define the pattern, '0' relaod TLR1 and '1' reload TLR2. + Second 32 bit pattern */ + + uint32_t RTC_PATTERN3; /*!< Define the pattern, '0' relaod TLR1 and '1' reload TLR2. + Third 32 bit pattern */ + + uint32_t RTC_PATTERN4; /*!< Define the pattern, '0' relaod TLR1 and '1' reload TLR2. + Fourth 32 bit pattern */ +} RTC_InitType; + + +/** + * @brief Structure definition of RTC DateTime + */ +typedef struct +{ + uint8_t Second; /*!< Specify the present second to be set to RTC clockwatch. + This parameter can be integer value in range from 0 to 59 */ + + uint8_t Minute; /*!< Specify the present minute to be set to RTC clockwatch. + This parameter can be integer value in range from 0 to 59 */ + + uint8_t Hour; /*!< Specify the present hour to be set to RTC clockwatch. + This parameter can be integer value in range from 0 to 23 */ + + uint8_t WeekDay; /*!< Specify the present day in the week to be set to RTC clockwatch. + This parameter can be an integer value in range from 0 to 7 */ + + uint8_t MonthDay; /*!< Specify the present day in the month to be set to RTC clockwatch. + This parameter can be an integer value in range from 1 to 31 (depends on month) */ + + uint8_t Month; /*!< Specify the present month to be set to RTC clockwatch. + This parameter can be an integer value in range from 1 to 12 (depends on month) */ + + uint16_t Year; /*!< Specify the present year to be set to RTC clockwatch. + This parameter can be an integer value in range from 0 to 3999 (depends on month) */ + +} RTC_DateTimeType; + +/** + * @} + */ + + +/** @defgroup RTC_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup RTC_Time_and_Data_Definitions Time and Data Definitions + * @{ + */ + +#define RTC_Month_January ((uint8_t)0x01) +#define RTC_Month_February ((uint8_t)0x02) +#define RTC_Month_March ((uint8_t)0x03) +#define RTC_Month_April ((uint8_t)0x04) +#define RTC_Month_May ((uint8_t)0x05) +#define RTC_Month_June ((uint8_t)0x06) +#define RTC_Month_July ((uint8_t)0x07) +#define RTC_Month_August ((uint8_t)0x08) +#define RTC_Month_September ((uint8_t)0x09) +#define RTC_Month_October ((uint8_t)0x10) +#define RTC_Month_November ((uint8_t)0x11) +#define RTC_Month_December ((uint8_t)0x12) + +#define RTC_Weekday_Monday ((uint8_t)0x01) +#define RTC_Weekday_Tuesday ((uint8_t)0x02) +#define RTC_Weekday_Wednesday ((uint8_t)0x03) +#define RTC_Weekday_Thursday ((uint8_t)0x04) +#define RTC_Weekday_Friday ((uint8_t)0x05) +#define RTC_Weekday_Saturday ((uint8_t)0x06) +#define RTC_Weekday_Sunday ((uint8_t)0x07) + +#define IS_SECOND(N) ((N) < 60) +#define IS_MINUTE(N) ((N) < 60) +#define IS_HOUR(N) ((N) < 24) +#define IS_WEEKDAY(N) (((N) > 0) && ((N) < 8)) +#define IS_MONTHDAY(N) (((N) > 0) && ((N) < 32)) +#define IS_MONTH(N) (((N) > 0) && ((N) < 13)) +#define IS_YEAR(N) (((N) > 0) && ((N) < 4000)) + +#define IS_MATCH_WEEKDAY(N) ((N) < 8) +#define IS_MATCH_MONTHDAY(N) ((N) < 32) +#define IS_MATCH_MONTH(N) ((N) < 13) +#define IS_MATCH_YEAR(N) ((N) < 4000) + + +/** + * @} + */ + + + +/** @defgroup RTC_Interrupts_Definitions Interrupts Definitions + * @{ + */ +#define RTC_IT_CLOCKWATCH ((uint8_t)1) /*!< RTC clock watch interrupt */ +#define RTC_IT_TIMER ((uint8_t)2) /*!< RTC timer interrupt */ + + +/** This macro checks if IT is a valid combination of interrupt */ +#define IS_RTC_IT(IT) (((IT) == RTC_IT_CLOCKWATCH) || \ + ((IT) == RTC_IT_TIMER)) + +/** + * @} + */ + +/** @defgroup RTC_Timer_Operating_Mode_Definitions Timer Operating Mode Definitions + * @{ + */ +#define RTC_TIMER_PERIODIC ((uint8_t)0) /*!< RTC timer periodic mode */ +#define RTC_TIMER_ONESHOT ((uint8_t)1) /*!< RTC timer one shot mode */ + + +/** This macro checks if IT is a valid combination of interrupt */ +#define IS_RTC_TIMER_MODE(IT) (((IT) == RTC_TIMER_PERIODIC) || \ + ((IT) == RTC_TIMER_ONESHOT)) + +/** + * @} + */ + +/** @defgroup RTC_Pattern_Size_Definitions Pattern Size Definitions + * @{ + */ + +#define IS_PATTERN(N) ((N) < 0x80) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions Exported Functions + * @{ + */ + +void RTC_Init(RTC_InitType* RTC_InitStruct); +void RTC_StructInit(RTC_InitType* RTC_InitStruct); +void RTC_Cmd(FunctionalState NewState); +void RTC_IT_Config(uint8_t RTC_IT, FunctionalState NewState); +ITStatus RTC_IT_Status(uint8_t RTC_IT); +void RTC_IT_Clear(uint8_t RTC_IT); + +void RTC_ClockwatchCmd(FunctionalState NewState); +void RTC_SetTimeDate(RTC_DateTimeType* RTC_DateTime); +void RTC_SetMatchTimeDate(RTC_DateTimeType* RTC_MatchDataTime); +void RTC_GetTimeDate(RTC_DateTimeType* RTC_DataTime); + +uint32_t RTC_GetTimerValue(void); +void RTC_AutoStart(FunctionalState NewState); +void RTC_SelectTrimmedClock(FunctionalState NewState); +uint32_t RTC_GetNumberIrqGenerated(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_RTC_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_spi.h b/drivers/inc/BlueNRG1_spi.h new file mode 100644 index 0000000..08d9d1b --- /dev/null +++ b/drivers/inc/BlueNRG1_spi.h @@ -0,0 +1,397 @@ +/** + ****************************************************************************** + * @file BlueNRG1_spi.h + * @author AMS VMA RF application team + * @version V2.1.0 + * @date 31-January-2017 + * @brief This file contains all the functions prototypes for the SPI firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_SPI_H +#define BLUENRG1_SPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup SPI_Peripheral SPI Peripheral + * @{ + */ + +/** @defgroup SPI_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Structure definition of SPI initialization + */ +typedef struct { + uint8_t SPI_Mode; /*!< Specifies the SPI operating mode. + This parameter can be a value of @ref SPI_mode */ + + uint8_t SPI_DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of @ref SPI_data_size */ + + uint8_t SPI_CPOL; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint8_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint32_t SPI_BaudRate; /*!< Specifies the Baud Rate value which will be + used to configure the transmit and receive SCK clock. + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ +} SPI_InitType; + + +/** + * @} + */ + + +/** @defgroup SPI_Exported_Constants Exported Constants + * @{ + */ + + +/** @defgroup SPI_Clock_Speed_Definition Clock Speed Definitions + * @{ + */ + +/* This macro checks if SPI baud rate is a valid value */ +#define IS_SPI_BAUDRATE(BAUDRATE) (((BAUDRATE)>=10000) && ((BAUDRATE)<=8000000)) + +/** +* @} +*/ + +/** @defgroup SPI_Communication_Mode_Definition Communication Mode Definition + * @{ + */ +#define SPI_FULL_DUPLEX_MODE ((uint32_t)0x00000000) +#define SPI_TRANSMIT_MODE ((uint32_t)0x00000001) +#define SPI_RECEIVE_MODE ((uint32_t)0x00000002) +#define SPI_COMBINED_MODE ((uint32_t)0x00000003) + + +#define IS_SPI_COM_MODE(MODE) (((MODE) == SPI_FULL_DUPLEX_MODE) || \ + ((MODE) == SPI_TRANSMIT_MODE) || \ + ((MODE) == SPI_RECEIVE_MODE) || \ + ((MODE) == SPI_COMBINED_MODE)) + +/** + * @} + */ + +/** @defgroup SPI_Mode_Definition Mode Definition + * @{ + */ + +#define SPI_FrmFrmt_Motorola ((uint8_t)0x0) /*!< Motorola SPI frame format */ +#define SPI_FrmFrmt_Microwire ((uint8_t)0x2) /*!< MicroWire frame format */ + +/* This macro checks if frame format value is valid */ +#define IS_SPI_FRMFRMT(FRMT) (((FRMT) == SPI_FrmFrmt_Motorola) || \ + ((FRMT) == SPI_FrmFrmt_Microwire)) + +/** + * @} + */ + +/** @defgroup SPI_Mode_Definition Mode Definition + * @{ + */ + +#define SPI_Mode_Master ((uint8_t)0x00) /*!< Master mode */ +#define SPI_Mode_Slave ((uint8_t)0x01) /*!< Slave mode */ + +/* This macro checks if MODE is a valid SPI mode */ +#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ + ((MODE) == SPI_Mode_Slave)) + +/** + * @} + */ + + +/** @defgroup SPI_Data_Size_Definition Data Size Definition + * @{ + */ +#define SPI_DataSize_32b ((uint8_t)0x1F) /*!< 32-bit data size */ +#define SPI_DataSize_31b ((uint8_t)0x1E) /*!< 31-bit data size */ +#define SPI_DataSize_30b ((uint8_t)0x1D) /*!< 30-bit data size */ +#define SPI_DataSize_29b ((uint8_t)0x1C) /*!< 29-bit data size */ +#define SPI_DataSize_28b ((uint8_t)0x1B) /*!< 28-bit data size */ +#define SPI_DataSize_27b ((uint8_t)0x1A) /*!< 27-bit data size */ +#define SPI_DataSize_26b ((uint8_t)0x19) /*!< 26-bit data size */ +#define SPI_DataSize_25b ((uint8_t)0x18) /*!< 25-bit data size */ +#define SPI_DataSize_24b ((uint8_t)0x17) /*!< 24-bit data size */ +#define SPI_DataSize_23b ((uint8_t)0x16) /*!< 23-bit data size */ +#define SPI_DataSize_22b ((uint8_t)0x15) /*!< 22-bit data size */ +#define SPI_DataSize_21b ((uint8_t)0x14) /*!< 21-bit data size */ +#define SPI_DataSize_20b ((uint8_t)0x13) /*!< 20-bit data size */ +#define SPI_DataSize_19b ((uint8_t)0x12) /*!< 19-bit data size */ +#define SPI_DataSize_18b ((uint8_t)0x11) /*!< 18-bit data size */ +#define SPI_DataSize_17b ((uint8_t)0x10) /*!< 17-bit data size */ +#define SPI_DataSize_16b ((uint8_t)0x0F) /*!< 16-bit data size */ +#define SPI_DataSize_15b ((uint8_t)0x0E) /*!< 15-bit data size */ +#define SPI_DataSize_14b ((uint8_t)0x0D) /*!< 14-bit data size */ +#define SPI_DataSize_13b ((uint8_t)0x0C) /*!< 13-bit data size */ +#define SPI_DataSize_12b ((uint8_t)0x0B) /*!< 12-bit data size */ +#define SPI_DataSize_11b ((uint8_t)0x0A) /*!< 11-bit data size */ +#define SPI_DataSize_10b ((uint8_t)0x09) /*!< 10-bit data size */ +#define SPI_DataSize_9b ((uint8_t)0x08) /*!< 9-bit data size */ +#define SPI_DataSize_8b ((uint8_t)0x07) /*!< 8-bit data size */ +#define SPI_DataSize_7b ((uint8_t)0x06) /*!< 7-bit data size */ +#define SPI_DataSize_6b ((uint8_t)0x05) /*!< 6-bit data size */ +#define SPI_DataSize_5b ((uint8_t)0x04) /*!< 5-bit data size */ +#define SPI_DataSize_4b ((uint8_t)0x03) /*!< 4-bit data size */ + +/* This macro checks if DATASIZE is a valid SPI data size value */ +#define IS_SPI_DATASIZE(DATASIZE) ((DATASIZE) < 0x20) + +/** + * @} + */ + +/** @defgroup SPI_Clock_Polarity_Definition Clock Polarity Definition + * @{ + */ + +#define SPI_CPOL_Low ((uint8_t)0) /*!< Clock polarity low */ +#define SPI_CPOL_High ((uint8_t)1) /*!< Clock polarity high */ + +/* This macro checks if CPOL is a valid clock polarity value */ +#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ + ((CPOL) == SPI_CPOL_High)) + + +/** + * @} + */ + +/** @defgroup SPI_Clock_Phase_Definition Clock Phase Definition + * @{ + */ + +#define SPI_CPHA_1Edge ((uint8_t)0) /*!< Clock phase 1st edge */ +#define SPI_CPHA_2Edge ((uint8_t)1) /*!< Clock phase 2nd edge */ + +/* This macro checks if CPHA is a valid clock phase value */ +#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ + ((CPHA) == SPI_CPHA_2Edge)) + +/** + * @} + */ + +/** @defgroup SPI_Interrupts_Mask_Definition Interrupts Mask Definition + * @{ + */ +#define SPI_IT_TE ((uint8_t)0x20) /*!< Transmit FIFO empty interrupt mask */ +#define SPI_IT_TUR ((uint8_t)0x10) /*!< Transmit underrun interrupt mask */ +#define SPI_IT_TX ((uint8_t)0x08) /*!< Tx interrupt mask */ +#define SPI_IT_RX ((uint8_t)0x04) /*!< Rx interrupt mask */ +#define SPI_IT_RT ((uint8_t)0x02) /*!< Rx timeout interrupt mask */ +#define SPI_IT_ROR ((uint8_t)0x01) /*!< Rx overrun interrupt mask */ +#define SPI_IT_MSK ((uint8_t)0x3F) /*!< Interrupt mask */ + +/* This macro checks if IT is a valid combination of interrupt */ +#define IS_SPI_CONFIG_IT(IT) ((((IT) & ~SPI_IT_MSK) == 0x00) && ((IT) != 0x00)) + + +/* This macro checks if IT is a valid clearable interrupt */ +#define IS_SPI_CLEAR_IT(IT) (((IT) == SPI_IT_TUR) || \ + ((IT) == SPI_IT_RT) || ((IT) == SPI_IT_ROR)) + +/* This macro checks if IT is a valid interrupt */ +#define IS_SPI_GET_IT(IT) (((IT) == SPI_IT_TX) || ((IT) == SPI_IT_RX) || \ + ((IT) == SPI_IT_RT) || ((IT) == SPI_IT_ROR) || \ + ((IT) == SPI_IT_TUR) || ((IT) == SPI_IT_TE)) + + +/** + * @} + */ + +/** @defgroup SPI_Flags_Definition Flags Definition + * @{ + */ +#define SPI_FLAG_TFE ((uint8_t)0x01) /*!< Tx FIFO empty flag */ +#define SPI_FLAG_TNF ((uint8_t)0x02) /*!< Tx FIFO not full flag */ +#define SPI_FLAG_RNE ((uint8_t)0x04) /*!< Rx FIFO not empty flag */ +#define SPI_FLAG_RFF ((uint8_t)0x08) /*!< Rx FIFO full flag */ +#define SPI_FLAG_BSY ((uint8_t)0x10) /*!< Busy flag */ + +/* This macro checks if FLAG is a valid flag */ +#define IS_SPI_GET_FLAG(FLAG) (((FLAG) == SPI_FLAG_TFE) || ((FLAG) == SPI_FLAG_TNF) || \ + ((FLAG) == SPI_FLAG_RNE) || ((FLAG) == SPI_FLAG_RFF) || \ + ((FLAG) == SPI_FLAG_BSY)) +/** + * @} + */ + +/** @defgroup SPI_DMA_Requests_Definition DMA Requests Definition + * @{ + */ + +#define SPI_DMAReq_Tx ((uint8_t)0x04) /*!< DMA TX request */ +#define SPI_DMAReq_Rx ((uint8_t)0x01) /*!< DMA RX request */ + +/* This macro checks if DMAREQ is a valid DMA request */ +#define IS_SPI_DMAREQ(DMAREQ) (((DMAREQ)==SPI_DMAReq_Tx) || ((DMAREQ)==SPI_DMAReq_Rx) || ((DMAREQ)==(SPI_DMAReq_Rx | SPI_DMAReq_Tx))) + +/** + * @} + */ + + +/** @defgroup SPI_Fifo_Level_Definition FIFO Level Definition + * @{ + */ + +#define SPI_FIFO_LEV_1 ((uint8_t)0) /*!< Interrupt when FIFO contains 1 element or more */ +#define SPI_FIFO_LEV_4 ((uint8_t)1) /*!< Interrupt when FIFO contains 4 elements or more */ +#define SPI_FIFO_LEV_8 ((uint8_t)2) /*!< Interrupt when FIFO contains 8 elements or more */ + +/* This macro checks if IS_SPI_FIFO_LEV is a valid FIFO level */ +#define IS_SPI_FIFO_LEV(FIFO_LEV) ( ((FIFO_LEV) == SPI_FIFO_LEV_1) || \ + ((FIFO_LEV) == SPI_FIFO_LEV_4) || \ + ((FIFO_LEV) == SPI_FIFO_LEV_8)) + +/** + * @} + */ + + +/** @defgroup SPI_Endian_Format_Definition Endian Format Definition + * @{ + */ + +#define SPI_ENDIAN_MSByte_MSBit ((uint8_t)0) /*!< Endian format MSByte first and MSbit first */ +#define SPI_ENDIAN_LSByte_MSBit ((uint8_t)1) /*!< Endian format LSByte first and MSbit first */ +#define SPI_ENDIAN_MSByte_LSBit ((uint8_t)2) /*!< Endian format MSByte first and LSbit first */ +#define SPI_ENDIAN_LSByte_LSBit ((uint8_t)3) /*!< Endian format LSByte first and LSbit first */ + +/** This macro checks if IS_SPI_ENDIAN is a valid FORMAT value */ +#define IS_SPI_ENDIAN(FORMAT) ( ((FORMAT) == SPI_ENDIAN_MSByte_MSBit) || \ + ((FORMAT) == SPI_ENDIAN_LSByte_MSBit) || \ + ((FORMAT) == SPI_ENDIAN_MSByte_LSBit) || \ + ((FORMAT) == SPI_ENDIAN_LSByte_LSBit)) +/** + * @} + */ + +/** @defgroup SPI_Delay_Between_Frames_Definition Delay Between Frames Definition + * @{ + */ + +/* This macro checks if IS_WAIT_VALUE is a valid value */ +#define IS_WAIT_VALUE(VALUE) ( (VALUE) < 16) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SPI_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup SPI_Exported_Functions Exported Functions + * @{ + */ + +/* SPI initialization and configuration */ +void SPI_StructInit(SPI_InitType* SPI_InitStruct); +void SPI_DeInit(void); +void SPI_Init(SPI_InitType* SPI_InitStruct); +void SPI_Cmd(FunctionalState NewState); +void SPI_ITConfig(uint8_t SPI_IT, FunctionalState NewState); +void SPI_DataSizeConfig(uint16_t SPI_DataSize); +void SPI_CommandSizeConfig(uint16_t SPI_DataSize); +void SPI_FrameFormatConfig(uint8_t SPI_FrameFormat); + +/* SPI data register access */ +void SPI_SendData(uint32_t Data); +uint32_t SPI_ReceiveData(void); + +/* Interrupt and status management */ +FlagStatus SPI_GetFlagStatus(uint16_t SPI_FLAG); +ITStatus SPI_GetITStatus(uint8_t SPI_IT); +void SPI_ClearITPendingBit(uint8_t SPI_IT); + +/* Clear RX and TX FIFO */ +void SPI_ClearRXFIFO(void); +void SPI_ClearTXFIFO(void); + +/* Communication mode configuration in SPI master mode */ +void SPI_SetMasterCommunicationMode(uint32_t Mode); +void SPI_SetDummyCharacter(uint32_t NullCharacter); +void SPI_SetNumFramesToReceive(uint16_t Number); +void SPI_SetNumFramesToTransmit(uint16_t Number); +void SPI_EnableWaitState(FunctionalState NewState); +void SPI_SlaveSwSelection(FunctionalState NewState); +void SPI_EndianFormatReception(uint8_t Endian); +void SPI_EndianFormatTransmission(uint8_t Endian); +void SPI_DelayBetweenFrames(uint8_t Delay); +void SPI_DelayDataInput(FunctionalState NewState); + +/* Special functionality */ +void SPI_SlaveModeOutputCmd(FunctionalState NewState); + +/* DMA channel control */ +void SPI_DMACmd(uint8_t SPI_DMAReq, FunctionalState NewState); + +/* SPI FIFO interrupt level */ +void SPI_TxFifoInterruptLevelConfig(uint8_t SPI_TX_FIFO_LEV); +void SPI_RxFifoInterruptLevelConfig(uint8_t SPI_RX_FIFO_LEV); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*BLUENRG1_SPI_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_sysCtrl.h b/drivers/inc/BlueNRG1_sysCtrl.h new file mode 100644 index 0000000..c1ff461 --- /dev/null +++ b/drivers/inc/BlueNRG1_sysCtrl.h @@ -0,0 +1,186 @@ +/** + ****************************************************************************** + * @file BlueNRG1_sysCtrl.h + * @author VMA Application Team + * @version V2.0.0 + * @date 21-March-2016 + * @brief This file contains all the functions prototypes for the System Controller + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_SYSCTRL_H +#define BLUENRG1_SYSCTRL_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup SystemControl System Control + * @{ + */ + +/** @defgroup SystemControl_Exported_Types Exported Types + * @{ + */ + + +/** + * @brief System Reset and Wakeup Sources + */ +#define RESET_NONE 0x0000 +#define RESET_SYSREQ 0x0001 +#define RESET_WDG 0x0002 +#define RESET_LOCKUP 0x0004 +#define RESET_BLE_BOR 0x0008 +#define RESET_BLE_POR 0x0010 +#define RESET_BLE_WAKEUP_FROM_IO9 0x0020 +#define RESET_BLE_WAKEUP_FROM_IO10 0x0040 +#define RESET_BLE_WAKEUP_FROM_IO11 0x0080 +#define RESET_BLE_WAKEUP_FROM_IO12 0x0100 +#define RESET_BLE_WAKEUP_FROM_IO13 0x0200 +#define RESET_BLE_WAKEUP_FROM_TIMER1 0x0400 +#define RESET_BLE_WAKEUP_FROM_TIMER2 0x0800 + +/** + * @} + */ + +/** @defgroup SystemControl_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup System_Clock_Frequency System Clock Frequency + * @{ + */ +#if (HS_SPEED_XTAL == HS_SPEED_XTAL_32MHZ) + #define SYST_CLOCK 32000000 /* System clock frequency */ +#elif (HS_SPEED_XTAL == HS_SPEED_XTAL_16MHZ) + #define SYST_CLOCK 16000000 /* System clock frequency */ +#else +#error "No definition for SYST_CLOCK" +#endif + +/** + * @} + */ + + +/** @defgroup Peripherals_Clock Peripherals Clock + * @{ + */ +#define CLOCK_PERIPH_GPIO ((uint32_t)0x00000001) +#define CLOCK_PERIPH_NVM ((uint32_t)0x00000002) +#define CLOCK_PERIPH_SYS_CONTROL ((uint32_t)0x00000004) +#define CLOCK_PERIPH_UART ((uint32_t)0x00000008) +#define CLOCK_PERIPH_SPI ((uint32_t)0x00000010) +#define CLOCK_PERIPH_WDG ((uint32_t)0x00000080) +#define CLOCK_PERIPH_ADC ((uint32_t)0x00000100) +#define CLOCK_PERIPH_I2C1 ((uint32_t)0x00000200) +#define CLOCK_PERIPH_I2C2 ((uint32_t)0x00000400) +#define CLOCK_PERIPH_MTFX1 ((uint32_t)0x00000800) +#define CLOCK_PERIPH_MTFX2 ((uint32_t)0x00001000) +#define CLOCK_PERIPH_RTC ((uint32_t)0x00002000) +#define CLOCK_PERIPH_DMA ((uint32_t)0x00010000) +#define CLOCK_PERIPH_RNG ((uint32_t)0x00020000) +#define CLOCK_PERIPH_PKA ((uint32_t)0x000C0000) + +#define IS_CLOCK_PERIPH(PERIPH) (((PERIPH) & 0x000F3F9F) != 0) +/** + * @} + */ + + + +/** @defgroup IO_sources_for_wakeup IO sources for wakeup + * @{ + */ + +#define WAKEUP_ON_IO9 ((uint8_t)0x01) /* Wakeup source is IO9 */ +#define WAKEUP_ON_IO10 ((uint8_t)0x02) /* Wakeup source is IO10 */ +#define WAKEUP_ON_IO11 ((uint8_t)0x04) /* Wakeup source is IO11 */ +#define WAKEUP_ON_IO12 ((uint8_t)0x08) /* Wakeup source is IO12 */ +#define WAKEUP_ON_IO13 ((uint8_t)0x10) /* Wakeup source is IO13 */ + +#define WAKEUP_ON_HIGH_STATE ((uint8_t)0) /* Wakeup on high state */ +#define WAKEUP_ON_LOW_STATE ((uint8_t)1) /* Wakeup on low state */ + +#define IS_WAKEUP_ON_IO(IOS) (((IOS) & 0x1F) != 0) + +#define IS_WAKEUP_ON_STATE(STATE) ( ((STATE) == WAKEUP_ON_HIGH_STATE) || ((STATE) == WAKEUP_ON_LOW_STATE) ) + +/** + * @} + */ + + +/** @defgroup External_Clock_Selection External Clock Selection + * @{ + */ + +#define XO_32MHZ ((uint8_t)1) /* The external clock XO used is a 32 MHz */ +#define XO_16MHZ ((uint8_t)0) /* The external clock XO used is a 16 MHz */ + +#define IS_XO_FREQ(XO) ( ((XO) == XO_32MHZ) || ((XO) == XO_16MHZ) ) + +/** + * @} + */ + + +/** + * @} + */ + + + +/** @defgroup SystemControl_Exported_Functions Exported Functions + * @{ + */ + +void SysCtrl_DeInit(void); +void SysCtrl_PeripheralClockCmd(uint32_t PeriphClock, FunctionalState NewState); +uint16_t SysCtrl_GetWakeupResetReason(void); + +void SysCtrl_WakeupFromIo(uint8_t IO, uint8_t LevelState, FunctionalState NewState); +void SysCtrl_SelectXO(uint8_t XOFreq); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_SYSCTRL_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_timer.h b/drivers/inc/BlueNRG1_timer.h new file mode 100644 index 0000000..71ac0b0 --- /dev/null +++ b/drivers/inc/BlueNRG1_timer.h @@ -0,0 +1,378 @@ +/** + ****************************************************************************** + * @file BlueNRG1_timer.h + * @author RF Application Team + * @date Jan-2020 + * @brief This file contains all the functions prototypes for the TIMER + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2020 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_TIMER_H +#define BLUENRG1_TIMER_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" +#include + +/** @defgroup TIMER_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Structure definition of TIMER initialization + */ +typedef struct +{ + uint16_t XTAL_StartupTime; /*!< XTAL startup in 2.44 us unit */ +/** + * Enable initial estimation of the frequency of the Low Speed Oscillator, otherwise it will be assumed fixed at 32.768 kHz. + * Ignored if periodic calibration is active (TIMER_PeriodicCalibration = TRUE). + */ + BOOL TIMER_InitialCalibration; + BOOL TIMER_PeriodicCalibration; /*!< Assume that 32 KHz clock requires periodic calibration, i.e. varies with temperature */ +} TIMER_InitType; + +typedef struct timer_calibration_s { + uint64_t last_calibration_time; /** Absolute system time when last calibration was performed */ + uint32_t period; /** Number of 16 MHz clock cycles in (2*(SLOW_COUNT+1) low speed oscillator periods */ + uint32_t freq; /** 2^39/period */ + uint8_t periodic_calibration; /** Tells whether periodic hardware calibration is needed or not */ + uint32_t last_calibration_machine_time; /** Last machine time when calibration was performed */ + +} TIMER_CalibrationType; + +/** + * @} + */ + +/** @defgroup TIMER_Exported_Constants Exported Constants + * @{ + */ +#define TIME_CONVERSION2 0 + +/** This define represents the marging we take for long sleep to allow the system to + avoid to have the counter wrapping. It is expressed in machine time, so it is variable + when using internal RO */ +#define TIMER_WRAPPING_MARGIN 4096 + +/** This #define represents the number of significant bits in the timer */ +#define TIMER_BITS 24 //32 +#define TIMER_MAX_VALUE (0xFFFFFFFFU >> (32-TIMER_BITS)) +#define CALIB_MAX_VALUE TIMER_MAX_VALUE >> 1 + +/*This threshold should be the time to allow the device to go correctly in sleep*/ +#define SLEEP_TIME_MIN 60 + +/** @defgroup Device_System_Delays System Delays + * @{ + */ + +#define DELAY_TX 56 +#define DELAY_TX_NO_CAL 27 +#define DELAY_RX 56 +#define DELAY_RX_NO_CAL 27 + +/** + * @} + */ + +#define TIMER1_BUSY 0x1 +#define TIMER2_BUSY 0x2 +#define WAKEUP_TIMER_BUSY 0x3 + +#define WAKEUP_TIMER_MASK 0x1 +#define TIMER1_TIMER_MASK 0x2 +#define TIMER2_TIMER_MASK 0x3 + +/** @defgroup TIMER_Ticks_Definition Ticks Definition + * @{ + */ +#define TIMER_SYSTICK_PER_SECOND 409600 +#define TIMER_SYSTICK_PER_10MS 4096 + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup TIMER_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup TIMER_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initialize the TIMER functionality + * @retval None + */ +void TIMER_Init(TIMER_InitType* TIMER_InitStruct); + +/** + * @brief Perform a low speed clock calibration and store results in the global context. + * It updates the XTAL startup time and the interpolator configuration. + * It updates also the cumulative STU variable, so it should be called peiodically to manage timer wrapping, + * regardless of actual need of periodic calibration. + * @warning This function is not re-entrant since it updates the context variable storing the system time. + * @retval None + */ +void TIMER_Calibrate(void); + +/** + * @brief Start the calibration routine. + * @retval None + */ +void TIMER_StartCalibration(void); + +/** + * @brief Return TRUE if a calibration is on going. It relies on the value of the interrupt status. + * Assumption is that no other modules are managing the interrupt status of the calibrator. + * @retval TRUE if calibration is running, FALSE otherwise. + */ +BOOL TIMER_IsCalibrationRunning(void); + +/** + * @brief Records the result of the last calibration in the internal context. + * It updates the XTAL startup time and the interpolator configuration. + * It updates also the cumulative STU variable, so it should be called peiodically to manage timer wrapping, + * regardless of actual need of periodic calibration. + * @warning This function is not re-entrant since it updates the context variable storing the system time. + * It should be called only in user context and not in interrupt context. + * @retval None + */ +void TIMER_UpdateCalibrationData(void); + +/** + * @brief Return the current system time in system time unit (STU). + * This is a counter that grows since the power up of the system and it never wraps. + * @return Current system time + */ +uint64_t TIMER_GetCurrentSysTime(void); + +/** + * @brief Set the wakeup time to the specified delay. The delay is converted in machine time and only 20 most significant bits + * are taken into account. The XTAL startup time is not taken into account for the wakeup, i.e. the system does not wait for + * the XTAL startup time parameter to trigger the interrupt. + * The delay is translated into machine time unit (MTU) and it is assigned to the wakeup register. + * @param delay: Delay from the current time expressed in system time unit (STU). Range is 0 to maximum value of STU. + * The maximum value STU is dependent on the speed of the low speed oscillator. + * A value too small will force the timer to wrap, so it is reccommended to use at least 5-10 STU. + * @param allow_sleep: Setting it to zero will prevent hardware to go to deep sleep, + * if other code commands the system to go to deep sleep. + * @warning This function should be called with interrupts disabled to avoid programming the timer with a value in the past + * @return Current time in MTU + */ +uint32_t TIMER_SetWakeupTime(uint32_t delay, BOOL allow_sleep); + +/** + * @brief Return the current calibration data. + * @retval None + */ +void TIMER_GetCurrentCalibrationData(TIMER_CalibrationType *data); + +/** + * @brief Disable Wakeup Timer, Timer1 and Timer2 enabling sleep. + * @retval None + */ +void TIMER_ClearRadioTimerValue(void); + +/** + * @brief Return the system time referred to the absolute machine time passed as parameter. + * @param time: Absolute machine time in the past + * @warning User should guarantee that call to this function are performed in a non-interruptible context. + * @return System time value + */ +uint64_t TIMER_GetPastSysTime(uint32_t time); + +/** + * @brief Return timer capture register value in STU. + * @return value in STU + */ +uint64_t TIMER_GetAnchorPoint(void); + +/** + * @brief Program the radio timer (a.k.a Timer1) as close as possible. + * @retval None + */ +void TIMER_SetRadioCloseTimeout(void); + +/** + * @brief Return the MTU corresponding to the STU passed as parameter. + * @param time: STU amount to be converted in MTU + * @warning This function is not re-entrant since it updates the context variable storing the system time. It should be called only in + * user context and not in interrupt context. + * @return MTU value + */ +uint32_t TIMER_SysTimeToMachineTime(uint32_t time); + +/** + * @brief Return the STU corresponding to the MTU passed as parameter. + * @param time: MTU amount to be converted in STU + * @warning This function is not re-entrant since it updates the context variable storing the system time. It should be called only in + * user context and not in interrupt context. + * @return STU value + */ +uint32_t TIMER_MachineTimeToSysTime(uint32_t time); + +/** + * @brief Return the system time referred to the absolute machine time passed as parameter. + * @param time: Absolute machine time in the future + * @warning User should guarantee that call to this function are performed in a non-interruptible context. + * @return System time value + */ +uint64_t TIMER_GetFutureSysTime(uint32_t time); + +/** + * @brief Return the system time referred to the time in microseconds passed as parameter. + * @param time: time in microseconds + * @return System time value + */ +uint32_t TIMER_UsToSystime(uint32_t time); + +/** + * @brief Return the machine time referred to the time in microseconds passed as parameter. + * @param time: time in microseconds + * @return Machine time value + */ +uint32_t TIMER_UsToMachinetime(uint32_t time); + +/** + * @brief Program either Timer1 or the Wakeup Timer if the device has enough time to settle after exit from sleep or not. + * If the timeout is enough in the future, a preconfigured radio transaction is going to trigger at the specified + * timeout. The timeout is translated into machine time unit (MTU) and it is assigned to the wakeup register. + * If it is sleeping, the CPU wakes up (no IRQ) when the absolute time mathches the 20 MSB of the timeout + * written in the register. The transmission or reception starts when the timer value matches the value of + * timeout plus the time the analog part needs to settle. All the 24 bits are considered in this case. + * An IRQ related to this event can be generated only when the transaction is completed. + * In order to get a precise timeout, the radio setup delays are taken into account. They differ if + * the event is a transmission or reception and if the PLL calibration is requested or not. + * @param timeout: Absolute time expressed in system time unit (STU). + * It must represent a time in the future. + * If timeout is less than current time, it is considered as it is in the future (wrapping). + * The maximum value in STU depends on the speed of the low speed oscillator. + * @param event_type: Specify if it is a TX (1) or RX (0) event. + * @param cal_req: Specify if PLL calibration is requested (1) or not (0). + * @warning This function should be called with interrupts disabled to avoid programming the timer with a value in the past. + * @retval 0 if a correct timeout has been programmed in the timeout register. + * @retval 1 if a correct timeout cannot be programmed (the timeout is too close). + */ +uint8_t TIMER_SetRadioTimerValue(uint32_t timeout, BOOL event_type, BOOL cal_req); + +/** + * @brief Update the value of period slow variable in RAM. + * @retval None + */ +void TIMER_updatePeriodSlow(void); + +/** + * @brief Update the value of wakeup_time_offset variable in RAM. + * @retval None + */ +void TIMER_updateWkupTimeOffset(void); + +/** + * @brief Return the status of the Radio timers and the last value programmed in the register. + * @note When Timer2 is on schedule, the time is expressed in microseconds. + * @param time: pointer to value which is going to have time value. + * @retval 0 if no timer has been programmed programmed. + * @retval 1 if Timer1 has been programmed. + * @retval 2 if Timer2 has been programmed. + * @retval 3 if Wakeup Timer has been programmed. + */ +uint8_t TIMER_GetRadioTimerValue(uint32_t* time); + +/** + * @brief Get the radio setup delay in system time. + * @param event_type: Specify if it is a TX (1) or RX (0) event. + * @param cal_req: Specify if PLL calibration is requested (1) or not (0). + * @return Radio setup delay in system time + */ +uint8_t TIMER_GetActivitySysDelay(uint8_t event_type, uint8_t cal_req); + +/** + * @brief Returns the next activities scheduled by the Timer Module. + * @param nextRadioActivity: pointer to value that is going to have last TIMEOUT value programmed + * @param nextRadioActivity: pointer to value that is going to have last HOST_WKUP_TIMER value programmed + * @retval None + */ +void TIMER_GetNextTimerActivity(uint32_t* nextRadioActivity, uint32_t* nextHostActivity); + +/** + * @brief Get the current absolute time. + */ +__STATIC_INLINE uint32_t TIMER_GetCurrentMachineTime(void) { return BLUE_CTRL->CURRENT_TIME; } + +/** + * @brief Set the host_wakeup_timer timeout. + */ +__STATIC_INLINE void TIMER_SetHostTimeoutReg(uint32_t value) { BLUE_CTRL->HOST_WKUP_TIMER = value; } + +/** + * @brief Get the host_wakeup_timer timeout. + */ +__STATIC_INLINE uint32_t TIMER_GetHostTimeoutReg(void) { return BLUE_CTRL->HOST_WKUP_TIMER; } + +/** + * @brief Get radio controller timer timeout. + */ +__STATIC_INLINE uint32_t TIMER_GetTimeoutReg(void) { return BLUE_CTRL->TIMEOUT; } + +/** + * @brief Set radio controller timer timeout. + */ +__STATIC_INLINE void TIMER_SetTimeoutReg(uint32_t value) { BLUE_CTRL->TIMEOUT = value; } + +/** + * @brief Enable BlueIRQ. + */ +__STATIC_INLINE void TIMER_EnableBlueIRQ(void) { NVIC_EnableIRQ(BLUE_CTRL_IRQn); } + +/** + * @brief Disable BlueIRQ. + */ +__STATIC_INLINE void TIMER_DisableBlueIRQ(void) { NVIC_DisableIRQ(BLUE_CTRL_IRQn); } + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_TIMER_H */ + +/******************* (C) COPYRIGHT 2020 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_uart.h b/drivers/inc/BlueNRG1_uart.h new file mode 100644 index 0000000..7c0572c --- /dev/null +++ b/drivers/inc/BlueNRG1_uart.h @@ -0,0 +1,355 @@ +/** + ****************************************************************************** + * @file BlueNRG1_uart.h + * @author VMA Application Team + * @version V2.1.0 + * @date 21-March-2016 + * @brief This file contains all the functions prototypes for the UART + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_UART_H +#define BLUENRG1_UART_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup UART_Peripheral UART Peripheral + * @{ + */ + +/** @defgroup UART_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Structure definition of UART initialization + */ +typedef struct +{ + uint32_t UART_BaudRate; /*!< This member configures the UART communication baud rate. */ + + uint8_t UART_WordLengthTransmit; /*!< Specifies the number of data bits transmitted in a frame. + This parameter can be a value of @ref UART_Word_Length */ + + uint8_t UART_WordLengthReceive; /*!< Specifies the number of data bits received in a frame. + This parameter can be a value of @ref UART_Word_Length */ + + uint8_t UART_StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref UART_Stop_Bits */ + + uint8_t UART_Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref UART_Parity */ + + uint8_t UART_Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref UART_Mode */ + + uint8_t UART_HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled + or disabled. + This parameter can be a value of @ref UART_Hardware_Flow_Control */ + + FunctionalState UART_FifoEnable; /*!< Specifies whether the FIFO is enabled or disabled. + This parameter can be a value of @ref UART_Fifo_Enable */ +} UART_InitType; + + +/** + * @} + */ + +/** @defgroup UART_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup UART_Word_Length_Definition Word Length Definition + * @{ + */ + +#define UART_WordLength_5b ((uint8_t)0) /*!< 5-bit word length */ +#define UART_WordLength_6b ((uint8_t)1) /*!< 6-bit word length */ +#define UART_WordLength_7b ((uint8_t)2) /*!< 7-bit word length */ +#define UART_WordLength_8b ((uint8_t)3) /*!< 8-bit word length */ + +/* This macro checks if LENGTH is a valid UART word length value */ +#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WordLength_5b) || \ + ((LENGTH) == UART_WordLength_6b) || \ + ((LENGTH) == UART_WordLength_7b) || \ + ((LENGTH) == UART_WordLength_8b)) +/** + * @} + */ + +/** @defgroup UART_Stop_Bits_Definition Stop Bits Definition + * @{ + */ + +#define UART_StopBits_1 ((uint8_t)0) /*!< 1 stop bit */ +#define UART_StopBits_2 ((uint8_t)1) /*!< 2 stop bits */ + +/* This macro checks if STOPBITS is a valid UART stop bits value */ +#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_StopBits_1) || \ + ((STOPBITS) == UART_StopBits_2)) +/** + * @} + */ + +/** @defgroup UART_Parity_Definition Parity Definition + * @{ + */ + +#define UART_Parity_No ((uint8_t)0) /*!< No parity */ +#define UART_Parity_Even ((uint8_t)1) /*!< Even parity */ +#define UART_Parity_Odd ((uint8_t)2) /*!< Odd parity */ + +/* This macro checks if PARITY is a valid UART parity value */ +#define IS_UART_PARITY(PARITY) (((PARITY) == UART_Parity_No) || \ + ((PARITY) == UART_Parity_Even) || \ + ((PARITY) == UART_Parity_Odd)) +/** + * @} + */ + +/** @defgroup UART_Mode_Definition Mode Definition + * @{ + */ + +#define UART_Mode_Rx ((uint8_t)0x01) /*!< Enables Rx */ +#define UART_Mode_Tx ((uint8_t)0x02) /*!< Enables Tx */ + +/* This macro checks if MODE is a valid UART mode value */ +#define IS_UART_MODE(MODE) ( (MODE)<= 3) + +/** + * @} + */ + +/** @defgroup UART_Hardware_Flow_Control_Definition Hardware Flow Control Definition + * @{ + */ +#define UART_HardwareFlowControl_None ((uint8_t)0x00) /*!< Disable the hardware flow control */ +#define UART_HardwareFlowControl_RTS ((uint8_t)0x01) /*!< Enables the RTS hardware flow control */ +#define UART_HardwareFlowControl_CTS ((uint8_t)0x02) /*!< Enables the CTS hardware flow control */ +#define UART_HardwareFlowControl_RTS_CTS ((uint8_t)0x03) /*!< Enables the RTS and CTS hardware flow control */ + +/* This macro checks if CONTROL is a valid UART hardware flow control value */ +#define IS_UART_HW_FLOW_CONTROL(CONTROL) ( (CONTROL) <= 3 ) + +/** + * @} + */ + + +/** @defgroup UART_Interrupt_Definition Interrupt Definition + * @{ + */ + +#define UART_IT_TXFE ((uint16_t)0x1000) /*!< Tx FIFO empty interrupt */ +#define UART_IT_XO ((uint16_t)0x0800) /*!< XOFF interrupt */ +#define UART_IT_OE ((uint16_t)0x0400) /*!< Overrun error interrupt */ +#define UART_IT_BE ((uint16_t)0x0200) /*!< Break error interrupt */ +#define UART_IT_PE ((uint16_t)0x0100) /*!< Parity error interrupt */ +#define UART_IT_FE ((uint16_t)0x0080) /*!< Framing error interrupt */ +#define UART_IT_RT ((uint16_t)0x0040) /*!< Receive error interrupt */ +#define UART_IT_TX ((uint16_t)0x0020) /*!< Transmit interrupt */ +#define UART_IT_RX ((uint16_t)0x0010) /*!< Receive interrupt */ +#define UART_IT_CTS ((uint16_t)0x0002) /*!< CTS interrupt */ + +/* This macro checks if IT is a valid combination of UART interrupt value */ +#define IS_UART_CONFIG_IT(IT) ((((IT) & (uint16_t)~0x1FF2) == 0x00) && ((IT) != (uint16_t)0x0000)) + + + +/** + * @} + */ + + +/** @defgroup UART_Flags_Definition Flags Definition + * @{ + */ + +#define UART_FLAG_CTS ((uint32_t)0x00000001) /*!< Clear to send flag */ +#define UART_FLAG_BUSY ((uint32_t)0x00000008) /*!< Busy flag */ +#define UART_FLAG_RXFE ((uint32_t)0x00000010) /*!< Receive FIFO empty flag */ +#define UART_FLAG_TXFF ((uint32_t)0x00000020) /*!< Transmit FIFO full flag */ +#define UART_FLAG_RXFF ((uint32_t)0x00000040) /*!< Receive FIFO full flag */ +#define UART_FLAG_TXFE ((uint32_t)0x00000080) /*!< Transmit FIFO empty flag */ + +#define UART_FLAG_FE ((uint32_t)0x80000001) /*!< Framing error flag */ +#define UART_FLAG_PE ((uint32_t)0x80000002) /*!< Parity error flag */ +#define UART_FLAG_BE ((uint32_t)0x80000004) /*!< Break error flag */ +#define UART_FLAG_OE ((uint32_t)0x80000008) /*!< Overrun error flag */ + +/* This macro checks if FLAG is a valid UART flag */ +#define IS_UART_FLAG(FLAG) (((FLAG) == UART_FLAG_CTS) || ((FLAG) == UART_FLAG_BUSY) || \ + ((FLAG) == UART_FLAG_RXFE) || ((FLAG) == UART_FLAG_TXFF) || \ + ((FLAG) == UART_FLAG_RXFF) || ((FLAG) == UART_FLAG_TXFE) || \ + ((FLAG) == UART_FLAG_OE) || ((FLAG) == UART_FLAG_FE) || \ + ((FLAG) == UART_FLAG_PE) || ((FLAG) == UART_FLAG_BE) ) + +/* This macro checks if FLAG is a valid UART clearable flag */ +#define IS_UART_CLEAR_FLAG(FLAG) (((FLAG) == UART_FLAG_FE) || ((FLAG) == UART_FLAG_PE) || \ + ((FLAG) == UART_FLAG_BE) || ((FLAG) == UART_FLAG_OE)) + +/* This macro checks if BAUDRATE is a valid UART baudrate */ +#define IS_UART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) <= 1000000)) + +/* This macro checks if DATA is a valid UART data */ +#define IS_UART_DATA(DATA) ((DATA) <= 0x1FF) + +/** + * @} + */ + +/** @defgroup UART_Fifo_Level_Definition FIFO Level Definition + * @{ + */ + +#define FIFO_LEV_1_64 ((uint8_t)0) /*!< FIFO threshold 1/64 */ +#define FIFO_LEV_1_32 ((uint8_t)1) /*!< FIFO threshold 1/32 */ +#define FIFO_LEV_1_16 ((uint8_t)2) /*!< FIFO threshold 1/16 */ +#define FIFO_LEV_1_8 ((uint8_t)3) /*!< FIFO threshold 1/8 */ +#define FIFO_LEV_1_4 ((uint8_t)4) /*!< FIFO threshold 1/4 */ +#define FIFO_LEV_1_2 ((uint8_t)5) /*!< FIFO threshold 1/2 */ +#define FIFO_LEV_3_4 ((uint8_t)6) /*!< FIFO threshold 3/4 */ + +/* This macro checks if TX_FIFO_LEV is a valid Tx FIFO level */ +#define IS_FIFO_LEV(FIFO_LEV) ( ((FIFO_LEV) == FIFO_LEV_1_64) || \ + ((FIFO_LEV) == FIFO_LEV_1_32) || \ + ((FIFO_LEV) == FIFO_LEV_1_16) || \ + ((FIFO_LEV) == FIFO_LEV_1_8) || \ + ((FIFO_LEV) == FIFO_LEV_1_4) || \ + ((FIFO_LEV) == FIFO_LEV_1_2) || \ + ((FIFO_LEV) == FIFO_LEV_3_4)) + +/** + * @} + */ + +/** @defgroup UART_Software_Flow_Control_Mode_Definition Software Flow Control Mode Definition + * @{ + */ +#define NO_SW_FLOW_CTRL ((uint8_t)0) /*!< No software flow control */ +#define SW_FLOW_CTRL_XON1_XOFF1 ((uint8_t)1) /*!< Software flow control XON1 and XOFF1 */ +#define SW_FLOW_CTRL_XON2_XOFF2 ((uint8_t)2) /*!< Software flow control XON2 and XOFF2 */ +#define SW_FLOW_CTRL_ALL_CHARS ((uint8_t)3) /*!< Software flow control XON1 and XOFF1, XON2 and XOFF2 */ + +/* This macro checks if SW_FLOW_CTRL is a valid software flow control value */ +#define IS_SW_FLOW_CTRL(SW_FLOW_CTRL) ( ((SW_FLOW_CTRL) == NO_SW_FLOW_CTRL) || \ + ((SW_FLOW_CTRL) == SW_FLOW_CTRL_XON1_XOFF1) || \ + ((SW_FLOW_CTRL) == SW_FLOW_CTRL_XON2_XOFF2) || \ + ((SW_FLOW_CTRL) == SW_FLOW_CTRL_ALL_CHARS)) +/** + * @} + */ + +/** @defgroup UART_DMA_Requests_Definition DMA Requests Definition + * @{ + */ + +#define UART_DMAReq_Tx ((uint8_t)0x02) +#define UART_DMAReq_Rx ((uint8_t)0x01) + +/* This macro checks if DMAREQ is a valid DMA request value */ +#define IS_UART_DMAREQ(DMAREQ) ((DMAREQ)<(uint8_t)4 && (DMAREQ)!=(uint8_t)0 ) + +/** + * @} + */ + +/** @defgroup UART_Timeout_Definition DMA Timeout + * @{ + */ + +/* This macro checks if VAL is a valid timeout value */ +#define IS_UART_TIMEOUT(VAL) ((VAL) < 0x400000 ) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup UART_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup UART_Exported_Functions Exported Functions + * @{ + */ + +void UART_DeInit(void); +void UART_Init(UART_InitType* UART_InitStruct); +void UART_StructInit(UART_InitType* UART_InitStruct); +void UART_Cmd(FunctionalState NewState); +void UART_ITConfig(uint16_t UART_IT, FunctionalState NewState); +void UART_SendData(uint16_t Data); +uint16_t UART_ReceiveData(void); +void UART_BreakCmd(FunctionalState NewState); +void UART_RequestToSendCmd(FunctionalState NewState); +FlagStatus UART_GetFlagStatus(uint32_t UART_FLAG); +void UART_ClearFlag(uint32_t UART_FLAG); +ITStatus UART_GetITStatus(uint16_t UART_IT); +void UART_ClearITPendingBit(uint16_t UART_IT); +void UART_TxFifoIrqLevelConfig(uint8_t UART_TxFifo_Level); +void UART_RxFifoIrqLevelConfig(uint8_t UART_RxFifo_Level); +void UART_RXTimeoutConfig(uint32_t UART_TimeoutMS); +void UART_Oversampling(FunctionalState NewState); +void UART_SwFlowControl(FunctionalState NewState); +void UART_RxSwFlowControlMode(uint8_t UART_RxSwFlowCtrlMode); +void UART_TxSwFlowControlMode(uint8_t UART_TxSwFlowCtrlMode); +void UART_XonAnyBit(FunctionalState NewState); +void UART_SpecialCharDetect(FunctionalState NewState); +void UART_Xon1Char(uint8_t UART_XonChar); +void UART_Xon2Char(uint8_t UART_XonChar); +void UART_Xoff1Char(uint8_t UART_XoffChar); +void UART_Xoff2Char(uint8_t UART_XoffChar); + +void UART_DMACmd(uint8_t UART_DMAReq, FunctionalState NewState); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_UART_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/BlueNRG1_wdg.h b/drivers/inc/BlueNRG1_wdg.h new file mode 100644 index 0000000..0eefb92 --- /dev/null +++ b/drivers/inc/BlueNRG1_wdg.h @@ -0,0 +1,127 @@ +/** + ****************************************************************************** + * @file BlueNRG1_WDG.h + * @author AMS RF Application Team + * @version V2.2.0 + * @date 27-April-2018 + * @brief This file contains all the functions prototypes for the WDG + * firmware library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2018 STMicroelectronics

+ ****************************************************************************** + */ +/** + * @file BlueNRG1_WDG.h + * @brief BlueNRG-1,2 Watchdog header file + * + +* \section WDG How tho use the Watchdog functionality? + + In order to use this functionality the best way is to add the watchdog reload in the main loop (and not on the WDG IRQ handler: WDG_Handler()). + User should follow these steps: + + 1: Add a Watchdog initialization function to be called before entering on main loop: (WATCHDOG_TIME is a timeout defined based on the application scenario): + + void WDG_Init(void) + { + SysCtrl_PeripheralClockCmd(CLOCK_PERIPH_WDG, ENABLE); + WDG_SetReload(RELOAD_TIME(WATCHDOG_TIME)); + WDG_Enable(); + } + + 2: Just call the reload function inside the main loop: + + while(1) + { + ..... + WDG_SetReload(RELOAD_TIME(WATCHDOG_TIME)); + } + + - NOTE: The option to use the WDG_Handler() it is not mandatory at all, and it is just an implementation choice. If user wants to use this method (not mandatory), then he must clear the pending bit associated to the watchdog (WDG_ClearITPendingBit()). + +**/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_WDG_H +#define BLUENRG1_WDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup WDG_Peripheral WDG Peripheral + * @{ + */ + +/** @defgroup WDG_Exported_Types Exported Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup WDG_Exported_Constants Exported Constants + * @{ + */ + +/** + * @} + */ + +/** @defgroup WDG_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup WDG_Exported_Functions Exported Functions + * @{ + */ +void WDG_SetWriteAccess(FunctionalState NewState); +FunctionalState WDG_GetWriteAccess(void); +void WDG_SetReload(uint32_t WDG_Reload); +uint32_t WDG_GetCounter(void); +void WDG_Enable(void); +void WDG_DisableReset(void); +void WDG_ITConfig(FunctionalState NewState); +ITStatus WDG_GetITStatus(void); +void WDG_ClearITPendingBit(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_WDG_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/inc/misc.h b/drivers/inc/misc.h new file mode 100644 index 0000000..b240eea --- /dev/null +++ b/drivers/inc/misc.h @@ -0,0 +1,135 @@ +/** + ****************************************************************************** + * @file misc.h + * @author VMA Application Team + * @version V2.0.0 + * @date 21-March-2016 + * @brief This file contains all the functions prototypes for the miscellaneous + * firmware library functions (add-on to CMSIS functions). + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG1_MISC_H +#define BLUENRG1_MISC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup MISC_Peripheral MISC Peripheral + * @{ + */ + +/** @defgroup MISC_Exported_Types Exported Types + * @{ + */ + + +/** + * @brief Structure definition of NVIC initialization + */ + +typedef struct +{ + uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. + This parameter can be a value of @ref IRQn_Type + (For the complete BlueNRG1 Device IRQ Channels list, please + refer to BlueNRG1.h file) */ + + uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel + specified in NVIC_IRQChannel. This parameter can be a value + between 0 and 3 */ + + FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel + will be enabled or disabled. + This parameter can be set either to ENABLE or DISABLE */ +} NVIC_InitType; + +/** + * @} + */ + +/** @defgroup MISC_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup Preemption_Priority_Definitions Preemption Priority Group Definitions + * @{ + */ + +/* IRQ priority high */ +#define HIGH_PRIORITY 1 + +/* IRQ priority medium */ +#define MED_PRIORITY 2 + +/* IRQ priority low */ +#define LOW_PRIORITY 3 + +/* This macro checks if PRIORITY is a valid WriteAccess value */ +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x04) + + +/** + * @} + */ + + +/** + * @} + */ + +/** @defgroup MISC_Exported_Macros Exported Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Exported_Functions Exported Functions + * @{ + */ + +void NVIC_Init(NVIC_InitType* NVIC_InitStruct); +void SystemSleepCmd(FunctionalState NewState); +void SysTick_State(FunctionalState NewState); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_MISC_H */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_adc.c b/drivers/src/BlueNRG1_adc.c new file mode 100644 index 0000000..eb1d484 --- /dev/null +++ b/drivers/src/BlueNRG1_adc.c @@ -0,0 +1,778 @@ +/** +****************************************************************************** +* @file BlueNRG1_adc.c +* @author RF Application Team +* @version V2.6.0 +* @date 30-January-2019 +* @brief This file provides all the ADC firmware functions. +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2016 STMicroelectronics

+****************************************************************************** +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_adc.h" + + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver +* @{ +*/ + +/** @addtogroup ADC_Peripheral ADC Peripheral +* @{ +*/ + + +/** @defgroup ADC_Private_Types Private Types +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup ADC_Private_Constants Private Constants +* @{ +*/ +#define ADC_VREF ((float)(2.4)) +#ifdef BLUENRG2_DEVICE +#define ADC_FS_OSR_32_64 ((float)(35442.0)) +#define ADC_FS_OSR_100_200 ((float)(41260.0)) +#else +#define ADC_FS_OSR_32_64 ((float)(16708.0)) +#define ADC_FS_OSR_100_200 ((float)(19450.0)) +#endif +#define ADC_KBATT ((float)(4.36)) +#define ADC_KTEMP ((float)(401.0)) +#define ADC_CTEMP ((float)(267.0)) + +#define ADC_FS_OSR_32_64_SKIP ((float)(32768.0)) +#define ADC_FS_OSR_100_200_SKIP ((float)(38147.0)) + +/** +* @} +*/ + + +/** @defgroup ADC_Private_Macros Private Macros +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup ADC_Private_Variables Private Variables +* @{ +*/ +static float slope = 1.0, offset = 0.0; + +/** +* @} +*/ + +/** @defgroup ADC_Private_Function Private Functions +* @{ +*/ + +/** +* @brief Convert raw ADC value in converted differential voltage value. +* @param raw_value: ADC raw value +* @retval float: converted differential voltage value +*/ +float ADC_ConvertDifferentialVoltage(int16_t raw_value, uint8_t attenuation) +{ + float pga, raw_value_f, divider; + + if( ADC->CONF_b.SKIP == 1) { + divider = ADC_FS_OSR_32_64_SKIP; + } + else { + divider = ADC_FS_OSR_32_64; + } + + pga = (float)attenuation; + raw_value_f = (float)raw_value; + + if(ADC->CONF_b.OSR == ADC_OSR_100 || ADC->CONF_b.OSR == ADC_OSR_200) { + if( ADC->CONF_b.SKIP == 1) { + divider = ADC_FS_OSR_100_200_SKIP; + } + else { + divider = ADC_FS_OSR_100_200; + } + } + + return ((1 + pga) * (raw_value_f / divider) * ADC_VREF); +} + +/** +* @brief Convert raw ADC value in converted single ended voltage value. +* @param raw_value ADC raw value +* @param channel: the selected single channel type +* @param vRef: the configured reference voltage +* @retval float: converted single ended voltage value +*/ +float ADC_ConvertSingleEndedVoltage(int16_t raw_value, uint8_t channel, uint8_t vRef, uint8_t attenuation) +{ + float pga, raw_value_f, divider; + + if( ADC->CONF_b.SKIP == 1) { + divider = ADC_FS_OSR_32_64_SKIP; + } + else { + divider = ADC_FS_OSR_32_64; + } + + pga = (float)attenuation; + raw_value_f = (float)raw_value; + + if(ADC->CONF_b.OSR == ADC_OSR_100 || ADC->CONF_b.OSR == ADC_OSR_200) { + if( ADC->CONF_b.SKIP == 1) { + divider = ADC_FS_OSR_100_200_SKIP; + } + else { + divider = ADC_FS_OSR_100_200; + } + } + + if(channel == ADC_Input_AdcPin1) + return ((1 + pga) * (0.6 + ((raw_value_f/divider) * ADC_VREF))); + else + return ((1 + pga) * (0.6 - ((raw_value_f/divider) * ADC_VREF))); +} + + +/** +* @brief Convert raw ADC value in battery level. +* @param raw_value ADC raw value +* @param vRef: the configured reference voltage +* @retval float: converted battery level +*/ +float ADC_ConvertBatterySensor(int16_t raw_value, uint8_t vRef) /* testare al variare di vref */ +{ + return (ADC_KBATT * (ADC_ConvertSingleEndedVoltage(raw_value, ADC_Input_AdcPin2, ADC_ReferenceVoltage_0V6, ADC_Attenuation_0dB))); +} + +/** +* @brief Convert raw ADC value in temperature level in Celsius degrees. +* @param raw_value ADC raw value +* @param vRef: the configured reference voltage +* @retval float: converted temperature level in Celsius degrees +*/ +float ADC_ConvertTemperatureSensor(int16_t raw_value, uint8_t vRef, uint8_t attenuation) +{ + return ((ADC_KTEMP * (ADC_ConvertSingleEndedVoltage(raw_value, ADC_Input_AdcPin2, ADC_ReferenceVoltage_0V6, ADC_Attenuation_0dB))) - ADC_CTEMP); +} +float ADC_ConvertTemperatureSensorFarenait(int16_t raw_value, uint8_t vRef, uint8_t attenuation) +{ + return ((722.0 * (ADC_ConvertSingleEndedVoltage(raw_value, ADC_Input_AdcPin2, ADC_ReferenceVoltage_0V6, ADC_Attenuation_0dB))) - 499.0); +} + +/** +* @} +*/ + + +/** @defgroup ADC_Public_Functions Public Functions +* @{ +*/ + +/** +* @brief Deinitializes ADC peripheral registers to their default reset values. +* @param None +* @retval None +*/ +void ADC_DeInit(void) +{ + /* Enable ADC reset state */ + ADC->CTRL_b.RESET = SET; +} + + +/** +* @brief Fills the ADC_InitStruct with default values. +* @param ADC_InitStruct: pointer to an @ref ADC_InitType structure which will be initialized. +* @retval None +*/ +void ADC_StructInit(ADC_InitType* ADC_InitStruct) +{ + /* Set the decimation rate */ + ADC_InitStruct->ADC_OSR = ADC_OSR_200; + + /* Select the input source */ + ADC_InitStruct->ADC_Input = ADC_Input_None; + + /* Set the reference voltage */ + ADC_InitStruct->ADC_ReferenceVoltage = ADC_ReferenceVoltage_0V6; + + /* Set the conversion mode */ + ADC_InitStruct->ADC_ConversionMode = ADC_ConversionMode_Single; + + /* Set the attenuation */ + ADC_InitStruct->ADC_Attenuation = ADC_Attenuation_0dB; +} + + +/** +* @brief Initializes the ADC peripheral according to the specified parameters +* in the ADC_InitStruct. +* @param ADC_InitStruct: pointer to an @ref ADC_InitType structure that contains +* the configuration information for the ADC peripheral. +* @retval None +*/ +void ADC_Init(ADC_InitType* ADC_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_ADC_OSR(ADC_InitStruct->ADC_OSR)); + assert_param(IS_ADC_INPUT(ADC_InitStruct->ADC_Input)); + assert_param(IS_ADC_CONVERSIONMODE(ADC_InitStruct->ADC_ConversionMode)); + assert_param(IS_ADC_ATTENUATION(ADC_InitStruct->ADC_Attenuation)); + assert_param(IS_ADC_REFERENCEVOLTAGE(ADC_InitStruct->ADC_ReferenceVoltage)); + + /* Set the decimation rate */ + ADC->CONF_b.OSR = ADC_InitStruct->ADC_OSR; + + /* Select the input source */ + if(ADC_InitStruct->ADC_Input == ADC_Input_Microphone) { + ADC->CONF_b.MIC_SEL = SET; + } + else { + ADC->CONF_b.MIC_SEL = RESET; + ADC->CONF_b.CHSEL = ADC_InitStruct->ADC_Input; + } + + /* Set the reference voltage */ + ADC->CONF_b.REFSEL = ADC_InitStruct->ADC_ReferenceVoltage; + + /* Set the conversion mode */ + if(ADC_InitStruct->ADC_ConversionMode == ADC_ConversionMode_Continuous) { + ADC->CONF_b.CONT = SET; + } + else { + ADC->CONF_b.CONT = RESET; + } + + /* Set the attenuation */ + ADC->CONF_b.PGASEL = ADC_InitStruct->ADC_Attenuation; + +} + + +/** +* @brief Enable disable the ADC conversion. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void ADC_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState==ENABLE) { + if(ADC->CONF_b.MIC_SEL) { + ADC->CTRL_b.MIC_ON = SET; + } + else { + ADC->CTRL_b.SWSTART = SET; + ADC->CTRL_b.ON = SET; + } + } + else { + ADC->CTRL_b.STOP = SET; + } +} + + +/** +* @brief Enable disable the ADC DMA feature. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void ADC_DmaCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState==ENABLE) { + ADC->CTRL_b.DMA_EN = SET; + } + else { + ADC->CTRL_b.DMA_EN = RESET; + } +} + + +/** +* @brief Specified the ADC input channel. +* @param adc_input: Specifies the input used for the conversion. +* This parameter can be a value of @ref ADC_Input. +* @retval None +*/ +void ADC_SelectInput(uint8_t AdcInput) +{ + /* Check the parameter */ + assert_param(IS_ADC_INPUT(AdcInput)); + + ADC->CONF_b.CHSEL = AdcInput; +} + +/** +* @brief Enable disable the ADC calibration procedure. +* If the automatic calibration must be enabled, +* call the following APIs: +* ADC_AutoOffsetUpdate(ENABLE); +* ADC_Calibration(ENABLE); +* If the automatic calibration must be disabled, +* call the following APIs: +* ADC_AutoOffsetUpdate(DISABLE); +* ADC_Calibration(DISABLE); +* +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void ADC_Calibration(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState==ENABLE) { + ADC->CTRL_b.CALEN = SET; + } + else { + ADC->CTRL_b.RSTCALEN = SET; + ADC->CTRL_b.CALEN = RESET; + } + +} + + +/** +* @brief Enable disable the ADC automatic update of the offset. +* If the automatic calibration must be enabled, +* call the following APIs: +* ADC_AutoOffsetUpdate(ENABLE); +* ADC_Calibration(ENABLE); +* If the automatic calibration must be disabled, +* call the following APIs: +* ADC_AutoOffsetUpdate(DISABLE); +* ADC_Calibration(DISABLE); +* +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void ADC_AutoOffsetUpdate(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState==ENABLE) { + ADC->CTRL_b.AUTO_OFFSET = SET; + } + else { + ADC->CTRL_b.AUTO_OFFSET = RESET; + } +} + + +/** +* @brief Enable disable the ADC threshold check. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void ADC_ThresholdCheck(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState==ENABLE) { + ADC->CTRL_b.ENAB_COMP = SET; + } + else { + ADC->CTRL_b.ENAB_COMP = RESET; + } +} + + +/** +* @brief Configure the ADC threshold. +* @param ThresholdLow: ADC threshold low value. +* ThresholdHigh: ADC threshold high value. +* @retval None +*/ +void ADC_ThresholdConfig(uint32_t ThresholdLow, uint32_t ThresholdHigh) +{ + + ADC->THRESHOLD_LO = ThresholdLow; + ADC->THRESHOLD_HI = ThresholdHigh; +} + +/** +* @brief Get the ADC offset value previously calculated +* internally with the auto calibration. +* @param None +* @retval uint16_t: Offset for correction of converter data. +*/ +uint16_t ADC_GetOffset(void) +{ + uint16_t value; + + /* Conversion done with filter bypassed */ + if(ADC->CONF_b.SKIP == 0) { + value = READ_REG(ADC->OFFSET_MSB); + } + /* Conversion done with filter not bypassed */ + else { + value = READ_REG(ADC->OFFSET_LSB); + } + + return value; +} + + +/** +* @brief Set the ADC offset value previously calculated +* internally with the auto calibration. +* The AUTO_OFFSET will perform this operation automatically. +* @param int32_t: Offset for correction of converter data. +* @retval None +*/ +void ADC_SetOffset(uint16_t Offset) +{ + + /* Conversion done with filter bypassed */ + if(ADC->CONF_b.SKIP == 0) { + ADC->OFFSET_MSB = Offset; + } + /* Conversion done with filter not bypassed */ + else { + ADC->OFFSET_LSB = Offset; + } +} + +/** +* @brief Configure the ADC conversion mode. +* @param cConvertionMode: the value can be +* @arg ADC_ConversionMode_Single single shot ADC conversion +* @arg ADC_ConversionMode_Continuous continuous ADC conversion +* @retval None +*/ +void ADC_ConversionMode(uint8_t ConvertionMode) +{ + /* Check the parameters */ + assert_param(IS_ADC_CONVERSIONMODE(ConvertionMode)); + + if(ConvertionMode==ADC_ConversionMode_Continuous) { + ADC->CONF_b.CONT = SET; + } + else { + ADC->CONF_b.CONT = RESET; + } + +} + +/** +* @brief Select the frequency of the clock signal for an external MEMS microphone (through IO0) +* @param Frequency: the value can be +* @arg ADC_MIC_800KH Enable the 800 kHz through IO0 for external MEMS microphone +* @arg ADC_MIC_1600KH Enable the 1.6 MHz through IO0 for external MEMS microphone +* @retval None +*/ +void ADC_SelectFrequencyMic(uint8_t Frequency) +{ + /* Check the parameters */ + assert_param(IS_ADC_MIC_FREQ_SEL(Frequency)); + + /* Check the value of Frequency */ + if(Frequency == ADC_MIC_800KHZ) { + ADC->CONF_b.DIG_FILT_CLK = SET; + } + else if(Frequency == ADC_MIC_1600KHZ) { + ADC->CONF_b.DIG_FILT_CLK = RESET; + } + +} + + +/** +* @brief Get the ADC flags. +* The read operation will clear the flags. +* @param none +* @retval uint8_t: the ADC flags as bitmask 0x0000b3b2b1b0: +* b3: ADC_FLAG_WDG +* b2: ADC_FLAG_EOC +* b1: ADC_FLAG_BUSY +* b0: ADC_FLAG_CAL. +*/ +uint8_t ADC_GetFlags(void) +{ + uint8_t flags; + + flags = (ADC->IRQRAW & 0x0F); + + return flags; +} + +/** +* @brief Get the status flag of ADC. +* The read operation will clear the flags. +* If more than one status flag must be read, +* then the function must be ADC_GetFlags(). +* @param ADC_Flag: the value can be +* @arg ADC_FLAG_CAL ADC End of Calibration flag +* @arg ADC_FLAG_BUSY ADC busy flag +* @arg ADC_FLAG_EOC ADC End of Conversion flag +* @arg ADC_FLAG_WDG ADC ADV value within set threshold +* @retval FlagStatus: functional state @ref FlagStatus +* This parameter can be: SET or RESET. +*/ +FlagStatus ADC_GetFlagStatus(uint8_t ADC_Flag) +{ + FlagStatus status; + + /* Check the parameters */ + assert_param(IS_ADC_GET_FLAG(ADC_Flag)); + + /* Check the status of the specified SPI flag */ + if (READ_BIT(ADC->IRQRAW, ADC_Flag) != (uint16_t)RESET) { + /* SPI_FLAG is set */ + status = SET; + } + else { + /* SPI_FLAG is reset */ + status = RESET; + } + + return status; +} + +/** +* @brief Get the status of the masked IT flag. +* The read operation will clear the flags. +* If more than one status flag must be read, +* then the function must be ADC_GetFlags(). +* @param ADC_Flag: the value can be +* @arg ADC_FLAG_CAL ADC End of Calibration flag +* @arg ADC_FLAG_BUSY ADC busy flag +* @arg ADC_FLAG_EOC ADC End of Conversion flag +* @arg ADC_FLAG_WDG ADC ADV value within set threshold +* @retval ITStatus: functional state @ref ITStatus +* This parameter can be: SET or RESET. +*/ +ITStatus ADC_GetITStatus(uint8_t ADC_Flag) +{ + ITStatus status; + + /* Check the parameters */ + assert_param(IS_ADC_GET_FLAG(ADC_Flag)); + + /* Check the status of the specified SPI interrupt */ + if (READ_BIT(ADC->IRQSTAT, ADC_Flag) != (uint16_t)RESET) { + /* ADC_Flag is set */ + status = SET; + } + else { + /* SPI_IT is reset */ + status = RESET; + } + + return status; +} + + + +/** +* @brief Enable disable the ADC IT flag. +* @param ADC_Flag: the value can be +* @arg ADC_FLAG_CAL ADC End of Calibration flag +* @arg ADC_FLAG_BUSY ADC busy flag +* @arg ADC_FLAG_EOC ADC End of Conversion flag +* @arg ADC_FLAG_WDG ADC ADV value within set threshold +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void ADC_ITConfig(uint8_t ADC_Flag, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_ADC_GET_FLAG(ADC_Flag)); + + if (NewState != DISABLE) { + /* Enable the selected SPI interrupts */ + CLEAR_BIT(ADC->IRQMASK, ADC_Flag); + } + else { + /* Disable the selected SPI interrupts */ + SET_BIT(ADC->IRQMASK, ADC_Flag); + } +} + +/** +* @brief Get the ADC converted value in Volt. +* @param dataType: the selected channel, this value can be +* @arg ADC_Input_AdcPin1 data from ADC pin1 +* @arg ADC_Input_AdcPin2 data from ADC pin2 +* @arg ADC_Input_AdcPin12 data from ADC pin12 +* @arg ADC_Input_Internal0V60V6 data from internal 0.6V +* @arg ADC_Input_Internal1V20V0 data from internal 1.2V +* @arg ADC_Input_BattSensor data from battery sensor +* @arg ADC_Input_TempSensor data from temperature sensor +* @param vRef: voltage reference configured, the value can be +* @arg ADC_ReferenceVoltage_0V6 Vref is 0.6 V +* @retval Converted ADC value in Volt +*/ +float ADC_GetConvertedData(uint8_t DataType, uint8_t Vref) +{ + int16_t raw_value; + uint8_t pga_reg; + + /* Check the parameters */ + assert_param(IS_ADC_INPUT(DataType)); + assert_param(IS_ADC_REFERENCEVOLTAGE(Vref)); + + raw_value = (int16_t)ADC_GetRawData(); + pga_reg = ADC->CONF_b.PGASEL; + + if(DataType==ADC_Input_AdcPin1) { + return ADC_ConvertSingleEndedVoltage(raw_value, (uint8_t)ADC_Input_AdcPin1, Vref, pga_reg); + } + else if(DataType==ADC_Input_AdcPin2) { + return ADC_ConvertSingleEndedVoltage(raw_value, (uint8_t)ADC_Input_AdcPin2, Vref, pga_reg); + } + else if(DataType==ADC_Input_AdcPin12 || DataType==ADC_Input_Internal0V60V6 || DataType==ADC_Input_Internal1V20V0) { + return ADC_ConvertDifferentialVoltage(raw_value, pga_reg); + } + else if(DataType==ADC_Input_BattSensor) { + return ADC_ConvertBatterySensor(raw_value, Vref); + } + else if(DataType==ADC_Input_TempSensor) { + return ADC_ConvertTemperatureSensor(raw_value, Vref, pga_reg); + } + return raw_value; +} + + +/** +* @brief Get the ADC raw value. +* @param None +* @retval ADC raw value +*/ +uint16_t ADC_GetRawData(void) +{ + uint16_t value; + + /* Conversion done with filter bypassed */ + if(ADC->CONF_b.SKIP == 0) { + value = READ_REG(ADC->DATA_CONV_MSB); + } + /* Conversion done with filter not bypassed */ + else { + value = READ_REG(ADC->DATA_CONV_LSB); + } + + return value; +} + + +/** +* @brief Enable/disable the COMP filter. +* This operation could be useful to speed up the conversion +* for signal at low frequency. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void ADC_Filter(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* If ENABLE the filter, then reset the SKIP bifield */ + if(NewState==ENABLE) { + ADC->CONF_b.SKIP = RESET; + } + + /* If DISABLE the filter, then set the SKIP bifield */ + else { + ADC->CONF_b.SKIP = SET; + } +} + + +/** +* @brief Generates the slope and the offset used for the software compensation. +* @param None +* @retval uint8_t 1 means No calibration points recorded. 0 Success. +*/ +uint8_t ADC_SwCalibration(void) +{ + uint32_t ifr0_v1, ifr0_v2, ifr0_v3; + float v1f, v2f, v3f; + + /* Read calibration values */ + ifr0_v1 = *(uint32_t*)0x100007D0; /* 0.0 V */ + ifr0_v2 = *(uint32_t*)0x100007D8; /* 1.8 V */ + ifr0_v3 = *(uint32_t*)0x100007E0; /* 3.6 V */ + + /* Check if the calibration points are valid */ + if(ifr0_v1 == 0xFFFFFFFF && ifr0_v2 == 0xFFFFFFFF && ifr0_v3 == 0xFFFFFFFF) { + return 1; + } + + /* Convert according to the ADC pin 2 formula with PGA 9.54 dB */ + v1f = (3 * (0.6 - (( ((float)((int16_t)(ifr0_v1>>16))) /ADC_FS_OSR_100_200) * ADC_VREF))); + v2f = (3 * (0.6 - (( ((float)((int16_t)(ifr0_v2>>16))) /ADC_FS_OSR_100_200) * ADC_VREF))); + v3f = (3 * (0.6 - (( ((float)((int16_t)(ifr0_v3>>16))) /ADC_FS_OSR_100_200) * ADC_VREF))); + + /* Calculate the slope */ + slope = 2.0 - ( (v3f - v1f)/3.6 ); + + /* Calculate the slope */ + offset = (v1f - 1.8 + v2f * slope) / 2.0; + + return 0; +} + +/** +* @brief Apply the slope and the offset in order to compensate the output value. +* Before call this function, the API ADC_SwCalibration() must be called and +* it must return 0 (success). +* value can be an ADC value from battery sensor or ADC pins. +* @param float The value coming from the API ADC_GetConvertedData(). +* @retval float The compensated ADC output value. +*/ +float ADC_CompensateOutputValue(float value) +{ + /* Apply slope and offset */ + return (float)((value * slope) - offset); +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_dma.c b/drivers/src/BlueNRG1_dma.c new file mode 100644 index 0000000..e980a53 --- /dev/null +++ b/drivers/src/BlueNRG1_dma.c @@ -0,0 +1,513 @@ +/** + ****************************************************************************** + * @file BlueNRG1_dma.c + * @author VMA Application Team + * @version V2.0.0 + * @date 21-March-2016 + * @brief This file provides all the DMA firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2015 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_dma.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @defgroup DMA_Peripheral DMA Peripheral + * @{ + */ + + +/** @defgroup DMA_Private_TypesDefinitions Private Type Definitions +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup DMA_Private_Defines Private Defines +* @{ +*/ +/* DMA registers Masks */ +#define CCR_CLEAR_MASK ((uint32_t)0xFFFF800F) + +/** +* @} +*/ + +/** @defgroup DMA_Private_Macros Private Macros +* @{ +*/ + +/* DMA Channelx interrupt pending bit masks */ +#define DMA_CHANNEL0_FLAG_MASK ((uint32_t)(DMA_FLAG_GL0 | DMA_FLAG_TC0 | DMA_FLAG_HT0 | DMA_FLAG_TE0)) +#define DMA_CHANNEL1_FLAG_MASK ((uint32_t)(DMA_FLAG_GL1 | DMA_FLAG_TC1 | DMA_FLAG_HT1 | DMA_FLAG_TE1)) +#define DMA_CHANNEL2_FLAG_MASK ((uint32_t)(DMA_FLAG_GL2 | DMA_FLAG_TC2 | DMA_FLAG_HT2 | DMA_FLAG_TE2)) +#define DMA_CHANNEL3_FLAG_MASK ((uint32_t)(DMA_FLAG_GL3 | DMA_FLAG_TC3 | DMA_FLAG_HT3 | DMA_FLAG_TE3)) +#define DMA_CHANNEL4_FLAG_MASK ((uint32_t)(DMA_FLAG_GL4 | DMA_FLAG_TC4 | DMA_FLAG_HT4 | DMA_FLAG_TE4)) +#define DMA_CHANNEL5_FLAG_MASK ((uint32_t)(DMA_FLAG_GL5 | DMA_FLAG_TC5 | DMA_FLAG_HT5 | DMA_FLAG_TE5)) +#define DMA_CHANNEL6_FLAG_MASK ((uint32_t)(DMA_FLAG_GL6 | DMA_FLAG_TC6 | DMA_FLAG_HT6 | DMA_FLAG_TE6)) +#define DMA_CHANNEL7_FLAG_MASK ((uint32_t)(DMA_FLAG_GL7 | DMA_FLAG_TC7 | DMA_FLAG_HT7 | DMA_FLAG_TE7)) + + +#define IS_DMA_ALL_PERIPH(PERIPH) (((PERIPH) == DMA_CH0) || \ + ((PERIPH) == DMA_CH1) || \ + ((PERIPH) == DMA_CH2) || \ + ((PERIPH) == DMA_CH3) || \ + ((PERIPH) == DMA_CH4) || \ + ((PERIPH) == DMA_CH5) || \ + ((PERIPH) == DMA_CH6) || \ + ((PERIPH) == DMA_CH7)) +/** +* @} +*/ + +/** @defgroup DMA_Private_Variables Private Variables +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup DMA_Private_FunctionPrototypes Private Function Prototypes +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup DMA_Private_Functions Private Functions +* @{ +*/ + + + +/** +* @} +*/ + +/** @defgroup DMA_Public_Functions Public Functions +* @{ +*/ + +/** + * @brief Deinitializes the DMAy Channelx registers to their default reset + * values. + * @param DMAy_Channelx: where y can be 1 to select the DMA and + * x can be 1 to 7 for DMA to select the DMA Channel. + * @retval None + */ +void DMA_DeInit(DMA_CH_Type* DMAy_Channelx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + + /* Disable the selected DMAy Channelx */ + DMAy_Channelx->CCR_b.EN = RESET; + + /* Reset DMAy Channelx control register */ + DMAy_Channelx->CCR = 0; + + /* Reset DMAy Channelx remaining bytes register */ + DMAy_Channelx->CNDTR = 0; + + /* Reset DMAy Channelx peripheral address register */ + DMAy_Channelx->CPAR = 0; + + /* Reset DMAy Channelx memory address register */ + DMAy_Channelx->CMAR = 0; + + if (DMAy_Channelx == DMA_CH1) + { + /* Reset interrupt pending bits for DMA Channel1 */ + SET_BIT(DMA->IFCR, DMA_CHANNEL1_FLAG_MASK); + } + else if (DMAy_Channelx == DMA_CH2) + { + /* Reset interrupt pending bits for DMA Channel2 */ + SET_BIT(DMA->IFCR, DMA_CHANNEL2_FLAG_MASK); + } + else if (DMAy_Channelx == DMA_CH3) + { + /* Reset interrupt pending bits for DMA Channel3 */ + SET_BIT(DMA->IFCR, DMA_CHANNEL3_FLAG_MASK); + } + else if (DMAy_Channelx == DMA_CH4) + { + /* Reset interrupt pending bits for DMA Channel4 */ + SET_BIT(DMA->IFCR, DMA_CHANNEL4_FLAG_MASK); + } + else if (DMAy_Channelx == DMA_CH5) + { + /* Reset interrupt pending bits for DMA Channel5 */ + SET_BIT(DMA->IFCR, DMA_CHANNEL5_FLAG_MASK); + } + else if (DMAy_Channelx == DMA_CH6) + { + /* Reset interrupt pending bits for DMA Channel6 */ + SET_BIT(DMA->IFCR, DMA_CHANNEL6_FLAG_MASK); + } + else if (DMAy_Channelx == DMA_CH7) + { + /* Reset interrupt pending bits for DMA Channel7 */ + SET_BIT(DMA->IFCR, DMA_CHANNEL7_FLAG_MASK); + } +} + +/** + * @brief Initializes the DMAy Channelx according to the specified + * parameters in the DMA_InitStruct. + * @param DMAy_Channelx: where y can be 1 to select the DMA and + * x can be 1 to 7 for DMA to select the DMA Channel. + * @param DMA_InitStruct: pointer to a DMA_InitType structure that + * contains the configuration information for the specified DMA Channel. + * @retval None + */ +void DMA_Init(DMA_CH_Type* DMAy_Channelx, DMA_InitType* DMA_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR)); + assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize)); + assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc)); + assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc)); + assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize)); + assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize)); + assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode)); + assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority)); + assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M)); + +/*--------------------------- DMAy Channelx CCR Configuration -----------------*/ + /* Get the DMAy_Channelx CCR value */ + tmpreg = DMAy_Channelx->CCR; + /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ + tmpreg &= CCR_CLEAR_MASK; + /* Configure DMAy Channelx: data transfer, data size, priority level and mode */ + /* Set DIR bit according to DMA_DIR value */ + /* Set CIRC bit according to DMA_Mode value */ + /* Set PINC bit according to DMA_PeripheralInc value */ + /* Set MINC bit according to DMA_MemoryInc value */ + /* Set PSIZE bits according to DMA_PeripheralDataSize value */ + /* Set MSIZE bits according to DMA_MemoryDataSize value */ + /* Set PL bits according to DMA_Priority value */ + /* Set the MEM2MEM bit according to DMA_M2M value */ + tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode | + DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc | + DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize | + DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M; + + /* Write to DMAy Channelx CCR */ + DMAy_Channelx->CCR = tmpreg; + +/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/ + /* Write to DMAy Channelx CNDTR */ + DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize; + +/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/ + /* Write to DMAy Channelx CPAR */ + DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr; + +/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/ + /* Write to DMAy Channelx CMAR */ + DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr; +} + +/** + * @brief Fills each DMA_InitStruct member with its default value. + * @param DMA_InitStruct: pointer to a DMA_InitType structure which will + * be initialized. + * @retval None + */ +void DMA_StructInit(DMA_InitType* DMA_InitStruct) +{ +/*-------------- Reset DMA init structure parameters values ------------------*/ + /* Initialize the DMA_PeripheralBaseAddr member */ + DMA_InitStruct->DMA_PeripheralBaseAddr = 0; + /* Initialize the DMA_MemoryBaseAddr member */ + DMA_InitStruct->DMA_MemoryBaseAddr = 0; + /* Initialize the DMA_DIR member */ + DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralSRC; + /* Initialize the DMA_BufferSize member */ + DMA_InitStruct->DMA_BufferSize = 0; + /* Initialize the DMA_PeripheralInc member */ + DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable; + /* Initialize the DMA_MemoryInc member */ + DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable; + /* Initialize the DMA_PeripheralDataSize member */ + DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + /* Initialize the DMA_MemoryDataSize member */ + DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + /* Initialize the DMA_Mode member */ + DMA_InitStruct->DMA_Mode = DMA_Mode_Normal; + /* Initialize the DMA_Priority member */ + DMA_InitStruct->DMA_Priority = DMA_Priority_Low; + /* Initialize the DMA_M2M member */ + DMA_InitStruct->DMA_M2M = DMA_M2M_Disable; +} + +/** + * @brief Enables or disables the specified DMAy Channelx. + * @param DMAy_Channelx: where y can be 1 to select the DMA and + * x can be 1 to 7 for DMA to select the DMA Channel. + * @param NewState: new state of the DMAy Channelx. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_Cmd(DMA_CH_Type* DMAy_Channelx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the selected DMAy Channelx */ + DMAy_Channelx->CCR_b.EN = SET; + } + else { + /* Disable the selected DMAy Channelx */ + DMAy_Channelx->CCR_b.EN = RESET; + } +} + + +/** + * @brief Enables or disables the specified DMA ADC Channel. + * @param DMA_AdcChannel: ADC channel from 0 to 7. + * @param NewState: new state of the DMA ADC Channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_SelectAdcChannel(uint8_t DMA_AdcChannel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ADC_CH(DMA_AdcChannel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the selected of DMA ADC Channel */ + SET_BIT(CKGEN_SOC->DMA_CONFIG, DMA_AdcChannel); + } + else { + /* Disable the selected of DMA ADC Channel */ + CLEAR_BIT(CKGEN_SOC->DMA_CONFIG, DMA_AdcChannel); + } +} + + +/** + * @brief Sets the number of data units in the current DMAy Channelx transfer. + * @param DMAy_Channelx: where y can be 1 to select the DMA and + * x can be 1 to 7 for DMA to select the DMA Channel. + * @param DataNumber: The number of data units in the current DMAy Channelx + * transfer. + * @note This function can only be used when the DMAy_Channelx is disabled. + * @retval None. + */ +void DMA_SetCurrDataCounter(DMA_CH_Type* DMAy_Channelx, uint16_t DataNumber) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + +/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/ + /* Write to DMAy Channelx CNDTR */ + DMAy_Channelx->CNDTR = (uint32_t)DataNumber; +} + +/** + * @brief Returns the number of remaining data units in the current + * DMAy Channelx transfer. + * @param DMAy_Channelx: where y can be 1 to select the DMA and + * x can be 1 to 7 for DMA to select the DMA Channel. + * @retval The number of remaining data units in the current DMAy Channelx + * transfer. + */ +uint16_t DMA_GetCurrDataCounter(DMA_CH_Type* DMAy_Channelx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + /* Return the number of remaining data units for DMAy Channelx */ + return ((uint16_t)(DMAy_Channelx->CNDTR)); +} + +/** + * @brief Enables or disables the specified DMAy Channelx interrupts. + * @param DMAy_Channelx: where y can be 1 to select the DMA and + * x can be 1 to 7 for DMA to select the DMA Channel. + * @param DMA_Flag: specifies the DMA interrupts sources to be enabled + * or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_Flag_TC: Transfer complete interrupt mask + * @arg DMA_Flag_HT: Half transfer interrupt mask + * @arg DMA_Flag_TE: Transfer error interrupt mask + * @param NewState: new state of the specified DMA interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_FlagConfig(DMA_CH_Type* DMAy_Channelx, uint32_t DMA_Flag, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_DMA_CONFIG_FLAG(DMA_Flag)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the selected DMA interrupts */ + SET_BIT(DMAy_Channelx->CCR, DMA_Flag); + } + else { + /* Disable the selected DMA interrupts */ + CLEAR_BIT(DMAy_Channelx->CCR, DMA_Flag); + } +} + +/** + * @brief Checks whether the specified DMAy Channelx flag is set or not. + * @param DMA_Flag: specifies the flag to check. + * This parameter can be one of the following values: + * @arg DMA_FLAG_GL1: DMA Channel1 global flag. + * @arg DMA_FLAG_TC1: DMA Channel1 transfer complete flag. + * @arg DMA_FLAG_HT1: DMA Channel1 half transfer flag. + * @arg DMA_FLAG_TE1: DMA Channel1 transfer error flag. + * @arg DMA_FLAG_GL2: DMA Channel2 global flag. + * @arg DMA_FLAG_TC2: DMA Channel2 transfer complete flag. + * @arg DMA_FLAG_HT2: DMA Channel2 half transfer flag. + * @arg DMA_FLAG_TE2: DMA Channel2 transfer error flag. + * @arg DMA_FLAG_GL3: DMA Channel3 global flag. + * @arg DMA_FLAG_TC3: DMA Channel3 transfer complete flag. + * @arg DMA_FLAG_HT3: DMA Channel3 half transfer flag. + * @arg DMA_FLAG_TE3: DMA Channel3 transfer error flag. + * @arg DMA_FLAG_GL4: DMA Channel4 global flag. + * @arg DMA_FLAG_TC4: DMA Channel4 transfer complete flag. + * @arg DMA_FLAG_HT4: DMA Channel4 half transfer flag. + * @arg DMA_FLAG_TE4: DMA Channel4 transfer error flag. + * @arg DMA_FLAG_GL5: DMA Channel5 global flag. + * @arg DMA_FLAG_TC5: DMA Channel5 transfer complete flag. + * @arg DMA_FLAG_HT5: DMA Channel5 half transfer flag. + * @arg DMA_FLAG_TE5: DMA Channel5 transfer error flag. + * @arg DMA_FLAG_GL6: DMA Channel6 global flag. + * @arg DMA_FLAG_TC6: DMA Channel6 transfer complete flag. + * @arg DMA_FLAG_HT6: DMA Channel6 half transfer flag. + * @arg DMA_FLAG_TE6: DMA Channel6 transfer error flag. + * @arg DMA_FLAG_GL7: DMA Channel7 global flag. + * @arg DMA_FLAG_TC7: DMA Channel7 transfer complete flag. + * @arg DMA_FLAG_HT7: DMA Channel7 half transfer flag. + * @arg DMA_FLAG_TE7: DMA Channel7 transfer error flag. + * + * @note + * The Global flag (DMAy_FLAG_GLx) is set whenever any of the other flags + * relative to the same channel is set (Transfer Complete, Half-transfer + * Complete or Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx or + * DMAy_FLAG_TEx). + * + * @retval The new state of DMA_Flag (SET or RESET). + */ +FlagStatus DMA_GetFlagStatus(uint32_t DMA_Flag) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_CH_FLAG(DMA_Flag)); + + /* Get DMA ISR register value */ + tmpreg = DMA->ISR; + + /* Check the status of the specified DMA flag */ + if ((tmpreg & DMA_Flag) != (uint32_t)RESET) + { + /* DMA_Flag is set */ + return SET; + } + else + { + /* DMA_Flag is reset */ + return RESET; + } + +} + + +/** + * @brief Clears the DMAy Channelx's pending flags. + * @param DMA_Flag: specifies the flag to clear. + * This parameter can be any combination (for the same DMA) of the following values: + * @arg DMA_FLAG_GL1: DMA Channel1 global flag. + * @arg DMA_FLAG_TC1: DMA Channel1 transfer complete flag. + * @arg DMA_FLAG_HT1: DMA Channel1 half transfer flag. + * @arg DMA_FLAG_TE1: DMA Channel1 transfer error flag. + * @arg DMA_FLAG_GL2: DMA Channel2 global flag. + * @arg DMA_FLAG_TC2: DMA Channel2 transfer complete flag. + * @arg DMA_FLAG_HT2: DMA Channel2 half transfer flag. + * @arg DMA_FLAG_TE2: DMA Channel2 transfer error flag. + * @arg DMA_FLAG_GL3: DMA Channel3 global flag. + * @arg DMA_FLAG_TC3: DMA Channel3 transfer complete flag. + * @arg DMA_FLAG_HT3: DMA Channel3 half transfer flag. + * @arg DMA_FLAG_TE3: DMA Channel3 transfer error flag. + * @arg DMA_FLAG_GL4: DMA Channel4 global flag. + * @arg DMA_FLAG_TC4: DMA Channel4 transfer complete flag. + * @arg DMA_FLAG_HT4: DMA Channel4 half transfer flag. + * @arg DMA_FLAG_TE4: DMA Channel4 transfer error flag. + * @arg DMA_FLAG_GL5: DMA Channel5 global flag. + * @arg DMA_FLAG_TC5: DMA Channel5 transfer complete flag. + * @arg DMA_FLAG_HT5: DMA Channel5 half transfer flag. + * @arg DMA_FLAG_TE5: DMA Channel5 transfer error flag. + * @arg DMA_FLAG_GL6: DMA Channel6 global flag. + * @arg DMA_FLAG_TC6: DMA Channel6 transfer complete flag. + * @arg DMA_FLAG_HT6: DMA Channel6 half transfer flag. + * @arg DMA_FLAG_TE6: DMA Channel6 transfer error flag. + * @arg DMA_FLAG_GL7: DMA Channel7 global flag. + * @arg DMA_FLAG_TC7: DMA Channel7 transfer complete flag. + * @arg DMA_FLAG_HT7: DMA Channel7 half transfer flag. + * @arg DMA_FLAG_TE7: DMA Channel7 transfer error flag. + * + * @note + * Clearing the Global flag (DMAy_FLAG_GLx) results in clearing all other flags + * relative to the same channel (Transfer Complete, Half-transfer Complete and + * Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx). + * + * @retval None + */ +void DMA_ClearFlag(uint32_t DMA_Flag) +{ + /* Check the parameters */ + assert_param(IS_DMA_CH_FLAG(DMA_Flag)); + + /* Clear the selected DMA flags */ + DMA->IFCR = DMA_Flag; + +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_flash.c b/drivers/src/BlueNRG1_flash.c new file mode 100644 index 0000000..9c21212 --- /dev/null +++ b/drivers/src/BlueNRG1_flash.c @@ -0,0 +1,374 @@ +/** +****************************************************************************** +* @file BlueNRG1_flash.c +* @author VMA Application Team +* @version V2.0.1 +* @date 21-March-2018 +* @brief This file provides all the FLASH firmware functions. +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2016 STMicroelectronics

+****************************************************************************** +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_flash.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver +* @{ +*/ + +/** @defgroup FLASH_Peripheral FLASH Peripheral +* @{ +*/ + +/** @defgroup FLASH_Private_TypesDefinitions Private Types Definitions +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup FLASH_Private_Defines Private Defines +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup FLASH_Private_Macros Private Macros +* @{ +*/ + + +/** +* @} +*/ + +/** @defgroup FLASH_Private_Variables Private Variables +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup FLASH_Private_Functions Private Functions +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup FLASH_Public_Functions Public Functions +* @{ +*/ + + + +/** +* @brief Erases a specified flash page. +* @param PageNumber: the page number. +* @retval None +*/ +void FLASH_ErasePage(uint16_t PageNumber) +{ + uint16_t pageAddress; + + assert_param(IS_PAGE_NUMBER(PageNumber)); + + /* Lock word to avoid undesired FLASH operation */ + if (flash_sw_lock != FLASH_UNLOCK_WORD) + return; + + pageAddress = (PageNumber * N_BYTES_PAGE)>>2; + + /* Clear IRQ */ + FLASH->IRQSTAT = 0x3F; + + /* Write the page address */ + FLASH->ADDRESS = pageAddress; + + /* Write the ERASE command */ + FLASH->COMMAND = FLASH_ERASE; + + FLASH_WaitCmdDone(); + + /* Verify */ + // return; +} + +/** +* @brief Erases all main Flash. +* @param None +* @retval None +*/ +void FLASH_EraseAllFlash(void) +{ + /* Lock word to avoid undesired FLASH operation */ + if (flash_sw_lock != FLASH_UNLOCK_WORD) + return; + + /* Clear IRQ */ + FLASH->IRQSTAT = 0x3F; + + /* Write the MASSERASE command */ + FLASH->COMMAND = FLASH_MASSERASE; + + FLASH_WaitCmdDone(); + +} + +/** +* @brief Flash read 32 bits. +* @param Address: address to read. + Address must be word aligned. +* @retval Data read +*/ +uint32_t FLASH_ReadWord(uint32_t Address) +{ + assert_param(IS_FLASH_ADDRESS(Address)); + + return (*((volatile uint32_t*)(Address))); +} + +/** +* @brief Flash read 8 bits. +* @param Address: address to write. +* @retval Data read +*/ +uint8_t FLASH_ReadByte(uint32_t Address) +{ + assert_param(IS_FLASH_ADDRESS(Address)); + + return (*((volatile uint8_t*)(Address))); +} + +/** +* @brief Flash write 32 bits. +* @param Address: address to write +* @param Data: word to write +* @retval None +*/ +void FLASH_ProgramWord(uint32_t Address, uint32_t Data) +{ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* Lock word to avoid undesired FLASH operation */ + if (flash_sw_lock != FLASH_UNLOCK_WORD) + return; + + /* Clear IRQ */ + FLASH->IRQSTAT = 0x3F; + + /* Write the page address */ + FLASH->ADDRESS = Address>>2; + + /* Write the data to program */ + FLASH->DATA0 = Data; + + /* Write the WRITE command */ + FLASH->COMMAND = FLASH_WRITE; + + FLASH_WaitCmdDone(); + + /* Verify */ + // return ; +} + +/** +* @brief Flash write 32 bits. +* @param Address: address to write +* @param Data: pointer to an array of 4 words to write +* @retval None +*/ +void FLASH_ProgramWordBurst(uint32_t Address, uint32_t* Data) +{ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* Lock word to avoid undesired FLASH operation */ + if (flash_sw_lock != FLASH_UNLOCK_WORD) + return; + + /* Clear IRQ */ + FLASH->IRQSTAT = 0x3F; + + /* Write the page address */ + FLASH->ADDRESS = Address>>2; + + /* Write the data to program */ + FLASH->DATA0 = Data[0]; + FLASH->DATA1 = Data[1]; + FLASH->DATA2 = Data[2]; + FLASH->DATA3 = Data[3]; + + /* Write the BURSTWRITE command */ + FLASH->COMMAND = FLASH_BURSTWRITE; + + FLASH_WaitCmdDone(); + + /* Verify */ + // return ; +} + +/** +* @brief Flash Lock +* @param None +* @retval None +*/ +void FLASH_Lock(void) +{ + flash_sw_lock = FLASH_LOCK_WORD; +} + +/** +* @brief Flash Unlock +* @param None +* @retval None +*/ +void FLASH_Unlock(void) +{ + flash_sw_lock = FLASH_UNLOCK_WORD; +} + +/** +* @brief Wait loop for CMDDONE status +* @param None +* @retval None +*/ +void FLASH_WaitCmdDone(void) +{ + /* Waits for Command Done */ + while(FLASH->IRQRAW_b.CMDDONE != SET); +} + + +/** +* @brief Clear CMDDONE flag +* @param None +* @retval None +*/ +void FLASH_ClearCmdDone(void) +{ + /* Clear the CMDDONE flag */ + SET_BIT(FLASH->IRQSTAT, Flash_CMDDONE); +} + + + +/** +* @brief Enables or disables the specified flash interrupts. +* @param FlashFlag: the value can be +* @arg Flash_CMDDONE Flash command done +* @arg Flash_CMDSTART Flash command start +* @arg Flash_CMDERR Flash command error +* @arg Flash_ILLCMD Flash illegal command written +* @arg Flash_READOK Flash mass read was OK +* @arg Flash_FLNREADY Flash not ready (sleep) +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void FLASH_ITConfig(uint8_t FlashFlag, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FLASH_FLAG(FlashFlag)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) { + SET_BIT(FLASH->IRQMASK, FlashFlag); + } + else if (NewState == DISABLE) { + CLEAR_BIT(FLASH->IRQMASK, FlashFlag); + } +} + + +/** +* @brief Clears the specific flash pending IT bit. +* @param FlashFlag: the FLASH flag to clear, this can be +* @arg Flash_CMDDONE Flash command done +* @arg Flash_CMDSTART Flash command start +* @arg Flash_CMDERR Flash command error +* @arg Flash_ILLCMD Flash illegal command written +* @arg Flash_READOK Flash mass read was OK +* @arg Flash_FLNREADY Flash not ready (sleep) +* @retval None +*/ +void FLASH_ClearITPendingBit(uint8_t FlashFlag) +{ + assert_param(IS_FLASH_FLAG(FlashFlag)) ; + + /* Clear the flags */ + FLASH->IRQSTAT = FlashFlag; +} + + +/** +* @brief Checks whether the specified FLASH raw flag is set or not. +* @param FlashFlag: the FLASH flag to check, this can be +* @arg Flash_CMDDONE Flash command done +* @arg Flash_CMDSTART Flash command start +* @arg Flash_CMDERR Flash command error +* @arg Flash_ILLCMD Flash illegal command written +* @arg Flash_READOK Flash mass read was OK +* @arg Flash_FLNREADY Flash not ready (sleep) +* @retval FlagStatus: functional state @ref FlagStatus +* This parameter can be: SET or RESET. +*/ +FlagStatus FLASH_GetFlagStatus(uint8_t FlashFlag) +{ + /* Check the parameters */ + assert_param(IS_FLASH_FLAG(FlashFlag)); + + if((FLASH->IRQRAW & FlashFlag) != (uint16_t)RESET) { + return SET; + } + else { + return RESET; + } +} + +/** +* @brief Clears the specific flash pending flags. +* @param FlashFlag: the FLASH flag to clear, this can be +* @arg Flash_CMDDONE Flash command done +* @arg Flash_CMDSTART Flash command start +* @arg Flash_CMDERR Flash command error +* @arg Flash_ILLCMD Flash illegal command written +* @arg Flash_READOK Flash mass read was OK +* @arg Flash_FLNREADY Flash not ready (sleep) +* @retval None +*/ +void FLASH_ClearFlag(uint8_t FlashFlag) +{ + assert_param(IS_FLASH_FLAG(FlashFlag)) ; + + /* Clear the flags */ + FLASH->IRQSTAT = FlashFlag; +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_gpio.c b/drivers/src/BlueNRG1_gpio.c new file mode 100644 index 0000000..91494c1 --- /dev/null +++ b/drivers/src/BlueNRG1_gpio.c @@ -0,0 +1,547 @@ +/** +****************************************************************************** +* @file BlueNRG1_gpio.c +* @author VMA Application Team +* @version V2.2.0 +* @date 31-January-2017 +* @brief This file provides all the GPIO firmware functions. +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2016 STMicroelectronics

+****************************************************************************** +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_gpio.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver +* @{ +*/ + +/** @addtogroup GPIO_Peripheral GPIO Peripheral +* @{ +*/ + +/** @defgroup GPIO_Private_TypesDefinitions Private Type Definitions +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup GPIO_Private_Defines Private Defines +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup GPIO_Private_Macros Private Macros +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup GPIO_Private_Variables Private Variables +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup GPIO_Private_FunctionPrototypes Private Function Prototypes +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup GPIO_Private_Functions Private Functions +* @{ +*/ + + + +/** +* @} +*/ + +/** @defgroup GPIO_Public_Functions Public Functions +* @{ +*/ + +/** +* @brief Deinitializes the GPIO peripheral registers to their default reset values. +* @param None +* @retval None +*/ +void GPIO_DeInit(void) +{ + /* Set all GPIO registers to default/reset configuration */ + GPIO->OEN = 0x00000000; + GPIO->PE = 0x03FFFFFF; + GPIO->DS = 0x00000000; + GPIO->IS = 0x00000000; + GPIO->IBE = 0x00000000; + GPIO->IEV = 0x00000000; + GPIO->IE = 0x00000000; + GPIO->IC = 0xFFFFFFFF; + GPIO->MODE0 = 0x00000000; + GPIO->MODE1 = 0x00000110; + GPIO->MFTX = 0x00000000; +} + + +/** +* @brief Initializes the GPIO peripheral according to the specified +* parameters in the GPIO_InitStruct. +* @param GPIO_InitStruct: pointer to a @ref GPIO_InitType structure that +* contains the configuration information for the specified GPIO peripheral. +* @retval None +*/ +void GPIO_Init(GPIO_InitType* GPIO_InitStruct) +{ + uint8_t tmp; + uint8_t gpio_mode = 0; + + /* Check the parameters */ + assert_param(IS_GPIO_PINS(GPIO_InitStruct->GPIO_Pin)); + assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); + assert_param(IS_FUNCTIONAL_STATE(GPIO_InitStruct->GPIO_Pull)); + assert_param(IS_FUNCTIONAL_STATE(GPIO_InitStruct->GPIO_HighPwr)); + + /* IO12 and IO13 cannot be programmed in output mode */ + assert_param( ((GPIO_InitStruct->GPIO_Pin & GPIO_Pin_12) != GPIO_Pin_12) || (GPIO_InitStruct->GPIO_Mode != GPIO_Output)); + assert_param( ((GPIO_InitStruct->GPIO_Pin & GPIO_Pin_13) != GPIO_Pin_13) || (GPIO_InitStruct->GPIO_Mode != GPIO_Output)); + + gpio_mode = GPIO_InitStruct->GPIO_Mode; + + /* Configure the IO mode */ + if(GPIO_InitStruct->GPIO_Mode == GPIO_Input) { + CLEAR_BIT(GPIO->OEN, GPIO_InitStruct->GPIO_Pin); + } + else if(GPIO_InitStruct->GPIO_Mode == GPIO_Output) { + gpio_mode = GPIO_Input; + SET_BIT(GPIO->OEN, GPIO_InitStruct->GPIO_Pin); + } + + for(uint8_t i = 0; i < GPIO_PIN_COUNT; i++) { + tmp = (uint8_t)((GPIO_InitStruct->GPIO_Pin>>i) & 0x01); + if(tmp!=0) { + + if(i < 8) { + MODIFY_REG(GPIO->MODE0, (0xF<<(i*4)), (gpio_mode << (i*4)) ); + } + else if((i > 7) && (i < 16)) { + MODIFY_REG(GPIO->MODE1, (0xF<<((i-8)*4)), (gpio_mode << ((i-8)*4)) ); + } +#ifdef BLUENRG2_DEVICE + else if((i > 15) && (i < 24)) { + MODIFY_REG(GPIO->MODE2, (0xF<<((i-16)*4)), (gpio_mode << ((i-16)*4)) ); + } + else if(i > 23) { + MODIFY_REG(GPIO->MODE3, (0xF<<((i-24)*4)), (gpio_mode << ((i-24)*4)) ); + } +#endif + } + } + + /* Set the current mode */ + if(GPIO_InitStruct->GPIO_HighPwr == ENABLE) { + SET_BIT(GPIO->DS, GPIO_InitStruct->GPIO_Pin); + } + else { + CLEAR_BIT(GPIO->DS, GPIO_InitStruct->GPIO_Pin); + } + + /* Set the pull on IO */ + if(GPIO_InitStruct->GPIO_Pull == ENABLE) { + SET_BIT(GPIO->PE, GPIO_InitStruct->GPIO_Pin); + } + else { + CLEAR_BIT(GPIO->PE, GPIO_InitStruct->GPIO_Pin); + } + +} + +/** +* @brief Fills the GPIO_InitStruct member with its default value. +* @param GPIO_InitStruct : pointer to a @ref GPIO_InitType structure which will +* be initialized. +* @retval None +*/ +void GPIO_StructInit(GPIO_InitType* GPIO_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_InitStruct->GPIO_Pin = 0x00000000; + GPIO_InitStruct->GPIO_Mode = GPIO_Input; + GPIO_InitStruct->GPIO_Pull = DISABLE; + GPIO_InitStruct->GPIO_HighPwr = DISABLE; +} + + +/** +* @brief Initializes the GPIO9, GPIO10 and GPIO11 according to the specified +* parameters in the GPIO_InitStruct. This setting is applied during low power modes. +* This feature is applicable only for BlueNRG-2. +* @param GPIO_InitStruct: pointer to a @ref GPIO_InitType structure that +* contains the configuration information for the specified GPIO peripheral. +* @retval None +*/ +void GPIO_InitLowPowerModes(GPIO_InitType* GPIO_InitStruct) +{ +#ifdef BLUENRG2_DEVICE + + /* Check the parameters */ + assert_param(IS_GPIO_PINS(GPIO_InitStruct->GPIO_Pin)); + assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); + assert_param(IS_FUNCTIONAL_STATE(GPIO_InitStruct->GPIO_Pull)); + assert_param(IS_FUNCTIONAL_STATE(GPIO_InitStruct->GPIO_HighPwr)); + + if((GPIO_InitStruct->GPIO_Pin&GPIO_Pin_9) == GPIO_Pin_9 || + (GPIO_InitStruct->GPIO_Pin&GPIO_Pin_10) == GPIO_Pin_10 || + (GPIO_InitStruct->GPIO_Pin&GPIO_Pin_11) == GPIO_Pin_11) { + + /* Configure the IO mode */ + if(GPIO_InitStruct->GPIO_Mode == GPIO_Input) { + SET_BIT(SYSTEM_CTRL->SLEEPIO_OEN, (GPIO_InitStruct->GPIO_Pin>>9)); + } + else if(GPIO_InitStruct->GPIO_Mode == GPIO_Output) { + CLEAR_BIT(SYSTEM_CTRL->SLEEPIO_OEN, (GPIO_InitStruct->GPIO_Pin>>9)); + } + + /* Set the current mode */ + if(GPIO_InitStruct->GPIO_HighPwr == ENABLE) { + SET_BIT(SYSTEM_CTRL->SLEEPIO_DS, (GPIO_InitStruct->GPIO_Pin>>9)); + } + else { + CLEAR_BIT(SYSTEM_CTRL->SLEEPIO_DS, (GPIO_InitStruct->GPIO_Pin>>9)); + } + + /* Set the pull on IO */ + if(GPIO_InitStruct->GPIO_Pull == ENABLE) { + SET_BIT(SYSTEM_CTRL->SLEEPIO_PE, (GPIO_InitStruct->GPIO_Pin>>9)); + } + else { + CLEAR_BIT(SYSTEM_CTRL->SLEEPIO_PE, (GPIO_InitStruct->GPIO_Pin>>9)); + } + } +#endif +} + + +/** +* @brief Set the output state of the GIO9, GIO10, GIO11 during low power modes. +* Only for BlueNRG-2 device. +* @param GPIO_Pin: specifies the GPIO pin pins to be retained +* This parameter can be GPIO_Pin_x where x can be (9, 10, 11) @ref GPIO_Pins_Definition. +* @retval None +*/ +void GPIO_WriteBitsLowPowerModes(uint32_t GPIO_Pins, BitAction BitVal) +{ +#ifdef BLUENRG2_DEVICE + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pins)); + assert_param(IS_GPIO_BIT_ACTION(BitVal)); + + /* Reset GPIO init structure parameters values */ + if((GPIO_Pins&GPIO_Pin_9) == GPIO_Pin_9 || + (GPIO_Pins&GPIO_Pin_10) == GPIO_Pin_10 || + (GPIO_Pins&GPIO_Pin_11) == GPIO_Pin_11) { + if (BitVal == Bit_SET) { + SET_BIT(SYSTEM_CTRL->SLEEPIO_OUT, (GPIO_Pins>>9)); + } + else { + CLEAR_BIT(SYSTEM_CTRL->SLEEPIO_OUT, (GPIO_Pins>>9)); + } + } +#endif +} + + +/** +* @brief Toggles data to the specified IO pin. +* @param GPIO_Pin: specifies the IO bits to be toggled. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* More than one pin can be specified in OR logic, i.e. (GPIO_Pin_0 | GPIO_Pin_1). +* @retval None +*/ +void GPIO_ToggleBitsLowPowerModes(uint32_t GPIO_Pins) +{ +#ifdef BLUENRG2_DEVICE + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pins)); + + /* Reset GPIO init structure parameters values */ + if((GPIO_Pins&GPIO_Pin_9) == GPIO_Pin_9 || + (GPIO_Pins&GPIO_Pin_10) == GPIO_Pin_10 || + (GPIO_Pins&GPIO_Pin_11) == GPIO_Pin_11) { + SYSTEM_CTRL->SLEEPIO_OUT ^= (GPIO_Pins>>9); + } +#endif +} + + +/** +* @brief Reads the specified input pin value. +* @param GPIO_Pin: specifies the GPIO pin bits to read. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* @retval The input pin value @ref BitAction. +*/ +BitAction GPIO_ReadBit(uint32_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if(READ_BIT(GPIO->DATA, GPIO_Pin)) { + return Bit_SET; + } + else { + return Bit_RESET; + } +} + + +/** +* @brief Sets the selected IO pin bit. +* @param GPIO_Pin: specifies the pins to be written. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* More than one pin can be specified in OR logic, i.e. (GPIO_Pin_0 | GPIO_Pin_1). +* @retval None +*/ +void GPIO_SetBits(uint32_t GPIO_Pins) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PINS(GPIO_Pins)); + + WRITE_REG(GPIO->DATS, GPIO_Pins); +} + +/** +* @brief Clears the selected IO pin bits. +* @param GPIO_Pin: specifies the pins to be written. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* More than one pin can be specified in OR logic, i.e. (GPIO_Pin_0 | GPIO_Pin_1). +* @retval None +*/ +void GPIO_ResetBits(uint32_t GPIO_Pins) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PINS(GPIO_Pins)); + + WRITE_REG(GPIO->DATC, GPIO_Pins); +} + +/** +* @brief Sets or clears the selected IO pin bit. +* @param GPIO_Pin: specifies the IO bits to be written. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* More than one pin can be specified in OR logic, i.e. (GPIO_Pin_0 | GPIO_Pin_1). +* @param BitVal: specifies the value to be written to the selected bit. +* This parameter can be any value of @ref BitAction. +* @retval None +*/ +void GPIO_WriteBit(uint32_t GPIO_Pins, BitAction BitVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PINS(GPIO_Pins)); + assert_param(IS_GPIO_BIT_ACTION(BitVal)); + + if (BitVal == Bit_SET) { + WRITE_REG(GPIO->DATS, GPIO_Pins); + } + else { + WRITE_REG(GPIO->DATC, GPIO_Pins); + } +} + +/** +* @brief Toggles data to the specified IO pin. +* @param GPIO_Pin: specifies the IO bits to be toggled. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* More than one pin can be specified in OR logic, i.e. (GPIO_Pin_0 | GPIO_Pin_1). +* @retval None +*/ +void GPIO_ToggleBits(uint32_t GPIO_Pins) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PINS(GPIO_Pins)); + + GPIO->DATA ^= GPIO_Pins; +} + +/** +* @brief Fills each GPIO_EXTIStruct member with its default value. +* @param GPIO_EXTIInitStruct : pointer to a @ref GPIO_EXTIConfigType structure. +* @retval None +*/ +void GPIO_EXTIStructInit(GPIO_EXTIConfigType* GPIO_EXTIInitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_EXTIInitStruct->GPIO_Pin = 0x00000000; + GPIO_EXTIInitStruct->GPIO_IrqSense = GPIO_IrqSense_Edge; + GPIO_EXTIInitStruct->GPIO_Event = GPIO_Event_Low; +} + + +/** +* @brief Selects the GPIO pins used as EXTI Line. +* @param EXTIConfig: pointer to a @ref GPIO_EXTIConfigType structure that +* contains the configuration information for the specified GPIO pins. +* @retval None +*/ +void GPIO_EXTIConfig(GPIO_EXTIConfigType* EXTIConfig) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PINS(EXTIConfig->GPIO_Pin)); + assert_param(IS_GPIO_IRQSENSE(EXTIConfig->GPIO_IrqSense)); + assert_param(IS_GPIO_EVENT(EXTIConfig->GPIO_Event)); + + /* Interrupt sense configuration */ + if (EXTIConfig->GPIO_IrqSense == GPIO_IrqSense_Level) { + /* Configure level detection */ + SET_BIT(GPIO->IS, EXTIConfig->GPIO_Pin); + } + else { + /* Configure edge detection */ + CLEAR_BIT(GPIO->IS, EXTIConfig->GPIO_Pin); + } + + /* Configure event */ + if (EXTIConfig->GPIO_Event == GPIO_Event_High) { + /* Configure interrupt on high level or rising edge event */ + SET_BIT(GPIO->IEV, EXTIConfig->GPIO_Pin); + CLEAR_BIT(GPIO->IBE, EXTIConfig->GPIO_Pin); + } + else if (EXTIConfig->GPIO_Event == GPIO_Event_Low) { + /* Configure interrupt on low level or falling edge event */ + CLEAR_BIT(GPIO->IEV, EXTIConfig->GPIO_Pin); + CLEAR_BIT(GPIO->IBE, EXTIConfig->GPIO_Pin); + } + else { + /* Configure interrupt on both edge */ + SET_BIT(GPIO->IBE, EXTIConfig->GPIO_Pin); + } + +} + +/** +* @brief Enables or disables interrupts on specified pins. +* @param GPIO_Pin: specifies the IO pins as an interrupt source. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* More than one pin can be specified in OR logic, i.e. (GPIO_Pin_0 | GPIO_Pin_1). +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void GPIO_EXTICmd(uint32_t GPIO_Pins, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PINS(GPIO_Pins)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + SET_BIT(GPIO->IE, GPIO_Pins); + } + else { + CLEAR_BIT(GPIO->IE, GPIO_Pins); + } +} + +/** +* @brief Clears the GPIO interrupt pending bits. +* @param GPIO_Pin: specifies the GPIO interrupt pending bit to clear. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* More than one pin can be specified in OR logic, i.e. (GPIO_Pin_0 | GPIO_Pin_1). +* @retval None +*/ +void GPIO_ClearITPendingBit(uint32_t GPIO_Pins) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PINS(GPIO_Pins)); + + WRITE_REG(GPIO->IC, GPIO_Pins); +} + + +/** +* @brief Checks whether the specified enabled GPIO interrupt is active. +* @param GPIO_Pin: Specifies the GPIO interrupt to check. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* @param FlagStatus: functional state @ref FlagStatus +* This parameter can be: SET or RESET. +*/ +FlagStatus GPIO_GetITPendingBit(uint32_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if(READ_BIT(GPIO->MIS, GPIO_Pin) != (uint32_t)RESET) { + return SET; + } + else { + return RESET; + } +} + + +/** +* @brief Checks whether the specified GPIO interrupt is active. +* @param GPIO_Pin: Specifies the GPIO interrupt to check. +* This parameter can be GPIO_Pin_x where x can be (0..25) @ref GPIO_Pins_Definition. +* QFN32 package: 15 pins, WLCSP32 package: 14 pins, QFN48 package: 26 pins. +* @param FlagStatus: functional state @ref FlagStatus +* This parameter can be: SET or RESET. +*/ +ITStatus GPIO_GetITStatusBit(uint32_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if(READ_BIT(GPIO->RIS, GPIO_Pin) != (uint32_t)RESET) { + return SET; + } + else { + return RESET; + } +} +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_i2c.c b/drivers/src/BlueNRG1_i2c.c new file mode 100644 index 0000000..9948eae --- /dev/null +++ b/drivers/src/BlueNRG1_i2c.c @@ -0,0 +1,742 @@ +/** + ****************************************************************************** + * @file BlueNRG1_i2c.c + * @author VMA Application Team + * @version V2.1.0 + * @date 21-March-2016 + * @brief This file provides all the I2C firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_i2c.h" + + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup I2C_Peripheral I2C Peripheral + * @{ + */ + +/** @defgroup I2C_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup I2C_Private_Defines Private Defines + * @{ + */ + +/* I2C Standard mode */ +#define I2C_CR_SM_STD (0x0) + +/* I2C Fast mode */ +#define I2C_CR_SM_FAST (0x1) + +#define I2C_CLOCK (16000000) + +#define I2C_SLAVE_ADDR_EXT10_SMK (0x03FF) + + +/** + * @} + */ + +/** @defgroup I2C_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup I2C_Private_Variables Private Variables + * @{ + */ +static __I uint16_t Foncycles[4] = {1, 3, 4, 6}; + +/** + * @} + */ + +/** @defgroup I2C_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup I2C_Public_Functions Public Functions + * @{ + */ + + +/** +* @brief Deinitializes the I2C peripheral registers to their default reset values. +* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type +* @retval None +*/ +void I2C_DeInit(I2C_Type* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Generate a stop condition */ + I2Cx->CR_b.FS_1 = SET; + + /* Disable the selected I2C peripheral / software reset */ + I2Cx->CR_b.PE = RESET; +} + + +/** + * @brief Initializes the I2Cx peripheral according to the specified + * parameters in the I2C_InitStruct. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_InitStruct: pointer to a @ref I2C_InitType structure that + * contains the configuration information for the specified I2C peripheral. +* @retval None + */ +void I2C_Init(I2C_Type* I2Cx, I2C_InitType* I2C_InitStruct) +{ + uint16_t foncycle; + uint32_t brcnt; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLOCK_SPEED_I2C(I2C_InitStruct->I2C_ClockSpeed)); + assert_param(IS_I2C_OPERATING_MODE(I2C_InitStruct->I2C_OperatingMode)); + assert_param(IS_I2C_FILTERING(I2C_InitStruct->I2C_Filtering)); + assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); + assert_param(IS_FUNCTIONAL_STATE(I2C_InitStruct->I2C_ExtendAddress)); + + /* Disable the selected I2C peripheral / software reset */ + I2Cx->CR_b.PE = RESET; + + /* Select the digital filtering */ + I2Cx->CR_b.FON = I2C_InitStruct->I2C_Filtering; + + /* Clock rate computation */ + foncycle = Foncycles[I2C_InitStruct->I2C_Filtering]; + brcnt = I2C_CLOCK - I2C_InitStruct->I2C_ClockSpeed * foncycle; + + /* Configure speed in standard mode */ + if (I2C_InitStruct->I2C_ClockSpeed <= 100000) + { + brcnt /= (I2C_InitStruct->I2C_ClockSpeed << 1); + + I2Cx->CR_b.SM = I2C_CR_SM_STD; + + /* @16MHz 0x0003=>250ns */ + I2Cx->SCR_b.SLSU = 0x003; + } + /* Configure speed in fast mode */ + else if (I2C_InitStruct->I2C_ClockSpeed <= 400000) + { + brcnt /= (I2C_InitStruct->I2C_ClockSpeed * 3); + + I2Cx->CR_b.SM = I2C_CR_SM_FAST; + + /* @16MHz 0x0002=>125ns */ + I2Cx->SCR_b.SLSU = 0x0002; + } + + /* Set I2C own address */ + MODIFY_REG(I2Cx->SCR, I2C_SLAVE_ADDR_EXT10_SMK, I2C_InitStruct->I2C_OwnAddress1); + + /* Configure the baud rate */ + I2Cx->BRCR_b.BRCNT = (uint16_t)brcnt; + + /* Configure the operating mode */ + I2Cx->CR_b.OM = I2C_InitStruct->I2C_OperatingMode; + + if(I2C_InitStruct->I2C_ExtendAddress == ENABLE) { + I2Cx->CR_b.SAM = SET; + } + else { + I2Cx->CR_b.SAM = RESET; + } + + /* Enable the selected I2C peripheral */ + I2Cx->CR_b.PE = SET; +} + + +/** + * @brief Fills the I2C_InitStruct with default values. + * @param I2C_InitStruct: pointer to an @ref I2C_InitType structure which will be initialized. + * @retval None + */ +void I2C_StructInit(I2C_InitType* I2C_InitStruct) +{ + /*---------------- Reset I2C init structure parameters values ----------------*/ + /* initialize the I2C_ClockSpeed member */ + I2C_InitStruct->I2C_ClockSpeed = 5000; + + /* initialize the I2C_OperatingMode member */ + I2C_InitStruct->I2C_OperatingMode = I2C_OperatingMode_Slave; + + /* initialize the I2C_Filtering member */ + I2C_InitStruct->I2C_Filtering = I2C_Filtering_Off; + + /* Initialize the I2C_OwnAddress1 member */ + I2C_InitStruct->I2C_OwnAddress1 = 0; + + /* Initialize the I2C_AddressingMode member */ + I2C_InitStruct->I2C_ExtendAddress = DISABLE; +} + +/** + * @brief Enables or disables the specified I2C peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_Cmd(I2C_Type* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the selected I2C peripheral */ + I2Cx->CR_b.PE = SET; + } + else { + /* Disable the selected I2C peripheral */ + I2Cx->CR_b.PE = RESET; + } +} + + +/** + * @brief Start an I2C transaction sending the frame specified. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param tr: pointer to an @ref I2C_TransactionType structure used + * for this transaction. + * @retval None. + */ +void I2C_BeginTransaction(I2C_Type* I2Cx, I2C_TransactionType* tr) +{ + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_OPERATION(tr->Operation)); + assert_param(IS_I2C_STARTBYTE(tr->StartByte)); + assert_param(IS_I2C_ADDRESSTYPE(tr->AddressType)); + assert_param(IS_I2C_OWN_ADDRESS1(tr->Address)); + assert_param(IS_I2C_STOPCONDITION(tr->StopCondition)); + assert_param(IS_I2C_LENGTH(tr->Length)); + + I2Cx->MCR = ((uint32_t)(tr->Operation)) | (((uint32_t)(tr->Address)) << 1) | + ((uint32_t)(tr->StartByte)) | ((uint32_t)(tr->AddressType)) | + ((uint32_t)(tr->StopCondition)) | (((uint32_t)(tr->Length)) << 15); + +} + + +/** + * @brief Enables or disables the general call feature. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GeneralCallCmd(I2C_Type* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) { + /* Enable generall call */ + I2Cx->CR_b.SGCM = SET; + } + else { + /* Disable generall call */ + I2Cx->CR_b.SGCM = RESET; + } +} + +/** + * @brief Enables or disables the specified I2C interrupts. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg I2C_IT_TXFE: Tx FIFO empty + * @arg I2C_IT_TXFNE: TX FIFO nearly empty + * @arg I2C_IT_TXFF: Tx FIFO full + * @arg I2C_IT_TXFOVR: Tx FIFO overflow + * @arg I2C_IT_RXFE: Rx FIFO empty + * @arg I2C_IT_RXFNF: Rx FIFO nearly full + * @arg I2C_IT_RXFF: Rx FIFO full + * @arg I2C_IT_LBR: Length number of bytes received + * @arg I2C_IT_RFSR: Read from slave request + * @arg I2C_IT_RFSE: Read from slave empty + * @arg I2C_IT_WTSR: Write to slave request + * @arg I2C_IT_MTD: Master transaction done + * @arg I2C_IT_STD: Slave transaction done + * @arg I2C_IT_SAL: Slave arbitration lost + * @arg I2C_IT_MAL: Master arbitration lost + * @arg I2C_IT_BERR: Bus error + * @arg I2C_IT_MTDWS: Master transaction done without stop + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ITConfig(I2C_Type* I2Cx, uint32_t I2C_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2C_IT(I2C_IT)); + + if (NewState != DISABLE) { + /* Enable the selected I2C interrupts */ + SET_BIT(I2Cx->IMSCR, I2C_IT); + } + else { + /* Disable the selected I2C interrupts */ + CLEAR_BIT(I2Cx->IMSCR, I2C_IT); + } +} + +/** + * @brief Fills the Tx FIFO with the specified data byte. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param Data: Byte to be transmitted. + * @retval None + */ +void I2C_FillTxFIFO(I2C_Type* I2Cx, uint8_t Data) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Write in the DR register the data to be sent */ + I2Cx->TFR = (uint32_t)Data; +} + +/** + * @brief Returns the most recent received data by the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @retval uint8_t The value of the received data. + */ +uint8_t I2C_ReceiveData(I2C_Type* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Return the data in the DR register */ + return I2Cx->RFR_b.RDATA; +} + + +/** + * @brief Returns the most recent received data by the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @retval None + */ +void I2C_FlushTx(I2C_Type* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Set flush tx flag */ + I2Cx->CR_b.FTX = SET; +} + + +/** + * @brief Return the status of the TX FIFO flush operation. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @retval I2C_OpStatus operation status @ref I2C_OpStatus + */ +I2C_OpStatus I2C_WaitFlushTx(I2C_Type* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Wait the flush of TX FIFO is completed */ + if(I2Cx->CR_b.FTX == SET) { + return I2C_OP_ONGOING; + } + else { + return I2C_OP_OK; + } +} + + +/** + * @brief Returns the most recent received data by the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @retval None + */ +void I2C_FlushRx(I2C_Type* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Set flush rx flag */ + I2Cx->CR_b.FRX = SET; +} + + +/** + * @brief Return the status of the RX FIFO flush operation. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @retval I2C_OpStatus operation status @ref I2C_OpStatus + */ +I2C_OpStatus I2C_WaitFlushRx(I2C_Type* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Wait the flush of TX FIFO is completed */ + if(I2Cx->CR_b.FRX == SET) { + return I2C_OP_ONGOING; + } + else { + return I2C_OP_OK; + } +} + +/** + * @brief Sets the transmit FIFO threshold by the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param TxThres: The value of the threshold 2-byte. + * @retval None + */ +void I2C_SetTxThreshold(I2C_Type* I2Cx, uint16_t TxThres) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_TX_THRESHOLD(TxThres)); + + /* Set the Tx FIFO Threshold */ + I2Cx->TFTR_b.THRESH_TX = TxThres; +} + +/** + * @brief Sets the receive FIFO threshold by the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param RxThres: The value of the threshold 2-byte. + */ +void I2C_SetRxThreshold(I2C_Type* I2Cx, uint16_t RxThres) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_RX_THRESHOLD(RxThres)); + + /* Set the Rx FIFO Threshold */ + I2Cx->RFTR_b.THRESH_RX = RxThres; +} + + +/** + * @brief Generate a stop condition. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @retval None + */ +void I2C_GenerateStopCondition(I2C_Type* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Generate a stop condition */ + I2Cx->CR_b.FS_1 = SET; +} + +/** + * @brief Set the hold time value for data transfer. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_HoldTime: specifies the hold time value. + * @retval None + */ +void I2C_SetHoldTime(I2C_Type* I2Cx, uint16_t I2C_HoldTime) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_HOLDTIME(I2C_HoldTime)); + + I2Cx->THDDAT = I2C_HoldTime; +} + +/** + * @brief Set the hold time value for start condition. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_HoldTime: specifies the hold time value. + * @retval None + */ +void I2C_SetHoldTimeStartCondition(I2C_Type* I2Cx, uint16_t I2C_HoldTime) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_HOLDTIME(I2C_HoldTime)); + + /* Standard mode */ + if(I2Cx->CR_b.SM == I2C_CR_SM_STD) { + I2Cx->THDSTA_FST_STD_b.THDSTA_STD = I2C_HoldTime; + } + else if(I2Cx->CR_b.SM == I2C_CR_SM_FAST) { + I2Cx->THDSTA_FST_STD_b.THDSTA_FST = I2C_HoldTime; + } +} + +/** + * @brief Set the setup time value for start condition. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_SetupTime: specifies the setup time value. + * @retval None + */ +void I2C_SetSetupTimeStartCondition(I2C_Type* I2Cx, uint16_t I2C_SetupTime) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_SETUPTIME(I2C_SetupTime)); + + /* Standard mode */ + if(I2Cx->CR_b.SM == I2C_CR_SM_STD) { + I2Cx->TSUSTA_FST_STD_b.TSUSTA_STD = I2C_SetupTime; + } + else if(I2Cx->CR_b.SM == I2C_CR_SM_FAST) { + I2Cx->TSUSTA_FST_STD_b.TSUSTA_FST = I2C_SetupTime; + } +} + +/** + * @brief Checks whether the specified I2C interrupt has occurred or not. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_IT: specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_TXFE: Tx FIFO empty + * @arg I2C_IT_TXFNE: TX FIFO nearly empty + * @arg I2C_IT_TXFF: Tx FIFO full + * @arg I2C_IT_TXFOVR: Tx FIFO overflow + * @arg I2C_IT_RXFE: Rx FIFO empty + * @arg I2C_IT_RXFNF: Rx FIFO nearly full + * @arg I2C_IT_RXFF: Rx FIFO full + * @arg I2C_IT_LBR: Length number of bytes received + * @arg I2C_IT_RFSR: Read from slave request + * @arg I2C_IT_RFSE: Read from slave empty + * @arg I2C_IT_WTSR: Write to slave request + * @arg I2C_IT_MTD: Master transaction done + * @arg I2C_IT_STD: Slave transaction done + * @arg I2C_IT_SAL: Slave arbitration lost + * @arg I2C_IT_MAL: Master arbitration lost + * @arg I2C_IT_BERR: Bus error + * @arg I2C_IT_MTDWS: Master transaction done without stop + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error + * @retval ITStatus: functional state @ref ITStatus + * This parameter can be: SET or RESET. + */ +ITStatus I2C_GetITStatus(I2C_Type* I2Cx, uint32_t I2C_IT) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_IT(I2C_IT)); + + /* Check the status of the specified I2C flag */ + if (READ_BIT(I2Cx->RISR, I2C_IT) != (uint32_t)RESET) { + /* I2C_IT is set */ + return SET; + } + else { + /* I2C_IT is reset */ + return RESET; + } +} + +/** + * @brief Checks whether the specified I2C interrupt has occurred or not. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_IT: specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_TXFE: Tx FIFO empty + * @arg I2C_IT_TXFNE: TX FIFO nearly empty + * @arg I2C_IT_TXFF: Tx FIFO full + * @arg I2C_IT_TXFOVR: Tx FIFO overflow + * @arg I2C_IT_RXFE: Rx FIFO empty + * @arg I2C_IT_RXFNF: Rx FIFO nearly full + * @arg I2C_IT_RXFF: Rx FIFO full + * @arg I2C_IT_LBR: Length number of bytes received + * @arg I2C_IT_RFSR: Read from slave request + * @arg I2C_IT_RFSE: Read from slave empty + * @arg I2C_IT_WTSR: Write to slave request + * @arg I2C_IT_MTD: Master transaction done + * @arg I2C_IT_STD: Slave transaction done + * @arg I2C_IT_SAL: Slave arbitration lost + * @arg I2C_IT_MAL: Master arbitration lost + * @arg I2C_IT_BERR: Bus error + * @arg I2C_IT_MTDWS: Master transaction done without stop + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error + * @retval ITStatus: functional state @ref ITStatus + * This parameter can be: SET or RESET. + */ +ITStatus I2C_GetITPendingBit(I2C_Type* I2Cx, uint32_t I2C_IT) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_IT(I2C_IT)); + + /* Check the status of the specified I2C flag */ + if (READ_BIT(I2Cx->MISR, I2C_IT) != (uint32_t)RESET) { + /* I2C_IT is set */ + return SET; + } + else { + /* I2C_IT is reset */ + return RESET; + } +} + + +/** + * @brief Clears the I2Cx interrupt pending bits. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg I2C_IT_TXFE: Tx FIFO empty + * @arg I2C_IT_TXFNE: TX FIFO nearly empty + * @arg I2C_IT_TXFF: Tx FIFO full + * @arg I2C_IT_TXFOVR: Tx FIFO overflow + * @arg I2C_IT_RXFE: Rx FIFO empty + * @arg I2C_IT_RXFNF: Rx FIFO nearly full + * @arg I2C_IT_RXFF: Rx FIFO full + * @arg I2C_IT_LBR: Length number of bytes received + * @arg I2C_IT_RFSR: Read from slave request + * @arg I2C_IT_RFSE: Read from slave empty + * @arg I2C_IT_WTSR: Write to slave request + * @arg I2C_IT_MTD: Master transaction done + * @arg I2C_IT_STD: Slave transaction done + * @arg I2C_IT_SAL: Slave arbitration lost + * @arg I2C_IT_MAL: Master arbitration lost + * @arg I2C_IT_BERR: Bus error + * @arg I2C_IT_MTDWS: Master transaction done without stop + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error + * @retval None + */ +void I2C_ClearITPendingBit(I2C_Type* I2Cx, uint32_t I2C_IT) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_IT(I2C_IT)); + /* Clear the selected I2C flags */ + WRITE_REG(I2Cx->ICR, I2C_IT); +} + + +/** + * @brief Get the present state of the operation executed by I2C block. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @retval I2C_OpStatus: the I2C operation status @ref I2C_OpStatus + */ +I2C_OpStatus I2C_GetStatus(I2C_Type* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Read the OP status field of the status register */ + return (I2C_OpStatus)I2Cx->SR_b.STATUS; +} + + + +/** + * @brief Enables or disables the I2C DMA interface. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_DMAReq: specifies the DMA request. + * This parameter can be any combination of the following values: + * @arg I2C_DMAReq_Tx: I2C DMA transmit request + * @arg I2C_DMAReq_Rx: I2C DMA receive request. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMACmd(I2C_Type* I2Cx, uint16_t I2C_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DMAREQ(I2C_DMAReq)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA transfer */ + I2Cx->CR |= I2C_DMAReq; + } + else + { + /* Disable the DMA transfer */ + I2Cx->CR &= ~I2C_DMAReq; + } +} + +/** + * @brief Enables or disables the I2C TX DMA burst mode. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMATxBurstMode(I2C_Type* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TX DMA burst mode */ + I2Cx->DMAR_b.BURST_TX = SET; + } + else + { + /* Disable the TX DMA burst mode */ + I2Cx->DMAR_b.BURST_TX = RESET; + } +} + +/** + * @brief Set the number of burst of data. + * If this number is smaller than the transaction length, only one single request are generated. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral @ref I2C_Type + * @param I2C_BurstSize: specifies the number of burst request. + * @retval None + */ +void I2C_DMATxBurstSize(I2C_Type* I2Cx, uint8_t I2C_BurstSize) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_BURSTSIZE(I2C_BurstSize)); + + I2Cx->DMAR_b.DBSIZE_TX = I2C_BurstSize; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_mft.c b/drivers/src/BlueNRG1_mft.c new file mode 100644 index 0000000..3cf6fc7 --- /dev/null +++ b/drivers/src/BlueNRG1_mft.c @@ -0,0 +1,461 @@ +/** + ****************************************************************************** + * @file BlueNRG1_mft.c + * @author VMA Application Team + * @version V2.1.0 + * @date 16-Feb-2018 + * @brief This file provides all the MFT firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_mft.h" + + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + + +/** @defgroup MFT_Peripheral MFT Peripheral + * @{ + */ + +/** @defgroup MFT_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup MFT_Private_Defines Private Defines + * @{ + */ + +/** + * @} + */ + +/** @defgroup MFT_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup MFT_Private_Variables Private Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup MFT_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ + + /** + * @} + */ + +/** @defgroup MFT_Public_Functions Public Functions + * @{ + */ + +/** + *@brief DeInit the MFTx peripheral. + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@retval None + */ +void MFT_DeInit(MFT_Type* MFTx) +{ + MFTx->TNPRSC = 0x00000000; + MFTx->TNCKC = 0x00000000; + MFTx->TNMCTRL = 0x00000000; + MFTx->TNICLR = 0x0000000F; + +} + + +/** + *@brief Initializes the MFTx peripheral according to the specified + * parameters in the MFT_InitStruct. + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_InitStruct: pointer to a @ref MFT_InitType structure that + * contains the configuration information for the specified MFT peripheral. + *@retval None + */ +void MFT_Init(MFT_Type* MFTx, MFT_InitType* MFT_InitStruct) +{ + + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + assert_param(IS_MFT_MODE(MFT_InitStruct->MFT_Mode)); + assert_param(IS_MFT_CLOCK_SEL(MFT_InitStruct->MFT_Clock1)); + assert_param(IS_MFT_CLOCK_SEL(MFT_InitStruct->MFT_Clock2)); + + MFTx->TNMCTRL_b.TNAEN = RESET; + MFTx->TNMCTRL_b.TNBEN = RESET; + + MFTx->TNCKC_b.TNC1CSEL = MFT_NO_CLK; + MFTx->TNCKC_b.TNC2CSEL = MFT_NO_CLK; + + if(MFT_InitStruct->MFT_Mode == MFT_MODE_1a) { + MFTx->TNMCTRL_b.TNMDSEL = MFT_MODE_1; + MFTx->TNMCTRL_b.TNPTEN = SET; + } + else { + MFTx->TNMCTRL_b.TNMDSEL = MFT_InitStruct->MFT_Mode; + MFTx->TNMCTRL_b.TNPTEN = RESET; + } + + MFTx->TNPRSC = MFT_InitStruct->MFT_Prescaler; + MFTx->TNMCTRL_b.TNEN = SET; + MFTx->TNCRA = MFT_InitStruct->MFT_CRA; + MFTx->TNCRB = MFT_InitStruct->MFT_CRB; + MFTx->TNMCTRL_b.TNEN = RESET; + + MFTx->TNCKC_b.TNC1CSEL = MFT_InitStruct->MFT_Clock1; + MFTx->TNCKC_b.TNC2CSEL = MFT_InitStruct->MFT_Clock2; +} + +/** + * @brief Fills each MFT_InitStruct member with its default value. + * @param MFT_InitStruct : pointer to a @ref MFT_InitType structure which will + * be initialized. + * @retval None + */ +void MFT_StructInit(MFT_InitType* MFT_InitStruct) +{ + /* Reset MFT init structure parameters values */ + MFT_InitStruct->MFT_Clock1 = MFT_NO_CLK; + MFT_InitStruct->MFT_Clock2 = MFT_NO_CLK; + MFT_InitStruct->MFT_CRA = 0; + MFT_InitStruct->MFT_CRB = 0; + MFT_InitStruct->MFT_Mode = MFT_MODE_1; + MFT_InitStruct->MFT_Prescaler = 0; +} + +/** + *@brief Enable/Disable the MFT + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + *@retval None + */ +void MFT_Cmd(MFT_Type* MFTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) { + MFTx->TNMCTRL_b.TNEN = SET; + } + else { + MFTx->TNMCTRL_b.TNEN = RESET; + } +} + + +/** + *@brief Configure edges sensibility of TnA and TnB + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_TnA_edge : falling or rising edge + *@param MFT_TnB_edge : falling or rising edge, these values can be + * @arg MFT_FALLING on rising edge + * @arg MFT_RISING on falling edge + *@retval None + */ +void MFT_TnEDGES(MFT_Type* MFTx, uint32_t MFT_TnA_edge, uint32_t MFT_TnB_edge) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + assert_param(IS_MFT_Tn_EDGE(MFT_TnA_edge)); + assert_param(IS_MFT_Tn_EDGE(MFT_TnB_edge)); + + MFTx->TNMCTRL_b.TNAEDG = MFT_TnA_edge; + MFTx->TNMCTRL_b.TNBEDG = MFT_TnB_edge; +} + +/** + *@brief Select trigger source for pulse-train generation in Mode 1a + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_Trigger : software or TnB trigger, this value can be + * @arg MFT_TnB_TRIGGER trigger on TnB edge + * @arg MFT_SOFTWARE_TRIGGER trigger software + *@retval None + */ +void MFT_PulseTrainTriggerSelect(MFT_Type* MFTx, uint32_t MFT_Trigger) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + assert_param(IS_MFT_PULSETRAIN_TRIGGER(MFT_Trigger)); + + MFTx->TNMCTRL_b.TNPTSE = MFT_Trigger; +} + +/** + *@brief Pulse-train trigger generation in Mode 1a + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@retval None + */ +void MFT_PulseTrainSoftwareTrigger(MFT_Type* MFTx) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + + MFTx->TNMCTRL_b.TNPTET = SET; +} + +/** + *@brief Return the status of the Pulse-train event trigger in Mode 1a + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@retval If pule-train event trigger has occurred or not: + * Possible values are: + * RESET: No Pulse-Train Event Trigger occurred. + * SET: Pulse-Train Event Trigger occurred. Pulse-train generation not yet finished. + */ +uint8_t MFT_PulseTrainEventTriggerStatus(MFT_Type* MFTx) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + + return MFTx->TNMCTRL_b.TNPTET; +} + +/** + *@brief Set or Reset TnAEN bit + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param TnX : set or reset, @ref MFT_TnAEN + * @arg MFT_TnA select internal pin TnA + * @arg MFT_TnB select internal pin TnB + *@param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + *@retval None + */ +void MFT_TnXEN(MFT_Type* MFTx, uint8_t TnX, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + assert_param(IS_MFT_TnX(TnX)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(TnX == MFT_TnA) { + MFTx->TNMCTRL_b.TNAEN = NewState; + } + else if(TnX == MFT_TnB) { + MFTx->TNMCTRL_b.TNBEN = NewState; + } +} + + +/** + *@brief Set or Reset TnAEN bit + *@param MFT_TimerType : select the timer and the pin, this value can be + * @arg MFT1_TIMERA Select Timer MFT1 and input TnA + * @arg MFT1_TIMERB Select Timer MFT1 and input TnB + * @arg MFT2_TIMERA Select Timer MFT2 and input TnA + * @arg MFT2_TIMERB Select Timer MFT2 and input TnB + *@param MFT_Pin : the IO number from IO0 to IO14 (0, 1, .. 14) + *@retval None + */ +void MFT_SelectCapturePin( uint32_t MFT_TimerType, uint8_t MFT_Pin) +{ + /* Check the parameters */ + assert_param(IS_MFT_TIMER(MFT_TimerType)); + assert_param(IS_MFT_INPUT_IO(MFT_Pin)); + + /* set counter */ + if(MFT_TimerType == MFT1_TIMERA) { + GPIO->MFTX_b.MFT1_TIMER_A = MFT_Pin; + } + else if(MFT_TimerType == MFT1_TIMERB) { + GPIO->MFTX_b.MFT1_TIMER_B = MFT_Pin; + } + else if(MFT_TimerType == MFT2_TIMERA) { + GPIO->MFTX_b.MFT2_TIMER_A = MFT_Pin; + } + else if(MFT_TimerType == MFT2_TIMERB) { + GPIO->MFTX_b.MFT2_TIMER_B = MFT_Pin; + } + +} + + +/** + *@brief Set the timer counter. + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_Cnt1 : set the counter value for CNT1 + *@param MFT_Cnt2 : set the counter value for CNT2 + *@retval None + */ +void MFT_SetCounter(MFT_Type* MFTx, uint16_t MFT_Cnt1, uint16_t MFT_Cnt2) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + + /* Set counters */ + MFTx->TNCNT1 = MFT_Cnt1; + MFTx->TNCNT2 = MFT_Cnt2; +} + + +/** + *@brief Set the timer counter1. + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_Cnt : set the counter value for CNT1 + *@retval None + */ +void MFT_SetCounter1(MFT_Type* MFTx, uint16_t MFT_Cnt) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + + /* Set counter */ + MFTx->TNCNT1 = MFT_Cnt; +} + +/** + *@brief Get the timer counter1. + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param None + *@retval uint16_t the counter 1 value + */ +uint16_t MFT_GetCounter1(MFT_Type* MFTx) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + + /* Return counter */ + return MFTx->TNCNT1; +} + +/** + *@brief Set the timer counter2. + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_Cnt : set the counter value for CNT2 + *@retval None + */ +void MFT_SetCounter2(MFT_Type* MFTx, uint16_t MFT_Cnt) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + + /* set counter */ + MFTx->TNCNT2 = MFT_Cnt; +} + +/** + *@brief Get the timer counter2. + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param None + *@retval uint16_t the counter 2 value + */ +uint16_t MFT_GetCounter2(MFT_Type* MFTx) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + + /* Return counter */ + return MFTx->TNCNT2; +} + +/** + *@brief Enable specific MFT interrupt + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_IrqSource: interrupt source to enable, this value can be + * @arg MFT_IT_TNA Select the interrupt source A + * @arg MFT_IT_TNB Select the interrupt source B + * @arg MFT_IT_TNC Select the interrupt source C + * @arg MFT_IT_TND Select the interrupt source D + *@param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + *@retval None + */ +void MFT_EnableIT(MFT_Type* MFTx, uint8_t MFT_IrqSource, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + assert_param(IS_MFT_INTERRUPT(MFT_IrqSource)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) { + SET_BIT(MFTx->TNICTRL, (MFT_IrqSource << 4)); + } + else { + CLEAR_BIT(MFTx->TNICTRL, (MFT_IrqSource << 4)); + } +} + +/** + *@brief Clear specific MFT interrupt + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_IrqSource: interrupt source to enable, this value can be + * @arg MFT_IT_TNA Select the interrupt source A + * @arg MFT_IT_TNB Select the interrupt source B + * @arg MFT_IT_TNC Select the interrupt source C + * @arg MFT_IT_TND Select the interrupt source D + *@retval None + */ +void MFT_ClearIT(MFT_Type* MFTx, uint8_t MFT_IrqSource) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + assert_param(IS_MFT_INTERRUPT(MFT_IrqSource)); + + SET_BIT(MFTx->TNICLR, MFT_IrqSource); +} + +/** + *@brief Return interrupt status + *@param MFTx: where x can be 1 or 2 to select the MFT peripheral @ref MFT_Type + *@param MFT_IrqSource: interrupt source to enable, this value can be + * @arg MFT_IT_TNA Select the interrupt source A + * @arg MFT_IT_TNB Select the interrupt source B + * @arg MFT_IT_TNC Select the interrupt source C + * @arg MFT_IT_TND Select the interrupt source D + *@retval ITStatus: functional state @ref ITStatus + * This parameter can be: SET or RESET. + */ +ITStatus MFT_StatusIT(MFT_Type* MFTx, uint8_t MFT_IrqSource) +{ + /* Check the parameters */ + assert_param(IS_MFT(MFTx)); + assert_param(IS_MFT_INTERRUPT(MFT_IrqSource)); + + if((MFTx->TNICTRL & MFT_IrqSource) != (uint32_t)RESET) { + return SET; + } + else { + return RESET; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_pka.c b/drivers/src/BlueNRG1_pka.c new file mode 100644 index 0000000..92d6025 --- /dev/null +++ b/drivers/src/BlueNRG1_pka.c @@ -0,0 +1,366 @@ +/** +****************************************************************************** +* @file BlueNRG1_pka.c +* @author VMA Application Team +* @version V1.0.0 +* @date 27-February-2017 +* @brief This file provides all the PKA firmware functions. +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2016 STMicroelectronics

+****************************************************************************** +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_pka.h" +#include "osal.h" +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver +* @{ +*/ + +/** @defgroup PKA_Peripheral PKA Peripheral +* @{ +*/ + +/** @defgroup PKA_Private_TypesDefinitions Private Types Definitions +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup PKA_Private_Defines Private Defines +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup PKA_Private_Macros Private Macros +* @{ +*/ + + +/** +* @} +*/ + +/** @defgroup PKA_Private_Variables Private Variables +* @{ +*/ + +/* 0b0000 00XY. X: PKA_DATA_PCX error Y: PKA_DATA_PCY error */ +static uint8_t PKA_SetDataError = 0x00; + +/** +* @} +*/ + +/** @defgroup PKA_Private_Functions Private Functions +* @{ +*/ + + +/** +* @} +*/ + +/** @defgroup PKA_Public_Functions Public Functions +* @{ +*/ + + +/** +* @brief PKA Software Reset. +* @param None +* @retval None +*/ +void PKA_Reset(void) +{ + /* Set Bit SFT_RST of CSR */ + PKA->CSR_b.SFT_RST = SET; + + /* the Bit SFT_RST must be reset after set */ + PKA->CSR_b.SFT_RST = RESET; +} + + +/** +* @brief PKA start processing command. +* @param None +* @retval ErrorStatus +* @note Assumes that Input Data have been already loaded into PKA memory! +*/ +void PKA_StartProcessing(void) +{ + /* Set Bit GO of CSR */ + PKA->CSR_b.GO = SET; + + /* the Bit GO must be reset before the end of calculation */ + PKA->CSR_b.GO = RESET; + +} + + +/** +* @brief Wait loop for READY status +* @param None +* @retval None +*/ +void PKA_WaitProcess(void) +{ + /* Wait PKA processing end */ + while(PKA->CSR_b.READY != SET); +} + + +/** +* @brief Return the READY status +* @param None +* @retval FlagStatus RESET if PKA is busy +*/ +FlagStatus PKA_GetProcessStatus(void) +{ + /* Wait PKA processing end */ + return (FlagStatus)(PKA->CSR_b.READY); +} + + +/** +* @brief PKA verification of process command. +* @param None +* @retval ErrorStatus +*/ +ErrorStatus PKA_VerifyProcess(void) +{ + uint32_t errorCode; + + if(PKA_SetDataError != 0x00) + return ERROR; + + errorCode = *(uint32_t *)(PKA_RAM_ECC_ADDR_KP_ERROR); + + if (errorCode == 0) { + return SUCCESS; + } + else { + return ERROR; + } +} + + +/** +* @brief Enables or disables the specified PKA interrupts. +* @param PkaFlag: the PKA flag to clear, this can be +* @arg PKA_PROCEND PKA process end +* @arg PKA_RAMERR PKA RAM error +* @arg PKA_ADDERR PKA address invalid +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void PKA_ITConfig(uint8_t PkaFlag, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_PKA_FLAG(PkaFlag)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) { + SET_BIT(PKA->IEN, PkaFlag); + } + else if (NewState == DISABLE) { + CLEAR_BIT(PKA->IEN, PkaFlag); + } +} + + +/** +* @brief Clears the specific PKA pending IT bit. +* @param PkaFlag: the PKA flag to clear, this can be +* @arg PKA_PROCEND PKA process end +* @arg PKA_RAMERR PKA RAM error +* @arg PKA_ADDERR PKA address invalid +* @retval None +*/ +void PKA_ClearITPendingBit(uint8_t PkaFlag) +{ + assert_param(IS_PKA_FLAG(PkaFlag)) ; + + /* Clear the flags */ + PKA->ISR = PkaFlag; +} + + +/** +* @brief Checks whether the specified PKA flag is set or not. +* @param PkaFlag: the PKA flag to clear, this can be +* @arg PKA_PROCEND PKA process end +* @arg PKA_RAMERR PKA RAM error +* @arg PKA_ADDERR PKA address invalid +* @retval FlagStatus: functional state @ref FlagStatus +* This parameter can be: SET or RESET. +*/ +FlagStatus PKA_GetFlagStatus(uint8_t PkaFlag) +{ + /* Check the parameters */ + assert_param(IS_PKA_FLAG(PkaFlag)); + + if((PKA->ISR & PkaFlag) != (uint16_t)RESET) { + return SET; + } + else { + return RESET; + } +} + + +/** +* @brief Internal Utility for PKA key range check +* @param a: pka key +* b: reference key +* bufferSize: key size +* @retval check result +*/ +static int rev_memcmp(uint8_t *a, const uint8_t *b, uint8_t bufferSize) +{ + uint_fast8_t i = bufferSize; + int retval = 0; + + do + { + i--; + retval = (int)a[i] - (int)b[i]; + if (retval !=0) + { + break; + } + } while (i != 0U); + + return retval; +} + + +/** +* @brief Write the PKA RAM with the input data. +* @param dataType: select the region of PKA RAM to write: +* @arg PKA_DATA_SK is the K value +* @arg PKA_DATA_PCX is the point X coordinate +* @arg PKA_DATA_PCY is the point Y coordinate +* @retval ErrorStatus +*/ +ErrorStatus PKA_SetData(uint8_t dataType, uint32_t* srcData) +{ + const uint8_t P256_P_LE[32] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff}; + const uint8_t BLE_P256_ABELIAN_ORDER_R_LE[32] = {0x51,0x25,0x63,0xFC,0xC2,0xCA,0xB9,0xF3,0x84,0x9E,0x17,0xA7,0xAD,0xFA,0xE6,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF}; + uint32_t StartAddress; + uint8_t idx; + + /* Check the parameters */ + assert_param(IS_PKA_CMD(dataType)); + + if (dataType == PKA_DATA_SK) { + if (rev_memcmp((uint8_t *) srcData, (uint8_t *)BLE_P256_ABELIAN_ORDER_R_LE, 32) >= 0) { + PKA_SetDataError |= 0x04; + return ERROR; + } + else { + PKA_SetDataError &= ~0x04; + } + StartAddress = PKA_RAM_ECC_ADDR_K; + } + + else if (dataType == PKA_DATA_PCX) { + if (rev_memcmp((uint8_t *) srcData, (uint8_t *)P256_P_LE, 32) >= 0) { + PKA_SetDataError |= 0x01; + return ERROR; + } + else { + PKA_SetDataError &= ~0x01; + } + StartAddress = PKA_RAM_ECC_ADDR_PX; + + } + + else if (dataType == PKA_DATA_PCY) { + if (rev_memcmp((uint8_t *) srcData, (uint8_t *)P256_P_LE, 32) >= 0) { + PKA_SetDataError |= 0x02; + return ERROR; + } + else { + PKA_SetDataError &= ~0x02; + } + StartAddress = PKA_RAM_ECC_ADDR_PY; + } + else + return ERROR; + + /* Write the source data to target PKA RAM address. */ + for (idx = 0; idx<8; idx++) + { + *(uint32_t *)(StartAddress + 4*idx) = srcData[idx]; + } + + /* A 9th word of zeros must be added */ + *(uint32_t *)(StartAddress + 32UL) = 0x00000000; + + return SUCCESS; +} + + +/** +* @brief Get from the PKA RAM the output data. +* @param dataType: select the region of PKA RAM to read: +* @arg PKA_DATA_SK is the K value +* @arg PKA_DATA_PCX is the point X coordinate +* @arg PKA_DATA_PCY is the point Y coordinate +* @retval ErrorStatus +*/ +ErrorStatus PKA_GetData(uint8_t dataType, uint8_t* dataTarget) +{ + uint32_t StartAddress; + + /* Check the parameters */ + assert_param(IS_PKA_CMD(dataType)); + + if (dataType == PKA_DATA_SK) + StartAddress = PKA_RAM_ECC_ADDR_K; + else if (dataType == PKA_DATA_PCX) + StartAddress = PKA_RAM_ECC_ADDR_PX; + else if (dataType == PKA_DATA_PCY) + StartAddress = PKA_RAM_ECC_ADDR_PY; + else return ERROR; + + /* Read the data to target PKA RAM address. */ + for(uint8_t i=0;i<32;i++) { + dataTarget[i] = ((uint8_t *)StartAddress)[i]; + } + + return SUCCESS; +} + + + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_radio.c b/drivers/src/BlueNRG1_radio.c new file mode 100644 index 0000000..bb7d443 --- /dev/null +++ b/drivers/src/BlueNRG1_radio.c @@ -0,0 +1,947 @@ +/** +****************************************************************************** +* @file BlueNRG1_radio.c +* @author RF Application Team +* @date Jan-2020 +* @brief This file provides all the BlueNRG-1,2 Radio Driver APIs. +* This driver is based on undocumented hardware features and +* it is strongly recommend to do not change it. +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2020 STMicroelectronics

+****************************************************************************** +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_radio.h" +#include "vtimer.h" +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver +* @{ +*/ + +/** @addtogroup Radio_Peripheral Radio Peripheral +* @{ +*/ + + +/** @defgroup Radio_Exported_Types Exported Types +* @{ +*/ + + + +/** +* @} +*/ + + +/** @defgroup Radio_Exported_Constants Exported Constants +* @{ +*/ + +/** @defgroup Radio_TXRX_Delay_Constants TXRX Delay Constants +* @{ +*/ + +#define TX_DELAY 0x09 +#define TX_DELAY1 0x09 +#define RX_DELAY 0x05 +#define RX_DELAY1 0x05 + +/** +* @} +*/ +#define IRQBLUE (BLUE_CTRL_IRQn) + +#define TIMER_OFF (0) +#define OFF_R_SLEEP (28) + +/** +* @} +*/ + +/** @defgroup Radio_Exported_Macros Exported Macros +* @{ +*/ +#define DISABLE_INTERRUPT(irqNum) {NVIC_DisableIRQ(irqNum);} +#define ENABLE_INTERRUPT(irqNum) {NVIC_EnableIRQ(irqNum);} +#define BLUE_STRUCT_PTR_CAST(x) (((BlueTransBlueStrctPtr_t)(int)(x)) & 0xffff) +#define BLUE_DATA_PTR_CAST(x) (((BlueTransBlueDataPtr_t)(int)(x)) & 0xffff) +#define TIME24_DIFF(a, b) (((int32_t)((a - b) << 8)) >> 8) +#define IS_STATE_VALID(STATEMACHINE_NO) (STATEMACHINE_NO < STATEMACHINE_COUNT) +#define IS_POWERLEVEL_VALID(POWER) (POWER < 16) +#define IS_RFCHANNEL_VALID(RF_CHANNEL) (RF_CHANNEL <40) + +#define MASK_INTERRUPTS() __disable_irq(); +#define UNMASK_INTERRUPTS() __enable_irq(); + + +/** +* @} +*/ + +/** @defgroup Radio_Private_Variables Private Variables +* @{ +*/ + +static volatile BlueGlob* const blueglob = &__blue_RAM.BlueGlobVar; // (BlueGlob*) BLUEGLOB_BASE; +static volatile BlueGlobPerMaster* const bluedata = __blue_RAM.BlueGlobPerMasterVar;// (BlueGlobPerMaster*) (BLUEGLOB_BASE+12); + +/* glabal variables */ +RadioGlobalParameters_t globalParameters; + +/** +* @} +*/ + + + + +/** @defgroup Radio_Private_Functions Private Functions +* @{ +*/ + +/** +* @brief Weak definition of RADIO_TimerOverrunCallback +* @param void +* @retval void +*/ +WEAK_FUNCTION(void RADIO_TimerOverrunCallback(void)); + +/** +* @brief Read RSSI +* @param None +* @retval int32_t: RSSI in dBm +*/ +static int32_t read_RSSI(void) +{ + int i = 0 ; + int rsi_dbm; + + while(i < 100 && (BLUE_CTRL->RADIO_CONFIG & 0x10000) != 0) + { + // dump_it = i++; + rsi_dbm = i++; // use rsi_dbm instead of dump_it which is in RAM2 + } + + int rssi_int16 = ((globalParameters.rssiLevel[0] >> 16) & 0xff00) | (globalParameters.rssiLevel[1] & 0xff) ; + int reg_agc = (globalParameters.rssiLevel[0] >> 16) & 0xff ; + + if(rssi_int16 == 0 || reg_agc > 0xb) + { + rsi_dbm = 127 ; + } + else + { + rsi_dbm = reg_agc * 6 -127 ; + while(rssi_int16 > 30) + { + rsi_dbm = rsi_dbm + 6 ; + rssi_int16 = rssi_int16 >> 1 ; + } + rsi_dbm = rsi_dbm + ((417*rssi_int16 + 18080)>>10) ; + } + + return rsi_dbm ; +} + +/** +* @brief write_radio_config. +* @param ptr +* @retval None +*/ +static void write_radio_config(char *ptr) +{ + /* rc_config[0] = 0x005b3402 ; // turn on X-tal */ + int var11 = ((int)ptr & 0xffff) | 0x10000 ; + BLUE_CTRL->RADIO_CONFIG = var11 ; + int i = 0 ; + while((BLUE_CTRL->RADIO_CONFIG & 0x10000) != 0) + { + i = i+1 ; + } +} + +/** +* @} +*/ + + + +/** @defgroup Radio_Exported_Functions Exported Functions +* @{ +*/ + + +/** +* @brief Radio ISR. Completed event is handled here. +* Besides, next packet is scheduled here. +* @param None +* @retval None +*/ +void RADIO_IRQHandler(void) +{ + uint32_t time; + uint32_t int_value = BLUE_CTRL->INTERRUPT; + + if ( (int_value & IRQ_DONE) != 0) { + /* Indicates that there is no scheduling for wakeup Timer */ + TIMER_updatePeriodSlow(); + /* Restore period_slow since it is rewritten by hardware */ + + /* if (!Is_Flash_Write_On_Going()) + { + BLUE_CTRL->RADIO_CONFIG = ((int)GVAR(rssi_level) & 0xffff) | 0x10000; + } */ + BLUE_CTRL->RADIO_CONFIG = ((int)(globalParameters.rssiLevel) & 0xffff) | 0x10000; + + ActionPacket* next, *actionPacketBackup; + BlueTransStruct *p; + + /* Copy status in order for callback to access it. */ + globalParameters.current_action_packet->status = int_value; + + if( ( globalParameters.current_action_packet->condRoutine(globalParameters.current_action_packet) ) == TRUE) { + next = globalParameters.current_action_packet->next_true; + } + else { + next = globalParameters.current_action_packet->next_false; + } + + if(next == NULL_0) { + /* timer2 off */ + BLUE_CTRL->TIMEOUT = TIMER_OFF | BLUE_SLEEP_ENABLE; + blueglob->Config = 0; + } + else { + blueglob->Config = (blueglob->Config & 0xFFF0) | (next->StateMachineNo | 0x48); + p= &next->trans_packet; + (bluedata + next->StateMachineNo)->stat_config = next->trans_config; + (bluedata + next->StateMachineNo)->txpoint = BLUE_STRUCT_PTR_CAST(p); + (bluedata + next->StateMachineNo)->rcvpoint = BLUE_STRUCT_PTR_CAST(p); + +#if defined(BLUENRG2_DEVICE) + (bluedata + next->StateMachineNo)->remap_chan = (bluedata+next->StateMachineNo)->remap_chan | 0x80; +#endif + + /* Packet will execute on time specified by WakeupTime */ + if( (next->ActionTag & TIMER_WAKEUP ) !=0 ) { + /* timer2 off */ + BLUE_CTRL->TIMEOUT = TIMER_OFF | BLUE_SLEEP_ENABLE; + + /* program timer at next->wakeuptime */ + if((next->ActionTag & RELATIVE ) !=0) { + time = (uint32_t)TIMER_GetCurrentSysTime() + TIMER_UsToSystime(next->WakeupTime); + HAL_VTimer_SetRadioTimerValue(time,(next->ActionTag & TXRX), (next->ActionTag & PLL_TRIG)); + } + else { + HAL_VTimer_SetRadioTimerValue(next->WakeupTime,(next->ActionTag & TXRX), (next->ActionTag & PLL_TRIG)); + } + + } + /* back to back */ + else { + } + } + + /* Accept the packet even with CRC Error */ + if( ( (int_value & IRQ_RCV_OK) != 0) || ( (int_value & IRQ_CRC_ERR) != 0) ) { + /* read RSSI */ + globalParameters.current_action_packet->rssi = read_RSSI(); + + /* bluedata->config = bluedata->config ^ 0x80 ; toggle NESN bit + bluedata->config = bluedata->config & 0x7F ; //reset NESN bit */ + + /* read time stamp */ + globalParameters.current_action_packet->timestamp_receive = TIMER_GetAnchorPoint(); + } + + actionPacketBackup = globalParameters.current_action_packet; + globalParameters.current_action_packet = next; + actionPacketBackup->dataRoutine(actionPacketBackup, next); + } + + if ( (int_value & IRQ_WAKEUP_2) != 0) { + HAL_VTIMER_TimeoutCallback(); + } + if (int_value & BIT_TIME_OVERRUN) { + // Timer overrun!!! + RADIO_TimerOverrunCallback(); + } + + /* clear interrupts */ + BLUE_CTRL->INTERRUPT = int_value; + + return ; +} + +/** +* @brief This routine force the radio to be stopped. After calling this function, +* the ISR is not triggered unless, "MakeActionPacketPending" API called again. +* @param None +* @retval TRUE +*/ +uint8_t RADIO_StopActivity(void) +{ + uint8_t retVal; + MASK_INTERRUPTS(); + blueglob->Config = 0; + retVal = HAL_VTimer_ClearRadioTimerValue(); + globalParameters.forceRadiotoStop = TRUE; + UNMASK_INTERRUPTS(); + return retVal; +} + + +/** +* @brief This routine sets the 40-bit receive and transmit packet count, to be used in +* encryption calculation. +* Both are pointers to char, and set the 39-bit counter + 1-bit MSB as defined in the +* Bluetooth Low Energy spec. One is for transmit packets, the other is for receive packets. +* @param StateMachineNo: state machine number in multi state. From 0 to 7. +* @param count_tx: 40-bit transmit packet count, to be used in encryption nounce calculation. +* @param count_rcv: 40-bit receive packet count, to be used in encryption nounce calculation. +* @retval None +*/ +void RADIO_SetEncryptionCount(uint8_t StateMachineNo, uint8_t *count_tx, uint8_t *count_rcv) +{ + /* Check the parameters */ + assert_param(IS_STATE_VALID(StateMachineNo)); + + for(uint8_t i = 0; i < 5; i++) { + (bluedata + StateMachineNo)->Pack_count_Rcv[i] = count_rcv[i]; + (bluedata + StateMachineNo)->Pack_count_Tx[i] = count_tx[i]; + } + return; +} + + +/** +* @brief This routines sets the 8-byte encryption initial vector, and the 16-byte encryption key. +* The definition of the encryption key and its initial value is according the Bluetooth Low Energy spec. +* @param StateMachineNo: state machine number in multi state. From 0 to 7. +* @param enc_iv: 8-byte encryption initial vector. +* @param enc_key: 16-byte encryption key. +* @retval None +*/ +void RADIO_SetEncryptionAttributes(uint8_t StateMachineNo, uint8_t *enc_iv, uint8_t *enc_key) +{ + uint8_t i = 0; + + /* Check the parameters */ + assert_param(IS_STATE_VALID(StateMachineNo)); + + for(i = 0; i < 8; i++) { + (bluedata + StateMachineNo)->enc_iv[i] = enc_iv[i]; + (bluedata + StateMachineNo)->enc_key[i] = enc_key[i]; + } + for(i = 8; i < 16; i++) { + (bluedata + StateMachineNo)->enc_key[i] = enc_key[i]; + } + + return ; +} + + +/** +* @brief This routine sets the channel map. If channel map is not in use, do not use it. The +* chan_remap constant is a 37-bit vector, one bit per channel from 0 to 36, with the +* LSB corresponding to the channel 0. If the corresponding bit is set, the channel is in use; if it is cleared, +* there is an automatic remap to another channel, as defined in the Bluetooth Low +* Energy specification. +* Setting all bits of the array to one, disables the channel remapping, and this is the mode +* that should be used if the Bluetooth channel remap is not in use. +* +* @param StateMachineNo: state machine number in multi state. From 0 to 7. +* @param chan_remap: a 37-bit vector, one bit per channel from 0 to 36, with the LSB corresponding to the channel 0 +* @retval None +*/ +void RADIO_SetChannelMap(uint8_t StateMachineNo,uint8_t *chan_remap) +{ + /* Check the parameters */ + assert_param(IS_STATE_VALID(StateMachineNo)); + + for(uint8_t i = 0; i < 5; i++) { + (bluedata + StateMachineNo)->chan_remap[i] = chan_remap[i]; + } + return ; +} + + +/** +* @brief This routine sets the channel and the channel increment. Channel and channel +* increment follows channel mapping corresponding to Bluetooth specification. +* RF channel 0: 2402 MHz -> channel 37 +* RF channel 1: 2404 MHz -> channel 0 +* RF channel 2: 2406 MHz -> channel 1 +* ... +* RF channel 11: 2424 MHz -> channel 10 +* RF channel 12: 2426 MHz -> channel 38 +* RF channel 13: 2428 MHz -> channel 11 +* RF channel 14: 2430 MHz -> channel 12 +* ... +* RF channel 38: 2478 MHz -> channel 36 +* RF channel 39: 2480 MHz -> channel 39 +* +* For the channel 37, 38 and 39 (RF channel 0, 12, 39): +* - The crc_init value should always be 0x555555. +* - There is no encryption. +* - The channel increment is dedicated, the channel sequence is: +* 37 -> 38 -> 39 -> 37 -> ... while for the other channels is: +* 0 -> 1 -> ... -> 36 -> 0 -> ... +* There is no channel map for these three channels. +* Valid values for packet length for these channels are from 6 to 37. +* @param StateMachineNo: state machine number in multi state. From 0 to 7. +* @param channel: frequency channel. From 0 to 39. +* @param channel_increment: determines the hoping value. +* @retval None +*/ +void RADIO_SetChannel(uint8_t StateMachineNo, uint8_t channel, uint8_t channel_increment) +{ + /* Check the parameters */ + assert_param(IS_STATE_VALID(StateMachineNo)); + assert_param(IS_RFCHANNEL_VALID(channel)); + + (bluedata + StateMachineNo)->unmapped_chan = channel; + (bluedata + StateMachineNo)->hop_incr = channel_increment; + + return ; +} + + +/** +* @brief This routine sets the NetworkID, the CRC init, and the SCA. +* @param StateMachineNo: state machine number in multi state. From 0 to 7. +* @param NetworkID: The NetworkID is the ID of the device. +* The user shall ensure that the NetworkID meets the following requirements: +* - It shall have no more than six consecutive zeros or ones. +* - It shall not have all four octets equal. +* - It shall have no more than 24 transitions. +* - It shall have a minimum of two transitions in the most significant six bits. +* @param crc_init: CRC initilization value. +* This value must be 0x555555 when channel frequency is one of these values: 37, 38, 39. +* @param sca: slow clock accuracy. Period duration of the 32 kHz clock (slow clock). +* "period_slow" defines the number of 16 MHz clock cycle in a 32 kHz period. +* Note: the number 16 MHz clock cycle in a 32 kHz period can be measured by the clockgen block. +* Note: If the application uses a CLK32K crystal then the value is a constant provided by the firmware. (488 = 16,000,000 / 32768) +* Note: If the application uses the 32 kHz RC clock, then its value is measured in the clock_gen. +* Note: not used here. This value should be set automatically in RADIO_CrystalCheck routine. +* @retval None +*/ +void RADIO_SetTxAttributes(uint8_t StateMachineNo, uint32_t NetworkID, uint32_t crc_init) +{ + /* Check the parameters */ + assert_param(IS_STATE_VALID(StateMachineNo)); + + (bluedata + StateMachineNo)->access_address = NetworkID; + (bluedata + StateMachineNo)->crc_init = crc_init; + + return; +} + + + +/** +* @brief Initializes the time between back-to-back radio transmissions. +* @param back_to_back_time: time between two packets if wakeupTimer is not used. Resolution is 1 us. +* @retval None +*/ +void RADIO_SetBackToBackTime(uint32_t back_to_back_time) +{ + globalParameters.back2backTime = back_to_back_time; + return; +} + + +/** +* @brief Configures the transmit power level. +* @param PowerLevel: power level which should set to this value: +* - 0 = -18 dBm, +* - 1 = -15 dBm, +* - 2 = -12 dBm, +* - 3 = -9 dBm, +* - 4 = -6 dBm, +* - 5 = -2 dBm, +* - 6 = 0 dBm, +* - 7 = 5 dBm. +* +* - 8 = -14 dBm, +* - 9 = -11 dBm, +* - 10 = -8 dBm, +* - 11 = -5 dBm, +* - 12 = -2 dBm, +* - 13 = 2 dBm, +* - 14 = 4 dBm, +* - 15 = 8 dBm. +* @retval None +*/ +void RADIO_SetTxPower(uint8_t PowerLevel) +{ + /* Check the parameters */ + assert_param(IS_POWERLEVEL_VALID(PowerLevel)); + + PowerLevel <<= 3; + for(int n = 0; n conf_byte5 = PowerLevel; + } + return; +} + + +/** +* @brief This routine turns encrypt ON and OFF. When the encryption is enabled, the hardware will add 4 bytes +* at the end of the packet as MIC (Message Authentication Code). So the user need to add 4 byte to the +* length of the packet. The parameters enable the encryption for both. There are two separated parameters +* for this function just compliance with previous version of the driver. +* @param StateMachineNo: state machine number in multi state. From 0 to 7. +* @param EncryptFlagTx: DISABLE: encryption is turned OFF for both TX and RX operations. +* ENABLE: encryption is turned OFF for both TX and RX operations. +* This parameter can be: ENABLE or DISABLE. +* @param EncryptFlagRcv: encryption is turned OFF for both TX and RX operations. +* ENABLE: encryption is turned OFF for both TX and RX operations. +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void RADIO_SetEncryptFlags(uint8_t StateMachineNo, FunctionalState EncryptFlagTx, FunctionalState EncryptFlagRcv) +{ + /* Check the parameters */ + assert_param(IS_STATE_VALID(StateMachineNo)); + assert_param(IS_FUNCTIONAL_STATE(EncryptFlagTx)); + assert_param(IS_FUNCTIONAL_STATE(EncryptFlagRcv)); + + if(EncryptFlagTx==ENABLE || EncryptFlagRcv==ENABLE) { + (bluedata + StateMachineNo)->config = (bluedata + StateMachineNo)->config | 0x0A; + } + else { + (bluedata + StateMachineNo)->config = (bluedata + StateMachineNo)->config & 0xF5; + } + return; +} + + +/** +* @brief This routine should be called after writing/modifying an action packet, and before it +* is executed via either the API mechanism, or the next mechanism. +* @param p: pointer to action packet. +* @retval None +*/ +void RADIO_SetReservedArea(ActionPacket *p) +{ + //p->WakeupTime = (uint32_t) (p->WakeupTime * 0.525); /* convert us to appropriated value. 1000 * 1/512000 = 1953.125 */ + + /* Check the parameters */ +// assert_param(IS_DELAY_VALID(p->WakeupTime)); + + p->trans_packet.datptr = BLUE_DATA_PTR_CAST(p->data); + + p->trans_packet.next = BLUE_STRUCT_PTR_CAST(&(p->trans_packet)); + + /* rcvlen[17:0] */ + if(p->ReceiveWindowLength < 0x40000) { + p->trans_packet.rcvlen[0] = (p->ReceiveWindowLength) & 0x000000FF ; + p->trans_packet.rcvlen[1] = (p->ReceiveWindowLength >> 8) & 0x000000FF ; + p->trans_packet.rcvlen[2] = (p->ReceiveWindowLength >> 16) & 0x00000003 ; + } + else if(p->ReceiveWindowLength < 0x100000) { + p->trans_packet.rcvlen[0] = (p->ReceiveWindowLength >> 2) & 0x000000FF ; + p->trans_packet.rcvlen[1] = (p->ReceiveWindowLength >> 10) & 0x000000FF ; + p->trans_packet.rcvlen[2] = (p->ReceiveWindowLength >> 18) & 0x00000003 ; + + p->trans_packet.rcvlen[2] |= 0x04; + } + else if(p->ReceiveWindowLength < 0x400000) { + p->trans_packet.rcvlen[0] = (p->ReceiveWindowLength >> 4) & 0x000000FF ; + p->trans_packet.rcvlen[1] = (p->ReceiveWindowLength >> 12) & 0x000000FF ; + p->trans_packet.rcvlen[2] = (p->ReceiveWindowLength >> 20) & 0x00000003 ; + + p->trans_packet.rcvlen[2] |= 0x08; + } + else if(p->ReceiveWindowLength < 0x1000000) { + p->trans_packet.rcvlen[0] = (p->ReceiveWindowLength >> 6) & 0x000000FF ; + p->trans_packet.rcvlen[1] = (p->ReceiveWindowLength >> 14) & 0x000000FF ; + p->trans_packet.rcvlen[2] = (p->ReceiveWindowLength >> 22) & 0x00000003 ; + + p->trans_packet.rcvlen[2] |= 0x0C; + } + else { + /* error */ + } + + if((p->ActionTag & TIMESTAMP_POSITION) == 0) { + p->trans_packet.rcvlen[2] |= TIMESTAMP_POSITION_LASTBIT; + } + else { + p->trans_packet.rcvlen[2] |= TIMESTAMP_POSITION_ACCESSADDRESS; + } + + /* p->trans_packet.rcvlen[2] = p->trans_packet.rcvlen[2] | 0x30 | 0x40 | TIMESTAMP_POSITION; */ + p->trans_packet.rcvlen[2] = p->trans_packet.rcvlen[2] | 0x30; + + p->trans_packet.timeout[0] = (globalParameters.back2backTime >> 0) & 0x000000FF; + p->trans_packet.timeout[1] = (globalParameters.back2backTime >> 8) & 0x000000FF; + p->trans_packet.timeout[2] = (globalParameters.back2backTime >> 16) & 0x0000000F; /* only 20 bits */ + + p->trans_packet.byte10 =0; + p->trans_packet.byte10 = (p->ActionTag & INC_CHAN) | (p->ActionTag & PLL_TRIG) | (p->ActionTag & TXRX); + + /* next state is zero */ + p->trans_packet.byte10 = p->trans_packet.byte10 & 0x1F; + + /* sleep . do not go to sleep*/ + p->trans_packet.byte10 = p->trans_packet.byte10 & 0xFB; + + /* for multi-state automatically increment the channel */ + p->trans_packet.byte10 = p->trans_packet.byte10 | ((p->StateMachineNo)<<5); + + /* enable all interrupts */ + p->trans_packet.byte11 = 0xFF; + + p->trans_config =0; + if( (p->ActionTag & TXRX) != 0) { + p->trans_config = 0x80; + } + + return ; +} + + +/** +* @brief This routine should be called for the first actionPacket that needs to be scheduled +* on the radio. For it to work OK, the WakeupTime should be valid, and the TIMER_WAKEUP flag set. +* Subsequent packets can be dispatched using the same process, or by providing non-NULL pointers +* to the next_true and next_false pointers of the ActionPacket. +* +* @param p: pointer to action packet. +* @retval uint8_t with following values: +* - 0x00 : Success. +* - 0xC4 : Radio is busy, action packet has not been executed. +*/ +uint8_t RADIO_MakeActionPacketPending(ActionPacket *p) +{ + uint8_t returnValue = SUCCESS_0; + uint32_t time,dummyTime; + + if(RADIO_GetStatus(&dummyTime) == BLUE_IDLE_0) + { + globalParameters.forceRadiotoStop = FALSE; + uint16_t statemachineNo; + BlueTransStruct *p1 ; + + /* timer2 off */ + BLUE_CTRL->TIMEOUT = TIMER_OFF | BLUE_SLEEP_ENABLE; + globalParameters.rssiLevel[0] = 0x2e86 ; + globalParameters.rssiLevel[1] = 0 ; + + int32_t* temp ; + temp = globalParameters.hot_ana_config_table_a; + blueglob->RadioConfigPtr = BLUE_DATA_PTR_CAST(temp) ; /* to be discussed */ + + /* Set_Radio_Config_Data(); */ /* to be discussed */ + + /* tell the schedular which table in SRAM should be applied and activate it */ + statemachineNo = 0x0007 & p->StateMachineNo; + + blueglob->Config = (blueglob->Config & 0xFFF0) | (statemachineNo | 0x48); + + (bluedata+statemachineNo)->txpoint_prev = 0; + (bluedata+statemachineNo)->rcvpoint_prev = 0; + (bluedata+statemachineNo)->txpoint_next = 0; + + p1= &p->trans_packet; + (bluedata+statemachineNo)->txpoint = BLUE_STRUCT_PTR_CAST(p1); + (bluedata+statemachineNo)->rcvpoint = BLUE_STRUCT_PTR_CAST(p1); + +#if defined(BLUENRG2_DEVICE) + (bluedata+statemachineNo)->remap_chan = (bluedata+statemachineNo)->remap_chan | 0x80; +#endif + + globalParameters.current_action_packet = p; + (bluedata+statemachineNo)->stat_config = p->trans_config; /* Transmision or reception for first packet */ + + /* program timer at next->wakeuptime */ + MASK_INTERRUPTS(); + if((p->ActionTag & RELATIVE ) !=0) { + time = (uint32_t)TIMER_GetCurrentSysTime() + TIMER_UsToSystime(p->WakeupTime); + returnValue = HAL_VTimer_SetRadioTimerValue(time,(p->ActionTag & TXRX), (p->ActionTag & PLL_TRIG)); + } + else { + returnValue = HAL_VTimer_SetRadioTimerValue(p->WakeupTime,(p->ActionTag & TXRX), (p->ActionTag & PLL_TRIG)); + } + UNMASK_INTERRUPTS(); + } + else { + returnValue = RADIO_BUSY_C4; + } + + return returnValue; +} + + +/** +* @brief Initializes the radio. +* @param hs_startup_time: start up time of the high speed (16 or 32 MHz) crystal oscillator in units of 625/256 us (~2.44 us). +* @param low_speed_osc: source for the 32 kHz slow speed clock: 1: internal RO; 0: external crystal. +* @param hot_table: reserved for future use, set to NULL. +* @param whitening: DISABLE: disable whitening for TX and RX. ENABLE: enable whitening for TX and RX. +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void RADIO_Init(uint32_t* hot_table, FunctionalState whitening) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(whitening)); + + DISABLE_INTERRUPT(IRQBLUE); + + blueglob->TxDelay = TX_DELAY; + blueglob->TxDelay1 = TX_DELAY1; + blueglob->RcvDelay = RX_DELAY; + blueglob->RcvDelay1 = RX_DELAY1; + + if(whitening == DISABLE) { + /* disable Transmision Whitening */ + blueglob->TxDelay |= 0x80; + blueglob->TxDelay1 |= 0x80; + + /* disable Receiving Whitening */ + blueglob->RcvDelay |= 0x80; + blueglob->RcvDelay1 |= 0x80; + } + + globalParameters.hardware_config.hot_ana_config_table = hot_table; + + blueglob->Config = 0; + BLUE_CTRL->TIMEOUT = TIMER_OFF | BLUE_SLEEP_ENABLE ; + BLUE_CTRL->HOST_WKUP_TIMER = TIMER_OFF | (1<INTERRUPT ; + BLUE_CTRL->INTERRUPT = int_value ; + + globalParameters.back2backTime = 71; /* 150 micro second */ + globalParameters.forceRadiotoStop = FALSE; + + RADIO_SetTxPower(11); + RADIO_SetEncryptFlags(0, DISABLE, DISABLE); + + ENABLE_INTERRUPT(IRQBLUE); + + return; +} + + +/** +* @brief This routine returns the status of the Radio whether it is busy or not. +* If it is busy, the time argument will be filled with absolute time value of next radio activity. +* User can use this value (in comparison with current time) to check that +* how long it is far to force the device to sleep or not. +* Note: when Timer2 is on schedule, time value is not absolute time. +* @param time: pointer to int value which is going to have time value. +* @retval uint8_t with following values: +* - 0 : BLUE_IDLE_0. Radio is not busy. +* - 1 : BLUE_BUSY_NOWAKEUP_T1. Radio is busy, but there is no wakeup timer on schedule but Timer1 is. +* - 2 : BLUE_BUSY_NOWAKEUP_T2. Radio is busy, but there is no wakeup timer on schedule but Timer2 is. +* - 3 : BLUE_BUSY_WAKEUP. Radio is busy and wakeup timer is on the schedule. +*/ +uint8_t RADIO_GetStatus(uint32_t *time) +{ + uint8_t retValue = BLUE_IDLE_0; + if((blueglob->Config & 0x8) != 0) + { + retValue = TIMER_GetRadioTimerValue(time); + } + return retValue; +} + + +/** +* @brief Starts tone transmission on selected channel. +* This API is dedicated for test and destroys context and multistate. +* So, after calling this function the radio should be re-initialized. +* @param RF_Channel: radio frequency channel number from 0 to 39. +* @param PowerLevel: power level which should set to this value: +* - 0 = -18 dBm, +* - 1 = -15 dBm, +* - 2 = -12 dBm, +* - 3 = -9 dBm, +* - 4 = -6 dBm, +* - 5 = -2 dBm, +* - 6 = 0 dBm, +* - 7 = 5 dBm. +* +* - 8 = -14 dBm, +* - 9 = -11 dBm, +* - 10 = -8 dBm, +* - 11 = -5 dBm, +* - 12 = -2 dBm, +* - 13 = 2 dBm, +* - 14 = 4 dBm, +* - 15 = 8 dBm. +* @retval None +*/ +void RADIO_StartTone(uint8_t RF_Channel, uint8_t powerLevel) +{ + /* Check the parameters */ + assert_param(IS_RFCHANNEL_VALID(RF_Channel)); + assert_param(IS_POWERLEVEL_VALID(powerLevel)); + + uint8_t channel; + uint8_t value1; + uint8_t value2; + uint32_t dummy; + char data[24]; + + if (RADIO_GetStatus(&dummy) == BLUE_IDLE_0) { + /* [EM:] Calculate the synt divide factor for 16 MHz quarts and +250 kHz offset wrt the channel center frequency + * Algorithmically MAK = F_rf*(2^20)/16 = F_rf*(2^16) + * With F_rf = (2402+2*RF_Channel)+0.25 MHz + * K corresponds to b19-b0 of MAK + * A corresponds to b22-b20 of MAK + * M corresponds to b27-b23 of MAK + */ + uint32_t kHz_250_scaled = 16384; /* = 0.250*2^20/16 */ + uint32_t MAK = ((2402+2*RF_Channel)<<16) - kHz_250_scaled; + uint8_t M = (MAK>>23)&0x1F; + uint8_t A = (MAK>>20)&0x07; + uint32_t K = (MAK&0x000FFFFF)+1; + uint8_t MOD3_DIG_TEST = (M<<3) | (A & 0x7); + uint8_t MOD2_DIG_TEST = ((K>>12) & 0xFF); + uint8_t MOD1_DIG_TEST = ((K>> 4) & 0xFF); + uint8_t MOD0_DIG_TEST = ((K&0x0F)<<4) | 0x09; + + value1 = 0x7E & 0x87; + + value1 |= (powerLevel << 3); + value2 = 0x3F & 0xF1; + powerLevel &= 0x07; + value2 |= (powerLevel << 1); + + channel = RF_Channel; + channel <<= 1; + data[0] = 0x03; + data[1] = 0x04; + data[2] = channel; // addr 0x4, value channel + data[3] = value1; // addr 0x5, value TX power + data[4] = 0x02; + data[5] = 0x1C; // addr 0x1C, value 0x73 + data[6] = 0x73; + data[7] = 0x03; + data[8] = 0x24; + data[9] = value2; // addr 0x24, value 0x3F + data[10] = 0x3F; // addr 0x25, value 0x3F + data[11] = 0x02; + data[12] = 0x23; + data[13] = 0x03; // addr 0x23, value 0x03 + data[14] = 0x02; + data[15] = 0x23; + data[16] = 0x07; // addr 0x23, value 0x07� + /*[EM:] Fix 204: force MAK values through MODx test registers */ + data[17] = 0x05; + data[18] = 0x28; + data[19] = MOD3_DIG_TEST; + data[20] = MOD2_DIG_TEST; + data[21] = MOD1_DIG_TEST; + data[22] = MOD0_DIG_TEST; + + data[23] = 0x0; + + write_radio_config(data); + } +} + + +/** +* @brief This routine starts tone transmission. +* This API is dedicated for test and destroys context and multistate. +* So, after calling this function the radio should be re-initialized. +* @param None +* @retval None +*/ +void RADIO_StopTone() +{ + char data[9]; + + data[0] = 0x04; + data[1] = 0x23; + data[2] = 0x00; // addr 0x23, value 0x00 + data[3] = 0x0E; // addr 0x24, value 0x0E + data[4] = 0x00; // addr 0x25, value 0x00 + data[5] = 0x02; //[EM:] Fix 204 + data[6] = 0x2B; // Reg MOD0_DIG_TEST@0x2B + data[7] = 0x08; // Reset to default value (disable mod test mode) + data[8] = 0x00; + write_radio_config(data); +} + + +/** +* @brief Encrypts plain text data using AES encryption with given input key and +* 128 bit block size +* @param Key: encryption key to be used. +* @param plainData: text data to be encrypted. +* @param cypherData: contains the encrypted data. +* @retval None +*/ +void RADIO_EncryptPlainData(uint8_t *Key, + uint8_t *plainData, + uint8_t *cypherData) +{ + uint32_t key[4] ; + uint32_t cleartext[4] ; + uint32_t ciphertext[4] ; + volatile uint32_t ii ; + + for(uint8_t i = 0; i < 4; i++) { + key[i] = ((uint32_t)Key[i*4]) | ((uint32_t)Key[i*4+1])<<8 | ((uint32_t)Key[i*4+2])<<16 | ((uint32_t)Key[i*4+3])<<24; + cleartext[i] = ((uint32_t)plainData[i*4]) | ((uint32_t)plainData[i*4+1])<<8 | ((uint32_t)plainData[i*4+2])<<16 | ((uint32_t)plainData[i*4+3])<<24; + } + + BLUE_CTRL->AES_KEY0 = key[3]; + BLUE_CTRL->AES_KEY1 = key[2]; + BLUE_CTRL->AES_KEY2 = key[1]; + BLUE_CTRL->AES_KEY3 = key[0]; + + BLUE_CTRL->CLEAR_TEXT0 = cleartext[3]; + BLUE_CTRL->CLEAR_TEXT1 = cleartext[2]; + BLUE_CTRL->CLEAR_TEXT2 = cleartext[1]; + BLUE_CTRL->CLEAR_TEXT3 = cleartext[0]; + + ii = 0 ; + while( ( BLUE_CTRL->STATUS & BIT_AES_READY) == 0 && ii < 100) { + ii++ ;} + + ciphertext[0] = BLUE_CTRL->AES_CYPHERTEXT3; + ciphertext[1] = BLUE_CTRL->AES_CYPHERTEXT2; + ciphertext[2] = BLUE_CTRL->AES_CYPHERTEXT1; + ciphertext[3] = BLUE_CTRL->AES_CYPHERTEXT0; + + for(uint8_t i = 0; i < 4; i++) { + cypherData[i*4] = ((uint8_t)ciphertext[i]); + cypherData[i*4+1] = (uint8_t)(ciphertext[i]>>8); + cypherData[i*4+2] = (uint8_t)(ciphertext[i]>>16); + cypherData[i*4+3] = (uint8_t)(ciphertext[i]>>24); + } + + return ; +} + + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2017 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_rng.c b/drivers/src/BlueNRG1_rng.c new file mode 100644 index 0000000..4407b4f --- /dev/null +++ b/drivers/src/BlueNRG1_rng.c @@ -0,0 +1,137 @@ +/** + ****************************************************************************** + * @file BlueNRG1_RNG.c + * @author VMA Application Team + * @version V2.0.0 + * @date 21-March-2016 + * @brief This file provides all the RNG firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_rng.h" + + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @defgroup RNG_Peripheral RNG Peripheral + * @{ + */ + +/** @defgroup RNG_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup RNG_Private_Defines Private Defines + * @{ + */ + + +/** + * @} + */ + +/** @defgroup RNG_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup RNG_Private_Variables Private Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup RNG_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup RNG_Private_Functions Private Functions + * @{ + */ + +/** + * @} + */ + +/** @defgroup RNG_Public_Functions Public Functions +* @{ +*/ + +/** + * @brief Enables or disables the specified RNG peripheral. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RNG_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Disable RNG peripheral */ + RNG->CR_b.DIS = RESET; + } + else { + /* Enable RNG peripheral */ + RNG->CR_b.DIS = SET; + } +} + + +/** + * @brief Checks if the RNG flag is set or not. +* @retval FlagStatus: functional state @ref FlagStatus +* This parameter can be: SET or RESET. + */ +FlagStatus RNG_GetFlagStatus(void) +{ + if (RNG->SR_b.RDY == SET) { + return SET; + } + else { + return RESET; + } + +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_rtc.c b/drivers/src/BlueNRG1_rtc.c new file mode 100644 index 0000000..45bc36b --- /dev/null +++ b/drivers/src/BlueNRG1_rtc.c @@ -0,0 +1,419 @@ +/** + ****************************************************************************** + * @file BlueNRG1_rtc.c + * @author VMA Application Team + * @version V2.1.0 + * @date 25-July-2018 + * @brief This file provides all the RTC firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_rtc.h" + + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @defgroup RTC_Peripheral RTC Peripheral + * @{ + */ + +/** @defgroup RTC_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Private_Defines Private Defines + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Private_Variables Private Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Public_Functions Public Functions +* @{ +*/ + +/** + * @brief Initializes the RTC peripheral according to the specified + * parameters in the RTC_InitStruct. + * @param RTC_InitStruct: pointer to a @ref RTC_InitType structure that + * contains the configuration information for the specified RTC peripheral. + * @retval None + */ +void RTC_Init(RTC_InitType* RTC_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_RTC_TIMER_MODE(RTC_InitStruct->RTC_operatingMode)); + assert_param(IS_PATTERN(RTC_InitStruct->RTC_PATTERN_SIZE)); + + RTC->TCR_b.OS = RTC_InitStruct->RTC_operatingMode; + + /** Delay between two write in RTC0->TCR register has to be + * at least 3 x 32k cycle + 2 CPU cycle. For that reason it + * is neccessary to add the delay. + */ + for (volatile uint32_t i=0; i<600; i++) { + __asm("NOP"); + } + + RTC->TCR_b.SP = RTC_InitStruct->RTC_PATTERN_SIZE; + + RTC->TLR1 = RTC_InitStruct->RTC_TLR1; + RTC->TLR2 = RTC_InitStruct->RTC_TLR2; + RTC->TPR1 = RTC_InitStruct->RTC_PATTERN1; + RTC->TPR2 = RTC_InitStruct->RTC_PATTERN2; + RTC->TPR3 = RTC_InitStruct->RTC_PATTERN3; + RTC->TPR4 = RTC_InitStruct->RTC_PATTERN4; + +} + +/** +* @brief Fills the RTC_InitStruct member with its default value. +* @param RTC_InitStruct : pointer to a @ref RTC_InitType structure which will +* be initialized. +* @retval None +*/ +void RTC_StructInit(RTC_InitType* RTC_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + RTC_InitStruct->RTC_operatingMode = RTC_TIMER_PERIODIC; + RTC_InitStruct->RTC_PATTERN_SIZE = 0; + + RTC_InitStruct->RTC_TLR1 = 0; + RTC_InitStruct->RTC_TLR2 = 0; + RTC_InitStruct->RTC_PATTERN1 = 0; + RTC_InitStruct->RTC_PATTERN2 = 0; + RTC_InitStruct->RTC_PATTERN3 = 0; + RTC_InitStruct->RTC_PATTERN4 = 0; +} + + +/** + * @brief Enables or disables selected RTC peripheral. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + RTC->TCR_b.EN = SET; + } + else { + RTC->TCR_b.EN = RESET; + + } +} + +/** + * @brief Enables or disables selected RTC interrupt. + * @param RTC_IT: specifies the RTC interrupts sources, the value can be + * @arg RTC_IT_CLOCKWATCH RTC clock watch interrupt flag + * @arg RTC_IT_TIMER RTC timer interrupt flag + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_IT_Config(uint8_t RTC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_RTC_IT(RTC_IT)); + + if (RTC_IT == RTC_IT_CLOCKWATCH) { + /* Enable the selected RTC interrupts */ + RTC->IMSC_b.WIMSC = NewState; + } + else { + /* Disable the selected RTC interrupts */ + RTC->IMSC_b.TIMSC = NewState; + } +} + +/** + * @brief Return the RTC interrupt status for the specified IT. + * @param RTC_IT: specifies the RTC interrupts sources, the value can be + * @arg RTC_IT_CLOCKWATCH RTC clock watch interrupt flag + * @arg RTC_IT_TIMER RTC timer interrupt flag + * @retval ITStatus: functional state @ref ITStatus + * This parameter can be: SET or RESET. + */ +ITStatus RTC_IT_Status(uint8_t RTC_IT) +{ + /* Check the parameters */ + assert_param(IS_RTC_IT(RTC_IT)); + + /* Check the status of the specified RTC flag */ + if ((RTC->RIS & RTC_IT) != RESET) { + /* RTC_IT is set */ + return SET; + } + else { + /* RTC_IT is reset */ + return RESET; + } +} + +/** + * @brief Clear selected RTC interrupt. + * @param RTC_IT: specifies the RTC interrupts sources, the value can be + * @arg RTC_IT_CLOCKWATCH RTC clock watch interrupt flag + * @arg RTC_IT_TIMER RTC timer interrupt flag + * @retval None + */ +void RTC_IT_Clear(uint8_t RTC_IT) +{ + /* Check the parameters */ + assert_param(IS_RTC_IT(RTC_IT)); + + RTC->ICR = RTC_IT; +} + + +/** + * @brief Enables or disables selected RTC clockwatch. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_ClockwatchCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + RTC->CTCR_b.CWEN = SET; + } + else { + RTC->CTCR_b.CWEN = RESET; + } +} + +/** + * @brief Initialize the RTC clockwatch with present time and date. + * @param RTC_DateTime: pointer to a @ref RTC_DateTimeType structure that + * contains the specified time and date setting. + * @retval None + */ +void RTC_SetTimeDate(RTC_DateTimeType* RTC_DateTime) +{ + /* Check the parameters */ + assert_param(IS_SECOND(RTC_DateTime->Second)); + assert_param(IS_MINUTE(RTC_DateTime->Minute)); + assert_param(IS_HOUR(RTC_DateTime->Hour)); + assert_param(IS_WEEKDAY(RTC_DateTime->WeekDay)); + assert_param(IS_MONTHDAY(RTC_DateTime->MonthDay)); + assert_param(IS_MONTH(RTC_DateTime->Month)); + assert_param(IS_YEAR(RTC_DateTime->Year)); + + /** Select seconds from the data structure */ + RTC->CWDLR_b.CWSECL = RTC_DateTime->Second; + + /** Select minutes from the data structure */ + RTC->CWDLR_b.CWMINL = RTC_DateTime->Minute; + + /** Select hours from the data structure */ + RTC->CWDLR_b.CWHOURL = RTC_DateTime->Hour; + + /** Select week day from the data structure */ + RTC->CWDLR_b.CWDAYWL = RTC_DateTime->WeekDay; + + /** Select month day from the data structure */ + RTC->CWDLR_b.CWDAYML = RTC_DateTime->MonthDay; + + /** Select month from the data structure */ + RTC->CWDLR_b.CWMONTHL = RTC_DateTime->Month; + + /* Store data to load register */ + RTC->CWYLR_b.CWYEARL = RTC_DateTime->Year; +} + +/** + * @brief Set the RTC clockwatch match date and time registers. + * @param RTC_MatchDataTime: pointer to a @ref RTC_DateTimeType structure that + * contains the matching time and date setting. + * @retval None + */ +void RTC_SetMatchTimeDate(RTC_DateTimeType* RTC_MatchDataTime) +{ + /* Check the parameters */ + assert_param(IS_SECOND(RTC_MatchDataTime->Second)); + assert_param(IS_MINUTE(RTC_MatchDataTime->Minute)); + assert_param(IS_HOUR(RTC_MatchDataTime->Hour)); + assert_param(IS_MATCH_WEEKDAY(RTC_MatchDataTime->WeekDay)); + assert_param(IS_MATCH_MONTHDAY(RTC_MatchDataTime->MonthDay)); + assert_param(IS_MATCH_MONTH(RTC_MatchDataTime->Month)); + assert_param(IS_MATCH_YEAR(RTC_MatchDataTime->Year)); + + /* Select seconds from the data structure */ + RTC->CWDMR_b.CWSECM = RTC_MatchDataTime->Second; + + /* Select minutes from the data structure */ + RTC->CWDMR_b.CWMINM = RTC_MatchDataTime->Minute; + + /* Select hours from the data structure */ + RTC->CWDMR_b.CWHOURM = RTC_MatchDataTime->Hour; + + /* Select week day from the data structure */ + RTC->CWDMR_b.CWDAYWM = RTC_MatchDataTime->WeekDay; + + /* Select month day from the data structure */ + RTC->CWDMR_b.CWDAYMM = RTC_MatchDataTime->MonthDay; + + /* Select month from the data structure */ + RTC->CWDMR_b.CWMONTHM = RTC_MatchDataTime->Month; + +/* Select year from the data structure */ + RTC->CWYMR_b.CWYEARM = RTC_MatchDataTime->Year; +} + +/** + * @brief Set the RTC clockwatch match date and time registers. + * @param RTC_DataTime: pointer to a @ref RTC_DateTimeType structure that + * is filled with the configured values of time and date. + * @retval None + */ +void RTC_GetTimeDate(RTC_DateTimeType* RTC_DataTime) +{ + /* Select seconds from the RTC register */ + RTC_DataTime->Second = RTC->CWDR_b.CWSEC; + + /* Select minutes from the RTC register */ + RTC_DataTime->Minute= RTC->CWDR_b.CWMIN; + + /* Select hours from the RTC register */ + RTC_DataTime->Hour= RTC->CWDR_b.CWHOUR; + + /* Select week day from the RTC register */ + RTC_DataTime->WeekDay = RTC->CWDR_b.CWDAYW; + + /* Select month day from the RTC register */ + RTC_DataTime->MonthDay = RTC->CWDR_b.CWDAYM; + + /* Select month from the RTC register */ + RTC_DataTime->Month = RTC->CWDR_b.CWMONTH; + + /* Select year from the RTC register */ + RTC_DataTime->Year = RTC->CWYR_b.CWYEAR; +} + +/** + * @brief Return the actual timer counter. + * @param None + * @retval uint32_t the current counter value. + */ +uint32_t RTC_GetTimerValue(void) +{ + /* Return the current Time Data Register */ + return RTC->TDR; +} + +/** + * @brief Return the actual number of interrupt generated by RTC. + * @param None + * @retval uint32_t the actual number of interrupt generated by RTC. + */ +uint32_t RTC_GetNumberIrqGenerated(void) +{ + /* Return the current Time Data Register */ + return RTC->TIN; +} + + +/** + * @brief Enables or disables the auto start on load register or pattern register write operation. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_AutoStart(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + RTC->TCR_b.S = SET; + } + else { + RTC->TCR_b.S = RESET; + } +} + + +/** + * @brief Enables or disables the use of the trimmed 32 kHz clock. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_SelectTrimmedClock(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + RTC->TCR_b.CLK = SET; + } + else { + RTC->TCR_b.CLK = RESET; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_spi.c b/drivers/src/BlueNRG1_spi.c new file mode 100644 index 0000000..901a1aa --- /dev/null +++ b/drivers/src/BlueNRG1_spi.c @@ -0,0 +1,709 @@ +/** +****************************************************************************** +* @file BlueNRG1_spi.c +* @author VMA Application Team + * @version V2.1.0 + * @date 31-January-2017 +* @brief This file provides all the SPI firmware functions. +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2016 STMicroelectronics

+****************************************************************************** +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_spi.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver +* @{ +*/ + +/** @addtogroup SPI_Peripheral SPI Peripheral +* @{ +*/ + +/** @defgroup SPI_Private_TypesDefinitions Private Types Definitions +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup SPI_Private_Defines Private Defines +* @{ +*/ + +#define MAX_SCR (255) +#define MAX_CPSVDR (254) +#define MIN_DIVIDER (1) +#define MAX_DIVIDER (65024) // MAX_CPSVDR * (MAX_SCR+1) + +#define SPI_CLOCK (16000000) + +/** +* @} +*/ + +/** @defgroup SPI_Private_Macros Private Macros +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup SPI_Private_Variables Private Variables +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup SPI_Private_FunctionPrototypes Private Function Prototypes +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup SPI_Private_Functions Private Functions +* @{ +*/ + +/** +* @brief SPI set baud rate function. +* @param Baudrate: the SPI baud rate up to 8MHz for master mode +* and 1MHz for slave mode. +* @retval None +*/ +void SPI_SetBaudrate(uint32_t Baudrate) +{ + uint32_t c; + uint8_t scr = 1; + uint8_t cpsr = 2; + + /* Check the parameters */ + assert_param(IS_SPI_BAUDRATE(Baudrate)); + + /* bit rate is: 16MHz / (CPSDVR * (1+SCR)) + and CPSDVR must be an even number from 2-254. + We calculate (1/2 * CPSDVR) * (1+SCR) */ + c = SPI_CLOCK / (2 * Baudrate); + + /* if the bit rate is possible */ + if ((c >= MIN_DIVIDER) && (c <= MAX_DIVIDER)) { + /* adjust the ratio CPSDVR / (SCR+1) */ + while (c > MAX_SCR) { + cpsr <<= 1; + c >>= 1; + } + scr = c - 1; + } + /* set dividers */ + SPI->CPSR = cpsr; + SPI->CR0_b.SCR = scr; +} + +/** +* @} +*/ + +/** @defgroup SPI_Public_Functions Public Functions +* @{ +*/ + +/** +* @brief Deinitializes the SPI peripheral registers to their default +* reset values. +* @param None +* @retval None +*/ +void SPI_DeInit(void) +{ + SPI->CR0 = 0x1C000000; + SPI->CR1 = 0x00000000; + SPI->CPSR = 0x00000000; + SPI->IMSC = 0x00000000; + SPI->ICR = 0x00000000; + SPI->DMACR = 0x00000000; + SPI->RXFRM = 0x00000000; + SPI->CHN = 0x00000000; + SPI->WDTXF = 0x00000000; +} + +/** +* @brief Initializes the SPI peripheral according to the specified +* parameters in the SPI_InitStruct. +* @param SPI_InitStruct: pointer to a @ref SPI_InitType structure that +* contains the configuration information for the specified SPI peripheral. +* @retval None +*/ +void SPI_Init(SPI_InitType* SPI_InitStruct) +{ + /* check the parameters */ + assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); + assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); + assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); + assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); + + /* Set the specified baud rate */ + SPI_SetBaudrate(SPI_InitStruct->SPI_BaudRate); + + /* Set SPI mode */ + SPI->CR1_b.MS = SPI_InitStruct->SPI_Mode; + + /* Set CPOL */ + SPI->CR0_b.SPO = SPI_InitStruct->SPI_CPOL; + + /* Set CPHA */ + SPI->CR0_b.SPH = SPI_InitStruct->SPI_CPHA; + + /* Set datasize */ + SPI->CR0_b.DSS = SPI_InitStruct->SPI_DataSize; +} + + +/** +* @brief Fills each SPI_InitStruct member with its default value. +* @param SPI_InitStruct: pointer to a @ref SPI_InitType structure which will be initialized. +* @retval None +*/ +void SPI_StructInit(SPI_InitType* SPI_InitStruct) +{ + /* Initialize the SPI_Mode member */ + SPI_InitStruct->SPI_Mode = SPI_Mode_Slave; + + /* Initialize the SPI_DataSize member */ + SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; + + /* Initialize the SPI_CPOL member */ + SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low; + + /* Initialize the SPI_CPHA member */ + SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge; + + /* Initialize the SPI_BaudRate member */ + SPI_InitStruct->SPI_BaudRate = 1000000; +} + +/** +* @brief Enables or disables the SPI peripheral. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void SPI_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the selected SPI peripheral */ + SPI->CR1_b.SSE = SET; + } + else { + /* Disable the selected SPI peripheral */ + SPI->CR1_b.SSE = RESET; + } +} + +/** +* @brief Enables or disables the specified SPI interrupts. +* @param SPI_IT: specifies the SPI interrupt source to be enabled or disabled. +* This parameter can be any combination of the following values: +* @arg SPI_IT_TX: Transmit FIFO half empty or less condition interrupt mask. +* @arg SPI_IT_RX: Receive FIFO half full or less condition interrupt mask. +* @arg SPI_IT_RT: Receive FIFO not empty and no read prior to timeout period interrupt mask. +* @arg SPI_IT_ROR: Receive FIFO written to while full condition interrupt mask. +* @arg SPI_IT_TUR: Transmit underrun interrupt mask. +* @arg SPI_IT_TE: Transmit FIFO empty interrupt mask. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void SPI_ITConfig(uint8_t SPI_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_CONFIG_IT(SPI_IT)); + + if (NewState != DISABLE) { + /* Enable the selected SPI interrupts */ + SET_BIT(SPI->IMSC, SPI_IT); + } + else { + /* Disable the selected SPI interrupts */ + CLEAR_BIT(SPI->IMSC, SPI_IT); + } +} + + +/** +* @brief Enables or disables the output if in slave mode. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void SPI_SlaveModeOutputCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the output */ + SPI->CR1_b.SOD = RESET; + } + else { + /* Disable the output */ + SPI->CR1_b.SOD = SET; + } +} + +/** +* @brief Transmits a Data through the SPI peripheral. +* @param Data: Data to be transmitted. +* @retval None +*/ +void SPI_SendData(uint32_t Data) +{ + /* Write in the DR register the data to be sent */ + SPI->DR = Data; +} + +/** +* @brief Returns the most recent received data by the SPI peripheral. +* @param None +* @retval The value of the received data. +*/ +uint32_t SPI_ReceiveData(void) +{ + /* Return the data in the DR register */ + return SPI->DR; +} + +/** +* @brief Configures the data size for the selected SPI. +* @param SPI_DataSize: specifies the SPI data size. +* This parameter can be one of the following values: +* @arg SPI_DataSize_32b: Set data frame format to 32bit +* ... +* @arg SPI_DataSize_5b: Set data frame format to 5bit +* @arg SPI_DataSize_4b: Set data frame format to 4bit +* @retval None +*/ +void SPI_DataSizeConfig(uint16_t SPI_DataSize) +{ + /* Check the parameters */ + assert_param(IS_SPI_DATASIZE(SPI_DataSize)); + + /* set the datasize */ + SPI->CR0_b.DSS = SPI_DataSize; +} + +/** +* @brief Configures the command size for the selected SPI. +* @param SPI_DataSize: specifies the SPI command size. +* This parameter can be one of the following values: +* @arg SPI_DataSize_32b: Set data frame format to 32bit +* ... +* @arg SPI_DataSize_5b: Set data frame format to 5bit +* @arg SPI_DataSize_4b: Set data frame format to 4bit +* @retval None +*/ +void SPI_CommandSizeConfig(uint16_t SPI_DataSize) +{ + /* Check the parameters */ + assert_param(IS_SPI_DATASIZE(SPI_DataSize)); + + /* set the datasize */ + SPI->CR0_b.CSS = SPI_DataSize; +} + +/** +* @brief Enable the wait state only for Microwire mode. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void SPI_EnableWaitState(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the wait state */ + SPI->CR1_b.MSPIWAIT = RESET; + } + else { + /* Disable the wait state */ + SPI->CR1_b.MSPIWAIT = SET; + } +} + + +/** +* @brief Configures the frame format for the selected SPI. +* @param SPI_FrameFormat: specifies the SPI frame format. +* This parameter can be one of the following values: +* @arg SPI_FrmFrmt_Motorola: Set the Motorola SPI frame format +* @arg SPI_FrmFrmt_Microwire: Set the MicroWire frame format +* @retval None +*/ +void SPI_FrameFormatConfig(uint8_t SPI_FrameFormat) +{ + /* Check the parameters */ + assert_param(IS_SPI_FRMFRMT(SPI_FrameFormat)); + + /* set the datasize */ + SPI->CR0_b.FRF = SPI_FrameFormat; +} + + +/** +* @brief Checks whether the specified SPI flag is set or not. +* @param SPI_FLAG: specifies the SPI flag to check. +* This parameter can be any combination of the following values: +* @arg SPI_IT_TX: Transmit FIFO half empty or less condition interrupt mask. +* @arg SPI_IT_RX: Receive FIFO half full or less condition interrupt mask. +* @arg SPI_IT_RT: Receive FIFO not empty and no read prior to timeout period interrupt mask. +* @arg SPI_IT_ROR: Receive FIFO written to while full condition interrupt mask. +* @arg SPI_IT_TUR: Transmit underrun interrupt mask. +* @arg SPI_IT_TE: Transmit FIFO empty interrupt mask. +* @retval FlagStatus: functional state @ref FlagStatus +* This parameter can be: SET or RESET. +*/ +FlagStatus SPI_GetFlagStatus(uint16_t SPI_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SPI_GET_FLAG(SPI_FLAG)); + + /* Check the status of the specified SPI flag */ + if (READ_BIT(SPI->SR, SPI_FLAG) != (uint16_t)RESET) { + /* SPI_FLAG is set */ + return SET; + } + else { + /* SPI_FLAG is reset */ + return RESET; + } + +} + +/** +* @brief Checks whether the specified SPI interrupt has occurred or not. +* @param SPI_IT: specifies the SPI interrupt source to check. +* This parameter can be one of the following values: +* @arg SPI_IT_TX: Transmit FIFO half empty or less condition interrupt mask. +* @arg SPI_IT_RX: Receive FIFO half full or less condition interrupt mask. +* @arg SPI_IT_RT: Receive FIFO not empty and no read prior to timeout period interrupt mask. +* @arg SPI_IT_ROR: Receive FIFO written to while full condition interrupt mask. +* @arg SPI_IT_TUR: Transmit underrun interrupt mask. +* @arg SPI_IT_TE: Transmit FIFO empty interrupt mask. +* @retval ITStatus: functional state @ref ITStatus +* This parameter can be: SET or RESET. +*/ +ITStatus SPI_GetITStatus(uint8_t SPI_IT) +{ + /* Check the parameters */ + assert_param(IS_SPI_GET_IT(SPI_IT)); + + /* Check the status of the specified SPI interrupt */ + if (READ_BIT(SPI->RIS, SPI_IT) != (uint16_t)RESET) { + /* SPI_IT is set */ + return SET; + } + else { + /* SPI_IT is reset */ + return RESET; + } + +} + +/** +* @brief Clears the SPI interrupt pending bits. +* @param SPI_IT: specifies the SPI interrupt pending bit to clear. +* This parameter can be one of the following values: +* @arg SPI_IT_TX: Transmit FIFO half empty or less condition interrupt mask. +* @arg SPI_IT_RX: Receive FIFO half full or less condition interrupt mask. +* @arg SPI_IT_RT: Receive FIFO not empty and no read prior to timeout period interrupt mask. +* @arg SPI_IT_ROR: Receive FIFO written to while full condition interrupt mask. +* @arg SPI_IT_TUR: Transmit underrun interrupt mask. +* @arg SPI_IT_TE: Transmit FIFO empty interrupt mask. +* @retval None +*/ +void SPI_ClearITPendingBit(uint8_t SPI_IT) +{ + /* Check the parameters */ + assert_param(IS_SPI_CLEAR_IT(SPI_IT)); + + /* Clear the selected SPI interrupt pending bit */ + CLEAR_BIT(SPI->ICR, SPI_IT); +} + +/** +* @brief Clear all data present within the RX FIFO of the SPI peripherial. +* SPI peripherial clocks have to be enabled first before the use. +* @param None +* @retval None +*/ +void SPI_ClearRXFIFO(void) +{ + /* Flush the data from SPI RX FIFO */ + while(SET == SPI_GetFlagStatus(SPI_FLAG_RNE) ) { + SPI_ReceiveData(); + } +} + +/** +* @brief Clear all data present within the TX FIFO of the SPI peripherial. +* SPI peripherial clocks have to be enabled first before the use. +* @param None +* @retval None +*/ +void SPI_ClearTXFIFO(void) +{ + uint32_t tmp; + + /* Enable read from the TX FIFO */ + SPI->ITCR_b.SWAPFIFO = SET; + + /* Flush the data from the TX FIFO till it is not empty. */ + while(0 == SPI->SR_b.TFE) { + tmp |= SPI->TDR; + } + + /* Disable the read from the TX FIFO */ + SPI->ITCR_b.SWAPFIFO = RESET; + +} + +/** +* @brief Set the SPI communication mode. +* @param Mode: specifies the SPI communication mode. +* This parameter can be one of the following values: +* @arg SPI_FULL_DUPLEX_MODE: SPI full duplex communication mode. +* @arg SPI_TRANSMIT_MODE: SPI transmit communication mode. +* @arg SPI_RECEIVE_MODE: SPI receive communication mode. +* @arg SPI_COMBINED_MODE: SPI combined communication mode. +* @retval None +*/ +void SPI_SetMasterCommunicationMode(uint32_t Mode) +{ + /* Check the parameters */ + assert_param(IS_SPI_COM_MODE(Mode)); + + /* Set the communication mode */ + SPI->CR0_b.SPIM = Mode; +} + +/** +* @brief Set the dummy character used for the SPI master communication. +* @param NullCharacter: Dummy character to be used. +* @retval None +*/ +void SPI_SetDummyCharacter(uint32_t NullCharacter) +{ + /* Set the dummy character */ + SPI->CHN = NullCharacter; +} + +/** +* @brief Set the number of frames to receive from slave. +* @param Number: Number of frames to receive. +* @retval None +*/ +void SPI_SetNumFramesToReceive(uint16_t Number) +{ + /* Set the number of frames to receive */ + SPI->RXFRM = Number; +} + +/** +* @brief Set the number of frames to transmit to slave +* @param Number: Number of frames to transmit. +* @retval None +*/ +void SPI_SetNumFramesToTransmit(uint16_t Number) +{ + /* Set the number of frames to transmit */ + SPI->WDTXF = Number; +} + + +/** +* @brief Master can select the slave by driving the CS pin by software. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void SPI_SlaveSwSelection(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the output */ + SPI->CR0_b.CS1 = RESET; + } + else { + /* Disable the output */ + SPI->CR0_b.CS1 = SET; + } +} + +/** +* @brief Master can select the slave by driving the CS pin by software. +* @param Endian: the endian format @ref SPI_Endian_Format_Definition +* @retval None +*/ +void SPI_EndianFormatReception(uint8_t Endian) +{ + /* Check the parameters */ + assert_param(IS_SPI_ENDIAN(Endian)); + + SPI->CR1_b.RENDN = Endian; +} + +/** +* @brief Master can select the slave by driving the CS pin by software. +* @param Endian: the endian format @ref SPI_Endian_Format_Definition +* @retval None +*/ +void SPI_EndianFormatTransmission(uint8_t Endian) +{ + /* Check the parameters */ + assert_param(IS_SPI_ENDIAN(Endian)); + + SPI->CR1_b.TENDN = Endian; +} + + +/** +* @brief Configure the delay between the frames. +* The MSPIWAIT value is used to insert a wait state between frames. +* The SSPFRM pulse duration is given by the equation: +* SSPCLKOUT x {MSPIWAIT - (SCR-1) / [2x(SCR+1)]}. +* When SCR=1, MSPIWAIT indicates the number of SSPCLKO cycle that +* the SSPFRM pulse duration should have between frames. +* @param Delay: this value must be less than or equal to 15. +* 0 means no delay (default). +* @retval None +*/ +void SPI_DelayBetweenFrames(uint8_t Delay) +{ + /* Check the parameters */ + assert_param(IS_SPI_ENDIAN(Delay)); + + SPI->CR1_b.MSPIWAIT = Delay; +} + + +/** +* @brief Master insert a delay of two clock cycle if enabled. +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void SPI_DelayDataInput(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the output */ + SPI->CR1_b.DATAINDEL = RESET; + } + else { + /* Disable the output */ + SPI->CR1_b.DATAINDEL = SET; + } +} + + +/** + * @brief Sets the SPI interrupt FIFO level. + * @param SPI_TX_FIFO_LEV: specifies the transmit interrupt FIFO level. + * This parameter can be one of the following values: + * @arg FIFO_TX_LEV_1: interrupt when TX FIFO contains 1 element or more + * @arg FIFO_TX_LEV_4: interrupt when TX FIFO contains 4 elements or more + * @arg FIFO_TX_LEV_8: interrupt when TX FIFO contains 8 elements or more + * @retval None + */ +void SPI_TxFifoInterruptLevelConfig(uint8_t SPI_TX_FIFO_LEV) +{ + /* Check the parameters */ + assert_param(IS_SPI_FIFO_LEV(SPI_TX_FIFO_LEV)); + + SPI->CR1_b.TXIFLSEL = SPI_TX_FIFO_LEV; +} + +/** + * @brief Sets the SPI interrupt FIFO level. + * @param SPI_RX_FIFO_LEV: specifies the receive interrupt FIFO level. + * This parameter can be one of the following values: + * @arg FIFO_RX_LEV_1: interrupt when RX FIFO contains 1 element or more + * @arg FIFO_RX_LEV_4: interrupt when RX FIFO contains 4 elements or more + * @arg FIFO_RX_LEV_8: interrupt when RX FIFO contains 8 elements or more + * + * @retval None + */ +void SPI_RxFifoInterruptLevelConfig(uint8_t SPI_RX_FIFO_LEV) +{ + /* Check the parameters */ + assert_param(IS_SPI_FIFO_LEV(SPI_RX_FIFO_LEV)); + + SPI->CR1_b.RXIFLSEL = SPI_RX_FIFO_LEV; +} + +/** + * @brief Enables or disables the SPI DMA interface. + * @param SPI_DMAReq: specifies the DMA request. + * This parameter can be any combination of the following values: + * @arg SPI_DMAReq_Tx: SPI DMA transmit request + * @arg SPI_DMAReq_Rx: SPI DMA receive request. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_DMACmd(uint8_t SPI_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_DMAREQ(SPI_DMAReq)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA transfer */ + SPI->DMACR |= SPI_DMAReq; + } + else + { + /* Disable the DMA transfer */ + SPI->DMACR &= (uint8_t)~SPI_DMAReq; + } +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_sysCtrl.c b/drivers/src/BlueNRG1_sysCtrl.c new file mode 100644 index 0000000..39df5d4 --- /dev/null +++ b/drivers/src/BlueNRG1_sysCtrl.c @@ -0,0 +1,284 @@ +/** + ****************************************************************************** + * @file BlueNRG1_sysCtrl.c + * @author VMA Application Team + * @version V2.0.1 + * @date 21-March-2016 + * @brief This file provides all the System Controller firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_sysCtrl.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @defgroup SysCtrl System Controller Driver + * @{ + */ + +/** @defgroup SysCtrl_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup SysCtrl_Private_Defines Private Defines + * @{ + */ + + +#define SOC_REASON_SYSREQ (0x00000002) +#define SOC_REASON_WDG (0x00000004) +#define SOC_REASON_LOCKUP (0x00000008) + +#define BLE_REASON_WAKEUP_RST (0x00000001) +#define BLE_REASON_BOR_RST (0x00000002 | BLE_REASON_WAKEUP_RST) +#define BLE_REASON_POR_RST (0x00000004 | BLE_REASON_WAKEUP_RST) +#define BLE_REASON_FROM_IO9 (0x00000008 | BLE_REASON_WAKEUP_RST) +#define BLE_REASON_FROM_IO10 (0x00000010 | BLE_REASON_WAKEUP_RST) +#define BLE_REASON_FROM_IO11 (0x00000020 | BLE_REASON_WAKEUP_RST) +#define BLE_REASON_FROM_IO12 (0x00000040 | BLE_REASON_WAKEUP_RST) +#define BLE_REASON_FROM_IO13 (0x00000080 | BLE_REASON_WAKEUP_RST) +#define BLE_REASON_FROM_TIMER1 (0x00000100 | BLE_REASON_WAKEUP_RST) +#define BLE_REASON_FROM_TIMER2 (0x00000400 | BLE_REASON_WAKEUP_RST) + + +/** + * @} + */ + +/** @defgroup SysCtrl_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup SysCtrl_Private_Variables Private Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup SysCtrl_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup SysCtrl_Public_Functions Public Functions + * @{ + */ + + +/** + * @brief De init function + * @param None + * @retval None + */ +void SysCtrl_DeInit(void) +{ + SYSTEM_CTRL->WKP_IO_IS = 0x00; + SYSTEM_CTRL->WKP_IO_IE = 0x03; + CKGEN_SOC->CLOCK_EN = 0x0003FFFF; + CKGEN_BLE->CLK32K_COUNT = 0x0000000F; + CKGEN_BLE->CLK32K_IT = 0x00000000; +} + + +/** + * @brief Enables the clock for the specified peripheral. + * @param PeriphClock: Peripheral to be enabled, this value can be + * @arg CLOCK_PERIPH_GPIO Clock of GPIO peripheral + * @arg CLOCK_PERIPH_NVM Clock of NVM peripheral + * @arg CLOCK_PERIPH_SYS_CONTROL Clock of SYSTEM CONTROL peripheral + * @arg CLOCK_PERIPH_UART Clock of UART peripheral + * @arg CLOCK_PERIPH_SPI Clock of SPI peripheral + * @arg CLOCK_PERIPH_WDG Clock of WATCHDOG peripheral + * @arg CLOCK_PERIPH_ADC Clock of ADC peripheral + * @arg CLOCK_PERIPH_I2C1 Clock of I2C1 peripheral + * @arg CLOCK_PERIPH_I2C2 Clock of I2C2 peripheral + * @arg CLOCK_PERIPH_MTFX1 Clock of MFTX1 peripheral + * @arg CLOCK_PERIPH_MTFX2 Clock of MFTX2 peripheral + * @arg CLOCK_PERIPH_RTC Clock of RTC peripheral + * @arg CLOCK_PERIPH_DMA Clock of DMA peripheral + * @arg CLOCK_PERIPH_RNG Clock of RNG peripheral + * @arg CLOCK_PERIPH_PKA Clock of PKA peripheral + * @param NewState: New state of the peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SysCtrl_PeripheralClockCmd(uint32_t PeriphClock, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CLOCK_PERIPH(PeriphClock)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) { + SET_BIT(CKGEN_SOC->CLOCK_EN, PeriphClock); + } + else { + CLEAR_BIT(CKGEN_SOC->CLOCK_EN, PeriphClock); + } +} + +/** + * @brief Get the wakeup reason. + * @param None + * @retval RESET_REASON_Type: wakeup reason @ref RESET_REASON_Type + */ +uint16_t SysCtrl_GetWakeupResetReason(void) +{ + uint32_t tmpSoc, tmpBle; + uint16_t wakeup_src; + + tmpSoc = CKGEN_SOC->REASON_RST; + tmpBle = CKGEN_BLE->REASON_RST; + + wakeup_src = RESET_NONE; + + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_FROM_IO9) == BLE_REASON_FROM_IO9)) { + wakeup_src |= RESET_BLE_WAKEUP_FROM_IO9; + } + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_FROM_IO10) == BLE_REASON_FROM_IO10)) { + wakeup_src |= RESET_BLE_WAKEUP_FROM_IO10; + } + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_FROM_IO11) == BLE_REASON_FROM_IO11)) { + wakeup_src |= RESET_BLE_WAKEUP_FROM_IO11; + } + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_FROM_IO12) == BLE_REASON_FROM_IO12)) { + wakeup_src |= RESET_BLE_WAKEUP_FROM_IO12; + } + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_FROM_IO13) == BLE_REASON_FROM_IO13)) { + wakeup_src |= RESET_BLE_WAKEUP_FROM_IO13; + } + + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_FROM_TIMER1) == BLE_REASON_FROM_TIMER1)) { + wakeup_src |= RESET_BLE_WAKEUP_FROM_TIMER1; + } + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_FROM_TIMER2) == BLE_REASON_FROM_TIMER2)) { + wakeup_src |= RESET_BLE_WAKEUP_FROM_TIMER2; + } + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_POR_RST) == BLE_REASON_POR_RST)) { + wakeup_src |= RESET_BLE_POR; + } + if ((tmpSoc == 0) && + ((tmpBle & BLE_REASON_BOR_RST) == BLE_REASON_BOR_RST)) { + wakeup_src |= RESET_BLE_BOR; + } + if (tmpSoc == SOC_REASON_SYSREQ) { + wakeup_src |= RESET_SYSREQ; + } + if (tmpSoc == SOC_REASON_WDG) { + wakeup_src |= RESET_WDG; + } + if((tmpSoc == SOC_REASON_LOCKUP)) { + wakeup_src |= RESET_LOCKUP; + } + + return wakeup_src; +} + + +/** +* @brief Configure the wakeup source from IO. +* @param IO: the IO selected as wakeup source, the value can be +* @arg WAKEUP_ON_IO9 Wakeup source is IO9 +* @arg WAKEUP_ON_IO10 Wakeup source is IO10 +* @arg WAKEUP_ON_IO11 Wakeup source is IO11 +* @arg WAKEUP_ON_IO12 Wakeup source is IO12 +* @arg WAKEUP_ON_IO13 Wakeup source is IO13 +* @param LevelState: select the level of the wakeup source, the value can be +* @arg WAKEUP_ON_HIGH_STATE Wakeup on high state +* @arg WAKEUP_ON_LOW_STATE Wakeup on low state +* @param NewState: functional state @ref FunctionalState +* This parameter can be: ENABLE or DISABLE. +* @retval None +*/ +void SysCtrl_WakeupFromIo(uint8_t IO, uint8_t LevelState, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_WAKEUP_ON_IO(IO)); + assert_param(IS_WAKEUP_ON_STATE(LevelState)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(LevelState == WAKEUP_ON_HIGH_STATE) { + SET_BIT(SYSTEM_CTRL->WKP_IO_IS, IO); + } + else { + CLEAR_BIT(SYSTEM_CTRL->WKP_IO_IS, IO); + } + + if(NewState == ENABLE) { + SET_BIT(SYSTEM_CTRL->WKP_IO_IE, IO); + } + else { + CLEAR_BIT(SYSTEM_CTRL->WKP_IO_IE, IO); + } + +} + +/** + * @brief Enable disable the XO clock divider for the system control. + * @param XOFreq: configure the system for the correct XO external clock used, the value can be +* @arg XO_32MHz enable the XO divider and expect a 32 MHz external clock. +* @arg XO_16MHz disable the XO divider and expect a 16 MHz external clock. + * @retval None + */ +void SysCtrl_SelectXO(uint8_t XOFreq) +{ + /* Check the parameters */ + assert_param(IS_XO_FREQ(XOFreq)); + + if(XOFreq == XO_32MHZ) { + SYSTEM_CTRL->CTRL_b.MHZ32_SEL = SET; + } + else if(XOFreq == XO_16MHZ) { + SYSTEM_CTRL->CTRL_b.MHZ32_SEL = RESET; + } +} + + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_timer.c b/drivers/src/BlueNRG1_timer.c new file mode 100644 index 0000000..8e04ae6 --- /dev/null +++ b/drivers/src/BlueNRG1_timer.c @@ -0,0 +1,824 @@ +/** + ****************************************************************************** + * @file BlueNRG1_timer.c + * @warning This module must not be included in applications based on the + * BLE stack library. In that case, the API implementation is managed by the library itself. + * The API calls remain the same. In the future release the BLE stack library will rely on + * the Timer module library. + * @author RF Application Team + * @date Jan-2020 + * @brief This file provides a set of function to manage the sleep timer. + * @details The basic support is provided by a low speed oscillator with a nominal speed of 32.768 kHz. + * The low speed oscillator provides a counter that increments at a nominal rate of 30.52 us. + * The counter is 24 bits wide and the low speed oscillator only increments bits 23:4 (most significant 20 bits) + * The remaining 4 bits are interpolated using the high speed 16 MHz clock. The counter unit are called conventionally + * machine time unit (MTU). + * At the end, the counter resolution will be about 1.91 us and it will wrap every 32 sec. + * It is important to notice that the interpolated bits will only be functional when the system is out of sleep. + * While in sleep only the 20 most significant bits will tick. + * The user can setup a timer that will wakeup the system (if asleep) and it will trigger an interrupt when the timer expires. + * The user timer will not take into account the high speed XTAL wakeup time. + * The possible options for the low speed oscillator are: + * - external 32.768 kHz XTAL + * - internal ring oscillator (RO) + * + * The external 32 kHz XTAL meets the assumption made above regarding the nominal speed. The internal RO, + * due to technology contraints, is very sensitive to temperature and so the frequency absolute value and its stability + * have a very wide spread compared to external 32 kHz XTAL. Due to this reason, the concept of calibration or compensation is + * introduced. The calibration process involves measuring the nominal 32 kHz period using the high speed 16 MHz clock, once + * this operation is performed, the software will compensate all the timing using the most recent calibration value, + * hardware will also use the calibration value to tune the interpolator for the least significant 4 bits. + * The calibration is started by hardware at power-on and software in all the other cases. + * As a rule of thumb, it can be assumed that the internal RO varies between 30kHz and 60 kHz and in general + * the lower the temperature, the higher the frequency. + * In order to cope with this variation a concept of system time unit (STU) is introduced. + * The STU is defined as scaled clock compared to MTU in order to: + * - handle variation of internal RO + * - express easily timing dictated by Bluetooth Low Energy protocol. + * + * The STU are absolute unit of time and each unit represent 625/256 us, that is about 2.44 us. + * The MTU, on the other hand, have a nominal value of 1.91 us, and this value can be assumed constant when using + * external 32 kHz clock, but it will vary (mainly with temperature variation) when using internal RO. + * As a design choice, use of MTU is reserved as much as possible to the driver, while STU is exposed to user. + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2020 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_timer.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver +* @{ +*/ + +/** @addtogroup TIMER_Peripheral TIMER Peripheral +* @{ +*/ + +/** @defgroup TIMER_Private_TypesDefinitions Private Types Definitions +* @{ +*/ +typedef struct timer_context_s { + uint64_t cumulative_time; /** Absolute system time since power up */ + uint64_t last_calibration_time; /** Absolute system time when last calibration was performed */ + uint32_t hs_startup_time; /** XTAL startup time in STU */ + uint8_t wakeup_time_offset; /** wakeup up time offset expressed in half slow period unit*/ + uint16_t period_slow; /** Number of 16 MHz cycles in a low speed oscillator period*/ + uint16_t last_period_slow; /** Number of 16 MHz cycles in a low speed oscillator period most recent */ + uint32_t period; /** Number of 16 MHz clock cycles in (2*(SLOW_COUNT+1)) low speed oscillator periods */ + uint32_t freq; /** 2^39/period */ + uint32_t freq1; /** Round(((freq/64)*0x753)/256) */ + uint32_t period1; /** Round (( ((period /256) * 0x8BCF6) + (((period % 256)* 0x8BCF6)/256)) / 32) */ + uint32_t last_period1; /** Period global in last calibration */ + uint32_t last_machine_time; /** Last machine time used to update cumulative time */ + uint32_t last_calibration_machine_time; /** Last machine time when calibration was performed */ + uint8_t periodic_calibration; /** Tells whether periodic hardware calibration is needed or not, i.e. lsosc speed varies with temperature, etc. */ + uint32_t host_time; /**Last programmed value in HOST_WKUP_TIMER register**/ + uint32_t wakeup_time; /**Last programmed value in TIMEOUT register**/ + uint8_t tx_cal_delay_st; /** Delay in STU between TIMEOUT+wakeup_time_offset and first transmitted bit when cal is requested**/ + uint8_t tx_no_cal_delay_st; /** Delay in STU between TIMEOUT+wakeup_time_offset and first transmitted bit when no cal is requested**/ + uint8_t rx_cal_delay_st; /** Delay in STU between TIMEOUT+wakeup_time_offset and rx window start when cal is requested**/ + uint8_t rx_no_cal_delay_st; /** Delay in STU between TIMEOUT+wakeup_time_offset and rx window start when no cal is requested**/ + int16_t roundingError; +} TIMER_ContextType; + +/** +* @} +*/ + +/** @defgroup TIMER_Private_Defines Private Defines +* @{ +*/ +/** +* @} +*/ + +/** @defgroup TIMER_Private_Macros Private Macros +* @{ +*/ + +#define TIMER_20MSB_MASK 0xFFFFF0 +#define TIME24_DIFF(a, b) (((int32_t)((a - b) << 8)) >> 8) +#define TIME_DIFF(a, b) (((int32_t)((a - b) << (32-TIMER_BITS))) >> (32-TIMER_BITS)) + +/* This define assumes that a is always greater than b */ +#define TIME_ABSDIFF(a, b) ((a - b) & TIMER_MAX_VALUE) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) < (b) )? (b) : (a) + +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_irq(); \ +/* Must be called in the same scope of ATOMIC_SECTION_BEGIN */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +#define TIMER_SEL_THR 20//75 + +#define TIMER_TX_EVENT 1 +#define TIMER_RX_EVENT 0 + +#define WAKEUP_TIMER_EN (1<<24) +#define TIMER1_EN (1<<25) + +/** +* @} +*/ + +/** @defgroup TIMER_Private_Variables Private Variables +* @{ +*/ +TIMER_ContextType TIMER_Context; +/** +* @} +*/ + +/** @defgroup TIMER_Private_FunctionPrototypes Private Function Prototypes +* @{ +*/ +static void _timer_start_calibration(void) +{ + /* Clear any pending interrupt */ + CKGEN_BLE->CLK32K_IT = 1; + CKGEN_BLE->CLK32K_PERIOD = 0; +} + +static void _get_calibration_data(TIMER_ContextType *context) +{ + uint32_t mult = 0x753 ; + uint32_t freq = CKGEN_BLE->CLK32K_FREQ; + uint32_t period = CKGEN_BLE->CLK32K_PERIOD; + uint32_t a1 = freq >> 6 ; + uint32_t a2 = a1 * mult ; + + uint32_t mul1 = 0x8BCF6 ; + uint32_t b1 = period >> 8 ; + uint32_t b2 = period & 0xff ; + + context->period1 = ((mul1 * b1) + ((b2 * mul1)>>8) + 16 )>>5 ; + context->freq1 = (a2 + 128) >> 8 ; + context->period = period; + context->freq = freq; + context->period_slow = ((period * 1365) >> 16); +} + +static void _timer_calibrate(TIMER_ContextType *context) +{ + _timer_start_calibration(); + + while(CKGEN_BLE->CLK32K_IT == 0); + _get_calibration_data(context); +} + +static void update_interpolator(uint16_t period_slow) +{ + __blue_RAM.BlueGlobVar.period_slow = period_slow; + /* The only mechanism to reload the table is to trigger a fake wakeup with no + radio activity. Otherwise the value of period slow will be loaded at the next wakeup timer timeout*/ + if ((__blue_RAM.BlueGlobVar.Config & 8U) == 0) { + /* Fake wakeup to make sure that interpolator take into account period_slow stored in RAM */ + /* Interrupt should be disabled because we can risk to wait for wrapping ??? */ + uint32_t timeout = (BLUE_CTRL->CURRENT_TIME + 2) & TIMER_MAX_VALUE; + while (timeout < 2) { + timeout = (BLUE_CTRL->CURRENT_TIME + 2) & TIMER_MAX_VALUE; + } + BLUE_CTRL->TIMEOUT = (timeout)| (1<<24); + while (BLUE_CTRL->CURRENT_TIME < (timeout)); + /*After the fake wake up, the interpolator needs about half slow clock + cycle before to start counting correctly. In this time interval, if TIMEOUT + register is written, the value of period_slow is ignored. This is a problem + if the first radio activity is scheduled with the timer1. */ + timeout = (BLUE_CTRL->CURRENT_TIME + 16) & TIMER_20MSB_MASK; + while (BLUE_CTRL->CURRENT_TIME < (timeout)); + /*Disabling timer*/ + BLUE_CTRL->TIMEOUT = (1 << 28); + } +} + +/** + * @brief Translate STU to MTU, it is implemented using integer operation and it is equivalent to: + * result=(time*625/256)*(frequency * 16)/1e6, where frequency is the current low speed frequency + * @param time: Time expressed in STU to be translated in STU + * @param freq: Frequency of lsosc expressed as (2048*f)/25 where f is the lsosc frequency expressed in Hz. + * @return Machine Time Units + */ +static uint32_t systime_to_machinetime(uint32_t time, uint32_t freq) +{ + #if TIME_CONVERSION2 + static volatile uint64_t time_tmp, time_tmp2; + time_tmp = (uint64_t)time*(uint64_t)freq; + time_tmp2 = ((time_tmp+(1U<<20))>>21); + return (uint32_t)time_tmp2; +#else + uint32_t time1 = (time >> 15) ; + uint32_t time2 = time & 0x7fff ; + uint32_t freq1 = freq >> 7 ; + uint32_t result = freq*time1 + ((time2 * freq1) >> 8) ; + return((result + 32) >> 6) ; +#endif +} + +/** + * @brief Translate microseconds in STU + * @param time: Time expressed in microseconds to be translated in STU + * @return System Time Units + */ +static uint32_t us_to_systime(uint32_t time) +{ + uint32_t t1, t2; + t1 = time * 0x68; + t2 = time * 0xDB; + return (t1 >> 8) + (t2 >> 16); +} + +/** + * @brief Translate microseconds in MTU + * @param time: Time expressed in microseconds to be translated in MTU + * @return Machine Time Units + */ +static uint32_t us_to_machinetime(uint32_t time) +{ + return systime_to_machinetime(us_to_systime(time),TIMER_Context.freq1); +} + +/** + * @brief Translate MTU to STU, it is implemented using integer operation and it is equivalent to: + * result=(time*25600)*period, where period is the current low speed period in seconds. + * @param time: Time expressed in STU to be translated in STU + * @param period1: Period of lsosc expressed as (3*62500*286331)*p where p is the lsosc period expressed in seconds. + * @return System Time Units + */ +static uint32_t machinetime_to_systime(uint32_t time, uint32_t period1, int16_t* round_err) +{ +#if TIME_CONVERSION2 + uint64_t period_global = (uint64_t)period1; + uint64_t result_tmp = period_global*(uint64_t)time; + uint32_t result_round = (uint32_t)((result_tmp+(1<<20))>>21); + return result_round; +#else + uint32_t time1 = (time >> 14); + uint32_t time2 = time & 0x3fff; + uint32_t per1 = period1 >> 8; + uint32_t result = period1*time1 + ((time2 * per1) >> 6) - (uint32_t)(int32_t)*round_err; + uint32_t result_round = (result + 64) >> 7; + uint32_t result_round_u32 = (result_round<<7)-result; + *round_err = (int16_t)result_round_u32; + return result_round; +#endif +} + +static uint64_t get_system_time_and_machine(TIMER_ContextType *context, uint32_t *current_machine_time) +{ + uint32_t difftime; + uint64_t new_time = context->cumulative_time; + *current_machine_time = BLUE_CTRL->CURRENT_TIME; + difftime = TIME_ABSDIFF(*current_machine_time, context->last_machine_time); + new_time += machinetime_to_systime(difftime,context->period1,&(context->roundingError)); + return new_time; +} + +static uint64_t get_system_time(TIMER_ContextType *context) +{ + uint32_t current_machine_time; + return get_system_time_and_machine(context, ¤t_machine_time); +} + +static void update_system_time(TIMER_ContextType *context) +{ + uint32_t current_machine_time; + current_machine_time = BLUE_CTRL->CURRENT_TIME; + uint32_t period = context->last_period1; + context->cumulative_time = context->last_calibration_time + \ + machinetime_to_systime(TIME_ABSDIFF(current_machine_time, + context->last_calibration_machine_time), + period, + &(context->roundingError)); + context->last_machine_time = current_machine_time; + context->last_calibration_machine_time = current_machine_time; + context->last_calibration_time = context->cumulative_time; + context->last_period1 = context->period1; +} + +static void _update_xtal_startup_time(uint16_t hs_startup_time, uint32_t freq1) +{ + uint32_t time1 = systime_to_machinetime(hs_startup_time, freq1) ; + if(time1 >= 1024) + time1 = 1023 ; + if (time1 < 8) + time1 = 8; + TIMER_Context.wakeup_time_offset = time1 >> 3; + if((__blue_RAM.BlueGlobVar.Config & 8U) == 0U) + __blue_RAM.BlueGlobVar.wakeup_time_offset = TIMER_Context.wakeup_time_offset; +} + +/** +* @} +*/ + +/** @defgroup TIMER_Public_Functions Public Functions +* @{ +*/ + +/** + * @brief Initialize the TIMER functionality + * @retval None + */ +void TIMER_Init(TIMER_InitType* TIMER_InitStruct) +{ + TIMER_Context.hs_startup_time = TIMER_InitStruct->XTAL_StartupTime; + + if (TIMER_InitStruct->TIMER_PeriodicCalibration || TIMER_InitStruct->TIMER_InitialCalibration) { + /* Make sure any pending calibration is over */ + while(CKGEN_BLE->CLK32K_IT == 0); + /* Set SLOW_COUNT to 23, that is calibrate over 24 clock periods, this number + cannot be changed without changing all the integer maths function in the + file */ + CKGEN_BLE->CLK32K_COUNT_b.SLOW_COUNT=23; + _timer_calibrate(&TIMER_Context); + /* For first time set last to current */ + TIMER_Context.last_period1 = TIMER_Context.period1; + } + else { + /* Assume fix frequency at 32.768 kHz */ + TIMER_Context.last_period1 = 0x00190000; + TIMER_Context.period1 = 0x00190000 ; + TIMER_Context.freq1 = 0x0028F5C2 ; + TIMER_Context.period = 23437; + TIMER_Context.freq = 23456748; + TIMER_Context.period_slow = 488; + } + TIMER_Context.periodic_calibration = TIMER_InitStruct->TIMER_PeriodicCalibration; + _update_xtal_startup_time(TIMER_Context.hs_startup_time, TIMER_Context.freq1); + update_interpolator(TIMER_Context.period_slow); + TIMER_Context.last_period_slow = TIMER_Context.period_slow; + TIMER_Context.cumulative_time = 0; + TIMER_Context.last_machine_time = BLUE_CTRL->CURRENT_TIME; + TIMER_Context.last_calibration_machine_time = TIMER_Context.last_machine_time; + TIMER_Context.last_calibration_time = 0; + TIMER_Context.tx_cal_delay_st = DELAY_TX + us_to_systime((__blue_RAM.BlueGlobVar.TxDelay1) & 0x7F); + TIMER_Context.tx_no_cal_delay_st = DELAY_TX_NO_CAL + us_to_systime((__blue_RAM.BlueGlobVar.TxDelay) & 0x7F); + TIMER_Context.rx_cal_delay_st = DELAY_RX + us_to_systime((__blue_RAM.BlueGlobVar.RcvDelay1) & 0x7F); + TIMER_Context.rx_no_cal_delay_st = DELAY_RX_NO_CAL + us_to_systime((__blue_RAM.BlueGlobVar.RcvDelay1) & 0x7F); +} + +/** + * @brief Perform a low speed clock calibration and store results in the global context. + * It updates the XTAL startup time and the interpolator configuration. + * It updates also the cumulative STU variable, so it should be called peiodically to manage timer wrapping, + * regardless of actual need of periodic calibration. + * @warning This function is not re-entrant since it updates the context variable storing the system time. + * @retval None + */ +void TIMER_Calibrate(void) +{ + if (TIMER_Context.periodic_calibration) { + TIMER_ContextType ContextToUpdate = TIMER_Context; + _timer_calibrate(&ContextToUpdate); + _update_xtal_startup_time(ContextToUpdate.hs_startup_time, ContextToUpdate.freq1); + if (ContextToUpdate.last_period_slow != ContextToUpdate.period_slow) { + update_interpolator(ContextToUpdate.period_slow); + ContextToUpdate.last_period_slow = ContextToUpdate.period_slow; + } + ATOMIC_SECTION_BEGIN(); + /* Copying only the updated fields. + Faster than memcpy: TIMER_Context = ContextToUpdate;*/ + TIMER_Context.wakeup_time_offset = ContextToUpdate.wakeup_time_offset; + TIMER_Context.period_slow = ContextToUpdate.period_slow; + TIMER_Context.last_period_slow = ContextToUpdate.last_period_slow; + TIMER_Context.period = ContextToUpdate.period; + TIMER_Context.freq = ContextToUpdate.freq; + TIMER_Context.freq1 = ContextToUpdate.freq1; + TIMER_Context.period1 = ContextToUpdate.period1; + TIMER_Context.last_period1 = ContextToUpdate.last_period1; + TIMER_Context.host_time = ContextToUpdate.host_time; + TIMER_Context.wakeup_time = ContextToUpdate.wakeup_time; + TIMER_Context.roundingError = ContextToUpdate.roundingError; + update_system_time(&TIMER_Context); + ATOMIC_SECTION_END(); + } + else + { + ATOMIC_SECTION_BEGIN(); + update_system_time(&TIMER_Context); + ATOMIC_SECTION_END(); + } +} + + +/** + * @brief Start the calibration routine. + * @retval None + */ +void TIMER_StartCalibration(void) +{ + if (TIMER_Context.periodic_calibration) { + _timer_start_calibration(); + } +} + +/** + * @brief Return TRUE if a calibration is on going. It relies on the value of the interrupt status. + * Assumption is that no other modules are managing the interrupt status of the calibrator. + * @retval TRUE if calibration is running, FALSE otherwise. + */ +BOOL TIMER_IsCalibrationRunning(void) +{ + /* Normally the calibration is triggered automatically by hardware only at power up (or hardware reset), + all other calibrations are started by software */ + return (CKGEN_BLE->CLK32K_IT == 0); +} + +/** + * @brief Records the result of the last calibration in the internal context. + * It updates the XTAL startup time and the interpolator configuration. + * It updates also the cumulative STU variable, so it should be called peiodically to manage timer wrapping, + * regardless of actual need of periodic calibration. + * @warning This function is not re-entrant since it updates the context variable storing the system time. + * It should be called only in user context and not in interrupt context. + * @retval None + */ +void TIMER_UpdateCalibrationData(void) +{ + if (TIMER_Context.periodic_calibration) { + TIMER_ContextType ContextToUpdate = TIMER_Context; + _get_calibration_data(&ContextToUpdate); + _update_xtal_startup_time(ContextToUpdate.hs_startup_time, ContextToUpdate.freq1); + if (ContextToUpdate.last_period_slow != ContextToUpdate.period_slow) { + update_interpolator(ContextToUpdate.period_slow); + ContextToUpdate.last_period_slow = ContextToUpdate.period_slow; + } + ATOMIC_SECTION_BEGIN(); + /* Copying only the updated fields. + Faster than memcpy: TIMER_Context = ContextToUpdate;*/ + TIMER_Context.wakeup_time_offset = ContextToUpdate.wakeup_time_offset; + TIMER_Context.period_slow = ContextToUpdate.period_slow; + TIMER_Context.last_period_slow = ContextToUpdate.last_period_slow; + TIMER_Context.period = ContextToUpdate.period; + TIMER_Context.freq = ContextToUpdate.freq; + TIMER_Context.freq1 = ContextToUpdate.freq1; + TIMER_Context.period1 = ContextToUpdate.period1; + TIMER_Context.last_period1 = ContextToUpdate.last_period1; + TIMER_Context.host_time = ContextToUpdate.host_time; + TIMER_Context.wakeup_time = ContextToUpdate.wakeup_time; + TIMER_Context.roundingError = ContextToUpdate.roundingError; + update_system_time(&TIMER_Context); + ATOMIC_SECTION_END(); + } + else + { + ATOMIC_SECTION_BEGIN(); + update_system_time(&TIMER_Context); + ATOMIC_SECTION_END(); + } +} + +/** + * @brief Return the current system time in system time unit (STU). + * This is a counter that grows since the power up of the system and it never wraps. + * @return Current system time + */ +uint64_t TIMER_GetCurrentSysTime(void) +{ + return get_system_time(&TIMER_Context); +} + +/** + * @brief Disable Wakeup Timer, Timer1 and Timer2 enabling sleep. + * @retval None + */ +void TIMER_ClearRadioTimerValue(void) +{ + BLUE_CTRL->TIMEOUT = 1<<28; +} + +/** + * @brief Return the system time referred to the absolute machine time passed as parameter. + * @param time: Absolute machine time in the future + * @warning User should guarantee that call to this function are performed in a non-interruptible context. + * @return System time value + */ +uint64_t TIMER_GetFutureSysTime(uint32_t time) +{ + uint32_t delta_systime = machinetime_to_systime(TIME_DIFF(time, TIMER_Context.last_machine_time), + TIMER_Context.period1, + &TIMER_Context.roundingError); + return TIMER_Context.cumulative_time+delta_systime; +} + +/** + * @brief Return the system time referred to the absolute machine time passed as parameter. + * @param time: Absolute machine time in the past + * @warning User should guarantee that call to this function are performed in a non-interruptible context. + * @return System time value + */ +uint64_t TIMER_GetPastSysTime(uint32_t time) +{ + uint32_t delta_systime, current_machine_time; + uint64_t current_system_time = get_system_time_and_machine(&TIMER_Context, ¤t_machine_time); + delta_systime = machinetime_to_systime(TIME_DIFF(current_machine_time, time), + TIMER_Context.period1, + &TIMER_Context.roundingError); + return current_system_time-delta_systime; +} + +/** + * @brief Return the current calibration data. + * @retval None + */ +void TIMER_GetCurrentCalibrationData(TIMER_CalibrationType *data) +{ + data->periodic_calibration = TIMER_Context.periodic_calibration; + data->freq = TIMER_Context.freq; + data->last_calibration_time = TIMER_Context.last_calibration_time; + data->period = TIMER_Context.period; + data->last_calibration_machine_time = TIMER_Context.last_calibration_machine_time; /** Last machine time when calibration was performed */ +} + +/** + * @brief Set the wakeup time to the specified delay. The delay is converted in machine time and only 20 most significant bits + * are taken into account. The XTAL startup time is not taken into account for the wakeup, i.e. the system does not wait for + * the XTAL startup time parameter to trigger the interrupt. + * The delay is translated into machine time unit (MTU) and it is assigned to the wakeup register. + * @param delay: Delay from the current time expressed in system time unit (STU). Range is 0 to maximum value of STU. + * The maximum value STU is dependent on the speed of the low speed oscillator. + * A value too small will force the timer to wrap, so it is reccommended to use at least 5-10 STU. + * @param allow_sleep: Setting it to zero will prevent hardware to go to deep sleep, + * if other code commands the system to go to deep sleep. + * @warning This function should be called with interrupts disabled to avoid programming the timer with a value in the past + * @return Current time in MTU + */ +uint32_t TIMER_SetWakeupTime(uint32_t delay, BOOL allow_sleep) +{ + uint32_t current_time; + delay = systime_to_machinetime(delay, TIMER_Context.freq1) ; + /* If the delay is too small (less than 1 tick) round to minimum 1 tick */ + delay = MAX(16,delay); + current_time = BLUE_CTRL->CURRENT_TIME; + /* 4 least significant bits are not taken into account. Let's round the value summing 8 */ + BLUE_CTRL->HOST_WKUP_TIMER = ((current_time + (delay + 8)) & TIMER_MAX_VALUE) | (1 << 24) | (allow_sleep ? (1 << 28): 0); + /*Warning: SLEEP_EN bit is not readable*/ + TIMER_Context.host_time = BLUE_CTRL->HOST_WKUP_TIMER; + return current_time; +} + +/** + * @brief Program either Timer1 or the Wakeup Timer if the device has enough time to settle after exit from sleep or not. + * If the timeout is enough in the future, a preconfigured radio transaction is going to trigger at the specified + * timeout. The timeout is translated into machine time unit (MTU) and it is assigned to the wakeup register. + * If it is sleeping, the CPU wakes up (no IRQ) when the absolute time mathches the 20 MSB of the timeout + * written in the register. The transmission or reception starts when the timer value matches the value of + * timeout plus the time the analog part needs to settle. All the 24 bits are considered in this case. + * An IRQ related to this event can be generated only when the transaction is completed. + * In order to get a precise timeout, the radio setup delays are taken into account. They differ if + * the event is a transmission or reception and if the PLL calibration is requested or not. + * @param timeout: Absolute time expressed in system time unit (STU). + * It must represent a time in the future. + * If timeout is less than current time, it is considered as it is in the future (wrapping). + * The maximum value in STU depends on the speed of the low speed oscillator. + * @param event_type: Specify if it is a TX (1) or RX (0) event. + * @param cal_req: Specify if PLL calibration is requested (1) or not (0). + * @warning This function should be called with interrupts disabled to avoid programming the timer with a value in the past. + * @retval 0 if a correct timeout has been programmed in the timeout register. + * @retval 1 if a correct timeout cannot be programmed (the timeout is too close). + */ +uint8_t TIMER_SetRadioTimerValue(uint32_t timeout, BOOL event_type, BOOL cal_req) +{ + uint32_t current_time, + relTimeout, + delay, + destination, + device_delay_st; + + uint8_t enable_sleep; + + if(event_type == TIMER_TX_EVENT) + { + if(cal_req) + { + device_delay_st = TIMER_Context.tx_cal_delay_st; + } + else + { + device_delay_st = TIMER_Context.tx_no_cal_delay_st; + } + } + else + { + if(cal_req) + { + device_delay_st = TIMER_Context.rx_cal_delay_st; + } + else + { + device_delay_st = TIMER_Context.rx_no_cal_delay_st; + } + } + + /* At this point, it is care of the upper layers to guarantee that the timeout represents an absolute time in the future */ + relTimeout = timeout - (uint32_t)get_system_time_and_machine(&TIMER_Context,¤t_time) - device_delay_st; + /* check if the relative timeout is bigger than wakeup time offset */ + if (relTimeout > (TIMER_SEL_THR + TIMER_Context.hs_startup_time)){ + /*time is not in the past. Program the wakeup_timer*/ + destination = WAKEUP_TIMER_EN; + enable_sleep = TRUE; + __blue_RAM.BlueGlobVar.wakeup_time_offset = TIMER_Context.wakeup_time_offset; + }else{ + /*This means that wakeup_timer will be programmed with a time in the past and it is not possible to program it. + Therefore Timer1 is selected and no sleep is requested */ + destination = TIMER1_EN; + enable_sleep = FALSE; + } + + delay = systime_to_machinetime(relTimeout, TIMER_Context.freq1) - \ + (__blue_RAM.BlueGlobVar.wakeup_time_offset << 3); + + BLUE_CTRL->TIMEOUT = ((current_time + delay) & TIMER_MAX_VALUE) | destination | (enable_sleep ? (1 << 28): 0); + /*Check if delay for the wakeup timer is in the past*/ + if ((int32_t)delay < 0 && (destination == WAKEUP_TIMER_EN)){ + BLUE_CTRL->TIMEOUT = 0; + return 1; + } + + TIMER_Context.wakeup_time = BLUE_CTRL->TIMEOUT; + return 0; +} + +/** + * @brief Return the status of the Radio timers and the last value programmed in the register. + * @note When Timer2 is on schedule, the time is expressed in microseconds. + * @param time: pointer to value which is going to have time value. + * @retval 0 if no timer has been programmed. + * @retval 1 if Timer1 has been programmed. + * @retval 2 if Timer2 has been programmed. + * @retval 3 if Wakeup Timer has been programmed. + */ +uint8_t TIMER_GetRadioTimerValue(uint32_t* time) +{ + uint8_t retValue = 0; + uint32_t timeOut = BLUE_CTRL->TIMEOUT; + *time = timeOut; + timeOut = (timeOut >> 24) & 0x07; + if(timeOut == TIMER2_TIMER_MASK) + { + retValue = TIMER2_BUSY; + } + else if(timeOut == TIMER1_TIMER_MASK) + { + retValue = TIMER1_BUSY; + } + else if(timeOut == WAKEUP_TIMER_MASK) + { + retValue = WAKEUP_TIMER_BUSY; + } + return retValue; +} + +/** + * @brief Update the value of period slow variable in RAM. + * @retval None + */ +void TIMER_updatePeriodSlow(void) +{ + __blue_RAM.BlueGlobVar.period_slow = TIMER_Context.period_slow; +} + +/** + * @brief Update the value of wakeup_time_offset variable in RAM. + * @retval None + */ +void TIMER_updateWkupTimeOffset(void) +{ + __blue_RAM.BlueGlobVar.wakeup_time_offset = TIMER_Context.wakeup_time_offset; +} + +/** + * @brief Returns the next activities scheduled by the Timer Module. + * @param nextRadioActivity: pointer to value that is going to have last TIMEOUT value programmed + * @param nextRadioActivity: pointer to value that is going to have last HOST_WKUP_TIMER value programmed + * @retval None + */ +void TIMER_GetNextTimerActivity(uint32_t* nextRadioActivity, uint32_t* nextHostActivity) +{ + *nextRadioActivity = TIMER_Context.wakeup_time; + *nextHostActivity = TIMER_Context.host_time; +} + +/** + * @brief Return the MTU corresponding to the STU passed as parameter. + * @param time: STU amount to be converted in MTU + * @warning This function is not re-entrant since it updates the context variable storing the system time. It should be called only in + * user context and not in interrupt context. + * @return MTU value + */ +uint32_t TIMER_SysTimeToMachineTime(uint32_t time) +{ + return systime_to_machinetime(time, TIMER_Context.freq1); +} + +/** + * @brief Return the STU corresponding to the MTU passed as parameter. + * @param time: MTU amount to be converted in STU + * @warning This function is not re-entrant since it updates the context variable storing the system time. It should be called only in + * user context and not in interrupt context. + * @return STU value + */ +uint32_t TIMER_MachineTimeToSysTime(uint32_t time) +{ + return machinetime_to_systime(time, TIMER_Context.period1, &TIMER_Context.roundingError); +} + +/** + * @brief Return the system time referred to the time in microseconds passed as parameter. + * @param time: time in microseconds + * @return System time value + */ +uint32_t TIMER_UsToSystime(uint32_t time) +{ + return us_to_systime(time); +} + +/** + * @brief Return the machine time referred to the time in microseconds passed as parameter. + * @param time: time in microseconds + * @return Machine time value + */ +uint32_t TIMER_UsToMachinetime(uint32_t time) +{ + return us_to_machinetime(time); +} + +/** + * @brief Return timer capture register value in STU. + * @return value in STU + */ +uint64_t TIMER_GetAnchorPoint(void){ + return TIMER_GetPastSysTime(BLUE_CTRL->TIMER_CAPTURE); +} + +/** + * @brief Program the radio timer (a.k.a Timer1) as close as possible. + * @retval None + */ +void TIMER_SetRadioCloseTimeout(void) +{ + ATOMIC_SECTION_BEGIN(); + uint32_t current_time = BLUE_CTRL->CURRENT_TIME; + uint32_t delay = 3 - (__blue_RAM.BlueGlobVar.wakeup_time_offset << 3); + BLUE_CTRL->TIMEOUT = ((current_time + delay ) & TIMER_MAX_VALUE) | TIMER1_EN; + ATOMIC_SECTION_END(); +} + +/** + * @brief Get the radio setup delay in system time. + * @param event_type: Specify if it is a TX (1) or RX (0) event. + * @param cal_req: Specify if PLL calibration is requested (1) or not (0). + * @return Radio setup delay in system time. + */ +uint8_t TIMER_GetActivitySysDelay(uint8_t event_type, uint8_t cal_req) +{ + if(event_type == TIMER_TX_EVENT) + { + if(cal_req) + { + return TIMER_Context.tx_cal_delay_st; + } + else + { + return TIMER_Context.tx_no_cal_delay_st; + } + } + else + { + if(cal_req) + { + return TIMER_Context.rx_cal_delay_st; + } + else + { + return TIMER_Context.tx_no_cal_delay_st; + } + } +} + +/** +* @} +*/ + +/** +* @} +*/ + +/** +* @} +*/ +/******************* (C) COPYRIGHT 2020 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_uart.c b/drivers/src/BlueNRG1_uart.c new file mode 100644 index 0000000..49f2815 --- /dev/null +++ b/drivers/src/BlueNRG1_uart.c @@ -0,0 +1,727 @@ +/** + ****************************************************************************** + * @file BlueNRG1_uart.c + * @author VMA Application Team + * @version V2.1.0 + * @date 21-March-2016 + * @brief This file provides all the UART firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_uart.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup UART_Peripheral UART Peripheral + * @{ + */ + +/** @defgroup UART_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup UART_Private_Defines Private Defines + * @{ + */ +#define UART_CLOCK (16000000) + +/* UART clock cycle for oversampling factor */ +#define UART_CLOCK_CYCLE16 (16) +#define UART_CLOCK_CYCLE8 (8) + +/* Max UART RX timeout value */ +#define UART_MAX_RX_TIMEOUT (0x3FFFFF) + +/** + * @} + */ + +/** @defgroup UART_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup UART_Private_Variables Private Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup UART_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup UART_Public_Functions Public Functions + * @{ + */ + + +/** + * @brief Enables or disables the UART peripheral. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the selected UART by setting the UARTEN bit in the UARTCR register */ + UART->CR_b.EN = SET; + } + else { + /* Disable the selected UART by clearing the UARTEN bit in the UARTCR register */ + UART->CR_b.EN = RESET; + } +} + + +/** +* @brief Deinitializes the UART peripheral registers to their default +* reset values. +* @param None +* @retval None +*/ +void UART_DeInit(void) +{ + UART->TIMEOUT = 0x000001FF; + UART->LCRH_RX = 0x00000000; + UART->IBRD = 0x00000000; + UART->FBRD = 0x00000000; + UART->LCRH_TX = 0x00000000; + UART->CR = 0x00040300; + UART->IFLS = 0x00000012; + UART->IMSC = 0x00000000; + UART->ICR = 0x00000000; + UART->DMACR = 0x00000000; + UART->XFCR = 0x00000000; + UART->XON1 = 0x00000000; + UART->XON2 = 0x00000000; + UART->XOFF1 = 0x00000000; + UART->XOFF2 = 0x00000000; +} + + +/** + * @brief Initializes the UART peripheral according to the specified + * parameters in the UART_InitStruct. + * @param UART_InitStruct: pointer to a @ref UART_InitType structure + * that contains the configuration information for the specified UART. + * @retval None + */ +void UART_Init(UART_InitType* UART_InitStruct) +{ + uint32_t divider; + uint16_t ibrd, fbrd; + + /* Check the parameters */ + assert_param(IS_UART_BAUDRATE(UART_InitStruct->UART_BaudRate)); + assert_param(IS_UART_WORD_LENGTH(UART_InitStruct->UART_WordLengthTransmit)); + assert_param(IS_UART_WORD_LENGTH(UART_InitStruct->UART_WordLengthReceive)); + assert_param(IS_UART_STOPBITS(UART_InitStruct->UART_StopBits)); + assert_param(IS_UART_PARITY(UART_InitStruct->UART_Parity)); + assert_param(IS_UART_MODE(UART_InitStruct->UART_Mode)); + assert_param(IS_UART_HW_FLOW_CONTROL(UART_InitStruct->UART_HardwareFlowControl)); + assert_param(IS_FUNCTIONAL_STATE(UART_InitStruct->UART_FifoEnable)); + + /*---------------------------- UART BaudRate Configuration -----------------------*/ + + if (UART->CR_b.OVSFACT == 0) + divider = (UART_CLOCK<<7) / (UART_CLOCK_CYCLE16 * UART_InitStruct->UART_BaudRate); + else + divider = (UART_CLOCK<<7) / (UART_CLOCK_CYCLE8 * UART_InitStruct->UART_BaudRate); + + ibrd = divider >> 7; + UART->IBRD = ibrd; + fbrd = ((divider - (ibrd <<7) + 1) >> 1); + if (fbrd > 0x3f) { + ibrd++; + fbrd = (fbrd - 0x3F) & 0x3F; + } + UART->FBRD = fbrd; + + /*---------------------------- UART Word Length Configuration -----------------------*/ + UART->LCRH_TX_b.WLEN_TX = UART_InitStruct->UART_WordLengthTransmit; + UART->LCRH_RX_b.WLEN_RX = UART_InitStruct->UART_WordLengthReceive; + + /*---------------------------- UART Stop Bits Configuration -----------------------*/ + UART->LCRH_TX_b.STP2_TX = UART_InitStruct->UART_StopBits; + UART->LCRH_RX_b.STP2_RX = UART_InitStruct->UART_StopBits; + + /*---------------------------- UART Parity Configuration -----------------------*/ + if(UART_InitStruct->UART_Parity == UART_Parity_No) { + UART->LCRH_TX_b.PEN_TX = RESET; + UART->LCRH_RX_b.PEN_RX = RESET; + } + else if(UART_InitStruct->UART_Parity == UART_Parity_Odd) { + UART->LCRH_TX_b.PEN_TX = SET; + UART->LCRH_TX_b.EPS_TX = RESET; + UART->LCRH_RX_b.PEN_RX = SET; + UART->LCRH_RX_b.EPS_RX = RESET; + } + else { + UART->LCRH_TX_b.PEN_TX = SET; + UART->LCRH_TX_b.EPS_TX = SET; + UART->LCRH_RX_b.PEN_RX = SET; + UART->LCRH_RX_b.EPS_RX = SET; + } + + /*---------------------------- UART Mode Configuration -----------------------*/ + UART->CR_b.RXE = UART_InitStruct->UART_Mode&1; + UART->CR_b.TXE = (UART_InitStruct->UART_Mode>>1)&1; + + /*---------------------------- UART Hardware flow control Configuration -----------------------*/ + UART->CR_b.RTSEN = UART_InitStruct->UART_HardwareFlowControl&1; + UART->CR_b.CTSEN = (UART_InitStruct->UART_HardwareFlowControl>>1)&1; + + /*---------------------------- UART Fifo Configuration -----------------------*/ + UART->LCRH_TX_b.FEN_TX = (uint8_t)UART_InitStruct->UART_FifoEnable; + UART->LCRH_RX_b.FEN_RX = (uint8_t)UART_InitStruct->UART_FifoEnable; + +} + +/** + * @brief Fills each UART_InitStruct member with its default value. + * @param UART_InitStruct: pointer to a @ref UART_InitTypeDef structure + * which will be initialized. + * @retval None + */ +void UART_StructInit(UART_InitType* UART_InitStruct) +{ + /* UART_InitStruct members default value */ + UART_InitStruct->UART_BaudRate = 115200; + UART_InitStruct->UART_WordLengthTransmit = UART_WordLength_8b; + UART_InitStruct->UART_WordLengthReceive = UART_WordLength_8b; + UART_InitStruct->UART_StopBits = UART_StopBits_1; + UART_InitStruct->UART_Parity = UART_Parity_No; + UART_InitStruct->UART_Mode = UART_Mode_Rx | UART_Mode_Tx; + UART_InitStruct->UART_HardwareFlowControl = UART_HardwareFlowControl_None; + UART_InitStruct->UART_FifoEnable = DISABLE; +} + +/** + * @brief Enables or disables the specified UART interrupts. + * @param UART_IT: specifies the UART interrupt sources to be enabled or disabled. + * This parameter can be a any combination of the following values: + * @arg UART_IT_TXFE: Tx FIFO empty interrupt + * @arg UART_IT_XO: XOFF interrupt + * @arg UART_IT_OE: Overrun error interrupt + * @arg UART_IT_BE: Break error interrupt + * @arg UART_IT_PE: Parity error interrupt + * @arg UART_IT_FE: Framing error interrupt + * @arg UART_IT_RT: Receive timeout interrupt + * @arg UART_IT_TX: Transmit interrupt + * @arg UART_IT_RX: Receive interrupt + * @arg UART_IT_CTS: CTS interrupt. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_ITConfig(uint16_t UART_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_CONFIG_IT(UART_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable specified interrupts */ + SET_BIT(UART->IMSC, UART_IT); + } + else { + /* Disable specified interrupts */ + CLEAR_BIT(UART->IMSC, UART_IT); + } +} + +/** + * @brief Transmits single data through the UART peripheral. + * @param Data: the data to transmit. + * @retval None + */ +void UART_SendData(uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_UART_DATA(Data)); + + /* Transmit Data */ + UART->DR = (Data & (uint16_t)0x01FF); +} + +/** + * @brief Returns the most recent received data by the UART peripheral. + * @param None + * @retval uint16_t: The received data. + */ +uint16_t UART_ReceiveData(void) +{ + /* Check the parameters */ + + /* Receive Data */ + return (uint16_t)(UART->DR & 0x00FF); +} + +/** + * @brief Enables or disables the break command. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_BreakCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + UART->LCRH_TX_b.BRK = (uint8_t)NewState; +} + +/** + * @brief Enables or disables the request to send command. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_RequestToSendCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + UART->CR_b.RTS = (uint8_t)NewState; +} + + +/** + * @brief Checks whether the specified UART flag is set or not. + * @param UART_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg UART_FLAG_CTS: Clear to send + * @arg UART_FLAG_BUSY: UART busy + * @arg UART_FLAG_RXFE: Receive FIFO empty + * @arg UART_FLAG_TXFF: Transmit FIFO full + * @arg UART_FLAG_RXFF: Receive FIFO full + * @arg UART_FLAG_TXFE: Transmit FIFO empty + * @arg UART_FLAG_FE: Framing error + * @arg UART_FLAG_PE: Parity error + * @arg UART_FLAG_BE: Break error + * @arg UART_FLAG_OE: Overrun error. +* @retval FlagStatus: functional state @ref FlagStatus +* This parameter can be: SET or RESET. + */ +FlagStatus UART_GetFlagStatus(uint32_t UART_FLAG) +{ + /* Check the parameters */ + assert_param(IS_UART_FLAG(UART_FLAG)); + + if (UART_FLAG & 0x80000000) { + if (UART->RSR & UART_FLAG) { + return SET; + } + else { + return RESET; + } + } + else { + if (UART->FR & UART_FLAG) { + return SET; + } + else { + return RESET; + } + } + +} + +/** + * @brief Clears the UART pending flags. + * @param UART_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg UART_FLAG_FE: Framing error + * @arg UART_FLAG_PE: Parity error + * @arg UART_FLAG_BE: Break error + * @arg UART_FLAG_OE: Overrun error + * @retval None + */ +void UART_ClearFlag(uint32_t UART_FLAG) +{ + /* Check the parameters */ + assert_param(IS_UART_CLEAR_FLAG(UART_FLAG)); + + UART->ECR = UART_FLAG; +} + +/** + * @brief Checks whether the specified UART interrupt has occurred or not. + * @param UART_IT: specifies the UART interrupt source to check. + * This parameter can be one of the following values: + * @arg UART_IT_TXFE: Tx FIFO empty interrupt + * @arg UART_IT_XO: XOFF interrupt + * @arg UART_IT_OE: Overrun error interrupt + * @arg UART_IT_BE: Break error interrupt + * @arg UART_IT_PE: Parity error interrupt + * @arg UART_IT_FE: Framing error interrupt + * @arg UART_IT_RT: Receive timeout interrupt + * @arg UART_IT_TX: Transmit interrupt + * @arg UART_IT_RX: Receive interrupt + * @arg UART_IT_CTS: CTS interrupt + * @retval ITStatus: functional state @ref ITStatus + * This parameter can be: SET or RESET. + */ +ITStatus UART_GetITStatus(uint16_t UART_IT) +{ + /* Check the parameters */ + assert_param(IS_UART_CONFIG_IT(UART_IT)); + + if ((UART->RIS & UART_IT) != (uint16_t)RESET) { + return SET; + } + else { + return RESET; + } +} + +/** + * @brief Clears the UART interrupt pending bits. + * @param UART_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg UART_IT_TXFE: Tx FIFO empty interrupt + * @arg UART_IT_XO: XOFF interrupt + * @arg UART_IT_OE: Overrun error interrupt + * @arg UART_IT_BE: Break error interrupt + * @arg UART_IT_PE: Parity error interrupt + * @arg UART_IT_FE: Framing error interrupt + * @arg UART_IT_RT: Receive timeout interrupt + * @arg UART_IT_TX: Transmit interrupt + * @arg UART_IT_RX: Receive interrupt + * @arg UART_IT_CTS: CTS interrupt + * + * @retval None + */ +void UART_ClearITPendingBit(uint16_t UART_IT) +{ + /* Check the parameters */ + assert_param(IS_UART_CONFIG_IT(UART_IT)); + + UART->ICR = UART_IT; +} + + +/** + * @brief Sets the UART interrupt FIFO level. + * @param UART_TxFifo_Level: specifies the transmit interrupt FIFO level. + * This parameter can be one of the following values: + * @arg FIFO_LEV_1_64: interrupt when Tx FIFO becomes <= 1/64 full = 1 + * @arg FIFO_LEV_1_32: interrupt when Tx FIFO becomes <= 1/32 full = 2 + * @arg FIFO_LEV_1_16: interrupt when Tx FIFO becomes <= 1/16 full = 4 + * @arg FIFO_LEV_1_8: interrupt when Tx FIFO becomes <= 1/8 full = 8 + * @arg FIFO_LEV_1_4: interrupt when Tx FIFO becomes <= 1/4 full = 16 + * @arg FIFO_LEV_1_2: interrupt when Tx FIFO becomes <= 1/2 full = 32 + * @arg FIFO_LEV_3_4: interrupt when Tx FIFO becomes <= 3/4 full = 48 + * @retval None + */ +void UART_TxFifoIrqLevelConfig(uint8_t UART_TxFifo_Level) +{ + /* Check the parameters */ + assert_param(IS_FIFO_LEV(UART_TxFifo_Level)); + + UART->IFLS_b.TXIFLSEL = UART_TxFifo_Level; +} + +/** + * @brief Sets the UART interrupt FIFO level. + * @param UART_RxFifo_Level: specifies the receive interrupt FIFO level. + * This parameter can be one of the following values: + * @arg FIFO_LEV_1_64: interrupt when Rx FIFO becomes >= 1/64 full = 1 + * @arg FIFO_LEV_1_32: interrupt when Rx FIFO becomes >= 1/32 full = 2 + * @arg FIFO_LEV_1_16: interrupt when Rx FIFO becomes >= 1/16 full = 4 + * @arg FIFO_LEV_1_8: interrupt when Rx FIFO becomes >= 1/8 full = 8 + * @arg FIFO_LEV_1_4: interrupt when Rx FIFO becomes >= 1/4 full = 16 + * @arg FIFO_LEV_1_2: interrupt when Rx FIFO becomes >= 1/2 full = 32 + * @arg FIFO_LEV_3_4: interrupt when Rx FIFO becomes >= 3/4 full = 48 + * @retval None + */ +void UART_RxFifoIrqLevelConfig(uint8_t UART_RxFifo_Level) +{ + /* Check the parameters */ + assert_param(IS_FIFO_LEV(UART_RxFifo_Level)); + + UART->IFLS_b.RXIFLSEL = UART_RxFifo_Level; +} + +/** + * @brief UART RX timeout. + * The RX timeout interrupt is asserted when + * the RX FIFO is not empty and no further data is received + * over a programmed timeout period. + * @param UART_TimeoutMS: is the timeout in milliseconds. + * @retval None + */ +void UART_RXTimeoutConfig(uint32_t UART_TimeoutMS) +{ + uint32_t timeout_val; + uint32_t tmp32; + + tmp32 = (UART->IBRD)<<4; + if (UART->CR_b.OVSFACT == 0) + timeout_val = (UART_TimeoutMS * 16 * 16000) / (((UART->FBRD)>>2) + tmp32); + else + timeout_val = (UART_TimeoutMS * 8 * 16000) / (((UART->FBRD)>>3) + tmp32); + + /* Set the timeout value */ + if(IS_UART_TIMEOUT(timeout_val)) { + UART->TIMEOUT = timeout_val; + } + else { + UART->TIMEOUT = UART_MAX_RX_TIMEOUT; + } +} + +/** + * @brief Enables or disables the UART oversampling. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_Oversampling(FunctionalState NewState) +{ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + /* Enable the UART oversampling factor */ + UART->CR_b.OVSFACT = 1; + } + else + { + /* Disable the UART oversampling factor */ + UART->CR_b.OVSFACT = 0; + } +} + +/** + * @brief Enables or disables the UART DMA interface. + * @param UART_DMAReq: specifies the DMA request. + * This parameter can be any combination of the following values: + * @arg UART_DMAReq_Tx: UART DMA transmit request. + * @arg UART_DMAReq_Rx: UART DMA receive request. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_DMACmd(uint8_t UART_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_DMAREQ(UART_DMAReq)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + /* Enable the DMA transfer for selected requests by setting the DMAT and/or + DMAR bits in the UART CR3 register */ + UART->DMACR |= UART_DMAReq; + } + else + { + /* Disable the DMA transfer for selected requests by clearing the DMAT and/or + DMAR bits in the UART CR3 register */ + UART->DMACR &= (uint8_t)~UART_DMAReq; + } +} + + + +/** + * @brief Enables or disables the UART software flow control. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_SwFlowControl(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable UART software flow control */ + UART->XFCR_b.SFEN = SET; + } + else { + /* Disable UART software flow control */ + UART->XFCR_b.SFEN = RESET; + } +} + + +/** + * @brief Sets the UART flow control mode for reception. + * @param UART_RxSwFlowCtrlMode: specifies the software flow control used for RX. + * This parameter can be one of the following values: + * @arg NO_SW_FLOW_CTRL: No software flow control + * @arg SW_FLOW_CTRL_XON1_XOFF1: Software flow control XON1 and XOFF1 + * @arg SW_FLOW_CTRL_XON2_XOFF2: Software flow control XON2 and XOFF2 + * @arg SW_FLOW_CTRL_ALL_CHARS: Software flow control XON1 and XOFF1, XON2 and XOFF2 + * @retval None + */ +void UART_RxSwFlowControlMode(uint8_t UART_RxSwFlowCtrlMode) +{ + /* Check the parameters */ + assert_param(IS_SW_FLOW_CTRL(UART_RxSwFlowCtrlMode)); + + UART->XFCR_b.SFRMOD = UART_RxSwFlowCtrlMode; +} + +/** + * @brief Sets the UART flow control mode for transmission. + * @param UART_TxSwFlowCtrlMode: specifies the software flow control used for TX. + * This parameter can be one of the following values: + * @arg NO_SW_FLOW_CTRL: No software flow control + * @arg SW_FLOW_CTRL_XON1_XOFF1: Software flow control XON1 and XOFF1 + * @arg SW_FLOW_CTRL_XON2_XOFF2: Software flow control XON2 and XOFF2 + * @arg SW_FLOW_CTRL_ALL_CHARS: Software flow control XON1 and XOFF1, XON2 and XOFF2 + * @retval None + */ +void UART_TxSwFlowControlMode(uint8_t UART_TxSwFlowCtrlMode) +{ + /* Check the parameters */ + assert_param(IS_SW_FLOW_CTRL(UART_TxSwFlowCtrlMode)); + + UART->XFCR_b.SFTMOD = UART_TxSwFlowCtrlMode; +} + + +/** + * @brief Enables or disables the UART XON any bit. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_XonAnyBit(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the UART XON any bit */ + UART->XFCR_b.XONANY = SET; + } + else { + /* Disable the UART XON any bit */ + UART->XFCR_b.XONANY = RESET; + } +} + + +/** + * @brief Enables or disables the UART special character detection. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_SpecialCharDetect(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /* Enable the UART special character detection */ + UART->XFCR_b.SPECHAR = SET; + } + else { + /* Disable the UART special character detection */ + UART->XFCR_b.SPECHAR = RESET; + } +} + + +/** + * @brief Sets the UART flow control mode for transmission. + * @param uint8_t: specifies the flow control character. + * @retval None + */ +void UART_Xon1Char(uint8_t UART_XonChar) +{ + /* Check the parameters */ + assert_param(IS_SW_FLOW_CTRL(UART_XonChar)); + + UART->XON1 = UART_XonChar; +} + +/** + * @brief Sets the UART flow control mode for transmission. + * @param uint8_t: specifies the flow control character. + * @retval None + */ +void UART_Xon2Char(uint8_t UART_XonChar) +{ + /* Check the parameters */ + assert_param(IS_SW_FLOW_CTRL(UART_XonChar)); + + UART->XON2 = UART_XonChar; +} + +/** + * @brief Sets the UART flow control mode for transmission. + * @param uint8_t: specifies the flow control character. + * @retval None + */ +void UART_Xoff1Char(uint8_t UART_XoffChar) +{ + /* Check the parameters */ + assert_param(IS_SW_FLOW_CTRL(UART_XoffChar)); + + UART->XOFF1 = UART_XoffChar; +} + +/** + * @brief Sets the UART flow control mode for transmission. + * @param uint8_t: specifies the flow control character. + * @retval None + */ +void UART_Xoff2Char(uint8_t UART_XoffChar) +{ + /* Check the parameters */ + assert_param(IS_SW_FLOW_CTRL(UART_XoffChar)); + + UART->XOFF2 = UART_XoffChar; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/BlueNRG1_wdg.c b/drivers/src/BlueNRG1_wdg.c new file mode 100644 index 0000000..56e1f48 --- /dev/null +++ b/drivers/src/BlueNRG1_wdg.c @@ -0,0 +1,225 @@ +/** + ****************************************************************************** + * @file BlueNRG1_WDG.c + * @author VMA Application Team + * @version V2.1.0 + * @date 27-March-2018 + * @brief This file provides all the WDG firmware functions. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2015 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRG1_wdg.h" + + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @defgroup WDG_Peripheral WDG Peripheral + * @{ + */ + +/** @defgroup WDG_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup WDG_Private_Defines Private Defines + * @{ + */ + +#define WDG_WRITE_ACCESS_UNLOCK ((uint32_t)0x1ACCE551) /*!< Enables WDG write access */ +#define WDG_WRITE_ACCESS_LOCK ((uint32_t)0x00000000) /*!< Disables WDG write access */ + +/** + * @} + */ + +/** @defgroup WDG_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup WDG_Private_Variables Private Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup WDG_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup WDG_Private_Functions Private Functions + * @{ + */ + +/** + * @} + */ + +/** @defgroup WDG_Public_Functions Public Functions +* @{ +*/ + +/** + * @brief Enables or disables write access to all the other WDG registers. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void WDG_SetWriteAccess(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + WDG->LOCK = WDG_WRITE_ACCESS_UNLOCK; + } + else { + WDG->LOCK = WDG_WRITE_ACCESS_LOCK; + } +} + + +/** + * @brief Get the write access state. + * @param None + * @retval NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + */ +FunctionalState WDG_GetWriteAccess(void) +{ + return (FunctionalState)!WDG->LOCK; + +} + +/** + * @brief Sets WDG reload value. + * @param WDG_Reload: specifies the WDG reload value. + * This parameter must be a number greater than 0. + * @retval None + */ +void WDG_SetReload(uint32_t WDG_Reload) +{ + /* Check the parameters */ + assert_param(WDG_Reload > 0); + WDG->LR = WDG_Reload; +} + +/** + * @brief Enables WDG reset. + * @param None + * @retval None + */ +void WDG_Enable(void) +{ + WDG->CR_b.INTEN = SET; + WDG->CR_b.RESEN = SET; +} + +/** + * @brief Disable WDG reset. + * @param None + * @retval None + */ +void WDG_DisableReset(void) +{ + WDG->CR_b.RESEN = RESET; +} + + +/** + * @brief Gets the WDG counter value. + * @param None + * @retval WDG counter value. + */ +uint32_t WDG_GetCounter(void) +{ + return WDG->VAL; +} + +/** + * @brief Enables or disables the WDG interrupt. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void WDG_ITConfig(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + WDG->CR_b.INTEN = SET; + } + else { + WDG->CR_b.INTEN = RESET; + } +} + +/** + * @brief Checks whether the WDG interrupt has occurred or not. + * @param None + * @retval ITStatus: functional state @ref ITStatus + * This parameter can be: SET or RESET. + */ +ITStatus WDG_GetITStatus(void) +{ + FlagStatus bitstatus = RESET; + + /* Check the status of the WDG interrupt */ + if (WDG->RIS != (uint32_t)RESET) { + bitstatus = SET; + } + + return bitstatus; +} + +/** + * @brief Clears the WDG's interrupt pending bit. + * @param None + * @retval None + */ +void WDG_ClearITPendingBit(void) +{ + WDG->ICR = 0xFFFFFFFF; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/ diff --git a/drivers/src/misc.c b/drivers/src/misc.c new file mode 100644 index 0000000..d70e8fd --- /dev/null +++ b/drivers/src/misc.c @@ -0,0 +1,157 @@ +/** + ****************************************************************************** + * @file misc.c + * @author VMA Application Team + * @version V2.0.0 + * @date 21-March-2016 + * @brief This file provides all the miscellaneous firmware functions (add-on + * to CMSIS functions). + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2016 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "misc.h" + +/** @addtogroup BLUENRG1_Peripheral_Driver BLUENRG1 Peripheral Driver + * @{ + */ + +/** @addtogroup MISC_Peripheral MISC Peripheral + * @{ + */ + +/** @defgroup MISC_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Private_Defines Provate Defines + * @{ + */ + +#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/** + * @} + */ + +/** @defgroup MISC_Private_Macros Private Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Private_Variables Private Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Public_Functions Public Function + * @{ + */ + +/** + * @brief Initializes the NVIC peripheral according to the specified + * parameters in the NVIC_InitStruct. + * @param NVIC_InitStruct: pointer to a @ref NVIC_InitTypeDef structure that contains + * the configuration information for the specified NVIC peripheral. + * @retval None + */ +void NVIC_Init(NVIC_InitType* NVIC_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); + + if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) + { + /* Compute the Corresponding IRQ Priority --------------------------------*/ + NVIC_SetPriority((IRQn_Type)NVIC_InitStruct->NVIC_IRQChannel, NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority); + + /* Enable the Selected IRQ Channels --------------------------------------*/ + NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } + else + { + /* Disable the Selected IRQ Channels -------------------------------------*/ + NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } +} + +/** + * @brief Enables or disables sleep/stop mode on system level. + * @param NewState: functional state @ref FunctionalState + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SystemSleepCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) { + /** Enable Sleep/Stop mode entry on system level */ + SCB->SCR |= 1<SCR &= ~(1<CTRL |= SysTick_CTRL_ENABLE_Msk; + } + else { + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + } +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/hal/inc/asm.h b/hal/inc/asm.h new file mode 100644 index 0000000..2343b41 --- /dev/null +++ b/hal/inc/asm.h @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2015 STMicroelectronics ******************** +* File Name : compiler.h +* Author : AMS - VMA RF Application team +* Version : V1.0.0 +* Date : 14-September-2015 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __ASM_H__ +#define __ASM_H__ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#if defined(__ICCARM__) || defined(__IAR_SYSTEMS_ASM__) +#define __CODE__ SECTION .text:CODE:REORDER:NOROOT(2) +#define __BSS__ SECTION .bss:DATA:NOROOT(2) +#define __EXPORT__ EXPORT +#define __IMPORT__ IMPORT +#define __THUMB__ THUMB +#define EXPORT_FUNC(f) f: +#define __END__ END +#define __SPACE__ DS8 +#define GLOBAL_VAR(val) val: +#define ENDFUNC +#define ALIGN_MEM(n) + +#else +#ifdef __GNUC__ +.syntax unified +.cpu cortex-m0 +.fpu softvfp +.thumb +#define __CODE__ .text +#define __BSS__ .bss +#define __EXPORT__ .global +#define __IMPORT__ .extern +#define __THUMB__ .thumb_func +#define __END__ .end +#define __SPACE__ .space +#define EXPORT_FUNC(f) f: +#define GLOBAL_VAR(val) val: +#define ENDFUNC +#define ALIGN_MEM(n) .align n>>1 + +#else +#ifdef __CC_ARM +#define __CODE__ AREA |.text|, CODE, READONLY +#define __THUMB__ +#define EXPORT_FUNC(f) f PROC +#define __BSS__ AREA |.bss|, DATA, READWRITE, NOINIT +#define __EXPORT__ EXPORT +#define __IMPORT__ IMPORT +#define __SPACE__ SPACE +#define GLOBAL_VAR(val) val +#define __END__ END +#define ENDFUNC ENDP +#define ALIGN_MEM(n) ALIGN n +#else + +#endif +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +//#ifndef __CC_ARM +//#define VARIABLE_SIZE 0 +//#else +//#define VARIABLE_SIZE 1 +//#endif + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ +#endif /* __ASM_H__ */ diff --git a/hal/inc/clock.h b/hal/inc/clock.h new file mode 100644 index 0000000..8b05feb --- /dev/null +++ b/hal/inc/clock.h @@ -0,0 +1,68 @@ +/** + ****************************************************************************** + * @file clock.h + * @author AMS - VMA RF Application team + * @version V1.0.0 + * @date 21-Sept-2015 + * @brief Header file for clock APIs based on SySTick + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2015 STMicroelectronics

+ ****************************************************************************** + */ +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include "bluenrg_x_device.h" + +/** + * @brief Number of clocks in one seconds. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * @brief This function initializes the clock library based on SysTick. + * + * @param None + * + * @retval None + */ +void Clock_Init(void); + +/** + * @brief This function returns the current system clock time. + * + * @param None + * + * @retval It returns current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + + +/** + * @brief This function waits for a given number of milliseconds. + * + * @param i delay in milliseconds + * + * @retval None + */ +void Clock_Wait(uint32_t i); + +/** + * @brief This function is called on SysTick_Handler() + * + */ +void SysCount_Handler(void); + +#endif /* __CLOCK_H__ */ + diff --git a/hal/inc/compiler.h b/hal/inc/compiler.h new file mode 100644 index 0000000..102735d --- /dev/null +++ b/hal/inc/compiler.h @@ -0,0 +1,304 @@ +/******************** (C) COPYRIGHT 2015 STMicroelectronics ******************** +* File Name : compiler.h +* Author : AMS - VMA RF Application team +* Version : V1.0.0 +* Date : 14-September-2015 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __COMPILER_H__ +#define __COMPILER_H__ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define QUOTEME(a) #a + +/** @addtogroup compiler_macros compiler macros + * @{ + */ + + +/** @addtogroup IAR_toolchain_macros IAR toolchain macros + * @{ + */ + +/** + * @brief This is the section dedicated to IAR toolchain + */ +#if defined(__ICCARM__) || defined(__IAR_SYSTEMS_ASM__) + +/** + * @brief PACKED + * Use the PACKED macro for variables that needs to be packed. + * Usage: PACKED(struct) myStruct_s + * PACKED(union) myStruct_s + */ +#define PACKED(decl) __packed decl + +/** + * @brief REQUIRED + * Use the REQUIRED macro for variables that must be always included. + * Usage: REQUIRED(static uint8_t my_array[16]) + * REQUIRED(static int my_int) + */ +#define REQUIRED(decl) __root decl + +/** + * @brief NORETURN_FUNCTION + * Use the NORETURN_FUNCTION macro to declare a no return function. + * Usage: NORETURN_FUNCTION(void my_noretrun_function(void)) + */ +#define NORETURN_FUNCTION(function) __noreturn function + +/** + * @brief NOSTACK_FUNCTION + * Use the NOSTACK_FUNCTION macro to indicate that function should not use any stack. + * Typical usage is for hard fault handler, to avoid altering the value of the stack pointer. + * Usage: NOSTACK_FUNCTION(void my_noretrun_function(void)) + */ +#define NOSTACK_FUNCTION(function) __stackless function + +/** + * @brief SECTION + * Use the SECTION macro to assign data or code in a specific section. + * Usage: SECTION(".my_section") + */ +#define SECTION(name) _Pragma(QUOTEME(location=name)) + +/** + * @brief ALIGN + * Use the ALIGN macro to specify the alignment of a variable. + * Usage: ALIGN(4) + */ +#define ALIGN(v) _Pragma(QUOTEME(data_alignment=v)) + +/** + * @brief WEAK_FUNCTION + * Use the WEAK_FUNCTION macro to declare a weak function. + * Usage: WEAK_FUNCTION(int my_weak_function(void)) + */ +#define WEAK_FUNCTION(function) __weak function + +/** + * @brief NO_INIT + * Use the NO_INIT macro to declare a not initialized variable in RAM + * Usage: NO_INIT(int my_no_init_var) + * Usage: NO_INIT(uint16_t my_no_init_array[10]) + */ +#define NO_INIT(var) __no_init var + + +/** + * @brief NO_INIT_SECTION + * Use the NO_INIT_SECTION macro to declare a not initialized variable in RAM in + * in a specific section. + * Usage: NO_INIT_SECTION(int my_no_init_var, "MySection") + * Usage: NO_INIT_SECTION(uint16_t my_no_init_array[10], "MySection") + */ +#define NO_INIT_SECTION(var, sect) SECTION(sect) __no_init var + +#define VARIABLE_SIZE 0 +#pragma segment = "CSTACK" +#define _INITIAL_SP __sfe( "CSTACK" ) /* Stack address */ +extern void __iar_program_start(void); +#define RESET_HANDLER __iar_program_start + +/** + * @} + */ + +/** @addtogroup Atollic_toolchain_macros Atollic toolchain macros + * @{ + */ + +/** + * @brief This is the section dedicated to Atollic toolchain + */ +#else +#ifdef __GNUC__ + +/** + * @brief PACKED + * Use the PACKED macro for variables that needs to be packed. + * Usage: PACKED(struct) myStruct_s + * PACKED(union) myStruct_s + */ +#define PACKED(decl) decl __attribute__((packed)) + +/** + * @brief REQUIRED + * Use the REQUIRED macro for variables that must be always included. + * Usage: REQUIRED(static uint8_t my_array[16]) + * REQUIRED(static int my_int) + */ +#define REQUIRED(var) var __attribute__((used)) + +/** + * @brief SECTION + * Use the SECTION macro to assign data or code in a specific section. + * Usage: SECTION(".my_section") + */ +#define SECTION(name) __attribute__((section(name))) + +/** + * @brief ALIGN + * Use the ALIGN macro to specify the alignment of a variable. + * Usage: ALIGN(4) + */ +#define ALIGN(N) __attribute__((aligned(N))) + +/** + * @brief WEAK_FUNCTION + * Use the WEAK_FUNCTION macro to declare a weak function. + * Usage: WEAK_FUNCTION(int my_weak_function(void)) + */ +#define WEAK_FUNCTION(function) __attribute__((weak)) function + +/** + * @brief NORETURN_FUNCTION + * Use the NORETURN_FUNCTION macro to declare a no return function. + * Usage: NORETURN_FUNCTION(void my_noretrun_function(void)) + */ +#define NORETURN_FUNCTION(function) __attribute__((noreturn)) function + +/** + * @brief NOSTACK_FUNCTION + * Use the NOSTACK_FUNCTION macro to indicate that function should not use any stack. + * Typical usage is for hard fault handler, to avoid altering the value of the stack pointer. + * Usage: NOSTACK_FUNCTION(void my_noretrun_function(void)) + */ +#define NOSTACK_FUNCTION(function) __attribute__((naked)) function + +/** + * @brief NO_INIT + * Use the NO_INIT macro to declare a not initialized variable placed in RAM + * Linker script has to make sure that section ".noinit" is not initialized + * Usage: NO_INIT(int my_no_init_var) + * Usage: NO_INIT(uint16_t my_no_init_array[10]) + */ +#define NO_INIT(var) var __attribute__((section(".noinit"))) + +/** + * @brief NO_INIT_SECTION + * Use the NO_INIT_SECTION macro to declare a not initialized variable. + * In order to work properly this macro should be aligned with the linker file. + * Usage: NO_INIT_SECTION(int my_no_init_var, "MySection") + * Usage: NO_INIT_SECTION(uint16_t my_no_init_array[10], "MySection") + */ +#define NO_INIT_SECTION(var, sect) var __attribute__((section(sect))) + +#define _INITIAL_SP (void(*)(void))(&_estack) +#define VARIABLE_SIZE 0 + + +/** @addtogroup Keil_toolchain_macros Keil toolchain macros + * @{ + */ + +/** + * @brief This is the section dedicated to Keil toolchain + */ +#else +#ifdef __CC_ARM + +/** + * @brief PACKED + * Use the PACKED macro for variables that needs to be packed. + * Usage: PACKED(struct) myStruct_s + * PACKED(union) myStruct_s + */ +#define PACKED(decl) decl __attribute__((packed)) + +/** + * @brief REQUIRED + * Use the REQUIRED macro for variables that must be always included. + * Usage: REQUIRED(static uint8_t my_array[16]) + * REQUIRED(static int my_int) + */ +#define REQUIRED(decl) decl __attribute__((used)) + +/** + * @brief SECTION + * Use the SECTION macro to assign data or code in a specific section. + * Usage: SECTION(".my_section") + */ +#define SECTION(name) __attribute__((section(name))) + +/** + * @brief ALIGN + * Use the ALIGN macro to specify the alignment of a variable. + * Usage: ALIGN(4) + */ +#define ALIGN(N) __attribute__((aligned(N))) + +/** + * @brief WEAK_FUNCTION + * Use the WEAK_FUNCTION macro to declare a weak function. + * Usage: WEAK_FUNCTION(int my_weak_function(void)) + */ +#define WEAK_FUNCTION(function) __weak function + +/** + * @brief NORETURN_FUNCTION + * Use the NORETURN_FUNCTION macro to declare a no return function. + * Usage: NORETURN_FUNCTION(void my_noretrun_function(void)) + */ +#define NORETURN_FUNCTION(function) __attribute__((noreturn)) function + +/** + * @brief NOSTACK_FUNCTION + * Use the NOSTACK_FUNCTION macro to indicate that function should not use any stack. + * Typical usage is for hard fault handler, to avoid altering the value of the stack pointer. + * In keil this is a dummy implementation since no equivalent function is available + * Usage: NOSTACK_FUNCTION(void my_noretrun_function(void)) + */ +#define NOSTACK_FUNCTION(function) function + +/** + * @brief NO_INIT + * Use the NO_INIT macro to declare a not initialized variable. + * Usage: NO_INIT(int my_no_init_var) + * Usage: NO_INIT(uint16_t my_no_init_array[10]) + */ +#define NO_INIT(var) var __attribute__((section( ".noinit.data" ), zero_init)) + +/** + * @brief NO_INIT_SECTION + * Use the NO_INIT_SECTION macro to declare a not initialized variable that should be placed in a specific section. + * Linker script is in charge of placing that section in RAM. + * Usage: NO_INIT_SECTION(int my_no_init_var, "MySection") + * Usage: NO_INIT_SECTION(uint16_t my_no_init_array[10], "MySection") + */ +#define NO_INIT_SECTION(var, sect) var __attribute__((section( sect ), zero_init)) + + +extern void __main(void); +extern int main(void); +extern unsigned int Image$$ARM_LIB_STACKHEAP$$ZI$$Limit; +#define _INITIAL_SP (void(*)(void))&Image$$ARM_LIB_STACKHEAP$$ZI$$Limit /* Stack address */ +#define VARIABLE_SIZE 1 + +/** + * @} + */ + +#else + +#error Neither ICCARM, CC ARM nor GNUC C detected. Define your macros. + +#endif +#endif +#endif + +/** + * @} + */ + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ +#endif /* __COMPILER_H__ */ diff --git a/hal/inc/crash_handler.h b/hal/inc/crash_handler.h new file mode 100644 index 0000000..0c2cda3 --- /dev/null +++ b/hal/inc/crash_handler.h @@ -0,0 +1,145 @@ +/** + ****************************************************************************** + * @file crash_handler.h + * @author AMS - VMA RF Application team + * @version V1.1.0 + * @date 25-November-2016 + * @brief This header file defines the crash handler framework useful for + * application issues debugging + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2015 STMicroelectronics

+ ****************************************************************************** + */ +#ifndef __CRASH_HANDLER_H_ +#define __CRASH_HANDLER_H_ + +#include +#include + +/** + * @brief Number of word for the Exception RAM Locations + */ +#define NMB_OF_EXCEP_RAM_WORD 10 + +/** + * @brief Base address to store the Crash Information + */ +#define CRASH_RAM_SIZE 40 + +/** + * @brief Signature Information: CRASH_SIGNATURE_BASE + */ +#define CRASH_SIGNATURE_BASE 0xBCEC0000 +/** + * @brief Signature Information: ASSERT_SIGNATURE + */ +#define ASSERT_SIGNATURE (CRASH_SIGNATURE_BASE + 0) +/** + * @brief Signature Information: NMI_SIGNATURE + */ +#define NMI_SIGNATURE (CRASH_SIGNATURE_BASE + 1) +/** + * @brief Signature Information: HARD_FAULT_SIGNATURE + */ +#define HARD_FAULT_SIGNATURE (CRASH_SIGNATURE_BASE + 2) +/** + * @brief Signature Information: WATCHDOG_SIGNATURE + */ +#define WATCHDOG_SIGNATURE (CRASH_SIGNATURE_BASE +3) + +/** + * @brief Typedef for the overall crash information (stack pointer, programm counter, registers, ...) + */ +typedef PACKED(struct) crash_infoS { + uint32_t signature; + uint32_t SP; + uint32_t R0; + uint32_t R1; + uint32_t R2; + uint32_t R3; + uint32_t R12; + uint32_t LR; + uint32_t PC; + uint32_t xPSR; +} crash_info_t; + + +extern crash_info_t crash_info_ram; + +/** + * @brief Macro to store in RAM the register information where an assert is verified. + * + * All the information stored are words (32 bit): + * - Assert Signature + * - SP + * - R0 + * - R1 + * - R2 + * - R3 + * - R12 + * - LR + * - PC + * - xPSR + */ +#define ASSERT_HANDLER(expression) { \ + volatile uint32_t * crash_info = (volatile uint32_t *)&crash_info_ram; \ + register uint32_t reg_content; \ + if (!(expression)) { \ + /* Init to zero the crash_info RAM locations */ \ + for (reg_content=0; reg_content
© COPYRIGHT 2015 STMicroelectronics
+ ****************************************************************************** + */ + +#include +#ifndef __FIFO_H__ +#define __FIFO_H__ + +typedef struct circular_fifo_s { + uint16_t tail; + uint16_t head; + uint16_t max_size; + uint8_t *buffer; + uint8_t alignment; +} circular_fifo_t; + +void fifo_init(circular_fifo_t *fifo, uint16_t max_size, uint8_t *buffer, uint8_t alignment); +uint16_t fifo_size(circular_fifo_t *fifo); +uint8_t fifo_put(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer); +uint8_t fifo_put_var_len_item(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer); +uint8_t fifo_get(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer); +uint8_t fifo_discard(circular_fifo_t *fifo, uint16_t size); +uint8_t fifo_get_ptr(circular_fifo_t *fifo, uint16_t size, uint8_t **ptr); +uint8_t fifo_get_var_len_item(circular_fifo_t *fifo, uint16_t *size, uint8_t *buffer); +uint8_t fifo_get_ptr_var_len_item(circular_fifo_t *fifo, uint16_t *size, uint8_t **ptr); +uint8_t fifo_discard_var_len_item(circular_fifo_t *fifo); +void fifo_flush(circular_fifo_t *fifo); +#endif /* __FIFO_H__ */ diff --git a/hal/inc/gp_timer.h b/hal/inc/gp_timer.h new file mode 100644 index 0000000..ca21eeb --- /dev/null +++ b/hal/inc/gp_timer.h @@ -0,0 +1,89 @@ +/** + ****************************************************************************** + * @file gp_timer.h + * @author AMS - RF Application team + * @version V1.1.0 + * @date 26-March-2018 + * @brief Header file for general purpose timer library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2015 STMicroelectronics

+ ****************************************************************************** + */ +#ifndef __GP_TIMER_H__ +#define __GP_TIMER_H__ + +#include "clock.h" + +/** + * @brief Timer structure. Use Timer_Set() to set the timer. + * + */ +struct timer { + tClockTime start; + tClockTime interval; +}; + +/** + * @brief This function sets a timer for a specific time. + * The function Timer_Expired() returns true if + * the timer has expired. + * + * @param[in] t Pointer to timer + * @param[in] interval The interval before the timer expires. + * + * @retval None + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * @brief This function resets the same interval that was + * given to the Timer_Set() function. The starting point of the interval is + * the last timer value when timer expired. Using this function + * makes the timer being stable over time. + * + * @param[in] t Pointer to timer + * + * @retval None + */ +void Timer_Reset(struct timer *t); + +/** + * @brief This function resets the same interval that was + * given to the Timer_Set() function. The starting point of the interval is + * the current time. For a stable timer over time, it is recommended to use + * the Timer_Reset() function. + * + * @param[in] t Pointer to timer + * + * @retval None + */ +void Timer_Restart(struct timer *t); + +/** + * @brief This function verifies if a timer has expired. + * + * @param[in] t Pointer to timer + * + * @retval 1 if the timer has expired, 0 if not expired. + */ +uint8_t Timer_Expired(struct timer *t); + +/** + * @brief This function returns the remaining time before the timer expires. + * + * @param[in] t Pointer to timer + * + * @retval The remaining time. + */ +tClockTime Timer_Remaining(struct timer *t); + +#endif /* __GP_TIMER_H__ */ diff --git a/hal/inc/hal_radio.h b/hal/inc/hal_radio.h new file mode 100644 index 0000000..6d52c89 --- /dev/null +++ b/hal/inc/hal_radio.h @@ -0,0 +1,56 @@ +/** + ****************************************************************************** + * @file hal_radio.h + * @author RF Application team + * @date Jan-2020 + * @brief BlueNRG-1,2 HAL radio APIs + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2020 STMicroelectronics

+ ****************************************************************************** + */ +#ifndef __HAL_RADIO_H_ +#define __HAL_RADIO_H_ + +#include "BlueNRG1_radio.h" + + +uint8_t HAL_RADIO_SendPacket(uint8_t channel, + uint32_t wakeup_time, + uint8_t* txBuffer, + uint8_t (*Callback)(ActionPacket*, ActionPacket*) ); + +uint8_t HAL_RADIO_SendPacketWithAck(uint8_t channel, + uint32_t wakeup_time, + uint8_t* txBuffer, + uint8_t* rxBuffer, + uint32_t receive_timeout, + uint8_t (*Callback)(ActionPacket*, ActionPacket*) + ); + +uint8_t HAL_RADIO_ReceivePacket(uint8_t channel, + uint32_t wakeup_time, + uint8_t* rxBuffer, + uint32_t receive_timeout, + uint8_t (*Callback)(ActionPacket*, ActionPacket*) ); + +uint8_t HAL_RADIO_ReceivePacketWithAck(uint8_t channel, + uint32_t wakeup_time, + uint8_t* rxBuffer, + uint8_t* txBuffer, + uint32_t receive_timeout, + uint8_t (*Callback)(ActionPacket*, ActionPacket*) + ); + +uint8_t HAL_RADIO_SetNetworkID(uint32_t ID); + + +#endif /* __HAL_RADIO_H_ */ diff --git a/hal/inc/hal_types.h b/hal/inc/hal_types.h new file mode 100644 index 0000000..d555634 --- /dev/null +++ b/hal/inc/hal_types.h @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file hal_types.h + * @author AMS - VMA RF Application team + * @version V1.0.1 + * @date 3-April-2018 + * @brief Header file that includes hal types for BlueNRG-1 SoC + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2015 STMicroelectronics

+ ****************************************************************************** + */ +#ifndef __HAL_TYPES_H__ +#define __HAL_TYPES_H__ + +#include + +/**@brief RESET,SET definition */ +typedef enum {RESET = 0, SET} FlagStatus, ITStatus; +/**@brief Macro that checks if STATE is a FlagStatus / ITStatus */ +#define IS_FLAGSTATUS(STATE) (((STATE) == RESET) || ((STATE) == SET)) +#define IS_ITSTATUS(STATE) IS_FLAGSTATUS(STATE) + +/**@brief DISABLE, ENABLE definition */ +typedef enum {DISABLE = 0, ENABLE} FunctionalState; +/** @brief Macro that checks if STATE is a FunctionalState */ +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum {SUCCESS = 0, ERROR} ErrorStatus; +/** @brief Macro that checks if STATE is a ErrorStatus */ +#define IS_ERROR_STATE(STATE) (((STATE) == SUCCESS) || ((STATE) == ERROR)) + + +/** @brief Macro that stores a 16-bit value into a buffer in Little Endian Format (2 bytes)*/ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +/** @brief Macro that returns a 16-bit value from a buffer where the value is stored in Little Endian Format */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t)*((uint8_t *)ptr)) | \ + ((uint16_t)*((uint8_t *)ptr + 1) << 8) ) + +/** @brief Macro that returns a value from a 32-bit buffer where the value is stored in Little Endian Format */ +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/** @brief Macro that stores a 32-bit value into a buffer in Little Endian Format (4 bytes) */ +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +/** @brief Booelan definition */ +typedef uint8_t BOOL; + +/**@brief TRUE, FALSE definition */ +#define TRUE ((BOOL)1U) +#define FALSE ((BOOL)0U) + +#endif /* __HAL_TYPES_H__ */ diff --git a/hal/inc/miscutil.h b/hal/inc/miscutil.h new file mode 100644 index 0000000..2dc21bf --- /dev/null +++ b/hal/inc/miscutil.h @@ -0,0 +1,99 @@ +/** + ****************************************************************************** + * @file miscutil.h + * @author AMS - RF Application team + * @version V1.2.0 + * @date 14-February-2020 + * @brief Header file for miscellaneous utilities. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2020 STMicroelectronics

+ ****************************************************************************** + */ +#ifndef __MISCUTIL_H__ +#define __MISCUTIL_H__ + +#include +#include "crash_handler.h" + + +#define DIE_ID_BLUENRG2 ((uint8_t)2) +#define DIE_ID_BLUENRG1 ((uint8_t)1) + +#define DIE_SW_ID_BLUENRG2N ((uint8_t)4) + + +/** + * @brief A structure that represents part information details + * + */ +typedef struct PartInfoS { + /** DIE ID number */ + uint8_t die_id; + /** Die major number */ + uint8_t die_major; + /** Die cut number */ + uint8_t die_cut; + /** JTAG ID */ + uint32_t jtag_id_code; + /** Flash size in bytes */ + uint32_t flash_size; +} PartInfoType; + +/** + * @brief This function return a structure with information about the device + * + * @param[out] partInfo Pointer to a PartInfoType structure + * + * @retval None + */ +void HAL_GetPartInfo(PartInfoType *partInfo); +/** + * @brief Get Crash Information utility + * + * This function return the crash information that are stored in RAM, by hard + * handler, nmi handler and assert handler. + * This function reset the crash information stored in RAM before it returns. + * So it avoid to report the same crash information after a normal reboot. + * + * @param[out] crashInfo Pointer to a crash_info_t structure + * + * @retval None + */ +void HAL_GetCrashInfo(crash_info_t *crashInfo); +/** + * @brief Set Crash Information utility + * + * This function stores crash information in RAM and reset the device + * Crash information can be retrieved by using API HAL_GetCrashInfo + * + * @param[in] msp Stack pointer containg crash info + * @param[out] signature CRash reason signature + * + * @retval None + */ +void HAL_CrashHandler(uint32_t msp, uint32_t signature); + +/** + * @brief Get Device ID, Version and Revision numbers + * + * This function returns the device ID, version and revision numbers. + * To be called by the BLE Stack for ensuring platform independence. + * + * @param[out] device_id Device ID (1 = BlueNRG-1; 2 = BlueNRG-2) + * @param[out] major_cut Device cut version/major number + * @param[out] minor_cut Device cut revision/minor number + * + * @retval None + */ +void BLEPLAT_get_part_info(uint8_t *device_id, uint8_t *major_cut, uint8_t *minor_cut); + +#endif /* __MISCUTIL_H__ */ diff --git a/hal/inc/osal.h b/hal/inc/osal.h new file mode 100644 index 0000000..793a997 --- /dev/null +++ b/hal/inc/osal.h @@ -0,0 +1,78 @@ +/** + ****************************************************************************** + * @file osal.h + * @author AMS - VMA RF Application team + * @version V1.1.0 + * @date 25-November-2016 + * @brief This header file defines the OS abstraction layer used by + * the BLE stack. OSAL defines the set of functions + * which needs to be ported to target operating system and + * target platform. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2015 STMicroelectronics

+ ****************************************************************************** + */ +#ifndef __OSAL_H__ +#define __OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * @brief This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + +/** + * @brief This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * @brief This function compares n bytes of two regions of memory + * + * @param[in] s1 First buffer to compare. + * @param[in] s2 Second buffer to compare. + * @param[in] size Number of bytes to compare. + * + * @return 0 if the two buffers are equal, 1 otherwise + */ +extern int Osal_MemCmp(void *s1,void *s2,unsigned int size); +#endif /* __OSAL_H__ */ diff --git a/hal/inc/radio_ota.h b/hal/inc/radio_ota.h new file mode 100644 index 0000000..2bb19e8 --- /dev/null +++ b/hal/inc/radio_ota.h @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2017 STMicroelectronics ******************** +* File Name : radio_ota.c +* Author : RF Application Team +* Version : V1.0.0 +* Date : May-2018 +* Description : OTA library for user application +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + ****************************************************************************** + * @file radio_ota.h + * @author AMS - RF Application team + * @version V1.0.0 + * @date 29-May-2018 + * @brief Header file for 2,4 GHz proprietary radio Over-the-Air FW upgrade APIs + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2018 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +/** @addtogroup BlueNRG1_StdPeriph_Examples +* @{ +*/ + +/** @addtogroup RADIO_Examples RADIO Examples +* @{ +*/ + +/** @addtogroup RADIO_TxRx RADIO TxRx Example +* @{ +*/ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/** + * @brief This function allows to give control to the OTA Reset Manager who handles + * the 2,4 GHz proprietary radio Over-the-Air FW upgrade procedure and the jump + * to the valid application to be run. + * + * @param None + * + * @retval None + */ +void OTA_Jump_To_Reset_Manager(void); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2017 STMicroelectronics *****END OF FILE****/ diff --git a/hal/inc/sleep.h b/hal/inc/sleep.h new file mode 100644 index 0000000..b673aef --- /dev/null +++ b/hal/inc/sleep.h @@ -0,0 +1,281 @@ +/** + ****************************************************************************** + * @file sleep.h + * @author AMS - RF Application team + * @version V1.2.0 + * @date 12-December-2018 + * @brief Header file for BlueNRG-1,2 Sleep management + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2018 STMicroelectronics

+ ****************************************************************************** + */ +/** + * @file sleep.h + * @brief BlueNRG Sleep management + * + +* \section Library BlueNRG-1, BlueNRG-2 Low Power management + + - The BlueNRG-1, BlueNRG-2 low power software combines the low power requests coming from + the application with the radio operating mode, choosing the best low power mode + applicable in the current scenario. + - This negotiation between the radio module and the application requests prevents data loss + and it is performed by the low power software APIs. User is requested to call the BlueNRG_Sleep(SleepModes sleepMode, uint8_t gpioWakeBitMask, uint8_t gpioWakeLevelMask) API. + - Refer to AN4820 "BlueNRG-1 and BlueNRG-2 low power modes" document for detailed description about the devices HW low power modes and SW support. + +* \section Sleep_API How BlueNRG_Sleep() API works? + + - BlueNRG_Sleep(SleepModes sleepMode, uint8_t gpioWakeBitMask, uint8_t gpioWakeLevelMask) must be + called on main application while loop, with selected sleep mode (SLEEPMODE_RUNNING, SLEEPMODE_CPU_HALT,SLEEPMODE_WAKETIMER,SLEEPMODE_NOTIMER), + gpio bit masks and level for selecting the external wakup source if applicable. + - BlueNRG_Sleep() API sets the actual sleep mode value (sleepMode_allowed variable) as combination of following components: + - BlueNRG_Sleep() sleepMode parameter value + - user sleep mode provided within App_SleepMode_Check() function + - BLE Stack sleep mode returned from BlueNRG_Stack_Perform_Deep_Sleep_Check() function. + + - sleepMode_allowed value determines actual sleep mode and associated actions: + - SLEEPMODE_RUNNING: + - It just reenables global interrupt operations (nothing else to be done); + - SLEEPMODE_CPU_HALT: + - __WFI() is called: it executes a wait for interrupt instruction and suspends the core execution until one of a number of events occurs. + - Global interrupt operations are re-enabled. + - SLEEPMODE_WAKETIMER, SLEEPMODE_NOTIMER: + - BlueNRG_InternalSleep(sleepMode_allowed, gpioWakeBitMask) is called, after wakeup sources setup. + + * \section Sleep_Modes How BlueNRG_InternalSleep() API works? (SLEEPMODE_WAKETIMER, SLEEPMODE_NOTIMER sleep modes) + + - When the BlueNRG-1 and BlueNRG-2 exit from SLEEPMODE_WAKETIMER, SLEEPMODE_NOTIMER low power mode a reset occurs: all the + peripherals configuration and the application context are lost. + - The BlueNRG_InternalSleep() API implements a mechanism to save and restore all the peripheral configuration and the application context when a power save procedure is called. + + - BlueNRG_InternalSleep(sleepMode_allowed, gpioWakeBitMask) performs the following main operations in order to enter in sleep mode (SLEEPMODE_WAKETIMER, SLEEPMODE_NOTIMER) and restore context: + + - Save the peripherals registers configurations on dedicated variables: System Control, FLASH CONFIG, NVIC, CKGEN, GPIO, UART, SPI, I2C, RNG, RNG, RTC, MFTX, SysTick, WDT, DMA, ADC, PKA. + - Enable deep sleep: SystemSleepCmd(ENABLE); + - Save the context by calling the calling the CS_contextSave() function on context_switch.s file. + + - When BlueNRG-1 and BlueNRG-2 exit from SLEEPMODE_WAKETIMER, SLEEPMODE_NOTIMER low power mode due to a wakeup reason, a reset occurs. The following main operations are done: + + - On reset the __low_level_init() function is called which checks the reset reason: + - Since the reset reason is a wakeup from sleep, it restores the context by calling the CS_contextRestore() function on context_switch.s file. + - Disable deep sleep (SystemSleepCmd(DISABLE)) + - Restore the peripherals registers configuration previously saved on dedicated variables FLASH CONFIG, NVIC, CKGEN, UART, SPI, I2C, RNG, RNG, RTC, MFTX, SysTick, WDT, DMA, ADC, PKA. + + - NOTE: From the application point of view, the exit from a low power procedure is fully transparent: when a wakeup from low power occurs, the CPU executes the next instruction after the low power function call. + + * \section Wakeup_WFI How to properly handle device entering in the Sleep mode with a wakeup source from GPIO active? + + If the user application wants to enter in sleep mode (SLEEPMODE_WAKETIMER or SLEEPMODE_NOTIMER) and starts the sleep procedure with a wakeup source + from GPIO already active, the system does not switch the power management off and remains blocked in the WFI instruction until an interrupt occurs. + In this context, if other defined wakeup sources occur, they are ignored. The only way to restart the code execution is through an interrupt occurring from any peripheral. + In addition to user specific needs, it is MANDATORY to enable, at NVIC level and GPIO level, the interrupt associated with the GPIO wakeup sources as follow: + - If wakeup source level is LOW, the associated IRQ level must be on falling edge (IRQ_ON_FALLING_EDGE); + - If wakeup source level is HIGH, the associated IRQ level must be on rising edge (IRQ_ON_RISING_EDGE). + The GPIO handler should handle also the interrupt associated with the edges, by clearing the interrupt cause. + If the application needs also GPIO interrupt on the other edge, it could enable both edges and discard the edge not needed in the GPIO handler. + + - Example: let's assume the wakeup source is IO13 with LOW level and no specific interrupt is enabled and associated to this IO at application level. + User must enable, at NVIC level, the interrupt on IO13 with IRQ level on falling edge. + + - while (1) { + BTLE_StackTick(); + + wakeup_source = WAKEUP_IO13; + wakeup_level = (WAKEUP_IO_LOW << WAKEUP_IO13); + + + + BlueNRG_Sleep(SLEEPMODE_NOTIMER, wakeup_source, wakeup_level, 0); + } + + * \section Wakeup_Reason How to properly handle a wakeup source from a wakeup GPIO (IO9, 10,11,12,13) for which an interrupt is also expected ? + + When in sleep mode, if a wakeup with associated IRQ handler occurs on a wakeup IO, the device is waked up, but the related IO user operations on associated IRQ handler cannot be properly handled. + This is due to the fact that an event on such IO allows to wake up the device in sleep mode, but, since the GPIO peripheral is in sleep mode, the associated IT pending bit is not set. + As consequence, on associated GpioHandler(), user application is not able to correctly check the IT pending bit and perform the related operations. + + After existing from sleep mode, the following checks on associated IO handler (GpioHandler()) must be performed: + + - use wakeupFromSleepFlag flag to verify that device actually exits from sleep mode and check if the wakeup source is the one associated to the specific IO (by using BlueNRG_WakeupSource() API). + + - Example: let's assume the wakeup source is IO12 and user application requires to perform specific operations on associated IRQ function (GPIO_handler()). + + - On main application user enables the sleep mode by setting IO12 as wakeup source: + + BlueNRG_Sleep(SLEEPMODE_WAKETIMER,WAKEUP_I12,WAKEUP_IOx_LOW<< WAKEUP_I12_SHIFT_MASK); + + - On BlueNRG1_it.c, the following changes must be applied on GPIO_Handler() function: + + void GPIO_Handler(void) + { + if ((GPIO_GetITPendingBit(GPIO_Pin_12) == SET) || ((wakeupFromSleepFlag) && (BlueNRG_WakeupSource() & WAKEUP_IO12))) + { + GPIO_ClearITPendingBit(GPIO_Pin_12); + + ... //User code to be executed when IRQ on IO12 occurs + } + } + +**/ + +#ifndef __SLEEP_H__ +#define __SLEEP_H__ + +#include "bluenrg_x_device.h" + +/** @brief Enumerations for the possible microcontroller sleep modes. + * - SLEEPMODE_RUNNING + * Everything is active and running. In practice this mode is not + * used, but it is defined for completeness of information. + * - SLEEPMODE_CPU_HALT + * Only the CPU is halted. The rest of the chip continues running + * normally. The chip will wake from any interrupt. + * - SLEEPMODE_WAKETIMER + * The device is in deep sleep and the timer clock sources remain running. + * Wakeup is possible from both GPIO and the Hal Virtual Timers. + * - SLEEPMODE_NOTIMER + * The device is in deep sleep. All the peripherals and clock sources are turned off. + * Wakeup is possible only from GPIOs IO9-IO10-IO11-IO12-IO13. + */ +typedef enum { + SLEEPMODE_RUNNING = 0, + SLEEPMODE_CPU_HALT = 1, + SLEEPMODE_WAKETIMER = 2, + SLEEPMODE_NOTIMER = 3, +} SleepModes; + +/** @brief Wakeup source IO9 Mask */ +#define WAKEUP_IO9 0x0001 + +/** @brief Wakeup source IO10 Mask */ +#define WAKEUP_IO10 0x0002 + +/** @brief Wakeup source IO11 Mask */ +#define WAKEUP_IO11 0x0004 + +/** @brief Wakeup source IO12 Mask */ +#define WAKEUP_IO12 0x0008 + +/** @brief Wakeup source IO13 Mask */ +#define WAKEUP_IO13 0x0010 + +/** @brief Wakeup source Blue block Sleep Timer 1 */ +#define WAKEUP_SLEEP_TIMER1 0x0020 + +/** @brief Wakeup source Blue block Sleep Timer 2 */ +#define WAKEUP_SLEEP_TIMER2 0x0040 + +/** @brief The Reset reason is not caused from a wakeup source but from a BOR reset */ +#define WAKEUP_BOR 0x0080 + +/** @brief The Reset reason is not caused from a wakeup source but from a POR reset */ +#define WAKEUP_POR 0x0100 + +/** @brief The Reset reason is not caused from a wakeup source but from a System reset request */ +#define WAKEUP_SYS_RESET_REQ 0x0200 + +/** @brief The Reset reason is not caused from a wakeup source but from a watchdog timer reset */ +#define WAKEUP_RESET_WDG 0x0400 + +/** @brief The Reset reason is not caused from a known wakeup source */ +#define NO_WAKEUP_RESET 0x0000 + +/** @brief The system wakes up when IOx level is low */ +#define WAKEUP_IOx_LOW 0x00 + +/** @brief The system wakes up when IOx level is high */ +#define WAKEUP_IOx_HIGH 0x01 + +/** @brief IO9 wake up shift mask */ +#define WAKEUP_IO9_SHIFT_MASK 0x00 + +/** @brief IO10 wake up shift mask */ +#define WAKEUP_IO10_SHIFT_MASK 0x01 + +/** @brief IO11 wake up shift mask */ +#define WAKEUP_IO11_SHIFT_MASK 0x02 + +/** @brief IO12 wakeup shift mask */ +#define WAKEUP_IO12_SHIFT_MASK 0x03 + +/** @brief IO13 wake up shift mask */ +#define WAKEUP_IO13_SHIFT_MASK 0x04 + +/** + * @brief This function allows to put the BlueNRG in low power state. + * + * This function allows to enter a desired sleep mode that is negotiated between BTLE stack needs and application needs. + * The application can provide the desired sleep mode using the parameter sleepMode. In addition to this, the application can + * optionally use the @ref App_SleepMode_Check to provide its desired sleep mode. + * The function will compute the sleep mode by combining the different requests and choosing the lowest possible power mode. + * + * The device can be configured with different wake sources + * according to the sleepMode parameter. The lowest power mode is obtained configuring the device in + * SLEEPMODE_NOTIMER. + * For all sleep modes, BlueNRG_Sleep() will return when the wakeup occours. + * + * @param sleepMode Sleep mode (see SleepModes enum) + * + * @param gpioWakeBitMask A bit mask of the GPIO that are allowed to wake + * the chip from deep sleep. A high bit in the mask will enable waking + * the chip if the corresponding GPIO changes state. bit0 is IO9, bit1 is + * IO10, bit2 is IO11, bit3 is IO12, bit4 is IO13, bits[5:7] are ignored. + * If this param is 0 the wakeup GPIO are ignored + * @param gpioWakeLevelMask A mask used to setup the active wakeup level: + * - 0: the system wakes up when IO is low + * - 1: the system wakes up when IO is high + * The level sensitive bit mask is the same of the gpioWakeBitMask parameter. + * + * @retval Status of the call + */ +uint8_t BlueNRG_Sleep(SleepModes sleepMode, + uint8_t gpioWakeBitMask, + uint8_t gpioWakeLevelMask); + + +/** + * @brief This function allows the application to define its desired sleep mode. + * + * The App_SleepMode_Check allows the application to set its desired sleep mode based on the application power management policy. + * When user calls @ref BlueNRG_Sleep, a negotiation occurs to define the sleep mode and this function is called to get + * inputs from application. + * It is important to notice that this function is executed with interrupts disabled + * + * @param sleepMode Sleep mode (see SleepModes enum) + * + * @retval Return the sleep mode possible and safe from the application point of view + * + * @note A weak implementation always returning SLEEPMODE_NOTIMER is provided as default + * when no application specifc behaviour is required. + */ + +SleepModes App_SleepMode_Check(SleepModes sleepMode); + + +/** + * @brief Return the wakeup source from reset. Possible value can be a combination of the : + * - WAKEUP_IO9 + * - WAKEUP_IO10 + * - WAKEUP_IO11 + * - WAKEUP_IO12 + * - WAKEUP_IO13 + * - WAKEUP_SLEEP_TIMER1 + * - WAKEUP_SLEEP_TIMER2 + * - WAKEUP_BOR + * - WAKEUP_POR + * - WAKEUP_SYS_RESET_REQ + * - WAKEUP_RESET_WDG + * - NO_WAKEUP_RESET + */ +uint16_t BlueNRG_WakeupSource(void); + +#endif diff --git a/hal/inc/vtimer.h b/hal/inc/vtimer.h new file mode 100644 index 0000000..a8f53e4 --- /dev/null +++ b/hal/inc/vtimer.h @@ -0,0 +1,278 @@ +/** + ****************************************************************************** + * @file vtimer.h + * @author RF Application Team + * @date Jan-2020 + * @brief vtimer and Radio timer high level APIs header file + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2020 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef VTIMER_H +#define VTIMER_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include "hal_types.h" +#include "sleep.h" +#include "BlueNRG1_timer.h" + +/** @defgroup VTIMER_Exported_Types Exported Types + * @{ + */ + +typedef enum { + RADIO_TIMER_OFF = 0, + RADIO_TIMER_PENDING = 1, +} RadioStatus; + +typedef void (*VTIMER_CallbackType)(void *); +typedef struct VTIMER_HandleTypeS { + uint64_t expiryTime; + VTIMER_CallbackType callback; + BOOL active; /*Managed by the timer tick. User does not have to care about this*/ + struct VTIMER_HandleTypeS *next; /*Managed by the timer tick. User does not have to care about this*/ + void *userData; +} VTIMER_HandleType; + +typedef void (*usr_cb_t)(void *); +typedef struct VTIMER_RadioHandleTypeS { + uint64_t expiryTime; /*When the first bit is transmitted or when the receive window is opened*/ + BOOL cal_req; + BOOL active; /*Managed by the timer tick. User does not have to care about this*/ + BOOL pending; /*Managed by the timer tick. User does not have to care about this*/ + BOOL event_type; +} VTIMER_RadioHandleType; + +typedef struct HAL_VTIMER_InitS { + uint16_t XTAL_StartupTime; /*!< XTAL startup in 2.44 us unit */ +/** + * Enable initial estimation of the frequency of the Low Speed Oscillator, otherwise it will be assumed fixed at 32.768 kHz. + * Ignored if periodic calibration is active (PeriodicCalibrationInterval != 0). + */ + BOOL EnableInitialCalibration; + uint16_t PeriodicCalibrationInterval; /*!< Periodic calibration interval in ms, to disable set to 0 */ +} HAL_VTIMER_InitType; + +/** + * @} + */ + +/** @defgroup Radio_Exported_Constants Exported Constants +* @{ +*/ +#define HAL_VTIMER_SUCCESS 0 +#define HAL_VTIMER_LATE 1 +#define HAL_VTIMER_CRITICAL 2 + +#define RADIO_ACTIVITY_MARGIN 204800 + +/* Threshold to take into account the calibration duration. TBR */ +#define CALIB_SAFE_THR 370 + +/* Minimum threshold in STU to safely clear radio timers. +The wakeup timer in the worst case triggers about 30us in advance. +This must be considered when the radio timer is cleared. +Then a window of about 30 us is considered as critical, that is +it is not sure the timer can be cleared properly*/ +#define CLEAR_TIME_MIN 14 + +#define BLUE_SLEEP_ENABLE (0x10000000) + +/** @defgroup HAL_VTimer_SetRadioTimerValue flags + * @{ + */ + +#define HAL_VTIMER_PLL_CALIB_REQ (0x01U) +#define HAL_VTIMER_PLL_CALIB_NOT_REQ (0x00U) +#define HAL_VTIMER_TX_EVENT (0x01U) +#define HAL_VTIMER_RX_EVENT (0x00U) + +/** + * @} + */ + +/** +* @} +*/ + +/** @defgroup VTIMER_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Starts a one-shot virtual timer for the given relative timeout value expressed in ms + * @param timerHandle: The virtual timer + * @param msRelTimeout: The relative time, from current time, expressed in ms + * @retval 0 if the timerHandle is valid. + * @retval 1 if the timerHandle already started. + */ +int HAL_VTimerStart_ms(VTIMER_HandleType *timerHandle, uint32_t msRelTimeout); + +/** + * @brief Stops the one-shot virtual timer specified if found + * @param timerHandle: The virtual timer + * @retval None + */ +void HAL_VTimer_Stop(VTIMER_HandleType *timerHandle); + +/** + * @brief This function return the current reference time expressed in system time units. + * The returned value can be used as absolute time parameter where needed in the other + * HAL_VTimer* APIs + * @return absolute current time expressed in system time units. + */ +uint32_t HAL_VTimerGetCurrentTime_sysT32(void); + +/** + * @brief This function returns the sum of an absolute time and a signed relative time. + * @param sysTime: Absolute time expressed in internal time units. + * @param msTime: Signed relative time expressed in ms. + * @note abs(msTime) <= 5242879 + * @return 32bit resulting absolute time expressed in internal time units. + */ +uint64_t HAL_VTimerAcc_sysT32_ms(uint64_t sysTime, int32_t msTime); + +/** + * @brief Returns the difference between two absolute times: sysTime1-sysTime2. + * The resulting value is expressed in ms. + * @param sysTime2: Absolute time expressed in internal time units. + * @param sysTime1: Absolute time expressed in internal time units. + * @return resulting signed relative time expressed in ms. + */ +int64_t HAL_VTimerDiff_ms_sysT32(uint64_t sysTime1, uint64_t sysTime2); + +/** + * @brief Starts a one-shot virtual timer for the given absolute timeout value + * expressed in internal time units. + * @param timerHandle: The virtual timer + * @param time: Absolute time expressed in STU. + * @retval 0 if the timerHandle is valid. + * @retval 1 if the timerHandle is not valid. It already started. + */ +int HAL_VTimerStart_sysT32(VTIMER_HandleType *timerHandle, uint64_t time); + +/** + * @brief Returns the absolute expiry time of a running timer expressed in internal time units. + * @param timerHandle: The virtual timer + * @param sysTime: Absolute time expressed in internal time units. + */ +int HAL_VTimerExpiry_sysT32(VTIMER_HandleType *timerHandle, uint64_t *sysTime); + +/** + * @brief Initialize the timer module. It must be placed in the initialization + * section of the application. + * @retval None + */ +void HAL_VTIMER_Init(HAL_VTIMER_InitType *HAL_TIMER_InitStruct); + +/** + * @brief Timer module state machine. Check and schedule the calibration. + * Check expired timers and execute user callback. + * It must be placed inside the infinite loop. + * @retval None + */ +void HAL_VTIMER_Tick(void); + +/** + * @brief Return the consensus of the Virtual timer management to go in sleep. + * @retval TRUE if all vtimers have been served and the calibration procedure has already finished. + * @retval FALSE if the vtimer Tick is still busy. + */ +uint8_t HAL_VTIMER_SleepCheck(void); + +/** + * @brief Returns the admitted sleep mode according to the next timer activity. + * @return Sleep mode + */ +SleepModes HAL_VTIMER_TimerSleepCheck(SleepModes sleepMode); + +/** + * @brief Virtual timer Timeout Callback. It must be called in the Blue handler + * if the host wake up timer bit in the radio controller interrupt/status + * register is active. + * @retval None + */ +void HAL_VTIMER_TimeoutCallback(void); + +/** + * @brief Radio activity finished. Not used yet + * @retval None + */ +void HAL_VTIMER_RadioTimerIsr(void); + +/** + * @brief Returns the number of timers in the queue. + * @return number of timers in the queue. + */ +uint32_t HAL_VTIMER_GetPendingTimers(void); + +/** + * @brief Schedules a radio activity for the given absolute timeout value expressed in STU + * If the calibration of the low speed oscillator is needed, if it is possible, + * the radio timer will be programmed with the latest calibration data. + * @param time: Absolute time expressed in STU. + * @param event_type: Specify if it is a TX (1) or RX (0) event. + * @param cal_req: Specify if PLL calibration is requested (1) or not (0). + * @retval 0 if radio activity has been scheduled succesfully. + * @retval 1 if radio activity has been rejected (it is too close or in the past). + */ +uint8_t HAL_VTimer_SetRadioTimerValue(uint32_t time, uint8_t event_type, uint8_t cal_req); + +/** + * @brief Disable Timer2. + * @retval None + */ +void HAL_VTimer_StopRadioTimer2(void); + +/** + * @brief Return the status of the radio timer. + * The timeout of the last radio timer activity taken into account by the Timer Module + * is saved in the variable passed as parameter. + * @param time: Pointer of the variable where the time of the last radio activity scheduled is stored + * The time is expressed in STU. + * @retval 0 if no radio timer is pending. + * @retval 1 if a radio timer is pending and it is not already expired. + */ +RadioStatus HAL_VTimer_GetRadioTimerValue(uint32_t *time); + +/** + * @brief Clear the last radio activity scheduled disabling the radio timer too. + * Furthermore, it returns if the timeout is too close with respect the current time and + * the radio activity might not be cleared in time. + * @retval 0 if the radio activity has been cleared successfully. + * @retval 2 if it might not be possible to clear the last radio activity. + */ +uint8_t HAL_VTimer_ClearRadioTimerValue(void); + +/** + * @brief Get the last anchorPoint in system time unit. + * @return TimerCapture register is system time unit. + */ +uint64_t HAL_VTIMER_GetAnchorPoint(void); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*VTIMER_H */ + +/******************* (C) COPYRIGHT 2020 STMicroelectronics *****END OF FILE****/ diff --git a/hal/src/clock.c b/hal/src/clock.c new file mode 100644 index 0000000..ef08179 --- /dev/null +++ b/hal/src/clock.c @@ -0,0 +1,84 @@ +/** +****************************************************************************** +* @file clock.c +* @author AMS - VMA RF Application Team +* @version V1.0.0 +* @date 14-September-2015 +* @brief clock APIs based on SySTick +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2015 STMicroelectronics

+****************************************************************************** +*/ +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" +#include "BlueNRG1_conf.h" +#include "clock.h" + +/** @addtogroup BlueNRG1_StdPeriph_Examples +* @{ +*/ + +/** @addtogroup UART Interrupt Example +* @{ +*/ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +#if ((HS_SPEED_XTAL == HS_SPEED_XTAL_32MHZ)&&(FORCE_CORE_TO_16MHZ != 1)) + #define SYSCLK_FREQ 32000000 /* System clock frequency */ +#elif (HS_SPEED_XTAL == HS_SPEED_XTAL_16MHZ)||(FORCE_CORE_TO_16MHZ == 1) + #define SYSCLK_FREQ 16000000 /* System clock frequency */ +#else +#error "No definition for SYSCLK_FREQ" +#endif + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static volatile tClockTime sys_tick_count; +const tClockTime CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ +void SysCount_Handler(void) +{ + sys_tick_count++; +} + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + /** Configure SysTick to generate Interrupt with 1ms period */ + SysTick_Config(SYSCLK_FREQ/1000 - 1); +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return sys_tick_count; +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + tClockTime start; + + start = Clock_Time(); + while(Clock_Time() - start < (tClockTime)i); +} +/*---------------------------------------------------------------------------*/ + diff --git a/hal/src/context_switch.s b/hal/src/context_switch.s new file mode 100644 index 0000000..49e5ed0 --- /dev/null +++ b/hal/src/context_switch.s @@ -0,0 +1,109 @@ +#include "../inc/asm.h" + + +//------------------------------------------------------------------------------ +// void CS_contextSave(void) +// void CS_contextRestore(void) +// +// These two functions are needed for the context switch during the power +// save procedure. The purpose of the CS_contextSave() function is to +// either save the current context and trigger sleeping through the 'WFI' +// instruction. +// The CS_contextRestore() function restores the context saved before +// to go in deep sleep. +// All the Cortex M0 registers are saved and restored plus after wakeup +// ----------------------------------------------------------------------------- + __CODE__ + __THUMB__ + __EXPORT__ CS_contextSave + __EXPORT__ CS_contextRestore + __IMPORT__ savedMSP + __IMPORT__ savedICSR + __IMPORT__ savedSHCSR + __IMPORT__ savedNVIC_ISPR +EXPORT_FUNC(CS_contextSave) + MRS R2, CONTROL /* load the CONTROL register into R2 */ + MRS R1, PSP /* load the process stack pointer into R1 */ + LDR R0, =0 + MSR CONTROL, R0 /* Switch to Main Stack Pointer */ + ISB +#ifdef CONTEXT_SAVE_V2 + SUB SP, #0x44 /* Move stack pointer in order to be sure that after wake up the __low_level_init() + will not corrupt data saved in the stack by CS_contextSave routine. + WARNING: this instruction breaks backward compatibility with previous CS_contextRestore. */ +#endif + + PUSH { r4 - r7, lr } /* store R4-R7 and LR (5 words) onto the stack */ + MOV R3, R8 /* move {r8 - r12} to {r3 - r7} */ + MOV R4, R9 + MOV R5, R10 + MOV R6, R11 + MOV R7, R12 + PUSH {R3-R7} /* store R8-R12 (5 words) onto the stack */ + + LDR R4, =savedMSP /* load address of savedMSP into R4 */ + MRS R3, MSP /* load the stack pointer into R3 */ + STR R3, [R4] /* store the MSP into savedMSP */ + + PUSH { r1, r2 } /* store PSP, CONTROL */ + + LDR R4, =0xE000ED04 /* load address of ICSR register into R4 */ + LDR R0, [R4] /* load the ICSR register value into R0 */ + LDR R4, =savedICSR /* load address of savedICSR into R4 */ + STR R0, [R4] /* store the ICSR register value into savedICSR */ + + LDR R4, =0xE000ED24 /* load address of SHCSR register into R4 */ + LDR R0, [R4] /* load the SHCSR register value into R0 */ + LDR R4, =savedSHCSR /* load address of savedSHCSR into R4 */ + STR R0, [R4] /* store the SHCSR register value into savedSHCSR */ + + LDR R4, =0xE000E200 /* load address of NVIC_ISPR register into R4 */ + LDR R0, [R4] /* load the NVIC_ISPR register value into R0 */ + LDR R4, =savedNVIC_ISPR /* load address of savedNVIC_ISPR into R4 */ + STR R0, [R4] /* store the NVIC_ISPR register value into savedNVIC_ISPR */ + + LDR R4, =0x40200008 /* setup the SYSTEM_CTRL->CTRL_b.MHZ32_SEL = 0 */ + LDR R7, [R4] + MOVS R0, #0 + STR R0, [R4] + + DSB + WFI /* all saved, trigger deep sleep */ + + STR R7, [R4] /* if WFI will be skipped restore the content of the + SYSTEM_CTRL->CTRL_b.MHZ32_SEL with the original value */ + ENDFUNC +EXPORT_FUNC(CS_contextRestore) + /* Even if we fall through the WFI instruction, we will immediately + * execute a context restore and end up where we left off with no + * ill effects. Normally at this point the core will either be + * powered off or reset (depending on the deep sleep level). */ + LDR R4, =savedMSP /* load address of savedMSP into R4 */ + LDR R4, [R4] /* load the MSP from savedMSP */ + MSR MSP, R4 /* restore the MSP from R4 */ + + SUB SP, #0x8 + POP { R0, R1 } /* load PSP from the stack in R0, and load CONTROL register from the stack in R1 */ + + POP { R3-R7 } /* load R8-R12 (5 words) from the stack */ + MOV R8, R3 /* mov {r3 - r7} to {r8 - r12} */ + MOV R9, R4 + MOV R10, R5 + MOV R11, R6 + MOV R12, R7 + POP { R4 - R7 } /* load R4-R7 (4 words) from the stack */ + POP { R2 } /* load LR from the stack */ +#ifdef CONTEXT_SAVE_V2 + ADD SP, #0x44 /* Restore MSP to the point where it was before pushing data to the stack in CS_contextSave */ +#endif + + MSR PSP, R0 /* restore PSP from R0 */ + MSR CONTROL , R1 /* restore CONTROL register from R1 */ + ISB + + BX R2 /*load PC (1 words) from the stack */ + + ENDFUNC + + ALIGN_MEM(4) + __END__ diff --git a/hal/src/fifo.c b/hal/src/fifo.c new file mode 100644 index 0000000..7fcb609 --- /dev/null +++ b/hal/src/fifo.c @@ -0,0 +1,175 @@ +/** + ****************************************************************************** + * @file fifo.c + * @author VMA RF Application Team + * @version V1.0.0 + * @date July-2015 + * @brief FIFO management sources + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2015 STMicroelectronics

+ ****************************************************************************** + */ +#include "fifo.h" +#include "osal.h" + +#define MIN(a, b) ((a <= b) ? (a) : (b)) +#define MAX(a, b) ((a < b) ? (b) : (a)) +#define FIFO_ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1)) +#define ADVANCE_QUEUE(index, size, max_size) ((index + size) % max_size) /* (((index + size) >= max_size) ? 0 : (index + size))*/ +#define FIFO_ALIGNMENT fifo->alignment +#define FIFO_GET_SIZE(fifo) ((fifo->tail>=fifo->head) ? (fifo->tail - fifo->head) : (fifo->max_size - (fifo->head - fifo->tail))) +#define VAR_LEN_ITEM_SIZE_LENGTH 2 + +/** +* @brief Initiliaze a circular fifo specfiyng also elements alignment +* The buffer allocated memory should max_size+maximum length of element, +* so that no wrapping occurs and each element is made of only linear buffer segments. +* @retval None +*/ + +void fifo_init(circular_fifo_t *fifo, uint16_t max_size, uint8_t *buffer, uint8_t alignment) +{ + fifo->tail = fifo->head = 0; + fifo->max_size = max_size; + fifo->buffer = buffer; + fifo->alignment = alignment; +} +/** +* @brief Return number of bytes held in the FIFO +* @retval None +*/ + +uint16_t fifo_size(circular_fifo_t *fifo) +{ + return FIFO_GET_SIZE(fifo); +} +void fifo_flush(circular_fifo_t *fifo) +{ + fifo->tail = fifo->head = 0; +} + + + +static uint8_t _fifo_put(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer, uint16_t index) +{ + uint16_t size_aligned = FIFO_ALIGN(size, FIFO_ALIGNMENT); + if ((FIFO_GET_SIZE(fifo) + size_aligned) < fifo->max_size) { /* <= */ + Osal_MemCpy(&fifo->buffer[index], buffer, size); + fifo->tail = ADVANCE_QUEUE(fifo->tail, size_aligned, fifo->max_size); + return 0; + } + return 1; +} + +//static uint8_t fifo_put_no_wrap(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer) +//{ +// uint16_t index = (fifo->tail == 0) ? fifo->max_size : fifo->tail; +// return (_fifo_put(fifo, size, buffer, index)); +//} + +/** +* @brief Put the buffer in the fifo (no wrapping) +* @retval None +*/ +uint8_t fifo_put(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer) +{ + return (_fifo_put(fifo, size, buffer, fifo->tail)); +} + +static uint8_t _fifo_get(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer, uint16_t index) +{ + uint16_t size_aligned = FIFO_ALIGN(size, FIFO_ALIGNMENT); + if (FIFO_GET_SIZE(fifo) >= size_aligned) { + Osal_MemCpy(buffer, &fifo->buffer[index], size); + fifo->head = ADVANCE_QUEUE(fifo->head, size_aligned, fifo->max_size); + + return 0; + } + return 1; +} + +static uint8_t fifo_get_no_wrap(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer) +{ + uint16_t index = (fifo->head == 0) ? fifo->max_size : fifo->head; + return (_fifo_get(fifo, size, buffer, index)); +} + +uint8_t fifo_get(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer) +{ + return (_fifo_get(fifo, size, buffer, fifo->head)); +} + +uint8_t fifo_put_var_len_item(circular_fifo_t *fifo, uint16_t size, uint8_t *buffer) +{ + uint8_t ret_val = 0; + uint16_t size_aligned = FIFO_ALIGN(size, FIFO_ALIGNMENT); + uint8_t length_size_aligned = FIFO_ALIGN(VAR_LEN_ITEM_SIZE_LENGTH, FIFO_ALIGNMENT); + + if ((FIFO_GET_SIZE(fifo) + size_aligned + length_size_aligned) < fifo->max_size) { + Osal_MemCpy(&fifo->buffer[fifo->tail], &size, VAR_LEN_ITEM_SIZE_LENGTH); + Osal_MemCpy(&fifo->buffer[fifo->tail + length_size_aligned], buffer, size); + + fifo->tail = ADVANCE_QUEUE(fifo->tail, size_aligned + length_size_aligned, fifo->max_size); + + } else { + ret_val = 1; + } + return ret_val; +} + + +uint8_t fifo_discard(circular_fifo_t *fifo, uint16_t size) +{ + uint16_t size_aligned = FIFO_ALIGN(size, FIFO_ALIGNMENT); + if (FIFO_GET_SIZE(fifo) >= size_aligned) { + fifo->head = ADVANCE_QUEUE(fifo->head, size_aligned, fifo->max_size); + return 0; + } + return 1; +} + +uint8_t fifo_get_ptr(circular_fifo_t *fifo, uint16_t size, uint8_t **ptr) +{ + uint16_t size_aligned = FIFO_ALIGN(size, FIFO_ALIGNMENT); + if (FIFO_GET_SIZE(fifo) >= size_aligned) { + *ptr = &fifo->buffer[fifo->head]; + return 0; + } + return 1; +} + +uint8_t fifo_get_var_len_item(circular_fifo_t *fifo, uint16_t *size, uint8_t *buffer) +{ + uint8_t ret_val = fifo_get(fifo, VAR_LEN_ITEM_SIZE_LENGTH, (uint8_t *) size); + if (ret_val == 0) { + ret_val = fifo_get_no_wrap(fifo, *size, buffer); + } + return ret_val; +} + +uint8_t fifo_get_ptr_var_len_item(circular_fifo_t *fifo, uint16_t *size, uint8_t **ptr) +{ + uint8_t ret_val = fifo_get_ptr(fifo, VAR_LEN_ITEM_SIZE_LENGTH, ptr); + if (ret_val == 0) { + *size = *((uint16_t *) *ptr); + } + return ret_val; +} +uint8_t fifo_discard_var_len_item(circular_fifo_t *fifo) +{ + uint16_t size; + uint8_t ret_val = fifo_get(fifo, VAR_LEN_ITEM_SIZE_LENGTH, (uint8_t *) &size); + if (ret_val == 0) { + ret_val = fifo_discard(fifo, size); + } + return ret_val; +} diff --git a/hal/src/gp_timer.c b/hal/src/gp_timer.c new file mode 100644 index 0000000..a27f0db --- /dev/null +++ b/hal/src/gp_timer.c @@ -0,0 +1,57 @@ +/** +****************************************************************************** +* @file gp_timer.c +* @author AMS - RF Application Team +* @version V1.1.0 +* @date 26-March-2018 +* @brief General purpose timer library. +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2018 STMicroelectronics

+****************************************************************************** +*/ +/* Includes ------------------------------------------------------------------*/ + +#include "clock.h" +#include "gp_timer.h" + +/*---------------------------------------------------------------------------*/ + +void Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} + +void Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} + +void Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} + +uint8_t Timer_Expired(struct timer *t) +{ + tClockTime diff = (Clock_Time() - t->start) + 1; + return (t->interval < diff); + +} + +tClockTime Timer_Remaining(struct timer *t) +{ + return (t->start + t->interval - Clock_Time()); +} + + + diff --git a/hal/src/hal_radio.c b/hal/src/hal_radio.c new file mode 100644 index 0000000..33abd3c --- /dev/null +++ b/hal/src/hal_radio.c @@ -0,0 +1,323 @@ +/** +****************************************************************************** +* @file hal_radio.c +* @author RF Application team +* @date Jan-2020 +* @brief BlueNRG-1,2 HAL radio APIs +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2020 STMicroelectronics

+****************************************************************************** +*/ +#include "hal_radio.h" +#include "BlueNRG1_timer.h" + +static ActionPacket aPacket[2]; +static uint32_t networkID = 0x88DF88DF; + +static uint8_t CondRoutineTrue(ActionPacket* p) +{ + return TRUE; +} + +static uint8_t dataRoutineNull(ActionPacket* current_action_packet, ActionPacket* next) +{ + return TRUE; +} + +static uint8_t CondRoutineRxTrue(ActionPacket* p) +{ + /* received a packet */ + if( ((p->status & BIT_TX_MODE) == 0) && ((p->status & IRQ_RCV_OK) != 0) ) { + /* packet received without CRC error */ + return TRUE; + } + return FALSE; +} + + +/** +* @brief This routine sets the network ID field for packet transmission and filtering for the receiving. +* Only two devices with same networkID can communicate with each other. +* @param ID: network ID based on bluetooth specification: +* 1. It shall have no more than six consecutive zeros or ones. +* 2. It shall not have all four octets equal. +* 3. It shall have no more than 24 transitions. +* 4. It shall have a minimum of two transitions in the most significant six bits. +* +* @retval uint8_t: return value +* - 0x00 : Success. +* - 0xC0 : Invalid parameter. +*/ +uint8_t HAL_RADIO_SetNetworkID(uint32_t ID) +{ + networkID = ID; + return 0; +} + + +/** +* @brief This routine sends a packet on a specific channel and at a specific time. +* @param channel: Frequency channel between 0 to 39. +* @param wakeup_time: Time of transmission in us. This is relative time regarding now. +* The relative time cannot be less than 100 us otherwise it might wrap around after 32.7 second. +* @param txBuffer: Pointer to TX data buffer. Second byte of this buffer must be the length of the data. +* @param Callback: This function is being called as data routine. +* First ActionPacket is current action packet and the second one is next action packet. +* @retval uint8_t return value +* - 0x00 : Success. +* - 0xC0 : Invalid parameter. +* - 0xC4 : Radio is busy, receiving has not been triggered. +*/ +uint8_t HAL_RADIO_SendPacket(uint8_t channel, + uint32_t wakeup_time, + uint8_t* txBuffer, + uint8_t (*Callback)(ActionPacket*, ActionPacket*) ) +{ + uint8_t returnValue = SUCCESS_0; + uint32_t dummy,time; + + time = (uint32_t)TIMER_GetCurrentSysTime() + TIMER_UsToSystime(wakeup_time); + + if(channel > 39) { + returnValue = INVALID_PARAMETER_C0; + } + + if(RADIO_GetStatus(&dummy) != BLUE_IDLE_0) { + returnValue = RADIO_BUSY_C4; + } + + if(returnValue == SUCCESS_0) { + uint8_t map[5]= {0xFF,0xFF,0xFF,0xFF,0xFF}; + RADIO_SetChannelMap(0, &map[0]); + RADIO_SetChannel(0, channel, 0); + RADIO_SetTxAttributes(0, networkID, 0x555555); + + aPacket[0].StateMachineNo = STATE_MACHINE_0; + aPacket[0].ActionTag = TXRX | PLL_TRIG; + aPacket[0].WakeupTime = time; + aPacket[0].ReceiveWindowLength = 0; /* does not affect for Tx */ + aPacket[0].data = txBuffer; + aPacket[0].next_true = NULL_0; + aPacket[0].next_false = NULL_0; + aPacket[0].condRoutine = CondRoutineTrue; + aPacket[0].dataRoutine = Callback; + + RADIO_SetReservedArea(&aPacket[0]); + returnValue = RADIO_MakeActionPacketPending(&aPacket[0]); + } + + return returnValue; +} + + +/** +* @brief This routine sends a packet on a specific channel and at a certain time then wait for receiving acknowledge. +* @param channel: Frequency channel between 0 to 39. +* @param wakeup_time: Time of transmission based on us. This is relative time regarding now. +* The relative time cannot be less than 100 us otherwise it might wrap around after 32.7 second. +* @param txBuffer: Pointer to TX data buffer. Secound byte of this buffer must be the length of the data. +* @param rxBuffer: Pointer to RX data buffer. Secound byte of this buffer must be the length of the data. +* @param receive_timeout: Time of RX window used to wait for the packet on us. +* @param callback: This function is being called as data routine. +* First ActionPacket is current action packet and the second one is next action packet. +* @retval uint8_t return value +* - 0x00 : Success. +* - 0xC0 : Invalid parameter. +* - 0xC4 : Radio is busy, receiving has not been triggered. +*/ +uint8_t HAL_RADIO_SendPacketWithAck(uint8_t channel, + uint32_t wakeup_time, + uint8_t* txBuffer, + uint8_t* rxBuffer, + uint32_t receive_timeout, + uint8_t (*Callback)(ActionPacket*, ActionPacket*) ) +{ + uint8_t returnValue = SUCCESS_0; + uint32_t dummy,time; + + time = (uint32_t)TIMER_GetCurrentSysTime() + TIMER_UsToSystime(wakeup_time); + + if(channel > 39) { + returnValue = INVALID_PARAMETER_C0; + } + + if(RADIO_GetStatus(&dummy) != BLUE_IDLE_0) { + returnValue = RADIO_BUSY_C4; + } + + if(returnValue == SUCCESS_0) { + uint8_t map[5]= {0xFF,0xFF,0xFF,0xFF,0xFF}; + RADIO_SetChannelMap(0, &map[0]); + RADIO_SetChannel(0, channel, 0); + + RADIO_SetTxAttributes(0, networkID, 0x555555); + + aPacket[0].StateMachineNo = STATE_MACHINE_0; + aPacket[0].ActionTag = TXRX | PLL_TRIG; + aPacket[0].WakeupTime = time; + aPacket[0].ReceiveWindowLength = 0; /* does not affect for Tx */ + aPacket[0].data = txBuffer; + aPacket[0].next_true = &aPacket[1]; + aPacket[0].next_false = &aPacket[1]; + aPacket[0].condRoutine = CondRoutineTrue; + aPacket[0].dataRoutine = dataRoutineNull; + + aPacket[1].StateMachineNo = STATE_MACHINE_0; + aPacket[1].ActionTag = 0; + aPacket[1].WakeupTime = wakeup_time; + aPacket[1].ReceiveWindowLength = receive_timeout; + aPacket[1].data = rxBuffer; + aPacket[1].next_true = NULL_0; + aPacket[1].next_false = NULL_0; + aPacket[1].condRoutine = CondRoutineTrue; + aPacket[1].dataRoutine = Callback; + + + RADIO_SetReservedArea(&aPacket[0]); + RADIO_SetReservedArea(&aPacket[1]); + returnValue = RADIO_MakeActionPacketPending(&aPacket[0]); + } + + return returnValue; +} + + +/** +* @brief This routine receives a packet on a specific channel and at a certain time. +* @param channel: Frequency channel between 0 to 39. +* @param wakeup_time: Time of transmission based on us. This is relative time regarding now. +* The relative time cannot be less than 100 us otherwise it might wrap around after 32.7 second. +* @param rxBuffer: Pointer to RX data buffer. Secound byte of this buffer must be the length of the data. +* @param receive_timeout: Time of RX window used to wait for the packet on us. +* @param callback: This function is being called as data routine. +* First ActionPacket is current action packet and the second one is next action packet. +* @retval uint8_t return value +* - 0x00 : Success. +* - 0xC0 : Invalid parameter. +* - 0xC4 : Radio is busy, receiving has not been triggered. +*/ +uint8_t HAL_RADIO_ReceivePacket(uint8_t channel, + uint32_t wakeup_time, + uint8_t* rxBuffer, + uint32_t receive_timeout, + uint8_t (*Callback)(ActionPacket*, ActionPacket*) ) +{ + uint8_t returnValue = SUCCESS_0; + uint32_t dummy,time; + + time = (uint32_t)TIMER_GetCurrentSysTime() + TIMER_UsToSystime(wakeup_time); + + if(channel > 39) { + returnValue = INVALID_PARAMETER_C0; + } + + if(RADIO_GetStatus(&dummy) != BLUE_IDLE_0) { + returnValue = RADIO_BUSY_C4; + } + + if(returnValue == SUCCESS_0) { + uint8_t map[5]= {0xFF,0xFF,0xFF,0xFF,0xFF}; + RADIO_SetChannelMap(0, &map[0]); + RADIO_SetChannel(0, channel, 0); + + RADIO_SetTxAttributes(0, networkID, 0x555555); + + aPacket[0].StateMachineNo = STATE_MACHINE_0; + aPacket[0].ActionTag = PLL_TRIG; + aPacket[0].WakeupTime = time;//wakeup_time; + aPacket[0].ReceiveWindowLength = receive_timeout; + aPacket[0].data = rxBuffer; + aPacket[0].next_true = NULL_0; + aPacket[0].next_false = NULL_0; + aPacket[0].condRoutine = CondRoutineTrue; + aPacket[0].dataRoutine = Callback; + + RADIO_SetReservedArea(&aPacket[0]); + returnValue = RADIO_MakeActionPacketPending(&aPacket[0]); + } + + return returnValue; +} + + +/** +* @brief This routine receives a packet on a specific channel and at a certain time. +* Then sends a packet as an acknowledgment. +* @param channel: frequency channel between 0 to 39. +* @param wakeup_time: time of transmission based on us. This is relative time regarding now. +* The relative time cannot be less than 100 us otherwise it might wrap around after 32.7 second. +* @param rxBuffer: points to received data buffer. second byte of this buffer determines the length of the data. +* @param txBuffer: points to data buffer to send. secound byte of this buffer must be the length of the buffer. +* @param receive_timeout: Time of RX window used to wait for the packet on us. +* @param callback: This function is being called as data routine. +* First ActionPacket is current action packet and the second one is next action packet. +* @retval uint8_t return value +* - 0x00 : Success. +* - 0xC0 : Invalid parameter. +* - 0xC4 : Radio is busy, receiving has not been triggered. +*/ +uint8_t HAL_RADIO_ReceivePacketWithAck(uint8_t channel, + uint32_t wakeup_time, + uint8_t* rxBuffer, + uint8_t* txBuffer, + uint32_t receive_timeout, + uint8_t (*Callback)(ActionPacket*, ActionPacket*) ) +{ + uint8_t returnValue = SUCCESS_0; + uint32_t dummy,time; + + time = (uint32_t)TIMER_GetCurrentSysTime() + TIMER_UsToSystime(wakeup_time); + + if(channel > 39) { + returnValue = INVALID_PARAMETER_C0; + } + + if(RADIO_GetStatus(&dummy) != BLUE_IDLE_0) { + returnValue = RADIO_BUSY_C4; + } + + if(returnValue == SUCCESS_0) { + uint8_t map[5]= {0xFF,0xFF,0xFF,0xFF,0xFF}; + RADIO_SetChannelMap(0, &map[0]); + RADIO_SetChannel(0,channel,0); + RADIO_SetTxAttributes(0, networkID,0x555555); + + aPacket[0].StateMachineNo = STATE_MACHINE_0; + aPacket[0].ActionTag = PLL_TRIG; + aPacket[0].WakeupTime = time;//wakeup_time; + aPacket[0].ReceiveWindowLength = receive_timeout; + aPacket[0].data = rxBuffer; + aPacket[0].next_true = &aPacket[1]; + aPacket[0].next_false = NULL_0; + aPacket[0].condRoutine = CondRoutineRxTrue; + aPacket[0].dataRoutine = Callback; + + aPacket[1].StateMachineNo = STATE_MACHINE_0; + aPacket[1].ActionTag = TXRX; + aPacket[1].WakeupTime = wakeup_time; + aPacket[1].ReceiveWindowLength = 0; /* does not affect for Tx */ + aPacket[1].data = txBuffer; + aPacket[1].next_true = NULL_0; + aPacket[1].next_false = NULL_0; + aPacket[1].condRoutine = CondRoutineTrue; + aPacket[1].dataRoutine = Callback; + + RADIO_SetReservedArea(&aPacket[0]); + RADIO_SetReservedArea(&aPacket[1]); + returnValue = RADIO_MakeActionPacketPending(&aPacket[0]); + } + + return returnValue; +} + + +/******************* (C) COPYRIGHT 2020 STMicroelectronics *****END OF FILE****/ diff --git a/hal/src/miscutil.c b/hal/src/miscutil.c new file mode 100644 index 0000000..06f95e8 --- /dev/null +++ b/hal/src/miscutil.c @@ -0,0 +1,130 @@ +/** +****************************************************************************** +* @file miscutil.c +* @author AMS - RF Application Team +* @version V1.2.0 +* @date 14-February-2020 +* @brief Miscellaneous utilities +****************************************************************************** +* @attention +* +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE +* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY +* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING +* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE +* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +* +*

© COPYRIGHT 2020 STMicroelectronics

+****************************************************************************** +*/ +/* Includes ------------------------------------------------------------------*/ +#include "bluenrg_x_device.h" +#include "miscutil.h" + +NO_INIT_SECTION(crash_info_t crash_info_ram, ".__crash_RAM"); + +/** @addtogroup BlueNRG1_Miscellaneous_Utilities +* @{ +*/ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define BLUENRG2_IDCODE (0x0200A041) + +#define BLUENRG2N_ID_BASE (0x1000001C) +#define BLUENRG2N_IDCODE (0xF200A044) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +void HAL_GetPartInfo(PartInfoType *partInfo) +{ + volatile uint32_t *ptr = (volatile uint32_t *)(CKGEN_SOC_BASE + 0x28); + volatile uint32_t *ptr_2n = (volatile uint32_t *)(BLUENRG2N_ID_BASE); + + partInfo->die_major = CKGEN_SOC->DIE_ID_b.VERSION; + partInfo->die_cut = CKGEN_SOC->DIE_ID_b.REV; + + partInfo->jtag_id_code = *ptr; + if (partInfo->jtag_id_code == BLUENRG2_IDCODE) { + + if (*ptr_2n == BLUENRG2N_IDCODE) + { + /* BlueNRG-2N id */ + partInfo->die_id = DIE_SW_ID_BLUENRG2N; + } + else + { + /* BlueNRG-2 id is conventionally 2 */ + partInfo->die_id = DIE_ID_BLUENRG2; + } + } else { + /* BlueNRG-1 id is conventionally 1 */ + partInfo->die_id = DIE_ID_BLUENRG1; + } + + /* Patch for early samples */ + if (partInfo->die_major == 0) + partInfo->die_major = 1; + + partInfo->flash_size = (FLASH->SIZE + 1) * 4; +} + +/** + * @brief Get Crash Information utility + */ +void HAL_GetCrashInfo(crash_info_t *crashInfo) +{ + *crashInfo = crash_info_ram; + /* Reset crash info value */ + crash_info_ram.signature = 0; +} +void HAL_CrashHandler(uint32_t msp, uint32_t signature) +{ + volatile uint32_t * crash_info = (volatile uint32_t *)&crash_info_ram; + register uint32_t reg_content; + /* Init to zero the crash_info RAM locations */ + for (reg_content=0; reg_content= ((uint32_t *) _MEMORY_RAM_BEGIN_)) && + (ptr <= ((uint32_t *) _MEMORY_RAM_END_))) + crash_info[reg_content] = *ptr; + } + NVIC_SystemReset(); + /* Go to infinite loop when Hard Fault exception occurs */ + while (1) + {} +} + +/** + * @brief Get Device ID, Version and Revision numbers + */ +void BLEPLAT_get_part_info(uint8_t *device_id, uint8_t *major_cut, uint8_t *minor_cut) +{ + PartInfoType partInfo; + + /* get partInfo */ + HAL_GetPartInfo(&partInfo); + + /* Set device ID */ + *device_id = partInfo.die_id; + + /* Set major cut */ + *major_cut = partInfo.die_major; + + /* Set minor cut */ + *minor_cut = partInfo.die_cut; +} + +/** + *@ +} */ /* End of group BlueNRG1_Miscellaneous_Utilities */ diff --git a/hal/src/radio_ota.c b/hal/src/radio_ota.c new file mode 100644 index 0000000..43cd0c9 --- /dev/null +++ b/hal/src/radio_ota.c @@ -0,0 +1,64 @@ +/******************** (C) COPYRIGHT 2017 STMicroelectronics ******************** +* File Name : radio_ota.c +* Author : RF Application Team +* Version : V1.0.0 +* Date : May-2018 +* Description : OTA library for user application +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + + +/* Includes ------------------------------------------------------------------*/ +#include +#include "radio_ota.h" +#include "BlueNRG1_conf.h" + +/** @addtogroup BlueNRG1_StdPeriph_Examples +* @{ +*/ + +/** @addtogroup RADIO_Examples RADIO Examples +* @{ +*/ + +/** @addtogroup RADIO_TxRx RADIO TxRx Example +* @{ +*/ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +#define OTA_NO_OPERATION (0x11) +#define OTA_APP_SWITCH_OP_CODE_NO_OPERATION (0xB0014211) +#define OTA_SWITCH_TO_OTA_RESET_MANAGER (OTA_APP_SWITCH_OP_CODE_NO_OPERATION + (OTA_NO_OPERATION*4)) + +void OTA_Jump_To_Reset_Manager(void) +{ + extern volatile uint32_t ota_sw_activation; + ota_sw_activation = OTA_SWITCH_TO_OTA_RESET_MANAGER; + + NVIC_SystemReset(); +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2017 STMicroelectronics *****END OF FILE****/ diff --git a/hal/src/sleep.c b/hal/src/sleep.c new file mode 100644 index 0000000..406a32d --- /dev/null +++ b/hal/src/sleep.c @@ -0,0 +1,752 @@ +/******************** (C) COPYRIGHT 2018 STMicroelectronics ******************** +* File Name : sleep.c +* Author : AMS - RF-Application Team +* Version : V1.2.1 +* Date : 24-October-2018 +* Description : BlueNRG Sleep management +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#include +#include +#include +#include "bluenrg_x_device.h" +#include "BlueNRG1_conf.h" +#include "sleep.h" +#include "misc.h" +#include "miscutil.h" + +#undef DEBUG_SLEEP_MODE +#define DEBUG_SLEEP_MODE 0 + +#define MIN(a,b) ((a) < (b) )? (a) : (b) + +#ifndef SAVE_CONTEXT_ON_CSTACK +#define SAVE_CONTEXT_ON_CSTACK 1 +#endif + +#if SAVE_CONTEXT_ON_CSTACK +#define CTXT +#else +#define CTXT static +#endif + +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_irq(); \ +/* Must be called in the same or in a lower scope of ATOMIC_SECTION_BEGIN */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +#define SHPR3_REG 0xE000ED20 + +#define WAKENED_FROM_BOR 0x03 +#define WAKENED_FROM_POR 0x05 +#define WAKENED_FROM_IO9 0x09 +#define WAKENED_FROM_IO10 0x11 +#define WAKENED_FROM_IO11 0x21 +#define WAKENED_FROM_IO12 0x41 +#define WAKENED_FROM_IO13 0x81 +#define WAKENED_FROM_BLUE_TIMER1 0x101 +#define WAKENED_FROM_BLUE_TIMER2 0x401 + +#define LOW_POWER_STANDBY 0x03 + +#define BLUE_CURRENT_TIME_REG 0x48000010 + +uint32_t cStackPreamble[CSTACK_PREAMBLE_NUMBER]; +volatile uint32_t* ptr ; + +#ifdef DEBUG_SLEEP_MODE +uint32_t sleepMode_selected[4]={0,}; +#endif + +#ifndef SLEEP_SAVE_N_RESTORE_UART +#define SLEEP_SAVE_N_RESTORE_UART 1 +#endif +#ifndef SLEEP_SAVE_N_RESTORE_SPI +#define SLEEP_SAVE_N_RESTORE_SPI 1 +#endif +#ifndef SLEEP_SAVE_N_RESTORE_I2C +#define SLEEP_SAVE_N_RESTORE_I2C 1 +#endif +#ifndef SLEEP_SAVE_N_RESTORE_RTC +#define SLEEP_SAVE_N_RESTORE_RTC 1 +#endif +#ifndef SLEEP_SAVE_N_RESTORE_MFTX1 +#define SLEEP_SAVE_N_RESTORE_MFTX1 1 +#endif +#ifndef SLEEP_SAVE_N_RESTORE_MFTX2 +#define SLEEP_SAVE_N_RESTORE_MFTX2 1 +#endif +#ifndef SLEEP_SAVE_N_RESTORE_WDG +#define SLEEP_SAVE_N_RESTORE_WDG 1 +#endif +#ifndef SLEEP_SAVE_N_RESTORE_DMA +#define SLEEP_SAVE_N_RESTORE_DMA 1 +#endif +#ifndef SLEEP_SAVE_N_RESTORE_ADC +#define SLEEP_SAVE_N_RESTORE_ADC 1 +#endif + +WEAK_FUNCTION(SleepModes App_SleepMode_Check(SleepModes sleepMode)) +{ + return SLEEPMODE_NOTIMER; +} +WEAK_FUNCTION(SleepModes BlueNRG_Stack_Perform_Deep_Sleep_Check(void)) +{ + return SLEEPMODE_NOTIMER; +} +WEAK_FUNCTION(SleepModes HAL_VTIMER_TimerSleepCheck(SleepModes sleepMode)) +{ + return SLEEPMODE_NOTIMER; +} + +#ifndef FORCE_CORE_TO_16MHZ +/* Macros to calculate the time diff between two machine times */ +#define INT_ASR(X,Y) ((X) >> (Y)) +#define INT_SHIFT_R(X, Y) ((int32_t)INT_ASR((int32_t)(X),(Y))) +#define TIME24_DIFF(TA, TB) (INT_SHIFT_R((uint32_t)((uint32_t)((TA) - (TB)) << 8), 8)) + + +/* Function to evaluate if the application has enough time to switch the frequency */ +static void frequency_switch(void) +{ + uint32_t currTimeTHR; + int32_t time_diff = -1; + volatile uint16_t reset_reason; + + /* Get the reset reason */ + reset_reason = SysCtrl_GetWakeupResetReason(); + + /* If the BLE radio is NOT active or the Wakeup comes from radio transaction, the frequency switch is safe */ + if (!((reset_reason & RESET_BLE_WAKEUP_FROM_TIMER1) || ((__blue_RAM.BlueGlobVar.Config & 8U) == 0))) { // ((*(volatile uint32_t*)0x200000C0 & 8U) == 0U))) { + /* Check if the next transaction is enough in the future */ + currTimeTHR = BLUE_CTRL->CURRENT_TIME; + time_diff = abs(TIME24_DIFF(rfTimeout, currTimeTHR)); + if (time_diff <= 32) { + currTimeTHR = BLUE_CTRL->CURRENT_TIME + 45; + /* Wait 45 clock tick until the first SPI transaction is executed */ + while (BLUE_CTRL->CURRENT_TIME <= currTimeTHR); + } + } + + AHBUPCONV->COMMAND = 0x15; +} +#endif + + +static void BlueNRG_InternalSleep(SleepModes sleepMode, uint8_t gpioWakeBitMask) +{ + uint32_t savedCurrentTime, nvicPendingMask, ioValue, ioLevel, ioEnabled; + PartInfoType partInfo; + uint8_t i; + + /* Variables used to store system peripheral registers in order to restore the state after + exit from sleep mode */ + +/* System Control saved */ + CTXT uint32_t SYS_Ctrl_saved; + /* NVIC Information Saved */ + CTXT uint32_t NVIC_ISER_saved, NVIC_IPR_saved[8], PENDSV_SYSTICK_IPR_saved; + /* CKGEN SOC Enabled */ + CTXT uint32_t CLOCK_EN_saved; + /* GPIO Information saved */ + CTXT uint32_t GPIO_DATA_saved, GPIO_OEN_saved, GPIO_PE_saved, GPIO_DS_saved, GPIO_IS_saved, GPIO_IBE_saved; + CTXT uint32_t GPIO_IEV_saved, GPIO_IE_saved, GPIO_MODE0_saved, GPIO_MODE1_saved, GPIO_IOSEL_MFTX_saved; +#ifdef BLUENRG2_DEVICE + CTXT uint32_t GPIO_MODE2_saved, GPIO_MODE3_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_UART + /* UART Information saved */ + CTXT uint32_t UART_TIMEOUT_saved, UART_LCRH_RX_saved, UART_IBRD_saved, UART_FBRD_saved; + CTXT uint32_t UART_LCRH_TX_saved, UART_CR_saved, UART_IFLS_saved, UART_IMSC_saved; + CTXT uint32_t UART_DMACR_saved, UART_XFCR_saved, UART_XON1_saved, UART_XON2_saved; + CTXT uint32_t UART_XOFF1_saved, UART_XOFF2_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_SPI + /* SPI Information saved */ + CTXT uint32_t SPI_CR0_saved, SPI_CR1_saved, SPI_CPSR_saved, SPI_IMSC_saved, SPI_DMACR_saved; + CTXT uint32_t SPI_RXFRM_saved, SPI_CHN_saved, SPI_WDTXF_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_I2C + /* I2C Information saved */ + CTXT uint32_t I2C_CR_saved[2], I2C_SCR_saved[2], I2C_TFTR_saved[2], I2C_RFTR_saved[2]; + CTXT uint32_t I2C_DMAR_saved[2], I2C_BRCR_saved[2], I2C_IMSCR_saved[2], I2C_THDDAT_saved[2]; + CTXT uint32_t I2C_THDSTA_FST_STD_saved[2], I2C_TSUSTA_FST_STD_saved[2]; +#endif + /* RNG Information saved */ + CTXT uint32_t RNG_CR_saved; + /* SysTick Information saved */ + CTXT uint32_t SYST_CSR_saved, SYST_RVR_saved; +#if SLEEP_SAVE_N_RESTORE_RTC + /* RTC Information saved */ + CTXT uint32_t RTC_CWDMR_saved, RTC_CWDLR_saved, RTC_CWYMR_saved, RTC_CWYLR_saved, RTC_CTCR_saved; + CTXT uint32_t RTC_IMSC_saved, RTC_TCR_saved, RTC_TLR1_saved, RTC_TLR2_saved, RTC_TPR1_saved; + CTXT uint32_t RTC_TPR2_saved, RTC_TPR3_saved, RTC_TPR4_saved; +#endif + /* MFTX Information saved */ +#if SLEEP_SAVE_N_RESTORE_MFTX1 + CTXT uint32_t T1CRA_saved, T1CRB_saved, T1PRSC_saved, T1CKC_saved, T1MCTRL_saved, T1ICTRL_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_MFTX2 + CTXT uint32_t T2CRA_saved, T2CRB_saved, T2PRSC_saved, T2CKC_saved, T2MCTRL_saved, T2ICTRL_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_WDG + /* WDT Information saved */ + CTXT uint32_t WDG_LR_saved, WDG_CR_saved, WDG_LOCK_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_DMA + /* DMA channel [0..7] Information saved */ + CTXT uint32_t DMA_CCR_saved[8], DMA_CNDTR_saved[8], DMA_CPAR_saved[8], DMA_CMAR[8]; +#endif +#if SLEEP_SAVE_N_RESTORE_ADC + /* ADC Information saved */ + CTXT uint32_t ADC_CTRL_saved, ADC_CONF_saved, ADC_IRQMASK_saved, ADC_OFFSET_LSB_saved, ADC_OFFSET_MSB_saved; + CTXT uint32_t ADC_THRESHOLD_HI_saved, ADC_THRESHOLD_LO_saved; +#endif + /* FlASH Config saved */ + CTXT uint32_t FLASH_CONFIG_saved; + /* PKA Information saved */ + CTXT uint32_t PKA_IEN_saved; + + /* Get partInfo */ + HAL_GetPartInfo(&partInfo); + + /* Save the peripherals configuration */ + /* System Control */ + SYS_Ctrl_saved = SYSTEM_CTRL->CTRL; + /* FLASH CONFIG */ + FLASH_CONFIG_saved = FLASH->CONFIG; + /* NVIC */ + NVIC_ISER_saved = NVIC->ISER[0]; + + // Issue with Atollic compiler +// memcpy(NVIC_IPR_saved, (void const *)NVIC->IP, sizeof(NVIC_IPR_saved)); + for (i=0; i<8; i++) { + NVIC_IPR_saved[i] = NVIC->IP[i]; + } + + + PENDSV_SYSTICK_IPR_saved = *(volatile uint32_t *)SHPR3_REG; + /* CKGEN SOC Enabled */ + CLOCK_EN_saved = CKGEN_SOC->CLOCK_EN; + /* GPIO */ + GPIO_DATA_saved = GPIO->DATA; + GPIO_OEN_saved = GPIO->OEN; + GPIO_PE_saved = GPIO->PE; + GPIO_DS_saved = GPIO->DS; + GPIO_IS_saved = GPIO->IS; + GPIO_IBE_saved = GPIO->IBE; + GPIO_IEV_saved = GPIO->IEV; + GPIO_IE_saved = GPIO->IE; + GPIO_MODE0_saved = GPIO->MODE0; + GPIO_MODE1_saved = GPIO->MODE1; +#ifdef BLUENRG2_DEVICE + GPIO_MODE2_saved = GPIO->MODE2; + GPIO_MODE3_saved = GPIO->MODE3; +#endif + GPIO_IOSEL_MFTX_saved = GPIO->MFTX; +#if SLEEP_SAVE_N_RESTORE_UART + /* UART */ + UART_TIMEOUT_saved = UART->TIMEOUT; + UART_LCRH_RX_saved = UART->LCRH_RX; + UART_IBRD_saved = UART->IBRD; + UART_FBRD_saved = UART->FBRD; + UART_LCRH_TX_saved = UART->LCRH_TX; + UART_CR_saved = UART->CR; + UART_IFLS_saved = UART->IFLS; + UART_IMSC_saved = UART->IMSC; + UART_DMACR_saved = UART->DMACR; + UART_XFCR_saved = UART->XFCR; + UART_XON1_saved = UART->XON1; + UART_XON2_saved = UART->XON2; + UART_XOFF1_saved = UART->XOFF1; + UART_XOFF2_saved = UART->XOFF2; +#endif +#if SLEEP_SAVE_N_RESTORE_SPI + /* SPI */ + SPI_CR0_saved = SPI->CR0; + SPI_CR1_saved = SPI->CR1; + SPI_CPSR_saved = SPI->CPSR; + SPI_IMSC_saved = SPI->IMSC; + SPI_DMACR_saved = SPI->DMACR; + SPI_RXFRM_saved = SPI->RXFRM; + SPI_CHN_saved = SPI->CHN; + SPI_WDTXF_saved = SPI->WDTXF; +#endif +#if SLEEP_SAVE_N_RESTORE_I2C + /* I2C */ + for (i=0; i<2; i++) { + I2C_Type *I2Cx = (I2C_Type*)(I2C2_BASE+ 0x100000*i); + I2C_CR_saved[i] = I2Cx->CR; + I2C_SCR_saved[i] = I2Cx->SCR; + I2C_TFTR_saved[i] = I2Cx->TFTR; + I2C_RFTR_saved[i] = I2Cx->RFTR; + I2C_DMAR_saved[i] = I2Cx->DMAR; + I2C_BRCR_saved[i] = I2Cx->BRCR; + I2C_IMSCR_saved[i] = I2Cx->IMSCR; + I2C_THDDAT_saved[i] = I2Cx->THDDAT; + I2C_THDSTA_FST_STD_saved[i] = I2Cx->THDSTA_FST_STD; + I2C_TSUSTA_FST_STD_saved[i] = I2Cx->TSUSTA_FST_STD; + } +#endif + /* RNG */ + RNG_CR_saved = RNG->CR; +#if SLEEP_SAVE_N_RESTORE_RTC + /* RTC */ + RTC_CWDMR_saved = RTC->CWDMR; + RTC_CWDLR_saved = RTC->CWDLR; + RTC_CWYMR_saved = RTC->CWYMR; + RTC_CWYLR_saved = RTC->CWYLR; + RTC_CTCR_saved = RTC->CTCR; + RTC_IMSC_saved = RTC->IMSC; + RTC_TCR_saved = RTC->TCR; + RTC_TLR1_saved = RTC->TLR1; + RTC_TLR2_saved = RTC->TLR2; + RTC_TPR1_saved = RTC->TPR1; + RTC_TPR2_saved = RTC->TPR2; + RTC_TPR3_saved = RTC->TPR3; + RTC_TPR4_saved = RTC->TPR4; +#endif + /* MFTX */ +#if SLEEP_SAVE_N_RESTORE_MFTX1 + T1CRA_saved = MFT1->TNCRA; + T1CRB_saved = MFT1->TNCRB; + T1PRSC_saved = MFT1->TNPRSC; + T1CKC_saved = MFT1->TNCKC; + T1MCTRL_saved = MFT1->TNMCTRL; + T1ICTRL_saved = MFT1->TNICTRL; +#endif +#if SLEEP_SAVE_N_RESTORE_MFTX2 + T2CRA_saved = MFT2->TNCRA; + T2CRB_saved = MFT2->TNCRB; + T2PRSC_saved = MFT2->TNPRSC; + T2CKC_saved = MFT2->TNCKC; + T2MCTRL_saved = MFT2->TNMCTRL; + T2ICTRL_saved = MFT2->TNICTRL; +#endif + /* SysTick */ + SYST_CSR_saved = SysTick->CTRL; + SYST_RVR_saved = SysTick->LOAD; +#if SLEEP_SAVE_N_RESTORE_WDG + /* WDT */ + WDG_LR_saved = WDG->LR; + WDG_CR_saved = WDG->CR; + if(WDG->LOCK == 0) { + WDG_LOCK_saved = 0x1ACCE551; + } else { + WDG_LOCK_saved = 0; + } +#endif +#if SLEEP_SAVE_N_RESTORE_DMA + /* DMA */ + for (i=0; i<8; i++) { + DMA_CH_Type *DMAx = (DMA_CH_Type*)(DMA_CH0_BASE+ 0x14*i); + DMA_CNDTR_saved[i] = DMAx->CNDTR; + DMA_CCR_saved[i] = DMAx->CCR; + DMA_CPAR_saved[i] = DMAx->CPAR; + DMA_CMAR[i] = DMAx->CMAR; + } +#endif +#if SLEEP_SAVE_N_RESTORE_ADC + /* ADC */ + ADC_CONF_saved = ADC->CONF; + ADC_IRQMASK_saved = ADC->IRQMASK; + ADC_OFFSET_MSB_saved = ADC->OFFSET_MSB; + ADC_OFFSET_LSB_saved = ADC->OFFSET_LSB; + ADC_THRESHOLD_HI_saved = ADC->THRESHOLD_HI; + ADC_THRESHOLD_LO_saved = ADC->THRESHOLD_LO; + ADC_CTRL_saved = ADC->CTRL; +#endif + + /* PKA */ + PKA_IEN_saved = PKA->IEN; + + // Enable the STANDBY mode + if (sleepMode == SLEEPMODE_NOTIMER) { + BLUE_CTRL->TIMEOUT |= LOW_POWER_STANDBY<<28; + } + + //Save the CSTACK number of words that will be restored at wakeup reset + i = 0; + ptr = __vector_table[0].__ptr ; + ptr -= CSTACK_PREAMBLE_NUMBER; + do { + cStackPreamble[i] = *ptr; + i++; + ptr++; + } while (i < CSTACK_PREAMBLE_NUMBER); + + /* If the wakeup source is already active, we can skip the sleep to speed-up + the application execution */ + ioEnabled = SYSTEM_CTRL->WKP_IO_IE; + ioLevel = SYSTEM_CTRL->WKP_IO_IS; + ioValue = (~((GPIO->DATA>>9) ^ ioLevel)) & ioEnabled; + if (ioValue){ + return; + } + + if (((partInfo.die_major<<4)|(partInfo.die_cut)) >= WA_DEVICE_VERSION) { + /* Lock the flash */ + flash_sw_lock = FLASH_LOCK_WORD; + /* Disable BOR */ + SET_BORconfigStatus(FALSE); + } + /* Copy of the BLUE_CTRL TIMEOUT register in RAM */ + rfTimeout = BLUE_CTRL->TIMEOUT; + + //Enable deep sleep + SystemSleepCmd(ENABLE); + //The __disable_irq() used at the beginning of the BlueNRG_Sleep() function + //masks all the interrupts. The interrupts will be enabled at the end of the + //context restore. Now induce a context save. + void CS_contextSave(void); + CS_contextSave(); + + //Disable deep sleep, because if no reset occours for an interrrupt pending, + //the register value remain set and if a simple CPU_HALT command is called from the + //application the BlueNRG-1 enters in deep sleep without make a context save. + //So, exiting from the deep sleep the context is restored with wrong random value. + SystemSleepCmd(DISABLE); + + if (!wakeupFromSleepFlag) { + + if((NVIC->ISPR[0]&(1<ISPR[0]; + if ((savedSHCSR != SCB->SHCSR) || //Verified if a SVCall Interrupt is pending + ((savedNVIC_ISPR != NVIC->ISPR[0]) && (nvicPendingMask & NVIC->ISER[0])) || //Verified if a NVIC Interrupt is pending + ((savedICSR & 0x10000000) != (SCB->ICSR & 0x10000000)) || // Verified if a PendSV interrupt is pending + (((savedICSR & 0x4000000) != (SCB->ICSR & 0x4000000)) && (SysTick->CTRL & 0x02))) { // Verified if a SysTick interrupt is pending + savedCurrentTime = (*(volatile uint32_t *)BLUE_CURRENT_TIME_REG) >> 4; + if (0xFFFFF >= (savedCurrentTime+3)) { //Check if the counter are wrapping + while ((savedCurrentTime+3) > ((*(volatile uint32_t *)BLUE_CURRENT_TIME_REG) >> 4)); //Not Wrap + } else { + while (((*(volatile uint32_t *)BLUE_CURRENT_TIME_REG) >> 4) != (savedCurrentTime + 3 - 0xFFFFF)); //Wrap + } + } + } + + /* Restore BOR configuration */ + if (((partInfo.die_major<<4)|(partInfo.die_cut)) >= WA_DEVICE_VERSION) { + /* Restore BOR configuration */ + SET_BORconfigStatus(TRUE); + /* Unlock the flash */ + flash_sw_lock = FLASH_UNLOCK_WORD; + } + + // Disable the STANDBY mode + if (sleepMode == SLEEPMODE_NOTIMER) { + BLUE_CTRL->TIMEOUT &= ~(LOW_POWER_STANDBY<<28); + } + } else { + + /* Start a new calibration, needed to signal if the HS is ready */ + CKGEN_BLE->CLK32K_IT = 1; + CKGEN_BLE->CLK32K_COUNT = 0; + CKGEN_BLE->CLK32K_PERIOD = 0; + + /* Restore the CSTACK number of words that will be saved before the sleep */ + i = 0; + ptr = __vector_table[0].__ptr ; + ptr -= CSTACK_PREAMBLE_NUMBER; + do { + *ptr = cStackPreamble[i]; + i++; + ptr++; + } while (i < CSTACK_PREAMBLE_NUMBER); + + + /* Restore the peripherals configuration */ + /* FLASH CONFIG */ + FLASH->CONFIG = FLASH_CONFIG_saved; + /* NVIC */ + NVIC->ISER[0] = NVIC_ISER_saved; + + // Issue with Atollic compiler +// memcpy((void *)NVIC->IP, (void*)NVIC_IPR_saved, sizeof(NVIC_IPR_saved)); + for (i=0; i<8; i++) { + NVIC->IP[i] = NVIC_IPR_saved[i]; + } + + *(volatile uint32_t *)SHPR3_REG = PENDSV_SYSTICK_IPR_saved; + /* CKGEN SOC Enabled */ + CKGEN_SOC->CLOCK_EN = CLOCK_EN_saved; + /* GPIO */ + GPIO->DATA = GPIO_DATA_saved; + GPIO->OEN = GPIO_OEN_saved; + GPIO->PE = GPIO_PE_saved; + GPIO->DS = GPIO_DS_saved; + GPIO->IEV = GPIO_IEV_saved; + GPIO->IBE = GPIO_IBE_saved; + GPIO->IS = GPIO_IS_saved; + GPIO->IC = GPIO_IE_saved; + GPIO->IE = GPIO_IE_saved; + GPIO->MODE0 = GPIO_MODE0_saved; + GPIO->MODE1 = GPIO_MODE1_saved; +#ifdef BLUENRG2_DEVICE + GPIO->MODE2 = GPIO_MODE2_saved; + GPIO->MODE3 = GPIO_MODE3_saved; +#endif + GPIO->MFTX = GPIO_IOSEL_MFTX_saved; +#if SLEEP_SAVE_N_RESTORE_UART + /* UART */ + UART->TIMEOUT = UART_TIMEOUT_saved; + UART->LCRH_RX = UART_LCRH_RX_saved; + UART->IBRD = UART_IBRD_saved; + UART->FBRD = UART_FBRD_saved; + UART->LCRH_TX = UART_LCRH_TX_saved; + UART->CR = UART_CR_saved; + UART->IFLS = UART_IFLS_saved; + UART->IMSC = UART_IMSC_saved; + UART->DMACR = UART_DMACR_saved; + UART->XFCR = UART_XFCR_saved; + UART->XON1 = UART_XON1_saved; + UART->XON2 = UART_XON2_saved; + UART->XOFF1 = UART_XOFF1_saved; + UART->XOFF2 = UART_XOFF2_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_SPI + /* SPI */ + SPI->CR0 = SPI_CR0_saved; + SPI->CR1 = SPI_CR1_saved; + SPI->CPSR = SPI_CPSR_saved; + SPI->IMSC = SPI_IMSC_saved; + SPI->DMACR = SPI_DMACR_saved; + SPI->RXFRM = SPI_RXFRM_saved; + SPI->CHN = SPI_CHN_saved; + SPI->WDTXF = SPI_WDTXF_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_I2C + /* I2C */ + for (i=0; i<2; i++) { + I2C_Type *I2Cx = (I2C_Type*)(I2C2_BASE+ 0x100000*i); + I2Cx->CR = I2C_CR_saved[i]; + I2Cx->SCR = I2C_SCR_saved[i]; + I2Cx->TFTR = I2C_TFTR_saved[i]; + I2Cx->RFTR = I2C_RFTR_saved[i]; + I2Cx->DMAR = I2C_DMAR_saved[i]; + I2Cx->BRCR = I2C_BRCR_saved[i]; + I2Cx->IMSCR = I2C_IMSCR_saved[i]; + I2Cx->THDDAT = I2C_THDDAT_saved[i]; + I2Cx->THDSTA_FST_STD = I2C_THDSTA_FST_STD_saved[i]; + I2Cx->TSUSTA_FST_STD = I2C_TSUSTA_FST_STD_saved[i]; + } +#endif + /* RNG */ + RNG->CR = RNG_CR_saved; + /* SysTick */ + SysTick->LOAD = SYST_RVR_saved; + SysTick->VAL = 0; + SysTick->CTRL = SYST_CSR_saved; +#if SLEEP_SAVE_N_RESTORE_RTC + /* RTC */ + RTC->CWDMR = RTC_CWDMR_saved; + RTC->CWDLR = RTC_CWDLR_saved; + RTC->CWYMR = RTC_CWYMR_saved; + RTC->CWYLR = RTC_CWYLR_saved; + RTC->CTCR = RTC_CTCR_saved; + RTC->IMSC = RTC_IMSC_saved; + RTC->TLR1 = RTC_TLR1_saved; + RTC->TLR2 = RTC_TLR2_saved; + RTC->TPR1 = RTC_TPR1_saved; + RTC->TPR2 = RTC_TPR2_saved; + RTC->TPR3 = RTC_TPR3_saved; + RTC->TPR4 = RTC_TPR4_saved; + RTC->TCR = RTC_TCR_saved; /* Enable moved at the end of RTC configuration */ +#endif + /* MFTX */ +#if SLEEP_SAVE_N_RESTORE_MFTX1 + MFT1->TNCRA = T1CRA_saved; + MFT1->TNCRB = T1CRB_saved; + MFT1->TNPRSC = T1PRSC_saved; + MFT1->TNCKC = T1CKC_saved; + MFT1->TNMCTRL = T1MCTRL_saved & ~((uint32_t)(1<<6)); + MFT1->TNICTRL = T1ICTRL_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_MFTX2 + MFT2->TNCRA = T2CRA_saved; + MFT2->TNCRB = T2CRB_saved; + MFT2->TNPRSC = T2PRSC_saved; + MFT2->TNCKC = T2CKC_saved; + MFT2->TNMCTRL = T2MCTRL_saved & ~((uint32_t)(1<<6)); + MFT2->TNICTRL = T2ICTRL_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_WDG + /* WDT */ + WDG->LR = WDG_LR_saved; + WDG->CR = WDG_CR_saved; + WDG->LOCK = WDG_LOCK_saved; +#endif +#if SLEEP_SAVE_N_RESTORE_DMA + /* DMA */ + for (i=0; i<8; i++) { + DMA_CH_Type *DMAx = (DMA_CH_Type*)(DMA_CH0_BASE+ 0x14*i); + DMAx->CNDTR = DMA_CNDTR_saved[i]; + DMAx->CCR = DMA_CCR_saved[i] ; + DMAx->CPAR = DMA_CPAR_saved[i]; + DMAx->CMAR = DMA_CMAR[i]; + } +#endif +#if SLEEP_SAVE_N_RESTORE_ADC + /* ADC */ + ADC->CONF = ADC_CONF_saved; + ADC->IRQMASK = ADC_IRQMASK_saved; + ADC->OFFSET_MSB = ADC_OFFSET_MSB_saved; + ADC->OFFSET_LSB = ADC_OFFSET_LSB_saved; + ADC->THRESHOLD_HI = ADC_THRESHOLD_HI_saved; + ADC->THRESHOLD_LO = ADC_THRESHOLD_LO_saved; + ADC->CTRL = ADC_CTRL_saved; +#endif + + /* PKA */ + PKA->IEN = PKA_IEN_saved; + //The five IRQs are linked to a real ISR. If any of the five IRQs + //triggered, then pend their ISR + //Capture the wake source from the BLE_REASON_RESET register + if ((CKGEN_SOC->REASON_RST == 0) && gpioWakeBitMask) { + if ((((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO9) == WAKENED_FROM_IO9) && (GPIO->IE & GPIO_Pin_9)) || + (((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO10) == WAKENED_FROM_IO10) && (GPIO->IE & GPIO_Pin_10)) || + (((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO11) == WAKENED_FROM_IO11) && (GPIO->IE & GPIO_Pin_11)) || + (((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO12) == WAKENED_FROM_IO12) && (GPIO->IE & GPIO_Pin_12)) || + (((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO13) == WAKENED_FROM_IO13) && (GPIO->IE & GPIO_Pin_13))) { + NVIC->ISPR[0] = 1<TIMEOUT &= ~(LOW_POWER_STANDBY<<28); + } + + /* Restore the System Control register to indicate which HS crystal is used */ + SYSTEM_CTRL->CTRL = SYS_Ctrl_saved; + + // Wait until the HS clock is ready. + // If SLEEPMODE_NOTIMER is set, wait the LS clock is ready. + if (sleepMode == SLEEPMODE_NOTIMER) { + DeviceConfiguration(FALSE, TRUE); + } else { + DeviceConfiguration(FALSE, FALSE); + } + + /* If the HS is a 32 MHz */ + if (SYS_Ctrl_saved & 1) { +#ifndef FORCE_CORE_TO_16MHZ + /* AHB up converter command register write*/ + frequency_switch(); +#endif + } + } +} + +uint8_t BlueNRG_Sleep(SleepModes sleepMode, + uint8_t gpioWakeBitMask, + uint8_t gpioWakeLevelMask) +{ + SleepModes app_sleepMode, ble_sleepMode, timer_sleepMode, sleepMode_allowed; + + /* Mask all the interrupt */ + ATOMIC_SECTION_BEGIN(); + + /* Flag to signal if a wakeup from standby or sleep occurred */ + wakeupFromSleepFlag = 0; + + ble_sleepMode = (SleepModes)BlueNRG_Stack_Perform_Deep_Sleep_Check(); + timer_sleepMode = HAL_VTIMER_TimerSleepCheck(sleepMode); + app_sleepMode = App_SleepMode_Check(sleepMode); + sleepMode_allowed = (SleepModes)MIN(app_sleepMode, sleepMode); + sleepMode_allowed = (SleepModes)MIN(timer_sleepMode, sleepMode_allowed); + sleepMode_allowed = (SleepModes)MIN(ble_sleepMode, sleepMode_allowed); + +#ifdef DEBUG_SLEEP_MODE + sleepMode_selected[sleepMode_allowed]++; +#endif + + if (sleepMode_allowed == SLEEPMODE_RUNNING) { + ATOMIC_SECTION_END(); + return SUCCESS; + } + + if (sleepMode_allowed == SLEEPMODE_CPU_HALT) { + /* Store the watchdog configuration and the disable it to avoid reset during CPU halt. */ + uint32_t WDG_CR_saved = WDG->CR; + WDG->CR = 0; + + /* Wait for interrupt is called: the core execution is halted until an event occurs. */ + __WFI(); + + /* Restore the watchdog functionality. */ + WDG->CR= WDG_CR_saved; + + ATOMIC_SECTION_END(); + return SUCCESS; + } + + /* Setup the Wakeup Source */ + SYSTEM_CTRL->WKP_IO_IS = gpioWakeLevelMask; + SYSTEM_CTRL->WKP_IO_IE = gpioWakeBitMask; + + BlueNRG_InternalSleep(sleepMode_allowed, gpioWakeBitMask); + + ATOMIC_SECTION_END(); + + return SUCCESS; +} + +uint16_t BlueNRG_WakeupSource(void) +{ + uint16_t src=NO_WAKEUP_RESET; + + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO9) == WAKENED_FROM_IO9)) { + src |= WAKEUP_IO9; + } + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO10) == WAKENED_FROM_IO10)) { + src |= WAKEUP_IO10; + } + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO11) == WAKENED_FROM_IO11)) { + src |= WAKEUP_IO11; + } + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO12) == WAKENED_FROM_IO12)) { + src |= WAKEUP_IO12; + } + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_IO13) == WAKENED_FROM_IO13)) { + src |= WAKEUP_IO13; + } + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_BLUE_TIMER1) == WAKENED_FROM_BLUE_TIMER1)) { + src |= WAKEUP_SLEEP_TIMER1; + } + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_BLUE_TIMER2) == WAKENED_FROM_BLUE_TIMER2)) { + src |= WAKEUP_SLEEP_TIMER2; + } + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_POR) == WAKENED_FROM_POR)) { + src |= WAKEUP_POR; + } + if ((CKGEN_SOC->REASON_RST == 0) && + ((CKGEN_BLE->REASON_RST & WAKENED_FROM_BOR) == WAKENED_FROM_BOR)) { + src |= WAKEUP_BOR; + } + if (CKGEN_SOC->REASON_RST == 2) { + src |= WAKEUP_SYS_RESET_REQ; + } + if (CKGEN_SOC->REASON_RST == 4) { + src |= WAKEUP_RESET_WDG; + } + + return src; +} diff --git a/hal/src/vtimer.c b/hal/src/vtimer.c new file mode 100644 index 0000000..52060fd --- /dev/null +++ b/hal/src/vtimer.c @@ -0,0 +1,756 @@ +/** + ****************************************************************************** + * @file vtimer.c + * @warning This module must not be included in applications based on the + * BLE stack library. In that case, the API implementation is managed by the library itself. + * The API calls remain the same. In the future release the BLE stack library will rely on + * the Timer module library. + * @author RF Application Team + * @date Jan-2020 + * @brief Virtual timer and Radio timer high level APIs + * @details This file implements the software layer that provides the virtualization of the + * resources of a single hardware timer in order to allocate many user virtual timers. + * Each instance of a virtual timer is placed in an queue ordered by the expiration time + * and it can be linked to a callback. + * The timer tick is in charge to execute the callback linked to each virtual timer + * and to update the hardware timeout to gurantee the expiration of the next virtual + * timer in the queue. + * A special virtual timer called calibration/anti-wrapping timer is automatically armed + * by the software. This timer can address two tasks: + * - it is in charge to maintain the never wrapping virtual time base. + * - if the slow clock calibration is enabled, it starts the calibration procedure at each + * calibration interval specified during the initialization. + * + * A timer is intended as an event programmed in the future at a certain absolute expiration time + * on a time base. In this implementation the time base grows on 64 bits. Then, it never wraps. + * However, due to hardware timer finite length and in order to maintain the timing coherency, the time base + * must be maintained at least one time before the hardware timer wraps. + * Then even if the slow clock calibration is disabled, the calibration/anti-wrapping timer + * is always active with the only role to maintain the time base and it will expire + * at a rate that depends on the hardware timer capability. + * The time base unit is a STU that is the unit exposed to the user and it is equal to 625/256 us. + * The calibration/anti-wrapping mechanism is not managed by the user. + * + * This software layer also exposes the possibility to program a radio timer. + * A radio timer allows the user to trigger an already configured radio event. + * This layer tries to exploit the last calibration values to program the radio activity + * in order to improve the accuracy. In this case, the radio event is not immediately programmed + * when it is requested, but only when the next calibration values are available. + * Since the calibration values are available inside the timer tick when the calibration is over, + * the application must ensure that the timer tick is called after the calibration timer + * expiration within a certain margin in order to avoid that the radio event is shifted in the + * past and cannot be anymore programmed. + * + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2020 STMicroelectronics

+ ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include +#include "BlueNRG1_timer.h" +#include "vtimer.h" +#include "sleep.h" + +/** @defgroup VTIMER_Private_TypesDefinitions Private Types Definitions + * @{ + */ + +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_irq(); \ +/* Must be called in the same scope of ATOMIC_SECTION_BEGIN */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) +#define MAX(a,b) ((a) < (b) )? (b) : (a) +#define MIN(a,b) ((a) > (b) )? (b) : (a) +#define DIFF8(a,b) ((a)>=(b) ? ((a)-(b)) : (256-((a)-(b)))) +#define INCREMENT_EXPIRE_COUNT_ISR (HAL_VTIMER_Context.expired_count = ((HAL_VTIMER_Context.expired_count + 1) == HAL_VTIMER_Context.served_count) ? HAL_VTIMER_Context.expired_count : (HAL_VTIMER_Context.expired_count + 1)) +#define INCREMENT_EXPIRE_COUNT ATOMIC_SECTION_BEGIN(); INCREMENT_EXPIRE_COUNT_ISR ; ATOMIC_SECTION_END(); + +/*Minimum programmable value in sys. unit for a radio activity to be in the future*/ +#if HS_SPEED_XTAL==HS_SPEED_XTAL_32MHZ +#define TIMER1_MARGIN 9 /*TBD*/ +#else +#define TIMER1_MARGIN 12 /*TBD*/ +#endif + +typedef struct HAL_VTIMER_ContextS { + uint32_t PeriodicCalibrationInterval; /*!< Periodic calibration interval in ms, to disable set to 0 */ + BOOL calibration_in_progress; /*!< Flag to indicate that a periodic calibration has been started */ + BOOL enableTimeBase; /*TBR*/ + uint32_t hs_startup_time; /*TBR*/ + VTIMER_HandleType *rootNode; + uint8_t expired_count; /* Progressive number to indicate expired timers */ + uint8_t served_count; /* Progressive number to indicate served expired timers */ +} HAL_VTIMER_ContextType; + +/** + * @} + */ + +/** @defgroup VTIMER_Private_Variables Private Variables + * @{ + */ +static HAL_VTIMER_ContextType HAL_VTIMER_Context; +static VTIMER_HandleType calibrationTimer; +static VTIMER_RadioHandleType radioTimer; + +/** + * @} + */ + +/** @defgroup VTIMER_Private_Variables Private Variables + * @{ + */ +static TIMER_CalibrationType calibrationData; + +/** + * @} + */ + +/** @defgroup VTIMER_Private_Function Private Function + * @{ + */ +static void calibration_callback (void *handle) +{ + TIMER_StartCalibration(); + HAL_VTIMER_Context.calibration_in_progress = TRUE; +} + +static VTIMER_HandleType * _remove_timer_in_queue(VTIMER_HandleType *rootNode, VTIMER_HandleType *handle) +{ + VTIMER_HandleType *current = rootNode; + VTIMER_HandleType *prev = NULL; + VTIMER_HandleType *returnValue = rootNode; + + while ((current!=NULL) && (current != handle)) { + prev = current; + current=current->next; + } + + if (current == NULL) { + /* Not found */ + } + else if (current == rootNode) { + /* New root node */ + returnValue = current->next; + } + else { + prev->next = current->next; + } + + return returnValue; +} + +static VTIMER_HandleType * _insert_timer_in_queue(VTIMER_HandleType *rootNode, VTIMER_HandleType *handle) +{ + VTIMER_HandleType *current = rootNode; + VTIMER_HandleType *prev = NULL; + VTIMER_HandleType *returnValue = rootNode; + + while ((current!=NULL) && (current->expiryTime < handle->expiryTime)) { + prev = current; + current=current->next; + } + + handle->next = current; + + if (prev == NULL) { + /* We are the new root */ + returnValue = handle; + } + else { + prev->next = handle; + } + + return returnValue; +} + +/* Set timeout and skip non active timers */ +static VTIMER_HandleType *_update_user_timeout(VTIMER_HandleType *rootNode, uint8_t *expired) +{ + VTIMER_HandleType *curr = rootNode; + VTIMER_HandleType *rootOrig = rootNode; + int32_t delay; + *expired =0; + while (curr != NULL) { + if (curr->active) { + ATOMIC_SECTION_BEGIN(); + delay = curr->expiryTime-TIMER_GetCurrentSysTime(); + + if (delay > 0) { + /* Protection against interrupt must be used to avoid that the called function will be interrupted + and so the timer programming will happen after the target time is already passed + leading to a timer expiring after timer wraps, instead of the expected delay */ + + TIMER_SetWakeupTime(delay, TRUE); + ATOMIC_SECTION_END(); + break; + } + else { + /* Timeout in the past or very close, what to do ??? */ + /* Set a flag for further processing ? or set a very close timeout ?*/ + *expired = 1; + ATOMIC_SECTION_END(); + break; + } + } + curr=curr->next; + } + if (*expired) + return rootOrig; + return curr; +} + +/* Check the number of expired timer from rootNode (ordered list of timers) and return the list of expired timers */ +static VTIMER_HandleType *_check_callbacks(VTIMER_HandleType *rootNode,VTIMER_HandleType **expiredList) +{ + VTIMER_HandleType *curr = rootNode; + VTIMER_HandleType *prev = NULL; + VTIMER_HandleType *returnValue = rootNode; + *expiredList = rootNode; + int32_t delay; + uint32_t expiredCount = 0; + + while (curr != NULL) { + if (curr->active) { + delay = curr->expiryTime-TIMER_GetCurrentSysTime(); + + if (delay > 0) { + /* End of expired timers list*/ + break; + } + } + prev = curr; + curr=curr->next; + expiredCount++; + } + + if (expiredCount) { + /* Some timers expired */ + prev->next=NULL; + returnValue = curr; + } + else { + /* No timer expired */ + *expiredList = NULL; + } + + return returnValue; +} + +static int _start_timer(VTIMER_HandleType *timerHandle, uint64_t time) +{ + uint8_t expired = 0; + + /* The timer is already started*/ + if(timerHandle->active) + { + return 1; + } + timerHandle->expiryTime = time; + timerHandle->active = TRUE; + if (_insert_timer_in_queue(HAL_VTIMER_Context.rootNode, timerHandle) == timerHandle) { + HAL_VTIMER_Context.rootNode = _update_user_timeout(timerHandle, &expired); + if (expired) { + /* A new root timer is already expired, mimic timer expire that is normally signaled + through the interrupt handler that increase the number of expired timers*/ + INCREMENT_EXPIRE_COUNT; + } + } + return expired; +} + +/*Check if it is time to program the pending radio timer (large timeouts). +1) The radio event is before the next calibration. Then the timer must be programmed. +2) The calibration timer expired but the calibration didn't start and the values not updated as expected. + Then the last calibration time is misleading. The radio timer must be programmed. +3) The radio event is after the next calibration event. Then the timer will be programmed with the latest values. +The check on the last calibration time is made even though the calibration is not needed in order to avoid counter wrapping +with timeouts far in the future. +*/ +void _check_radio_activity(VTIMER_RadioHandleType * timerHandle, uint8_t *expired) +{ + uint32_t sys_delay; + uint64_t nextCalibrationEvent,currentTime; + + *expired = 0; + if (timerHandle->pending){ + nextCalibrationEvent = calibrationData.last_calibration_time + \ + HAL_VTIMER_Context.PeriodicCalibrationInterval; + + ATOMIC_SECTION_BEGIN(); + currentTime = TIMER_GetCurrentSysTime(); + + if((timerHandle->expiryTime < (nextCalibrationEvent + RADIO_ACTIVITY_MARGIN)) \ + || \ + (currentTime > (nextCalibrationEvent + CALIB_SAFE_THR))) + { + sys_delay = TIMER_GetActivitySysDelay(timerHandle->event_type,timerHandle->cal_req); + if (timerHandle->expiryTime > currentTime + sys_delay + TIMER1_MARGIN){ + *expired = TIMER_SetRadioTimerValue(timerHandle->expiryTime, timerHandle->event_type,timerHandle->cal_req); + ATOMIC_SECTION_END(); + timerHandle->pending = FALSE; /*timer has been served. No more pending*/ + timerHandle->active = TRUE; /*timer has been programmed and it becomes ACTIVE*/ + } + else{ + ATOMIC_SECTION_END(); + *expired = 1; + } + } + else{ + ATOMIC_SECTION_END(); + TIMER_SetTimeoutReg(1<<28); + } + } +} + +static void _virtualTimeBaseEnable(FunctionalState state) +{ + if(state != DISABLE) + { + if (HAL_VTIMER_Context.enableTimeBase == FALSE) + { + calibration_callback(&calibrationTimer); + HAL_VTIMER_Context.enableTimeBase = TRUE; + } + } + else + { + HAL_VTimer_Stop(&calibrationTimer); + HAL_VTIMER_Context.enableTimeBase = FALSE; + } +} + +/** + * @} + */ + + +/** @defgroup VTIMER_Public_Function Public Function + * @{ + */ + +/** + * @brief Return the status of the radio timer. + * The timeout of the last radio timer activity taken into account by the Timer Module + * is saved in the variable passed as parameter. + * @param time: Pointer of the variable where the time of the last radio activity scheduled is stored + * The time is expressed in STU. + * @retval 0 if no radio timer is pending. + * @retval 1 if a radio timer is pending and it is not already expired. + */ +RadioStatus HAL_VTimer_GetRadioTimerValue(uint32_t *time) +{ + *time = radioTimer.expiryTime; + if (radioTimer.pending || radioTimer.active) + return RADIO_TIMER_PENDING; + else + return RADIO_TIMER_OFF; +} + +/** + * @brief Clear the last radio activity scheduled disabling the radio timer too. + * Furthermore, it returns if the timeout is too close with respect the current time and + * the radio activity might not be cleared in time. + * @retval 0 if the radio activity has been cleared successfully. + * @retval 2 if it might not be possible to clear the last radio activity. + */ +uint8_t HAL_VTimer_ClearRadioTimerValue(void) +{ + int64_t time_diff; + uint8_t retVal; + + TIMER_ClearRadioTimerValue(); + radioTimer.active = FALSE; + radioTimer.pending = FALSE; + + ATOMIC_SECTION_BEGIN(); + time_diff = radioTimer.expiryTime \ + - TIMER_GetCurrentSysTime() \ + - TIMER_GetActivitySysDelay(radioTimer.event_type,radioTimer.cal_req) \ + - HAL_VTIMER_Context.hs_startup_time; + ATOMIC_SECTION_END(); + /* + if(time_diff <= 0) + retVal = HAL_VTIMER_LATE; +*/ + if (time_diff < CLEAR_TIME_MIN) + retVal = HAL_VTIMER_CRITICAL; + else{ + retVal = HAL_VTIMER_SUCCESS; + } + return retVal; +} + +/** + * @brief Disable Timer2. + * @retval None + */ +void HAL_VTimer_StopRadioTimer2(void) +{ + TIMER_ClearRadioTimerValue(); +} + +/** + * @brief Virtual timer Timeout Callback. It must be called in the Blue handler + * if the host wake up timer bit in the radio controller interrupt/status + * register is active. + * @retval None + */ +void HAL_VTIMER_TimeoutCallback(void) +{ + /* Disable host timer and enable the sleep*/ + TIMER_SetHostTimeoutReg(1<<28); + INCREMENT_EXPIRE_COUNT_ISR; +} + +/** + * @brief Radio activity finished. Not used yet + * @retval None + */ +void HAL_VTIMER_RadioTimerIsr(void) +{ + radioTimer.active = FALSE; +} + +/** + * @brief Starts a one-shot virtual timer for the given absolute timeout value + * expressed in internal time units. + * @param timerHandle: The virtual timer + * @param time: Absolute time expressed in STU. + * @retval 0 if the timerHandle is valid. + * @retval 1 if the timerHandle is not valid. It is already started. + */ +int HAL_VTimerStart_sysT32(VTIMER_HandleType *timerHandle, uint64_t time) +{ + uint8_t retVal; + retVal = _start_timer(timerHandle, time); + _virtualTimeBaseEnable(ENABLE); + return retVal; +} + +/** + * @brief Starts a one-shot virtual timer for the given relative timeout value expressed in ms + * @param timerHandle: The virtual timer + * @param msRelTimeout: The relative time, from current time, expressed in ms + * @retval 0 if the timerHandle is valid. + * @retval 1 if the timerHandle is not valid. It is already started. + */ +int HAL_VTimerStart_ms(VTIMER_HandleType *timerHandle, uint32_t msRelTimeout) +{ + uint64_t temp = msRelTimeout; + uint8_t retVal; + retVal = _start_timer(timerHandle, TIMER_GetCurrentSysTime() + (temp*TIMER_SYSTICK_PER_10MS)/10); + _virtualTimeBaseEnable(ENABLE); + return retVal; +} + +/** + * @brief Schedules a radio activity for the given absolute timeout value expressed in STU + * If the calibration of the low speed oscillator is needed, if it is possible, + * the radio timer will be programmed with the latest calibration data. + * @param time: Absolute time expressed in STU. + * @param event_type: Specify if it is a TX (1) or RX (0) event. + * @param cal_req: Specify if PLL calibration is requested (1) or not (0). + * @retval 0 if radio activity has been scheduled succesfully. + * @retval 1 if radio activity has been rejected (it is too close or in the past). + */ +uint8_t HAL_VTimer_SetRadioTimerValue(uint32_t time, uint8_t event_type, uint8_t cal_req) +{ + uint8_t retVal = 0; + + radioTimer.event_type = event_type; + radioTimer.cal_req = cal_req; + radioTimer.expiryTime = calibrationData.last_calibration_time + (uint32_t)(time - (uint32_t)calibrationData.last_calibration_time); + radioTimer.active = FALSE; + radioTimer.pending = TRUE; + + _check_radio_activity(&radioTimer, &retVal); + + if (retVal){ + radioTimer.pending = FALSE; + } + _virtualTimeBaseEnable(ENABLE); + return retVal; +} + +/** + * @brief Stops the one-shot virtual timer specified if found + * @param timerHandle: The virtual timer + * @retval None + */ +void HAL_VTimer_Stop(VTIMER_HandleType *timerHandle) +{ + VTIMER_HandleType *rootNode = _remove_timer_in_queue(HAL_VTIMER_Context.rootNode, timerHandle); + uint8_t expired = 0; + timerHandle->active=FALSE; + if (HAL_VTIMER_Context.rootNode != rootNode && rootNode != NULL) { + HAL_VTIMER_Context.rootNode = _update_user_timeout(rootNode, &expired); + if (expired) { + /* A new root timer is already expired, mimic timer expire */ + INCREMENT_EXPIRE_COUNT; + } + } + else + HAL_VTIMER_Context.rootNode = rootNode; +} + +/** + * @brief This function return the current reference time expressed in system time units. + * The returned value can be used as absolute time parameter where needed in the other + * HAL_VTimer* APIs + * @return absolute current time expressed in system time units. + */ +uint32_t HAL_VTimerGetCurrentTime_sysT32(void) +{ + return ((uint32_t ) TIMER_GetCurrentSysTime()); +} + +/** + * @brief Get the last anchorPoint in system time unit. + * @return TimerCapture register in system time unit. + */ +uint64_t HAL_VTIMER_GetAnchorPoint(void) +{ + return TIMER_GetAnchorPoint(); +} + +/** + * @brief This function returns the sum of an absolute time and a signed relative time. + * @param sysTime: Absolute time expressed in internal time units. + * @param msTime: Signed relative time expressed in ms. + * @note abs(msTime) <= 5242879 + * @return 32bit resulting absolute time expressed in internal time units. + */ +uint64_t HAL_VTimerAcc_sysT32_ms(uint64_t sysTime, int32_t msTime) +{ + int32_t sysTick = (msTime * TIMER_SYSTICK_PER_10MS)/10; + return (sysTime+sysTick); +} + +/** + * @brief Returns the difference between two absolute times: sysTime1-sysTime2. + * The resulting value is expressed in ms. + * @param sysTime2: Absolute time expressed in internal time units. + * @param sysTime1: Absolute time expressed in internal time units. + * @return resulting signed relative time expressed in ms. + */ +int64_t HAL_VTimerDiff_ms_sysT32(uint64_t sysTime1, uint64_t sysTime2) +{ + return ((sysTime1-sysTime2)*10)/TIMER_SYSTICK_PER_10MS; +} + +/** + * @brief Returns the absolute expiry time of a running timer expressed in internal time units. + * @param timerHandle: The virtual timer + * @param sysTime: Absolute time expressed in internal time units. + */ +int HAL_VTimerExpiry_sysT32(VTIMER_HandleType *timerHandle, uint64_t *sysTime) +{ + *sysTime = timerHandle->expiryTime; + return 0; +} + +/** + * @brief Returns the number of timers in the queue. + * @return number of timers in the queue. + */ +uint32_t HAL_VTIMER_GetPendingTimers(void) +{ + VTIMER_HandleType *curr = HAL_VTIMER_Context.rootNode; + uint32_t counter = 0; + while (curr != NULL) { + counter++; + curr = curr->next; + } + return counter; +} + +/** + * @brief Initialize the timer module. It must be placed in the initialization + * section of the application. + * @retval None + */ +void HAL_VTIMER_Init(HAL_VTIMER_InitType *HAL_TIMER_InitStruct) +{ + TIMER_InitType TIMER_InitStruct; + TIMER_EnableBlueIRQ(); + TIMER_InitStruct.TIMER_InitialCalibration = HAL_TIMER_InitStruct->EnableInitialCalibration; + TIMER_InitStruct.TIMER_PeriodicCalibration = HAL_TIMER_InitStruct->PeriodicCalibrationInterval; + TIMER_InitStruct.XTAL_StartupTime = HAL_TIMER_InitStruct->XTAL_StartupTime; + TIMER_Init(&TIMER_InitStruct); + TIMER_GetCurrentCalibrationData(&calibrationData); + HAL_VTIMER_Context.rootNode = NULL; + HAL_VTIMER_Context.enableTimeBase = TRUE; /*TBR*/ + radioTimer.active = FALSE; + radioTimer.pending = FALSE; + HAL_VTIMER_Context.hs_startup_time = HAL_TIMER_InitStruct->XTAL_StartupTime; /*TBR*/ + HAL_VTIMER_Context.expired_count=0; + HAL_VTIMER_Context.served_count=0; + HAL_VTIMER_Context.PeriodicCalibrationInterval = (TIMER_SYSTICK_PER_10MS * HAL_TIMER_InitStruct->PeriodicCalibrationInterval)/10; + HAL_VTIMER_Context.calibration_in_progress = FALSE; + + if (HAL_VTIMER_Context.PeriodicCalibrationInterval == 0) + HAL_VTIMER_Context.PeriodicCalibrationInterval = TIMER_MachineTimeToSysTime(TIMER_MAX_VALUE-TIMER_WRAPPING_MARGIN); + else + HAL_VTIMER_Context.PeriodicCalibrationInterval = MIN(HAL_VTIMER_Context.PeriodicCalibrationInterval, + TIMER_MachineTimeToSysTime(TIMER_MAX_VALUE-TIMER_WRAPPING_MARGIN)); + calibrationTimer.callback = calibration_callback; + calibrationTimer.userData = NULL; + _start_timer(&calibrationTimer, TIMER_GetCurrentSysTime() + HAL_VTIMER_Context.PeriodicCalibrationInterval); +} + +/** + * @brief Timer module state machine. Check and schedule the calibration. + * Check expired timers and execute user callback. + * It must be placed inside the infinite loop. + * @retval None + */ +void HAL_VTIMER_Tick(void) +{ + uint8_t expired = 0; + + if(radioTimer.active){ + if(radioTimer.expiryTime < TIMER_GetCurrentSysTime()){ + radioTimer.active = FALSE; + } + } + + /* Check for expired timers */ + while (DIFF8(HAL_VTIMER_Context.expired_count,HAL_VTIMER_Context.served_count)) { + VTIMER_HandleType *expiredList, *curr; + uint8_t to_be_served = DIFF8(HAL_VTIMER_Context.expired_count,HAL_VTIMER_Context.served_count); + + HAL_VTIMER_Context.rootNode = _check_callbacks(HAL_VTIMER_Context.rootNode, &expiredList); + /* Call all the user callbacks */ + curr=expiredList; + while (curr != NULL) { + /* Save next pointer, in case callback start the timer again */ + VTIMER_HandleType *next = curr->next; + curr->active = FALSE; + if (curr->callback) + curr->callback(curr); + curr = next; + } + HAL_VTIMER_Context.rootNode = _update_user_timeout(HAL_VTIMER_Context.rootNode, &expired); + if (expired == 1) { + /* A new root timer is already expired, mimic timer expire */ + INCREMENT_EXPIRE_COUNT; + } + HAL_VTIMER_Context.served_count += to_be_served; + } + + /* Check for periodic calibration */ + if (HAL_VTIMER_Context.calibration_in_progress) { + if (TIMER_IsCalibrationRunning() == FALSE) { + /* Calibration is completed */ + HAL_VTIMER_Context.calibration_in_progress = FALSE; + /* Collect calibration data */ + TIMER_UpdateCalibrationData(); + TIMER_GetCurrentCalibrationData(&calibrationData); + _check_radio_activity(&radioTimer,&expired); + /* Schedule next calibration event */ + _start_timer(&calibrationTimer, TIMER_GetCurrentSysTime() + HAL_VTIMER_Context.PeriodicCalibrationInterval); + } + } + /* if there is a periodic calibration, start it in advance during the active phase */ + else{ + if(calibrationData.periodic_calibration){ + if( TIMER_GetCurrentSysTime() > calibrationData.last_calibration_time + TIMER_SYSTICK_PER_SECOND) + { + HAL_VTimer_Stop(&calibrationTimer); + calibration_callback(&calibrationTimer); + } + } + } +} + +/** + * @brief Returns the admitted sleep mode according to the next timer activity. + * @return Sleep mode + */ +SleepModes HAL_VTIMER_TimerSleepCheck(SleepModes sleepMode) +{ + uint32_t nextRadioActivity, nextHostActivity; + uint8_t timerState; + + if (HAL_VTIMER_SleepCheck() == FALSE) + { + return SLEEPMODE_RUNNING; + } + + TIMER_GetNextTimerActivity(&nextRadioActivity,&nextHostActivity); + timerState = TIMER_GetRadioTimerValue(&nextRadioActivity); + + if((__blue_RAM.BlueGlobVar.Config & 8U) != 0U) + { + if((radioTimer.active || radioTimer.pending) && !(timerState == TIMER1_BUSY)) + { + /*No Radio SPI transactions must occur within a certain margin*/ + if(radioTimer.expiryTime < (TIMER_GetCurrentSysTime() + \ + TIMER_GetActivitySysDelay(radioTimer.event_type,radioTimer.cal_req) + \ + HAL_VTIMER_Context.hs_startup_time) + \ + SLEEP_TIME_MIN) + { + return(SLEEPMODE_CPU_HALT); + } + + TIMER_SetTimeoutReg(nextRadioActivity); + } + else + { + /*A radio timer has been programmed through the TxRxPack*/ + /*Timer1 and wakeup timer are programmed only through + the timer module*/ + if ((timerState == TIMER2_BUSY) || (timerState == TIMER1_BUSY)) + { + return SLEEPMODE_CPU_HALT; + } + } + sleepMode = SLEEPMODE_WAKETIMER; + } + + if(HAL_VTIMER_Context.rootNode->active && HAL_VTIMER_Context.rootNode != NULL) + { + if((HAL_VTIMER_Context.rootNode->next == NULL) && (HAL_VTIMER_Context.rootNode == &calibrationTimer)) + { + if(sleepMode == SLEEPMODE_NOTIMER) + { + _virtualTimeBaseEnable(DISABLE); + TIMER_SetHostTimeoutReg(BLUE_SLEEP_ENABLE); + return SLEEPMODE_NOTIMER; + } + } + if(HAL_VTIMER_Context.rootNode->expiryTime < (TIMER_GetCurrentSysTime() + SLEEP_TIME_MIN)) + { + return SLEEPMODE_CPU_HALT; + } + TIMER_SetHostTimeoutReg(nextHostActivity | BLUE_SLEEP_ENABLE); + sleepMode = SLEEPMODE_WAKETIMER; + } + return sleepMode; +} + +/** + * @brief Return the consensus of the Virtual timer management to go in sleep. + * @retval TRUE if all vtimers have been served and the calibration procedure has already finished. + * @retval FALSE if the vtimer Tick is still busy. + */ +uint8_t HAL_VTIMER_SleepCheck(void) +{ + return ((HAL_VTIMER_Context.expired_count == HAL_VTIMER_Context.served_count) && (HAL_VTIMER_Context.calibration_in_progress == FALSE)); +} + +/** + * @} + */ + + /******************* (C) COPYRIGHT 2020 STMicroelectronics *****END OF FILE****/ diff --git a/soc/inc/BlueNRG1.h b/soc/inc/BlueNRG1.h new file mode 100644 index 0000000..dd5bd06 --- /dev/null +++ b/soc/inc/BlueNRG1.h @@ -0,0 +1,3411 @@ +/* + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLI + * ED 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 L + * IABLE 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 LI + * ABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTW + * ARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file BlueNRG1.h + * @brief CMSIS HeaderFile + * @version 2.2.1 + * @date 04. December 2018 + * @note Generated by SVDConv V3.3.21 on Tuesday, 04.12.2018 12:11:02 + * from File 'BlueNRG1.svd', + * last modified on Tuesday, 04.12.2018 11:11:02 + */ + + + +/** @addtogroup STMicroelectronics + * @{ + */ + + +/** @addtogroup BlueNRG1 + * @{ + */ + + +#ifndef BLUENRG1_H +#define BLUENRG1_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ Interrupt Number Definition ================ */ +/* =========================================================================================================================== */ + +typedef enum { +/* ======================================= ARM Cortex-M0 Specific Interrupt Numbers ======================================== */ + Reset_IRQn = -15, /*!< -15 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< -14 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< -13 Hard Fault, all classes of Fault */ + SVCall_IRQn = -5, /*!< -5 System Service Call via SVC instruction */ + PendSV_IRQn = -2, /*!< -2 Pendable request for system service */ + SysTick_IRQn = -1, /*!< -1 System Tick Timer */ +/* ========================================== BlueNRG1 Specific Interrupt Numbers ========================================== */ + GPIO_IRQn = 0, /*!< 0 GPIO bus interrupt */ + NVM_IRQn = 1, /*!< 1 Non-volatile memory (Flash) controller interrupt */ + UART_IRQn = 4, /*!< 4 UART interrupt */ + SPI_IRQn = 5, /*!< 5 SPI interrupt */ + BLUE_CTRL_IRQn = 6, /*!< 6 BLUE controller interrupt */ + WDG_IRQn = 7, /*!< 7 Watchdog interrupt */ + ADC_IRQn = 13, /*!< 13 ADC interrupt */ + I2C2_IRQn = 14, /*!< 14 I2C 2 interrupt */ + I2C1_IRQn = 15, /*!< 15 I2C 1 interrupt */ + MFT1A_IRQn = 17, /*!< 17 Multi functional timer MFT1 interrupt A */ + MFT1B_IRQn = 18, /*!< 18 Multi functional timer MFT1 interrupt B */ + MFT2A_IRQn = 19, /*!< 19 Multi functional timer MFT2 interrupt A */ + MFT2B_IRQn = 20, /*!< 20 Multi functional timer MFT2 interrupt B */ + RTC_IRQn = 21, /*!< 21 RTC interrupt */ + PKA_IRQn = 22, /*!< 22 PKA interrupt */ + DMA_IRQn = 23 /*!< 23 DMA interrupt */ +} IRQn_Type; + + + +/* =========================================================================================================================== */ +/* ================ Processor and Core Peripheral Section ================ */ +/* =========================================================================================================================== */ + +/* =========================== Configuration of the ARM Cortex-M0 Processor and Core Peripherals =========================== */ +#define __CM0_REV 0x0000U /*!< CM0 Core Revision */ +#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __FPU_PRESENT 0 /*!< FPU present or not */ + + +/** @} */ /* End of group Configuration_of_CMSIS */ + +#include "core_cm0.h" /*!< ARM Cortex-M0 processor and core peripherals */ +#include "system_BlueNRG1.h" /*!< BlueNRG1 System */ + +#ifndef __IM /*!< Fallback for older CMSIS versions */ + #define __IM __I +#endif +#ifndef __OM /*!< Fallback for older CMSIS versions */ + #define __OM __O +#endif +#ifndef __IOM /*!< Fallback for older CMSIS versions */ + #define __IOM __IO +#endif + + +/* ======================================== Start of section using anonymous unions ======================================== */ +#if defined (__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined (__ICCARM__) + #pragma language=extended +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" + #pragma clang diagnostic ignored "-Wgnu-anonymous-struct" + #pragma clang diagnostic ignored "-Wnested-anon-types" +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning 586 +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief GPIO Controller (GPIO) + */ + +typedef struct { /*!< (@ 0x40000000) GPIO Structure */ + __IOM uint32_t DATA; /*!< (@ 0x00000000) IO0 to IO14 data value.

Writing to a bit will + drive the written value on the corresponding + IO when it is configured in GPIO mode and + the output direction. Reading a bit indicates + the pin value

*/ + __IOM uint32_t OEN; /*!< (@ 0x00000004) GPIO output enable register (1 bit per GPIO).
  • 0: + input mode.
  • 1: output mode
*/ + __IOM uint32_t PE; /*!< (@ 0x00000008) Pull enable (1 bit per IO).
  • 0: pull disabled.
  • 1: + pull enabled
*/ + __IOM uint32_t DS; /*!< (@ 0x0000000C) IO driver strength (1 bit per IO).
  • 0: + 2mA.
  • 1: 4 mA
*/ + __IOM uint32_t IS; /*!< (@ 0x00000010) Interrupt sense register (1 bit per IO).
  • 0: + edge detection.
  • 1: level detection
*/ + __IOM uint32_t IBE; /*!< (@ 0x00000014) Interrupt edge register (1 bit per IO).
  • 0: + single edge.
  • 1: both edges
*/ + __IOM uint32_t IEV; /*!< (@ 0x00000018) Interrupt event register (1 bit per IO).
  • 0: + falling edge or low level.
  • 1: rising + edge or high level
*/ + __IOM uint32_t IE; /*!< (@ 0x0000001C) Interrupt mask register (1 bit per IO).
  • 0: + interrupt disabled.
  • 1: interrupt + enabled.
*/ + __IM uint32_t RIS; /*!< (@ 0x00000020) Raw interrupt status register (1 bit per IO) */ + __IM uint32_t MIS; /*!< (@ 0x00000024) Masked interrupt status register (1 bit per IO) */ + __OM uint32_t IC; /*!< (@ 0x00000028) Interrupt clear register (1 bit per IO).
  • 0: + no effect.
  • 1: clear interrupt
*/ + + union { + __IOM uint32_t MODE0; /*!< (@ 0x0000002C) Select mode for IO0 to IO7.
  • 000b: GPIO + mode.
  • 001b: Serial1 mode.
  • 100b: + Serial0 mode.
  • 101b: Microphone/ADC + mode.
*/ + + struct { + __IOM uint32_t IO0 : 3; /*!< [2..0] IO0 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO1 : 3; /*!< [6..4] IO1 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO2 : 3; /*!< [10..8] IO2 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO3 : 3; /*!< [14..12] IO3 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO4 : 3; /*!< [18..16] IO4 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO5 : 3; /*!< [22..20] IO5 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO6 : 3; /*!< [26..24] IO6 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO7 : 3; /*!< [30..28] IO7 mode */ + } MODE0_b; + } ; + + union { + __IOM uint32_t MODE1; /*!< (@ 0x00000030) Select mode for IO8 to IO14.
  • 000b: GPIO + mode.
  • 001b: Serial1 mode.
  • 100b: + Serial0 mode.
  • 101b: Microphone/ADC + mode.
*/ + + struct { + __IOM uint32_t IO8 : 3; /*!< [2..0] IO8 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO9 : 3; /*!< [6..4] IO9 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO10 : 3; /*!< [10..8] IO10 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO11 : 3; /*!< [14..12] IO11 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO12 : 3; /*!< [18..16] IO12 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO13 : 3; /*!< [22..20] IO13 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO14 : 3; /*!< [26..24] IO14 mode */ + } MODE1_b; + } ; + __IM uint32_t RESERVED[2]; + __IOM uint32_t DATS; /*!< (@ 0x0000003C) Set some bits of DATA when in GPIO mode without + affecting the others (1 bit per IO).
  • 0: + no effect.
  • 1: set at 1 the bit
*/ + __IOM uint32_t DATC; /*!< (@ 0x00000040) Clear some bits of DATA when in GPIO mode without + affecting the others (1 bit per IO).
  • 0: + no effect.
  • 1: clear at 0 the bit
*/ + + union { + __IOM uint32_t MFTX; /*!< (@ 0x00000044) Select the IO to be used as capture input for + the MFTX timers */ + + struct { + __IOM uint32_t MFT1_TIMER_A : 8; /*!< [7..0] Selects which IO must be used as input pin TnA for the + MFT1 peripheral. Only mode 2 and mode 4.
  • 0x00: IO0.
  • 0x01: + IO1
  • 0x02: IO2
  • ...
  • 0x0E: IO14
*/ + __IOM uint32_t MFT1_TIMER_B : 8; /*!< [15..8] Selects which IO must be used as input pin TnB for the + MFT1 peripheral. Only mode 2 and mode 4.
  • 0x00: IO0.
  • 0x01: + IO1
  • 0x02: IO2
  • ...
  • 0x0E: IO14
*/ + __IOM uint32_t MFT2_TIMER_A : 8; /*!< [23..16] Selects which IO must be used as input pin TnA for + the MFT2 peripheral. Only mode 2 and mode 4.
  • 0x00: + IO0.
  • 0x01: IO1
  • 0x02: IO2
  • ...
  • 0x0E: + IO14
*/ + __IOM uint32_t MFT2_TIMER_B : 8; /*!< [31..24] Selects which IO must be used as input pin TnB for + the MFT2 peripheral. Only mode 2 and mode 4.
  • 0x00: + IO0.
  • 0x01: IO1
  • 0x02: IO2
  • ...
  • 0x0E: + IO14
*/ + } MFTX_b; + } ; +} GPIO_Type; /*!< Size = 72 (0x48) */ + + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Flash Controller (FLASH) + */ + +typedef struct { /*!< (@ 0x40100000) FLASH Structure */ + __IOM uint16_t COMMAND; /*!< (@ 0x00000000) Commands for the module */ + __IM uint16_t RESERVED; + __IOM uint16_t CONFIG; /*!< (@ 0x00000004) Configure the wrapper */ + __IM uint16_t RESERVED1; + + union { + __IOM uint16_t IRQSTAT; /*!< (@ 0x00000008) Flash status interrupt (masked) */ + + struct { + __IOM uint16_t CMDDONE : 1; /*!< [0..0] Command is done. 1: clear the interrupt pending bit. */ + __IOM uint16_t CMDSTART : 1; /*!< [1..1] Command is started. 1: clear the interrupt pending bit. */ + __IOM uint16_t CMDERR : 1; /*!< [2..2] Command written while BUSY. 1: clear the interrupt pending + bit. */ + __IOM uint16_t ILLCMD : 1; /*!< [3..3] Illegal command written. 1: clear the interrupt pending + bit. */ + __IOM uint16_t READOK : 1; /*!< [4..4] Mass read was OK. 1: clear the interrupt pending bit. */ + __IOM uint16_t FLNREADY : 1; /*!< [5..5] Flash not ready (sleep). 1: clear the interrupt pending + bit. */ + } IRQSTAT_b; + } ; + __IM uint16_t RESERVED2; + + union { + __IOM uint16_t IRQMASK; /*!< (@ 0x0000000C) Mask for interrupts */ + + struct { + __IOM uint16_t CMDDONE : 1; /*!< [0..0] Command is done. */ + __IOM uint16_t CMDSTART : 1; /*!< [1..1] Command is started. */ + __IOM uint16_t CMDERR : 1; /*!< [2..2] Command written while BUSY */ + __IOM uint16_t ILLCMD : 1; /*!< [3..3] Illegal command written */ + __IOM uint16_t READOK : 1; /*!< [4..4] Mass read was OK. */ + __IOM uint16_t FLNREADY : 1; /*!< [5..5] Flash not ready (sleep). */ + } IRQMASK_b; + } ; + __IM uint16_t RESERVED3; + + union { + __IOM uint16_t IRQRAW; /*!< (@ 0x00000010) Status interrupts (unmasked) */ + + struct { + __IOM uint16_t CMDDONE : 1; /*!< [0..0] Command is done. */ + __IOM uint16_t CMDSTART : 1; /*!< [1..1] Command is started. */ + __IOM uint16_t CMDERR : 1; /*!< [2..2] Command written while BUSY */ + __IOM uint16_t ILLCMD : 1; /*!< [3..3] Illegal command written */ + __IOM uint16_t READOK : 1; /*!< [4..4] Mass read was OK. */ + __IOM uint16_t FLNREADY : 1; /*!< [5..5] Flash not ready (sleep). */ + } IRQRAW_b; + } ; + __IM uint16_t RESERVED4; + __IM uint16_t SIZE; /*!< (@ 0x00000014) Indicates the size of the main Flash */ + __IM uint16_t RESERVED5; + __IOM uint32_t ADDRESS; /*!< (@ 0x00000018) Address for programming Flash, will auto-increment */ + __IM uint32_t RESERVED6[9]; + __IOM uint32_t DATA0; /*!< (@ 0x00000040) Program cycle data */ + __IOM uint32_t DATA1; /*!< (@ 0x00000044) Program cycle data */ + __IOM uint32_t DATA2; /*!< (@ 0x00000048) Program cycle data */ + __IOM uint32_t DATA3; /*!< (@ 0x0000004C) Program cycle data */ +} FLASH_Type; /*!< Size = 80 (0x50) */ + + + +/* =========================================================================================================================== */ +/* ================ SYSTEM_CTRL ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief System controller (SYSTEM_CTRL) + */ + +typedef struct { /*!< (@ 0x40200000) SYSTEM_CTRL Structure */ + __IOM uint8_t WKP_IO_IS; /*!< (@ 0x00000000) Level selection for wakeup IO (1 bit for IO) + IO[13:9].
  • 0: The system wakes up + when IO is low.
  • 1: The system wakes + up when IO is high.
*/ + __IM uint8_t RESERVED[3]; + __IOM uint8_t WKP_IO_IE; /*!< (@ 0x00000004) Enables the IO that wakes up the device (1 bit + for IO) IO[13:9].
  • 0: The wakes up + feature on the IO is disabled.
  • 1: + The wakes up feature on the IO is enabled.
*/ + __IM uint8_t RESERVED1[3]; + + union { + __IOM uint8_t CTRL; /*!< (@ 0x00000008) XO frequency indication to provide by the application */ + + struct { + __IOM uint8_t MHZ32_SEL : 1; /*!< [0..0] Indicates the crystal frequency used in the application.
  • 0: + The 16 MHz is selected.
  • 1: The 32 MHz is selected.
*/ + } CTRL_b; + } ; +} SYSTEM_CTRL_Type; /*!< Size = 9 (0x9) */ + + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief UART (UART) + */ + +typedef struct { /*!< (@ 0x40300000) UART Structure */ + + union { + __IOM uint16_t DR; /*!< (@ 0x00000000) Data Register */ + + struct { + __IOM uint16_t DATA : 8; /*!< [7..0] UART data register:
  • Receive: read data character.
  • Trans + it: write data character.
*/ + __IM uint16_t FE : 1; /*!< [8..8] Frame error. This bit is set to 1 if the received character + did not have a valid stop bit. In FIFO mode, this error + is associated with the character at the top of the FIFO. */ + __IM uint16_t PE : 1; /*!< [9..9] Parity error. This bit is set to 1 if the parity of the + received data character does not match the parity selected + as defined by bits 2 and 7 of the LCRH_RX register. In + FIFO mode, this error is associated with the character + at the top of the FIFO. */ + __IM uint16_t BE : 1; /*!< [10..10] Break error. This bit is set to 1 if a break condition + was detected, indicating that the received data input was + held low for longer than a full-word transmission time + (defined as start, data, parity and stop bits). In FIFO + mode, this error is associated with the character at the + top of the FIFO. When a break occurs, only one 0 character + is loaded into the FIFO. The next character is only enabled + after the receive data input goes to HIGH (marking state), + and the next valid start bit is received */ + __IM uint16_t OE : 1; /*!< [11..11] Overrun error. This bit is set to 1 if data is received + and the receive FIFO is already full. This is cleared to + 0b once there is an empty space in the FIFO and a new character + can be written to it. The FIFO content remains valid since + no further data is written when the FIFO is full, only + the content of the shift register is overwritten. */ + } DR_b; + } ; + __IM uint16_t RESERVED; + + union { + union { + __IM uint32_t RSR; /*!< (@ 0x00000004) Receive Status Register */ + + struct { + __IM uint32_t FE : 1; /*!< [0..0] Frame error. This bit is set to 1 if the received character + did not have a valid stop bit (a valid stop bit is 1).This + bit is cleared to 0b after a write to ECR. In FIFO mode, + this error is associated with the character at the top + of the FIFO. */ + __IM uint32_t PE : 1; /*!< [1..1] Parity error. This bit is set to 1 if the parity of the + received data character does not match the parity selected + as defined by bits 2 and 7 of the LCRH_RX register.This + bit is cleared to 0b after a write to ECR. In FIFO mode, + this error is associated with the character at the top + of the FIFO. */ + __IM uint32_t BE : 1; /*!< [2..2] Break error. This bit is set to 1 if a break condition + was detected, indicating that the received data input was + held low for longer than a full-word transmission time + (defined as start, data, parity and stop bits). This bit + is cleared to 0b after a write to ECR. In FIFO mode, this + error is associated with the character at the top of the + FIFO. When a break occurs, only one 0 character is loaded + into the FIFO. The next character is only enabled after + the receive data input goes to HIGH (marking state), and + */ + __IM uint32_t OE : 1; /*!< [3..3] Overrun error. This bit is set to 1 if data is received + and the receive FIFO is already full. This is cleared to + 0 by a write to ECR (data value is not important). The + FIFO contents remain valid since no further data is written + when the FIFO is full, only the content of the shift register + are overwritten. The CPU or DMA must now read the data + in order to empty the FIFO. */ + } RSR_b; + } ; + __IOM uint32_t ECR; /*!< (@ 0x00000004) Error Clear Register. A write to this register + clears the framing (FE), parity (PE), break + (BE), and overrun (OE) errors. */ + }; + __IM uint32_t RESERVED1; + + union { + __IOM uint32_t TIMEOUT; /*!< (@ 0x0000000C) Timeout Register */ + + struct { + __IOM uint32_t PERIOD : 22; /*!< [21..0] Timeout period configuration. This bit field contains + the timeout period for the UART timeout interrupt assertion. + The receive timeout interrupt is asserted when the receive + FIFO is not empty and no further data is received over + a programmed timeout period. The duration before the timeout + interrupt will assert is calculated by the following formula:

Timeout_D + ration = (TIMEOUT_PERIOD) / (OVSP * Baud_Rate)

or

Timeout_Duration + = (TIMEOUT_PERIOD) * Baud_Divisor * Tuartclk

*/ + } TIMEOUT_b; + } ; + __IM uint32_t RESERVED2[2]; + + union { + __IM uint16_t FR; /*!< (@ 0x00000018) Flag Register */ + + struct { + __IM uint16_t CTS : 1; /*!< [0..0] Clear to send. */ + __IM uint16_t : 2; + __IM uint16_t BUSY : 1; /*!< [3..3] UART Busy. If this bit is set to 1, the UART is busy + transmitting data. This bit remains set until the complete + byte, including all the stop bits, has been sent from the + shift register. However, if the transmit section of the + UART is disabled in the middle of a transmission, the BUSY + bit gets cleared. This bit is set again once the transmit + section is re-enabled to complete the remaining transmission.This + bit is set as soon as the transmit FIFO becomes nonempty + (regardless of whether the UART is enabled or */ + __IM uint16_t RXFE : 1; /*!< [4..4] Receive FIFO empty. If the FIFO is disabled (bit FEN + = 0b), this bit is set when the receive holding register + is empty. If the FIFO is enabled (FEN = 1b), the RXFE bit + is set when the receive FIFO is empty. */ + __IM uint16_t TXFF : 1; /*!< [5..5] Transmit FIFO full. If the FIFO is disabled (bit FEN + = 0b), this bit is set when the transmit holding register + is full. If the FIFO is enabled (FEN = 1b), the TXFF bit + is set when the transmit FIFO is full. */ + __IM uint16_t RXFF : 1; /*!< [6..6] Receive FIFO full. If the FIFO is disabled (bit FEN = + 0b), this bit is set when the receive holding register + is full. If the FIFO is enabled (FEN = 1b), the RXFF bit + is set when the receive FIFO is full. */ + __IM uint16_t TXFE : 1; /*!< [7..7] Transmit FIFO empty. If the FIFO is disabled (bit FEN + = 0b), this bit is set when the transmit holding register + is empty. If the FIFO is enabled (FEN = 1b), the TXFE bit + is set when the transmit FIFO is empty. */ + __IM uint16_t : 1; + __IM uint16_t DCTS : 1; /*!< [9..9] Delta Clear To Send. This bit is set CTS changes since + the last read of the FR register. */ + __IM uint16_t : 3; + __IM uint16_t RTXDIS : 1; /*!< [13..13] Remote Transmitter Disabled (software flow control). + This bit indicates an Xoff character was sent to the remote + transmitter to stop it after the received FIFO has passed + over its trigger limit. This bit is cleared when a Xon + character is sent to the remote transmitter. */ + } FR_b; + } ; + __IM uint16_t RESERVED3; + + union { + __IOM uint8_t LCRH_RX; /*!< (@ 0x0000001C) Receive Line Control Register */ + + struct { + __IM uint8_t : 1; + __IOM uint8_t PEN_RX : 1; /*!< [1..1] RX parity enable:
  • 0: Parity disabled.
  • 1: + Parity enabled.
*/ + __IOM uint8_t EPS_RX : 1; /*!< [2..2] RX even parity selection, when the parity is enabled.
  • 0: + Odd parity generation and checking is performed during + reception, which check for an odd number of 1s in data + and parity bits.
  • 1: Even parity generation and + checking is performed during reception, which check for + an even number of 1s in data and parity bits.
*/ + __IOM uint8_t STP2_RX : 1; /*!< [3..3] RX two stop bits select. This bit enables the check for + two stop bits being received:
  • 0: 1 stop bit received.
  • 1: + 2 stop bits received.
*/ + __IOM uint8_t FEN_RX : 1; /*!< [4..4] RX enable FIFOs. This bit enables/disables the receive + RX FIFO buffer:
  • 0: RX FIFO is disabled (character + mode).
  • 1: RX FIFO is enabled.
*/ + __IOM uint8_t WLEN_RX : 2; /*!< [6..5] RX Word length. This bit field indicates the number of + data bits received in a frame as follows:
  • 00b: 5 + bits.
  • 01b: 6 bits.
  • 10b: 7 bits.
  • 11b: + 8 bits.
*/ + __IOM uint8_t SPS_RX : 1; /*!< [7..7] RX stick parity select:
  • 0: stick parity is disabled.
  • 1: + when PEN_RX = 1b (parity enabled) and EPS_RX = 1b (even + parity), the parity is checked as a 0. When PEN_RX = 1b + and EPS_RX = 0b (odd parity), the parity bit is checked + as a 1.
*/ + } LCRH_RX_b; + } ; + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + __IM uint32_t RESERVED6; + + union { + __IOM uint16_t IBRD; /*!< (@ 0x00000024) Integer Baud Rate Register */ + + struct { + __IOM uint16_t DIVINT : 16; /*!< [15..0] Baud rate integer. The baud rate divisor is calculated + as follows:

When OVSFACT = 0b in the CR register: Baud + rate divisor = (Frequency (UARTCLK)/(16*Baud rate))

When + OVSFACT = 1b in CR register: Baud rate divisor = (Frequency + (UARTCLK)/(8*Baud rate))

where Frequency (UARTCLK) is + the UART reference clock frequency. The baud rate divisor + comprises the integer value (DIVINT) and the fractional + value (DIVFRAC). The contents of the IBRD and FBRD registers + are not updated until transmission or recept */ + } IBRD_b; + } ; + __IM uint16_t RESERVED7; + + union { + __IOM uint8_t FBRD; /*!< (@ 0x00000028) Fractional Baud Rate Register */ + + struct { + __IOM uint8_t DIVFRAC : 6; /*!< [5..0] Baud rate fraction. Baud rate integer. The baud rate + divisor is calculated as follows:

When OVSFACT = 0b in + the CR register: Baud rate divisor = (Frequency (UARTCLK)/(16*Baud + rate))

When OVSFACT = 1b in CR register: Baud rate + divisor = (Frequency (UARTCLK)/(8*Baud rate))

where + Frequency (UARTCLK) is the UART reference clock frequency. + The baud rate divisor comprises the integer value (DIVINT) + and the fractional value (DIVFRAC). The contents of the + IBRD and FBRD registers are not updated until tr */ + } FBRD_b; + } ; + __IM uint8_t RESERVED8; + __IM uint16_t RESERVED9; + + union { + __IOM uint8_t LCRH_TX; /*!< (@ 0x0000002C) Transmit Line Control Register */ + + struct { + __IOM uint8_t BRK : 1; /*!< [0..0] Send break. This bit allows a continuous low-level to + be forced on TX output, after completion of the current + character. This bit must be asserted for at least one complete + frame transmission time in order to generate a break condition. + The transmit FIFO contents remain unaffected during a break + condition.
  • 0: Normal transmission.
  • 1: Break + condition transmission.
*/ + __IOM uint8_t PEN_TX : 1; /*!< [1..1] TX parity enable:
  • 0: Parity disabled.
  • 1: + Parity Enable.
*/ + __IOM uint8_t EPS_TX : 1; /*!< [2..2] TX even parity select. This bit selects the parity generation, + when the parity is enabled (PEN_TX =1b). This bit has no + effect when parity is disabled (PEN_TX = 0b).
  • 0: + Odd parity generation and checking is performed during + transmission, which check for an odd number of 1s in data + and parity bits.
  • 1: Even parity generation and + checking is performed during transmission, which check + for an even number of 1s in data and parity bits.
*/ + __IOM uint8_t STP2_TX : 1; /*!< [3..3] TX two stop bits select. This bit enables the check for + two stop bits being received:
  • 0: 1 stop bit received.
  • 1: + 2 stop bits received.
*/ + __IOM uint8_t FEN_TX : 1; /*!< [4..4] TX Enable FIFO. This bit enables/disables the transmit + TX FIFO buffer:
  • 0: TX FIFO is disabled (character + mode), i.e. the TX FIFO becomes a 1-byte deep holding register.
  • 1 + TX FIFO is enabled.
*/ + __IOM uint8_t WLEN_TX : 2; /*!< [6..5] TX word length. This bit field indicates the number of + data bits transmitted in a frame as follows:
  • 00b: + 5 bits.
  • 01b: 6 bits.
  • 10b: 7 bits.
  • 11b: + 8 bits.
*/ + __IOM uint8_t SPS_TX : 1; /*!< [7..7] TX Stick parity check:
  • 0: stick parity disable.
  • 1: + when PEN_TX = 1b (parity enabled) and EPS_TX = 1b (even + parity), the parity is transmitted as a 0. When PEN_TX + = 1b and EPS_TX = 0b (odd parity), the parity bit is transmitted + as a 1.
*/ + } LCRH_TX_b; + } ; + __IM uint8_t RESERVED10; + __IM uint16_t RESERVED11; + + union { + __IOM uint32_t CR; /*!< (@ 0x00000030) Control Register */ + + struct { + __IOM uint32_t EN : 1; /*!< [0..0] UART enable. This bit enables the UART.
  • 0: UART + is disabled.
  • 1: UART is enabled. Data transmission + and reception can occur. When the UART is disabled in the + middle of transmission or reception, it completes the current + character before stopping.
*/ + __IM uint32_t : 2; + __IOM uint32_t OVSFACT : 1; /*!< [3..3] UART oversampling factor.This bit enables the UART oversampling + factor. If UARTCLK is 16 MHz thus max. baud-rate is 1 Mbaud + when OVSFACT = 0b, and 2 Mbaud when OVSFACT = 1b.
  • 0: + UART it is 16 UARTCLK clock cycles.
  • 1: UART it + is 8 UARTCLK clock cycles.
*/ + __IM uint32_t : 4; + __IOM uint32_t TXE : 1; /*!< [8..8] Transmit enable.
  • 0b: UART TX disabled.
  • 1b: + UART TX enabled.
*/ + __IOM uint32_t RXE : 1; /*!< [9..9] Receive enable.
  • 0b: UART RX disabled.
  • 1b: + UART RX enabled.
*/ + __IM uint32_t : 1; + __IOM uint32_t RTS : 1; /*!< [11..11] Request to send.
  • 0: RTS is high.
  • 1: + RTS is low.
*/ + __IM uint32_t : 2; + __IOM uint32_t RTSEN : 1; /*!< [14..14] RTS hardware flow control enable.
  • 0b: RTS disabled.
  • 1b + RTS enabled. Data is only requested when there is space + in the receive FIFO for it to be received.
*/ + __IOM uint32_t CTSEN : 1; /*!< [15..15] CTS hardware flow control enable.
  • 0b: CTS disabled.
  • 1b + CTS enabled. Data is only transmitted when the CTS is asserted.
+ */ + __IOM uint32_t STA_B_DURATION : 4; /*!< [19..16] START bit duration Receiver state. These bits can be + used to configure the START bit duration (in clock cycles) + to get the bit sampled in the middle of the UART receiver. + These bits can be used only when using high baud rates + (IBRD = 1, FBRD >= 0 and OVSFACT = 1). Below the formula + to calculate the START bit duration receiver state:

STA_B_DURATION + = Integer(Fuartclk/(2* BAUD RATE)) - 1

Example: when + UARTCLK = 16 MHz and BAUD RATE = 2.0 Mbps then STA_B_DURATION + = 4 - 1 = 3. STA_B_DURATION field should */ + } CR_b; + } ; + + union { + __IOM uint8_t IFLS; /*!< (@ 0x00000034) Interrupt FIFO level select register */ + + struct { + __IOM uint8_t TXIFLSEL : 3; /*!< [2..0] Transmit interrupt FIFO level select. This bit field + selects the trigger points for TX FIFO interrupt:
  • 000b: + Interrupt when FIFO >= 1/64 empty.
  • 001b: Interrupt + when FIFO >= 1/32 empty.
  • 010b: Interrupt when FIFO + >= 1/16 empty.
  • 011b: Interrupt when FIFO >= 1/8 + empty.
  • 100b: Interrupt when FIFO >= 1/4 empty.
  • 101b: + Interrupt when FIFO >= 1/2 empty.
  • 110b: Interrupt + when FIFO >= 3/4 empty.
*/ + __IOM uint8_t RXIFLSEL : 3; /*!< [5..3] Receive interrupt FIFO level select. This bit field selects + the trigger points for RX FIFO interrupt:
  • 000b: + Interrupt when FIFO >= 1/64 full.
  • 001b: Interrupt + when FIFO >= 1/32 full.
  • 010b: Interrupt when FIFO + >= 1/16 full.
  • 011b: Interrupt when FIFO >= 1/8 + full.
  • 100b: Interrupt when FIFO >= 1/4 full.
  • 101b: + Interrupt when FIFO >= 1/2 full.
  • 110b: Interrupt + when FIFO >= 3/4 full.
*/ + } IFLS_b; + } ; + __IM uint8_t RESERVED12; + __IM uint16_t RESERVED13; + + union { + __IOM uint16_t IMSC; /*!< (@ 0x00000038) Interrupt Mask Set/Clear Register */ + + struct { + __IM uint16_t : 1; + __IOM uint16_t CTSMIM : 1; /*!< [1..1] Clear to send modem interrupt mask. On a read, the current + mask for the CTSMIM interrupt is returned.
  • 0: Clears + the mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + __IM uint16_t : 2; + __IOM uint16_t RXIM : 1; /*!< [4..4] Receive interrupt mask. On a read, the current mask for + the RXIM interrupt is returned.
  • 0: Clears the mask + (interrupt is disabled).
  • 1: Sets the mask (interrupt + is enabled).
*/ + __IOM uint16_t TXIM : 1; /*!< [5..5] Transmit interrupt mask. On a read, the current mask + for the TXIM interrupt is returned.
  • 0: Clears the + mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + __IOM uint16_t RTIM : 1; /*!< [6..6] Receive timeout interrupt mask. On a read, the current + mask for the RTIM interrupt is returned.
  • 0: Clears + the mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + __IOM uint16_t FEIM : 1; /*!< [7..7] Framing error interrupt mask. On a read, the current + mask for the FEIM interrupt is returned.
  • 0: Clears + the mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + __IOM uint16_t PEIM : 1; /*!< [8..8] Parity error interrupt mask. On a read, the current mask + for the PEIM interrupt is returned.
  • 0: Clears the + mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + __IOM uint16_t BEIM : 1; /*!< [9..9] Break error interrupt mask. On a read, the current mask + for the BEIM interrupt is returned.
  • 0: Clears the + mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + __IOM uint16_t OEIM : 1; /*!< [10..10] Overrun error interrupt mask. On a read, the current + mask for the OEIM interrupt is returned.
  • 0: Clears + the mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + __IOM uint16_t XOFFIM : 1; /*!< [11..11] XOFF interrupt mask. On a read, the current mask for + the XOFFIM interrupt is returned.
  • 0: Clears the + mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + __IOM uint16_t TXFEIM : 1; /*!< [12..12] TX FIFO empty interrupt mask. On a read, the current + mask for the TXFEIM interrupt is returned.
  • 0: Clears + the mask (interrupt is disabled).
  • 1: Sets the mask + (interrupt is enabled).
*/ + } IMSC_b; + } ; + __IM uint16_t RESERVED14; + + union { + __IM uint16_t RIS; /*!< (@ 0x0000003C) Raw Interrupt Status Register */ + + struct { + __IM uint16_t : 1; + __IM uint16_t CTSMIS : 1; /*!< [1..1] Clear to send interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t : 2; + __IM uint16_t RXIS : 1; /*!< [4..4] Receive interrupt status.
  • 0: The interrupt is + not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t TXIM : 1; /*!< [5..5] Transmit interrupt status.
  • 0: The interrupt is + not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t RTIS : 1; /*!< [6..6] Receive timeout interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t FEIS : 1; /*!< [7..7] Framing error interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t PEIS : 1; /*!< [8..8] Parity error interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t BEIS : 1; /*!< [9..9] Break error interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t OEIS : 1; /*!< [10..10] Overrun error interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t XOFFIS : 1; /*!< [11..11] XOFF interrupt status.
  • 0: The interrupt is not + pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t TXFEIS : 1; /*!< [12..12] TX FIFO empty interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + } RIS_b; + } ; + __IM uint16_t RESERVED15; + + union { + __IM uint16_t MIS; /*!< (@ 0x00000040) Masked Interrupt Status Register */ + + struct { + __IM uint16_t : 1; + __IM uint16_t CTSMMIS : 1; /*!< [1..1] Clear to send masked interrupt status.
  • 0: The + interrupt is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t : 2; + __IM uint16_t RXMIS : 1; /*!< [4..4] Receive masked interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t TXMIS : 1; /*!< [5..5] Transmit masked interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t RTMIS : 1; /*!< [6..6] Receive timeout masked interrupt status.
  • 0: The + interrupt is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t FEMIS : 1; /*!< [7..7] Framing error masked interrupt status.
  • 0: The + interrupt is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t PEMIS : 1; /*!< [8..8] Parity error masked interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t BEMIS : 1; /*!< [9..9] Break error masked interrupt status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t OEMIS : 1; /*!< [10..10] Overrun error masked interrupt status.
  • 0: The + interrupt is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t XOFFMIS : 1; /*!< [11..11] XOFF interrupt masked status.
  • 0: The interrupt + is not pending.
  • 1: The interrupt is pending.
*/ + __IM uint16_t TXFEMIS : 1; /*!< [12..12] TX FIFO empty masked interrupt status.
  • 0: The + interrupt is not pending.
  • 1: The interrupt is pending.
*/ + } MIS_b; + } ; + __IM uint16_t RESERVED16; + + union { + __OM uint16_t ICR; /*!< (@ 0x00000044) Interrupt Clear Register */ + + struct { + __IM uint16_t : 1; + __OM uint16_t CTSMIC : 1; /*!< [1..1] Clear to send modem interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __IM uint16_t : 2; + __OM uint16_t RXIC : 1; /*!< [4..4] Receive interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __OM uint16_t TXIC : 1; /*!< [5..5] Transmit interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __OM uint16_t RTIC : 1; /*!< [6..6] Receive timeout interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __OM uint16_t FEIC : 1; /*!< [7..7] Framing error interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __OM uint16_t PEIC : 1; /*!< [8..8] Parity error interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __OM uint16_t BEIC : 1; /*!< [9..9] Break error interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __OM uint16_t OEIC : 1; /*!< [10..10] Overrun error interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __OM uint16_t XOFFIC : 1; /*!< [11..11] XOFF interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + __OM uint16_t TXFEIC : 1; /*!< [12..12] TX FIFO empty interrupt clear.
  • 0: No effect.
  • 1: + Clears the interrupt.
*/ + } ICR_b; + } ; + __IM uint16_t RESERVED17; + + union { + __IOM uint8_t DMACR; /*!< (@ 0x00000048) DMA control register */ + + struct { + __IOM uint8_t RXDMAE : 1; /*!< [0..0] Receive DMA enable bit.
  • 0: DMA mode is disabled + for reception.
  • 1: DMA mode is enabled for reception.
*/ + __IOM uint8_t TXDMAE : 1; /*!< [1..1] Transmit DMA enable bit.
  • 0: DMA mode is disabled + for transmit.
  • 1: DMA mode is enabled for transmit.
*/ + __IM uint8_t : 1; + __IOM uint8_t DMAONERR : 1; /*!< [3..3] DMA on error.
  • 0: UART error interrupt status has + no impact in receive DMA mode.
  • 1: DMA receive requests + are disabled when the UART error interrupt is asserted.
*/ + } DMACR_b; + } ; + __IM uint8_t RESERVED18; + __IM uint16_t RESERVED19; + __IM uint32_t RESERVED20; + + union { + __IOM uint8_t XFCR; /*!< (@ 0x00000050) XON/XOFF Control Register */ + + struct { + __IOM uint8_t SFEN : 1; /*!< [0..0] Software flow control enable.
  • 0: Software flow + control disable.
  • 1: software flow control enable.
*/ + __IOM uint8_t SFRMOD : 2; /*!< [2..1] Software receive flow control mode:
  • 00b: Receive + flow control is disabled.
  • 01b: Xon1, Xoff1 characters + are used in receiving software flow control.
  • 10b: + Xon2, Xoff2 characters are used in receiving software flow + control.
  • 11b: Xon1 and Xon2, Xoff1 and Xoff2 characters + are used in receiving software flow control.
*/ + __IOM uint8_t SFTMOD : 2; /*!< [4..3] Software transmit flow control mode:
  • 00b: Transmit + flow control is disabled.
  • 01b: Xon1, Xoff1 characters + are used in transmitting software flow control.
  • 10b: + Xon2, Xoff2 characters are used in transmitting software + flow control.
  • 11b: Xon1 and Xon2, Xoff1 and Xoff2 + characters are used in transmitting software flow control.
*/ + __IOM uint8_t XONANY : 1; /*!< [5..5] Xon-any bit:
  • 0: Incoming character must match + Xon programmed value(s) to be a valid Xon.
  • 1: Any + incoming character is considered as a valid Xon.
*/ + __IOM uint8_t SPECHAR : 1; /*!< [6..6] Special character detection bit.
  • 0: Special character + detection disabled.
  • 1: Special character detection + enabled.
*/ + } XFCR_b; + } ; + __IM uint8_t RESERVED21; + __IM uint16_t RESERVED22; + + union { + __IOM uint8_t XON1; /*!< (@ 0x00000054) Register used to store the Xon1 character used + for software flow control */ + + struct { + __IOM uint8_t XON1 : 8; /*!< [7..0] Value of Xon1 character used in the software flow control */ + } XON1_b; + } ; + __IM uint8_t RESERVED23; + __IM uint16_t RESERVED24; + + union { + __IOM uint8_t XON2; /*!< (@ 0x00000058) Register used to store the Xon2 character used + for software flow control */ + + struct { + __IOM uint8_t XON2 : 8; /*!< [7..0] Value of Xon2 character used in the software flow control */ + } XON2_b; + } ; + __IM uint8_t RESERVED25; + __IM uint16_t RESERVED26; + + union { + __IOM uint8_t XOFF1; /*!< (@ 0x0000005C) Register used to store the Xoff1 character used + for software flow control */ + + struct { + __IOM uint8_t XOFF1 : 8; /*!< [7..0] Value of Xoff1 character used in the software flow control */ + } XOFF1_b; + } ; + __IM uint8_t RESERVED27; + __IM uint16_t RESERVED28; + + union { + __IOM uint8_t XOFF2; /*!< (@ 0x00000060) Register used to store the Xoff2 character used + for software flow control */ + + struct { + __IOM uint8_t XOFF2 : 8; /*!< [7..0] Value of Xoff2 character used in the software flow control */ + } XOFF2_b; + } ; + __IM uint8_t RESERVED29; + __IM uint16_t RESERVED30; +} UART_Type; /*!< Size = 100 (0x64) */ + + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Serial peripheral interface (SPI) + */ + +typedef struct { /*!< (@ 0x40400000) SPI Structure */ + + union { + __IOM uint32_t CR0; /*!< (@ 0x00000000) Control Register 0 */ + + struct { + __IOM uint32_t DSS : 5; /*!< [4..0] Data size select. (DSS+1) defines the number of bits:
  • 0x00: + Reserved.
  • 0x01: Reserved.
  • 0x02: Reserved.
  • 0x03: + 4-bit data.
  • 0x04: 5-bit data.
  • ...
  • 0x1F: + 32-bit data.
*/ + __IM uint32_t : 1; + __IOM uint32_t SPO : 1; /*!< [6..6] Clock polarity.
  • 0: Steady state of clock polarity + is low.
  • 1: Steady state of clock polarity is high.
*/ + __IOM uint32_t SPH : 1; /*!< [7..7] Clock phase.
  • 0: Steady state of clock phase is + low.
  • 1: Steady state of clock phase is high.
*/ + __IOM uint32_t SCR : 8; /*!< [15..8] Serial Clock Rate.

The SRC value is used to generate + the transmit and receive bit rate of the SPI. The bit rate + is: f_SPICLK / (CPSDVR * (1 + SCR)), where CPSDVR is an + even value from 2 to 254 and SCR is a value from 0 to 255.

*/ + __IOM uint32_t CSS : 5; /*!< [20..16] Command Size Select (in MicroWire mode). (CSS+1) defines + the number of bits:
  • 0x00: Reserved.
  • 0x01: + Reserved.
  • 0x02: Reserved.
  • 0x03: 4-bit data.
  • 0x04: + 5-bit data.
  • ...
  • 0x1F: 32-bit data.
*/ + __IOM uint32_t FRF : 2; /*!< [22..21] Frame format.
  • 00b: Motorola SPI frame format.
  • 10b: + National MicroWire frame format.
*/ + __IOM uint32_t SPIM : 2; /*!< [24..23] SPI transmission mode.
  • 00b: Full duplex mode.
  • 01b: + Transmit mode.
  • 10b: Receive mode.
  • 11b: + Combined mode.
*/ + __IM uint32_t : 1; + __IOM uint32_t CS1 : 1; /*!< [26..26] Chip Selection for slave one
  • 0: the slave 1 + is selected.
  • 1: the slave 1 is not selected.
*/ + } CR0_b; + } ; + + union { + __IOM uint32_t CR1; /*!< (@ 0x00000004) Control Register 1 */ + + struct { + __IM uint32_t : 1; + __IOM uint32_t SSE : 1; /*!< [1..1] SPI enable.
  • 0: SPI disable.
  • 1: SPI enable.
*/ + __IOM uint32_t MS : 1; /*!< [2..2] Master or slave mode select.
  • 0: Master mode.
  • 1: + Slave mode.
*/ + __IOM uint32_t SOD : 1; /*!< [3..3] Slave mode output disable (slave mode only).
  • 0: + SPI can drive the MISO signal in slave mode.
  • 1: + SPI must not drive the MISO signal in slave mode.
In + multiple slave system, it is possible for a SPI master + to broadcast a message to all slaves in the system while + ensuring only one slave drives data onto the serial output + line MISO. */ + __IOM uint32_t RENDN : 2; /*!< [5..4] Receive endian format.
  • 00b: The element is received + MSByte-first and MSbit-first.
  • 01b: The element + is received LSByte-first and MSbit-first.
  • 10b: + The element is received MSByte-first and LSbit-first.
  • 11b: + The element is received LSByte-first and LSbit-first.
The + cases 00b and 11b are set for data frame size from 4 to + 32 bits. The cases 01b and 10b are set only for data frame + size 16, 24 and 32 bits. */ + __IOM uint32_t MWAIT : 1; /*!< [6..6] MicroWire Wait Sate Bit Enable */ + __IOM uint32_t RXIFLSEL : 3; /*!< [9..7] Receive interrupt FIFO level select. This bit field selects + the trigger points to receive FIFO interrupt:
  • 000b: + RX FIFO contains 1 element or more.
  • 001b: RX FIFO + contains 4 elements or more.
  • 010b: RX FIFO contains + 8 elements or more.
  • Others: Reserved.
*/ + __IOM uint32_t TXIFLSEL : 3; /*!< [12..10] Transmit interrupt FIFO level select. This bit field + selects the trigger points to transmit FIFO interrupt:
  • 000b: + TX FIFO contains 1 element or more.
  • 001b: TX FIFO + contains 4 elements or more.
  • 010b: TX FIFO contains + 8 elements or more.
  • Others: Reserved.
*/ + __IM uint32_t : 1; + __IOM uint32_t MSPIWAIT : 4; /*!< [17..14] SPI Wait mode. This value is used to insert a wait + state between frames. */ + __IOM uint32_t TENDN : 2; /*!< [19..18] Transmit endian format.
  • 00b: The element is + transmitted MSByte-first and MSbit-first.
  • 01b: + The element is transmitted LSByte-first and MSbit-first.
  • 10b: + The element is transmitted MSByte-first and LSbit-first.
  • 11b: + The element is transmitted LSByte-first and LSbit-first.
The + cases 00b and 11b are set for data frame size from 4 to + 32 bits. The cases 01b and 10b are set only for data frame + size 16, 24 and 32 bits. */ + __IM uint32_t : 1; + __IOM uint32_t DATAINDEL : 1; /*!< [21..21] Data input delay.
  • 0: No delay is inserted in + data input.
  • 1: A delay of 2 clock cycles is inserted + in the data input path.
*/ + } CR1_b; + } ; + + union { + __IOM uint32_t DR; /*!< (@ 0x00000008) Data Register */ + + struct { + __IOM uint32_t DATA : 32; /*!< [31..0] Transmit/Receive data:
  • Read: RX FIFO is read.
  • Write: + TX FIFO is written.
Data must be right-justified + when a data size of less than 32-bit is programmed. Unused + bits are ignored by the transmit logic. The receive logic + automatically right-justifies data. */ + } DR_b; + } ; + + union { + __IM uint8_t SR; /*!< (@ 0x0000000C) Status Register */ + + struct { + __IM uint8_t TFE : 1; /*!< [0..0] Transmit FIFO empty:
  • 0: TX FIFO is not empty.
  • 1: + TX FIFO is empty.
*/ + __IM uint8_t TNF : 1; /*!< [1..1] Transmit FIFO not full:
  • 0: TX FIFO is full.
  • 1: + TX FIFO is not full.
*/ + __IM uint8_t RNE : 1; /*!< [2..2] Receive FIFO not empty:
  • 0: RX FIFO is empty.
  • 1: + RX FIFO is not empty.
*/ + __IM uint8_t RFF : 1; /*!< [3..3] Receive FIFO full:
  • 0: RX FIFO is not full.
  • 1: + RX FIFO is full.
*/ + __IM uint8_t BSY : 1; /*!< [4..4] SPI busy flag:
  • 0: SPI is idle.
  • 1: SPI + is currently transmitting and/or receiving a frame or the + TX FIFO is not empty.
*/ + } SR_b; + } ; + __IM uint8_t RESERVED; + __IM uint16_t RESERVED1; + + union { + __IOM uint8_t CPSR; /*!< (@ 0x00000010) Clock prescale register */ + + struct { + __IOM uint8_t CPSDVSR : 8; /*!< [7..0] Clock prescale divisor.It must be an even number from + 2 to 254. The value is used to generate the transmit and + receive bit rate of the SPI. The bit rate is:

FSSPCLK + / [CPSDVR x (1+SCR)]

where SCR is a value from 0 to + 255, programmed through the SSP_CR0 register. */ + } CPSR_b; + } ; + __IM uint8_t RESERVED2; + __IM uint16_t RESERVED3; + + union { + __IOM uint8_t IMSC; /*!< (@ 0x00000014) Interrupt mask set or clear register */ + + struct { + __IOM uint8_t RORIM : 1; /*!< [0..0] Receive overrun interrupt mask:
  • 0: RX FIFO written + to while full condition interrupt is masked (irq disabled).
  • 1: + RX FIFO written to while full condition interrupt is not + masked (irq enabled).
*/ + __IOM uint8_t RTIM : 1; /*!< [1..1] Receive timeout interrupt mask:
  • 0: RX FIFO not + empty or no read prior to the timeout period interrupt + is masked (irq disabled).
  • 1: RX FIFO not empty + or no read prior to the timeout period interrupt is not + masked (irq enabled).
*/ + __IOM uint8_t RXIM : 1; /*!< [2..2] Receive FIFO interrupt mask:
  • 0: Receive interrupt + is masked (irq disabled).
  • 1: Receive interrupt + is not masked (irq enabled).
*/ + __IOM uint8_t TXIM : 1; /*!< [3..3] Transmit FIFO interrupt mask:
  • 0: Transmit interrupt + is masked (irq disabled).
  • 1: Transmit interrupt + is not masked (irq enabled).
*/ + __IOM uint8_t TURIM : 1; /*!< [4..4] Transmit underrun interrupt mask:
  • 0: Transmit + underrun interrupt is masked (irq disabled).
  • 1: + Transmit underrun interrupt is not masked (irq enabled).
*/ + __IOM uint8_t TEIM : 1; /*!< [5..5] Transmit FIFO empty interrupt mask:
  • 0: TX FIFO + empty interrupt is masked (irq disabled).
  • 1: TX + FIFO empty interrupt is not masked (irq enabled).
*/ + } IMSC_b; + } ; + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + + union { + __IM uint8_t RIS; /*!< (@ 0x00000018) Raw interrupt status register */ + + struct { + __IM uint8_t RORRIS : 1; /*!< [0..0] Receive overrun raw interrupt status */ + __IM uint8_t RTRIS : 1; /*!< [1..1] Receive time out raw interrupt status */ + __IM uint8_t RXRIS : 1; /*!< [2..2] Receive raw interrupt status */ + __IM uint8_t TXRIS : 1; /*!< [3..3] Transmit raw interrupt status */ + __IM uint8_t TURRIS : 1; /*!< [4..4] Transmit underrun raw interrupt Status */ + __IM uint8_t TERIS : 1; /*!< [5..5] Transmit FIFO Empty Raw Interrupt Status */ + } RIS_b; + } ; + __IM uint8_t RESERVED6; + __IM uint16_t RESERVED7; + + union { + __IM uint8_t MIS; /*!< (@ 0x0000001C) Masked Interrupt Status Register */ + + struct { + __IM uint8_t RORMIS : 1; /*!< [0..0] Receive Overrun Masked Interrupt Status: gives the interrupt + status after masking of the receive overrun interrupt. */ + __IM uint8_t RTMIS : 1; /*!< [1..1] Receive Time Out Masked Interrupt Status: gives the interrupt + status after masking of receive timeout interrupt. */ + __IM uint8_t RXMIS : 1; /*!< [2..2] Receive Masked Interrupt Status: gives the interrupt + status after masking of the receive interrupt. */ + __IM uint8_t TXMIS : 1; /*!< [3..3] Transmit Masked Interrupt Status: gives the interrupt + status after masking of the transmit interrupt. */ + __IM uint8_t TURMIS : 1; /*!< [4..4] Transmit Underrun Masked Interrupt Status: gives the + interrupt status after masking of the transmit underrun + interrupt. */ + __IM uint8_t TEMIS : 1; /*!< [5..5] Transmit FIFO Empty Masked Interrupt Status: gives the + interrupt status after masking of the transmit FIFO empty + interrupt. */ + } MIS_b; + } ; + __IM uint8_t RESERVED8; + __IM uint16_t RESERVED9; + + union { + __OM uint8_t ICR; /*!< (@ 0x00000020) Interrupt clear register */ + + struct { + __OM uint8_t RORIC : 1; /*!< [0..0] Receive Overrun Clear Interrupt: writing 1 clears the + receive overrun interrupt. */ + __OM uint8_t RTIC : 1; /*!< [1..1] Receive Time Out Clear Interrupt: writing 1 clears the + receive timeout interrupt. */ + __OM uint8_t TURIC : 1; /*!< [2..2] Transmit Underrun Clear Interrupt: writing 1 clears the + transmit overrun interrupt. */ + } ICR_b; + } ; + __IM uint8_t RESERVED10; + __IM uint16_t RESERVED11; + + union { + __IOM uint8_t DMACR; /*!< (@ 0x00000024) SPI DMA control register */ + + struct { + __IOM uint8_t RXDMASE : 1; /*!< [0..0] Single receive DMA request.
  • 0: Single transfer + DMA in receive disable.
  • 1: Single transfer DMA + in receive enable.
*/ + __IM uint8_t : 1; + __IOM uint8_t TXDMASE : 1; /*!< [2..2] Signle transmit DMA request.
  • 0: Single transfer + DMA in transmit disable.
  • 1: Single transfer DMA + in transmit enable.
*/ + } DMACR_b; + } ; + __IM uint8_t RESERVED12; + __IM uint16_t RESERVED13; + __IOM uint16_t RXFRM; /*!< (@ 0x00000028) SPI Receive Frame register. Indicates the number + of frames to receive from the slave. */ + __IM uint16_t RESERVED14; + __IOM uint32_t CHN; /*!< (@ 0x0000002C) Dummy character register */ + __IOM uint16_t WDTXF; /*!< (@ 0x00000030) SPI transmit FIFO receive frame number. Indicates + the number of frames to receive from the + transmit FIFO. */ + __IM uint16_t RESERVED15; + __IM uint32_t RESERVED16[19]; + + union { + __IOM uint8_t ITCR; /*!< (@ 0x00000080) Integration test control register */ + + struct { + __IM uint8_t : 1; + __IOM uint8_t SWAPFIFO : 1; /*!< [1..1] FIFO control mode:
  • 0: FIFO normal mode. Write + in TDR register puts data in TX FIFO and read from TDR + register read data from RX FIFO.
  • 1: FIFO swapped + mode. Write in TDR register puts data in RX FIFO and read + from TDR register read data from TX FIFO.
*/ + } ITCR_b; + } ; + __IM uint8_t RESERVED17; + __IM uint16_t RESERVED18; + __IM uint32_t RESERVED19[2]; + __IOM uint32_t TDR; /*!< (@ 0x0000008C) FIFO Test Data Register */ +} SPI_Type; /*!< Size = 144 (0x90) */ + + + +/* =========================================================================================================================== */ +/* ================ WDG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Watchdog (WDG) + */ + +typedef struct { /*!< (@ 0x40700000) WDG Structure */ + + union { + __IOM uint32_t LR; /*!< (@ 0x00000000) Watchdog Load Register */ + + struct { + __IOM uint32_t LOAD : 32; /*!< [31..0] Watchdog load value. Value from which the counter is + to decrement. When this register is written to, the count + is immediately restarted from the new value. */ + } LR_b; + } ; + + union { + __IM uint32_t VAL; /*!< (@ 0x00000004) Watchdog Value Register */ + + struct { + __IM uint32_t WDTVAL : 32; /*!< [31..0] Watchdog load value. When read, returns the current + value of the decrementing watchdog counter. A write has + no effect. */ + } VAL_b; + } ; + + union { + __IOM uint8_t CR; /*!< (@ 0x00000008) Watchdog Control Register */ + + struct { + __IOM uint8_t INTEN : 1; /*!< [0..0] Watchdog interrupt enable. Enable the interrupt event:
  • 0: + watchdog interrupt is disabled.
  • 1: watchdog interrupt + is enabled.
*/ + __IOM uint8_t RESEN : 1; /*!< [1..1] Watchdog reset enable. Enable the watchdog reset output:
  • 0: + watchdog reset is disabled.
  • 1: watchdog reset is + enabled.
*/ + } CR_b; + } ; + __IM uint8_t RESERVED; + __IM uint16_t RESERVED1; + + union { + __IOM uint32_t ICR; /*!< (@ 0x0000000C) Watchdog Interrupt Clear Register */ + + struct { + __IOM uint32_t WDTICLR : 32; /*!< [31..0] Watchdog interrupt enable:
  • Writing any value + will clear the watchdog interrupt and reloads the counter + from the LR register.
  • A read returns zero.
*/ + } ICR_b; + } ; + + union { + __IM uint8_t RIS; /*!< (@ 0x00000010) Watchdog Raw Interrupt Status Register */ + + struct { + __IM uint8_t RIS : 1; /*!< [0..0] Watchdog raw interrupt status bit. Reflects the status + of the interrupt status from the watchdog:
  • 0: watchdog + interrupt is not active.
  • 1: watchdog interrupt + is active.
Read-only bit. A write has no effect. */ + } RIS_b; + } ; + __IM uint8_t RESERVED2; + __IM uint16_t RESERVED3; + + union { + __IM uint8_t MIS; /*!< (@ 0x00000014) Watchdog Masked Interrupt Status Register */ + + struct { + __IM uint8_t MIS : 1; /*!< [0..0] Watchdog masked interrupt status bit. Masked value of + watchdog interrupt status:
  • 0: watchdog interrupt + is not active.
  • 1: watchdog interrupt is active.
Read-onl + bit. A write has no effect. */ + } MIS_b; + } ; + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + __IM uint32_t RESERVED6[762]; + + union { + __IOM uint32_t LOCK; /*!< (@ 0x00000C00) Watchdog Lock Register */ + + struct { + __IOM uint32_t LOCKVAL : 32; /*!< [31..0] Watchdog lock value. When read, returns the lock status:
  • 0: + Write access to all watchdog other registers is enabled.
  • 1: + Write access to all watchdog other registers is disabled.
When + written, allows enabling or disabling write access to all + other watchdog registers:
  • Writing 0x1ACCE551: Write + access to all other registers is enabled.
  • Writing + any other value: Write access to all other registers is + disabled.
*/ + } LOCK_b; + } ; +} WDG_Type; /*!< Size = 3076 (0xc04) */ + + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief ADC (ADC) + */ + +typedef struct { /*!< (@ 0x40800000) ADC Structure */ + + union { + __IOM uint16_t CTRL; /*!< (@ 0x00000000) ADC control register */ + + struct { + __IOM uint16_t ON : 1; /*!< [0..0] Starts ADC analog subsystem. This bit must be set before + starting a conversion.
  • 0: ADC is OFF.
  • 1: + ADC is ON.
This bit works for all the mode except + the microphone mode. */ + __IOM uint16_t CALEN : 1; /*!< [1..1] The automatic calibration routine is enabled if both + AUTO_OFFSET and CALEN bitfields are set. The result of + the calibration is placed in the OFFSET register according + to the SKIP bitfield value.
  • 0: disable the automatic + calibration.
  • 1: enable the automatic calibration.
This + bitfield can be set to 0 only by setting to 1 the bitfield + RSTCALEN. */ + __IOM uint16_t SWSTART : 1; /*!< [2..2] Starts the ADC conversion phase when set. This bit works + for all the mode except the microphone mode. */ + __IOM uint16_t RESET : 1; /*!< [3..3] Reset all the ADC APB registers when set (CTRL, CONF, + DATA_CONV_THRESHOLD_HI, THRESHOLD_LO). */ + __IOM uint16_t STOP : 1; /*!< [4..4] Permits to stop the continuous conversion. 1: stop the + continuous conversion and switch off the ADC. The bitfields + SWSTART, ON, DMA_EN and MIC_ON are auto-cleared if set. + This bit is auto-cleared by the hardware so it is always + read at 0. */ + __IOM uint16_t ENAB_COMP : 1; /*!< [5..5] Enables the window comparator when set to 1. WDOG flag + is ADC_SR register is set if the converted value is between + ADCTHRESHOLD_HI and ADCTHRESHOLD_LO value. */ + __IOM uint16_t RSTCALEN : 1; /*!< [6..6] Disable the calibration phase when set to 1. This bit + has to be set to disable the calibration each time calibration + is enabled. */ + __IOM uint16_t AUTO_OFFSET : 1; /*!< [7..7] The automatic calibration routine is enabled if both + AUTO_OFFSET and CALEN bitfields are set. The result of + the calibration is placed in the OFFSET register according + to the SKIP bitfield value.
  • 0: disable the automatic + calibration.
  • 1: enable the automatic calibration.
This + bitfield can be set to 0 only by setting to 1 the bitfield + RSTCALEN. */ + __IOM uint16_t MIC_ON : 1; /*!< [8..8] Starts ADC analog subsystem only for microphone mode.
  • 0: + ADC is OFF.
  • 1: ADC is ON.
*/ + __IOM uint16_t DMA_EN : 1; /*!< [9..9] Enables the DMA.
  • 0: DMA is disabled.
  • 1: + DMA is enabled.
*/ + } CTRL_b; + } ; + __IM uint16_t RESERVED; + + union { + __IOM uint32_t CONF; /*!< (@ 0x00000004) ADC configuration register */ + + struct { + __IM uint32_t : 1; + __IOM uint32_t CHSEL : 3; /*!< [3..1] Select the input channel:
  • 000b: All switches open.
  • 001b: + Single ended through ADC2 pin. InP=VREF (internal), InN=ADC2 + pin.
  • 010b: Single ended through ADC1 pin. InP=ADC1 + pin, InN=VREF (internal).
  • 011b: Differential ADC1 + pin - ADC2 pin, InP=ADC1 pin, InN=ADC2 pin.
  • 101b: + Battery level detector. InP=0.6V (internal), InN=VBATSENS.
  • 110b: + Short InN=InP=0.6V (internal).
*/ + __IOM uint32_t REFSEL : 2; /*!< [5..4] Set the VREF for single ended conversion:
  • 00b: + 0.0V.
  • 10b: 0.6V.
*/ + __IOM uint32_t OSR : 2; /*!< [7..6] Set the ADC resolution:
  • 00b: Set the oversampling + ratio to 200.
  • 01b: Set the oversampling ratio to + 100.
  • 10b: Set the oversampling ratio to 64.
  • 11b: + Set the oversampling ratio to 32.
*/ + __IOM uint32_t PGASEL : 2; /*!< [9..8] Set the input attenuator value:
  • 000b: Input attenuator + at 0 dB.
  • 001b: Input attenuator at 6.02 dB.
  • 010b: + Input attenuator at 9.54 dB.
*/ + __IM uint32_t : 1; + __IOM uint32_t CONT : 1; /*!< [11..11] Enable the continuous conversion mode:
  • 0: Single + conversion.
  • 1: Continuous conversion.
*/ + __IM uint32_t : 6; + __IOM uint32_t SKIP : 1; /*!< [18..18] It permits to bypass the filter COMP to speed up the + conversion for signal at low frequency:
  • 0: Filter + not bypassed.
  • 1: Filter bypassed.
According + to the value of this bitfield, the behaviour of the ADC + changes as follows: if SKIP is 0: the first 10 converted + samples in ADC mode continuous should be discarded by the + user (3 if SKIP is 1). The converted date are in DATA_CONV_MSB + (DATA_CONV_LSB if SKIP is 1). The calibration result is + in OFFSET_MSB (OFFSET_LSB if SKIP is 1). */ + __IM uint32_t : 1; + __IOM uint32_t DIG_FILT_CLK : 1; /*!< [20..20] Frequency clock selection value on GPIO0 when MIC_SEL=1:
  • 0: + 0.8 MHz.
  • 1: 1.6 MHz.
*/ + __IM uint32_t : 1; + __IOM uint32_t MIC_SEL : 1; /*!< [22..22] Provides the clock on GPIO:
  • 0: Do not provided + any external clock source.
  • 1: Provide clock source + from GPIO.
*/ + } CONF_b; + } ; + + union { + __IM uint8_t IRQSTAT; /*!< (@ 0x00000008) IRQ masked status register */ + + struct { + __IM uint8_t ENDCAL : 1; /*!< [0..0] 1: when the calibration is completed. Clear on register + read. */ + __IM uint8_t : 1; + __IM uint8_t EOC : 1; /*!< [2..2] 1: when the conversion is completed. Clear on register + read. */ + __IM uint8_t WDOG : 1; /*!< [3..3] 1: when the data is within the thresholds. Clear on register + read. */ + } IRQSTAT_b; + } ; + __IM uint8_t RESERVED1; + __IM uint16_t RESERVED2; + + union { + __IOM uint8_t IRQMASK; /*!< (@ 0x0000000C) It sets the mask for ADC interrupt */ + + struct { + __IOM uint8_t ENDCAL : 1; /*!< [0..0] Interrupt mask for the end of calibration event:
  • 0: + Interrupt is enabled.
  • 1: Interrupt is disabled.
*/ + __IM uint8_t : 1; + __IOM uint8_t EOC : 1; /*!< [2..2] Interrupt mask for the end of conversion event:
  • 0: + Interrupt is enabled.
  • 1: Interrupt is disabled.
*/ + __IOM uint8_t WDOG : 1; /*!< [3..3] Interrupt mask for the within the threhsold event:
  • 0: + Interrupt is enabled.
  • 1: Interrupt is disabled.
*/ + } IRQMASK_b; + } ; + __IM uint8_t RESERVED3; + __IM uint16_t RESERVED4; + + union { + __IM uint8_t IRQRAW; /*!< (@ 0x00000010) IRQ status raw register */ + + struct { + __IM uint8_t ENDCAL : 1; /*!< [0..0] 1: when the calibration is completed. Clear on register + read. */ + __IM uint8_t : 1; + __IM uint8_t EOC : 1; /*!< [2..2] 1: when the conversion is completed. Clear on register + read. */ + __IM uint8_t WDOG : 1; /*!< [3..3] 1: when the data is inside the thresholds. Clear on register + read. */ + } IRQRAW_b; + } ; + __IM uint8_t RESERVED5; + __IM uint16_t RESERVED6; + __IM uint16_t DATA_CONV_LSB; /*!< (@ 0x00000014) Result of the conversion LSB in two complement + format. If the filter is bypassed, the bitfield + SKIP is 1, the DATA_CONV_MSB is negligible + and the ADC converted data is the DATA_CONV_LSB + * 1.08 (corrective factor). If the filter + is not bypassed, the bitfield SKIP is 0, + the DATA_CONV_LSB is negligeble. */ + __IM uint16_t DATA_CONV_MSB; /*!< (@ 0x00000016) Result of the conversion MSB in two complement + format. If the filter is not bypassed, the + bitfield SKIP is 0, the DATA_CONV_LSB is + negligible and the ADC converted data is + the DATA_CONV_MSB. If the filter is bypassed, + the bitfield SKIP is 1, the DATA_CONV_MSB + is negligeble. */ + __IOM uint16_t OFFSET_LSB; /*!< (@ 0x00000018) Offset for correction of converted data. If the + bitfield SKIP is 0, the 16-bit offset is + in OFFSET_MSB, while if the bitfield SKIP + is 1, the 16-bit offset is in OFFSET_LSB. */ + __IOM uint16_t OFFSET_MSB; /*!< (@ 0x0000001A) Offset for correction of converted data. If the + bitfield SKIP is 0, the 16-bit offset is + in OFFSET_MSB, while if the bitfield SKIP + is 1, the 16-bit offset is in OFFSET_LSB. */ + __IM uint32_t RESERVED7; + + union { + __IOM uint8_t SR_REG; /*!< (@ 0x00000020) ADC status register */ + + struct { + __IM uint8_t : 1; + __IOM uint8_t BUSY : 1; /*!< [1..1] 1: during conversion. */ + __IM uint8_t : 1; + __IOM uint8_t WDOG : 1; /*!< [3..3] If ENAB_COMP=1, this bit indicates the result of the + conversion is between high and low threshold:
  • 0: + DATAOUT[31:0] is NOT between THRESHOLD_HI and THRESHOLD_LO + values.
  • 1: DATAOUT[31:0] is between THRESHOLD_HI + and THRESHOLD_LO values.
*/ + } SR_REG_b; + } ; + __IM uint8_t RESERVED8; + __IM uint16_t RESERVED9; + __IOM uint32_t THRESHOLD_HI; /*!< (@ 0x00000024) High threshold for window comparator */ + __IOM uint32_t THRESHOLD_LO; /*!< (@ 0x00000028) Low threshold for window comparator */ +} ADC_Type; /*!< Size = 44 (0x2c) */ + + + +/* =========================================================================================================================== */ +/* ================ CKGEN_SOC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Clock Gen SOC (CKGEN_SOC) + */ + +typedef struct { /*!< (@ 0x40900000) CKGEN_SOC Structure */ + __IM uint32_t RESERVED[2]; + + union { + __IM uint8_t REASON_RST; /*!< (@ 0x00000008) Indicates the reset reason from Cortex-M0 */ + + struct { + __IM uint8_t : 1; + __IM uint8_t SYSREQ : 1; /*!< [1..1] Reset caused by Cortex-M0 debug asserting SYSRESETREQ */ + __IM uint8_t WDG : 1; /*!< [2..2] Reset caused by assertion of watchdog reset */ + __IM uint8_t LOCKUP : 1; /*!< [3..3] Reset caused by Cortex-M0 asserting LOCKUP signal */ + } REASON_RST_b; + } ; + __IM uint8_t RESERVED1; + __IM uint16_t RESERVED2; + __IM uint32_t RESERVED3[4]; + + union { + __IM uint32_t DIE_ID; /*!< (@ 0x0000001C) Identification information of the device */ + + struct { + __IM uint32_t REV : 4; /*!< [3..0] Cut revision */ + __IM uint32_t VERSION : 4; /*!< [7..4] Cut version */ + __IM uint32_t PRODUCT : 4; /*!< [11..8] Product */ + } DIE_ID_b; + } ; + + union { + __IOM uint32_t CLOCK_EN; /*!< (@ 0x00000020) Enable or gates the APB clock of the peripherals */ + + struct { + __IOM uint32_t GPIO : 1; /*!< [0..0] GPIO clock */ + __IOM uint32_t NVM : 1; /*!< [1..1] Flash controller clock */ + __IOM uint32_t SYSCTRL : 1; /*!< [2..2] System controller clock */ + __IOM uint32_t UART : 1; /*!< [3..3] UART clock */ + __IOM uint32_t SPI : 1; /*!< [4..4] SPI clock */ + __IM uint32_t : 2; + __IOM uint32_t WDOG : 1; /*!< [7..7] Watchdog clock */ + __IOM uint32_t ADC : 1; /*!< [8..8] ADC clock */ + __IOM uint32_t I2C1 : 1; /*!< [9..9] I2C1 clock */ + __IOM uint32_t I2C2 : 1; /*!< [10..10] I2C2 clock */ + __IOM uint32_t MFT1 : 1; /*!< [11..11] MFT1 clock */ + __IOM uint32_t MFT2 : 1; /*!< [12..12] MFT2 clock */ + __IOM uint32_t RTC : 1; /*!< [13..13] RTC clock */ + __IM uint32_t : 2; + __IOM uint32_t DMA : 1; /*!< [16..16] DMA AHB clock */ + __IOM uint32_t RNG : 1; /*!< [17..17] RNG AHB clock */ + __IOM uint32_t PKA : 2; /*!< [19..18] PKA AHB clock and RAM */ + } CLOCK_EN_b; + } ; + + union { + __IOM uint8_t DMA_CONFIG; /*!< (@ 0x00000024) DMA config */ + + struct { + __IOM uint8_t ADC_CH0 : 1; /*!< [0..0] Select ADC on DMA channel 0 instead of peripheral */ + __IOM uint8_t ADC_CH1 : 1; /*!< [1..1] Select ADC on DMA channel 1 instead of peripheral */ + __IOM uint8_t ADC_CH2 : 1; /*!< [2..2] Select ADC on DMA channel 2 instead of peripheral */ + __IOM uint8_t ADC_CH3 : 1; /*!< [3..3] Select ADC on DMA channel 3 instead of peripheral */ + __IOM uint8_t ADC_CH4 : 1; /*!< [4..4] Select ADC on DMA channel 4 instead of peripheral */ + __IOM uint8_t ADC_CH5 : 1; /*!< [5..5] Select ADC on DMA channel 5 instead of peripheral */ + __IOM uint8_t ADC_CH6 : 1; /*!< [6..6] Select ADC on DMA channel 6 instead of peripheral */ + __IOM uint8_t ADC_CH7 : 1; /*!< [7..7] Select ADC on DMA channel 7 instead of peripheral */ + } DMA_CONFIG_b; + } ; + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; +} CKGEN_SOC_Type; /*!< Size = 40 (0x28) */ + + + +/* =========================================================================================================================== */ +/* ================ I2C2 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief I2C2 (I2C2) + */ + +typedef struct { /*!< (@ 0x40A00000) I2C2 Structure */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000000) I2C Control register */ + + struct { + __IOM uint32_t PE : 1; /*!< [0..0] I2C enable disable:
  • 0: I2C disable.
  • 1: + I2C enable.
This bit when deasserted works as + software reset for I2C peripheral. */ + __IOM uint32_t OM : 2; /*!< [2..1] Select the operating mode:
  • 00b: Slave mode. The + peripheral can only respond (transmit/receive) when addressed + by a master device
  • 01b: Master mode. The peripheral + works in a multi-master system where itself cannot be addressed + by another master device. It can only initiate a new transfer + as master device.
  • 10b: Master/slave mode. The peripheral + works in a multi-master system where itself can be addressed + by another master device, besides to initiate a transfer + as master device.
  • 0: 7-bit addressing mode.
  • 1: + 10-bit addressing mode.
*/ + __IOM uint32_t SM : 2; /*!< [5..4] Speed mode. SM defines the speed mode related to the + serial bit rate:
  • 0: Standard mode (up to 100 K/s).
  • 1: + Fast mode (up to 400 K/s).
*/ + __IOM uint32_t SGCM : 1; /*!< [6..6] Slave general call mode defines the operating mode of + the slave controller when a general call is received. This + setting does not affect the hardware general call that + is always managed in transparent mode.
  • 0: transparent + mode, the slave receiver recognizes the general call but + any action is taken by the hardware after the decoding + of the message included in the Rx FIFO.
  • 1: direct + mode, the slave receiver recognizes the general call and + executes directly (without software intervention) the r */ + __IOM uint32_t FTX : 1; /*!< [7..7] FTX flushes the transmit circuitry (FIFO, fsm). The configuration + of the I2C node (register setting) is not affected by the + flushing operation. The flushing operation is performed + on modules working on different clock domains (system and + I2C clocks) and needs several system clock cycles before + being completed. Upon completion, the I2C node (internal + logic) clears this bit. The application must not access + the Tx FIFO during the flushing operation and should poll + on this bit waiting for completion.
    • 0: */ + __IOM uint32_t FRX : 1; /*!< [8..8] FRX flushes the receive circuitry (FIFO, fsm).The configuration + of the I2C node (register setting) is not affected by the + flushing operation. The flushing operation is performed + on modules working on different clock domains (system and + I2C clocks) and needs several system clock cycles before + to be completed. Upon completion, the I2C node (internal + logic) clears this bit. The application must not access + the Rx FIFO during the flushing operation and should poll + on this bit waiting for the completion.
      • */ + __IOM uint32_t DMA_TX_EN : 1; /*!< [9..9] Enables the DMA TX interface.
        • 0: Idle state, the + DMA TX interface is disabled.
        • 1: Run state, the + DMA TX interface is enabled.
        On the completion + of the DMA transfer, the DMA TX interface is automatically + turned off clearing this bit when the end of transfer signal + coming from the DMA is raised. DMA_TX_EN and DMA_RX_EN + must not enabled at the same time. */ + __IOM uint32_t DMA_RX_EN : 1; /*!< [10..10] Enables the DMA RX interface.
        • 0: Idle state, + the DMA RX interface is disabled.
        • 1: Run state, + the DMA RX interface is enabled.
        On the completion + of the DMA transfer, the DMA RX interface is automatically + turned off clearing this bit when the end of transfer signal + coming from the DMA is raised. DMA_TX_EN and DMA_RX_EN + must not enabled at the same time. */ + __IM uint32_t : 2; + __IOM uint32_t FON : 2; /*!< [14..13] Filtering on sets the digital filters on the SDA, SCL + line, according to the I2C bus requirements, when standard + open-drain pads are used:
        • 00b: No digital filters + are inserted.
        • 01b: Digital filters (filter 1 ck + wide spikes) are inserted.
        • 10b: Digital filters + (filter 2 ck wide spikes) are inserted.
        • 11b: Digital + filters (filter 4 ck wide spikes) are inserted.
        */ + __IOM uint32_t FS_1 : 1; /*!< [15..15] Force stop enable bit. When set to 1b, the STOP condition + is generated.
        • 0: Force stop disabled.
        • 1: + Enable force stop.
        */ + } CR_b; + } ; + + union { + __IOM uint32_t SCR; /*!< (@ 0x00000004) I2C Slave Control register */ + + struct { + __IOM uint32_t SA7 : 7; /*!< [6..0] Slave address 7-bit. SA7 includes the slave address 7-bit + or the LSB bits of the slave address 10-bit */ + __IOM uint32_t ESA10 : 3; /*!< [9..7] Extended slave address 10-bit. ESA10 includes the extension + (MSB bits) to the SA7 register field in case of slave addressing + mode set to 10-bit */ + __IM uint32_t : 6; + __IOM uint32_t SLSU : 16; /*!< [31..16] Slave data setup time. SLSU defines the data setup + time after SCL clock stretching in terms of i2c_clk cycles. + Data setup time is actually equal to SLSU-1 clock cycles. + The typical values for i2c_clk of 16 MHz are SLSU = 5 in + standard mode and SLSU = 3 in fast modes. */ + } SCR_b; + } ; + __IM uint32_t RESERVED; + + union { + __IOM uint32_t MCR; /*!< (@ 0x0000000C) I2C master control register */ + + struct { + __IOM uint32_t OP : 1; /*!< [0..0] Operation
        • 0: Indicates a master write operation.
        • 1: + Indicates a master read operation.
        */ + __IOM uint32_t A7 : 7; /*!< [7..1] Address. Includes the 7-bit address or the LSB bits of + the10-bit address used to initiate the current transaction */ + __IOM uint32_t EA10 : 3; /*!< [10..8] Extended address. Includes the extension (MSB bits) + of the field A7 used to initiate the current transaction */ + __IOM uint32_t SB : 1; /*!< [11..11] Start byte:
        • 0: The start byte procedure is not + applied to the current transaction.
        • 1: The start + byte procedure is prefixed to the current transaction.
        */ + __IOM uint32_t AM : 2; /*!< [13..12] Address type:
        • 00b: The transaction is initiated + by a general call command. In this case the fields OP, + A7, EA10 are don't care.
        • 01b: The transaction is + initiated by the 7-bit address included in the A7 field.
        • 10b: + The transaction is initiated by the 10-bit address included + in the EA10 and A7 fields.
        */ + __IOM uint32_t P : 1; /*!< [14..14] Stop condition:
        • 0: The current transaction is + not terminated by a STOP condition. A repeated START condition + is generated on the next operation which is required to + avoid to stall the I2C line.
        • 1: The current transaction + is terminated by a STOP condition.
        */ + __IOM uint32_t LENGTH : 11; /*!< [25..15] Transaction length. Defines the length, in terms of + the number of bytes to be transmitted (MW) or received + (MR). In case of write operation, the payload is stored + in the Tx FIFO. A transaction can be larger than the Tx + FIFO size. In case of read operation the length refers + to the number of bytes to be received before generating + a not-acknowledge response. A transaction can be larger + than the Rx FIFO size. The I2C clock line is stretched + low until the data in Rx FIFO are consumed. */ + } MCR_b; + } ; + + union { + __IOM uint8_t TFR; /*!< (@ 0x00000010) I2C transmit FIFO register */ + + struct { + __IOM uint8_t TDATA : 8; /*!< [7..0] Transmission Data. TDATA contains the payload related + to a master write or read-from-slave operation to be written + in the Tx FIFO. TDATA(0) is the first LSB bit transmitted + over the I2C line.

        In case of master write operation, + the Tx FIFO shall be preloaded otherwise the I2C controller + cannot start the operation until data are available.

        In + case of read-from-slave operation, when the slave is addressed, + the interrupt RISR:RFSR bit is asserted and the CPU shall + download the data in the FIFO. If the */ + } TFR_b; + } ; + __IM uint8_t RESERVED1; + __IM uint16_t RESERVED2; + + union { + __IM uint32_t SR; /*!< (@ 0x00000014) I2C status register */ + + struct { + __IM uint32_t OP : 2; /*!< [1..0] Operation:

        • 00b: MW: master write operation.
        • 01b: + MR: master read operation.
        • 10b: WTS: write-to-slave + operation.
        • 11b: RFS: read-from-slave operation.
        */ + __IM uint32_t STATUS : 2; /*!< [3..2] Controller status. Valid for the operations MW, MR, WTS + RFS:
        • 00b: NOP: No operation is in progress.
        • 01b: + ON_GOING: An operation is ongoing.
        • 10b: OK: The + operation (OP field) has been completed successfully.
        • 11b: + ABORT: The operation (OP field) has been aborted due to + the occurrence of the event described in the CAUSE field.
        */ + __IM uint32_t CAUSE : 3; /*!< [6..4] Abort cause. This field is valid only when the STATUS + field contains the ABORT tag. Others: reserved.
        • 000b: + NACK_ADDR: The master receives a not-acknowledge after + the transmission of the address. Valid for the operation + MW, MR.
        • 001b: NACK_DATA: The master receives a + not-acknowledge during the data phase of a MW operation. + Valid for the operation MW.
        • 011b: ARB_LOST: The + master loses the arbitration during a MW or MR operation. + Valid for the operation MW, MR.
        • 100b: BERR_START: */ + __IM uint32_t TYPE : 2; /*!< [8..7] Receive type. Valid only for the operation WTS:
          • 00b: + FRAME: The slave has received a normal frame.
          • 01b: + GCALL: The slave has received a general call. If the it + I2C_CR:SGCM is set to 1, the general call is directly executed + without software intervention and only the control code + word is reported in FIFO (LENGTH =0).
          • 10b: HW_GCALL: + The slave has received a hardware general call.
          */ + __IM uint32_t LENGTH : 10; /*!< [18..9] Transfer length. For an MR, WTS operation the LENGTH + field defines the actual size of the subsequent payload, + in terms of number of bytes. For an MW, RFS operation the + LENGTH field defines the actual number of bytes transferred + by the master/slave device. For a WTS operation if the + transfer length exceeds 2047 bytes, the operation is stopped + by the slave returning a NACK handshake and the flag OVFL + is set. For an RFS operation if the transfer length exceeds + 2047 bytes, the operation continues normally but */ + __IM uint32_t : 10; + __IM uint32_t DUALF : 1; /*!< [29..29] Dual flag (slave mode):
          • 0: Received address + matched with slave address (SA7).
          • 1: Received address + matched with dual slave address (DSA7).
          Cleared + by hardware after a Stop condition or repeated Start condition, + bus error or when PE=0. */ + } SR_b; + } ; + + union { + __IM uint8_t RFR; /*!< (@ 0x00000018) I2C receive FIFO register */ + + struct { + __IM uint8_t RDATA : 8; /*!< [7..0] Receive data. RDATA contains the received payload, related + to a master read or write-to-slave operation, to be read + from the Rx FIFO. The RDATA(0) is the first LSB bit received + over the I2C line. In case the FIFO is full, the I2C controller + stretches automatically the I2C clock line until a new + entry is available.

          For a write-to-slave operation, when + the slave is addressed, the interrupt I2C_RISR:WTSR bit + is asserted for notification to the CPU. In CPU mode the + FIFO management shall be based on the asser */ + } RFR_b; + } ; + __IM uint8_t RESERVED3; + __IM uint16_t RESERVED4; + + union { + __IOM uint16_t TFTR; /*!< (@ 0x0000001C) I2C transmit FIFO threshold register */ + + struct { + __IOM uint16_t THRESH_TX : 10; /*!< [9..0] Threshold TX, contains the threshold value, in terms + of number of bytes, of the Tx FIFO.

          When the number of + entries of the Tx FIFO is less or equal than the threshold + value, the interrupt bit I2C_RISR:TXFNE is set in order + to request the loading of data to the application.

          */ + } TFTR_b; + } ; + __IM uint16_t RESERVED5; + + union { + __IOM uint16_t RFTR; /*!< (@ 0x00000020) I2C receive FIFO threshold register */ + + struct { + __IOM uint16_t THRESH_RX : 10; /*!< [9..0] Threshold RX, contains the threshold value, in terms + of number of bytes, of the Rx FIFO.

          When the number of + entries of the RX FIFO is greater than or equal to the + threshold value, the interrupt bit RISR:RXFNF is set in + order to request the download of received data to the application. + The application shall download the received data based + on the threshold. (RISR:RXFNF).

          */ + } RFTR_b; + } ; + __IM uint16_t RESERVED6; + + union { + __IOM uint16_t DMAR; /*!< (@ 0x00000024) I2C DMA register */ + + struct { + __IM uint16_t : 8; + __IOM uint16_t DBSIZE_TX : 3; /*!< [10..8] Destination burst size. This register field is valid + only if the BURST_TX bit is set to '1'. If burst size is + smaller than the transaction length, only single request + are generated. */ + __IOM uint16_t BURST_TX : 1; /*!< [11..11] Defines the type of DMA request generated by the DMA + TX interface.
          • 0: Single request mode. Transfers + a single data (one byte) in the TX FIFO.
          • 1: Burst + request mode. Transfers a programmed burst of data according + to DBSIZE_TX field.
          When the burst mode is programmed, + the DMA transfer can be completed by one or more single + requests as required. */ + } DMAR_b; + } ; + __IM uint16_t RESERVED7; + + union { + __IOM uint16_t BRCR; /*!< (@ 0x00000028) I2C Baud-rate counter register */ + + struct { + __IOM uint16_t BRCNT : 16; /*!< [15..0] Baud rate counter. BRCNT defines the counter value used + to set up the I2C baud rate in standard and fast mode, + when the peripheral is operating in master mode. */ + } BRCR_b; + } ; + __IM uint16_t RESERVED8; + + union { + __IOM uint32_t IMSCR; /*!< (@ 0x0000002C) I2C interrupt mask set/clear register */ + + struct { + __IOM uint32_t TXFEM : 1; /*!< [0..0] TX FIFO empty mask. TXFEM enables the interrupt bit TXFE:
          • 0: + TXFE interrupt is disabled.
          • 1: TXFE interrupt is + enabled.
          */ + __IOM uint32_t TXFNEM : 1; /*!< [1..1] TX FIFO nearly empty mask. TXFNEM enables the interrupt + bit TXFNE:
          • 0: TXFNE interrupt is disabled.
          • 1: + TXFNE interrupt is enabled.
          */ + __IOM uint32_t TXFFM : 1; /*!< [2..2] TX FIFO full mask. TXFFM enables the interrupt bit TXFF:
          • 0: + TXFF interrupt is disabled.
          • 1: TXFF interrupt is + enabled.
          */ + __IOM uint32_t TXFOVRM : 1; /*!< [3..3] TX FIFO overrun mask. TXOVRM enables the interrupt bit + TXOVR:
          • 0: TXOVR interrupt is disabled.
          • 1: + TXOVR interrupt is enabled.
          */ + __IOM uint32_t RXFEM : 1; /*!< [4..4] RX FIFO empty mask. RXFEM enables the interrupt bit RXFE:
          • 0: + RXFE interrupt is disabled.
          • 1: RXFE interrupt is + enabled.
          */ + __IOM uint32_t RXFNFM : 1; /*!< [5..5] RX FIFO nearly full mask. RXNFM enables the interrupt + bit RXNF:
          • 0: RXNF interrupt is disabled.
          • 1: + RXNF interrupt is enabled
          */ + __IOM uint32_t RXFFM : 1; /*!< [6..6] RX FIFO full mask. RXFFM enables the interrupt bit RXFF:
          • 0: + RXFF interrupt is disabled.
          • 1: RXFF interrupt is + enabled.
          */ + __IM uint32_t : 9; + __IOM uint32_t RFSRM : 1; /*!< [16..16] Read-from-Slave request mask. RFSRM enables the interrupt + bit RFSR:
          • 0: RFSR interrupt is disabled.
          • 1: + RFSR interrupt is enabled.
          */ + __IOM uint32_t RFSEM : 1; /*!< [17..17] Read-from-Slave empty mask. RFSEM enables the interrupt + bit RFSE:
          • 0: RFSE interrupt is disabled.
          • 1: + RFSE interrupt is enabled.
          */ + __IOM uint32_t WTSRM : 1; /*!< [18..18] Write-to-Slave request mask. WTSRM enables the interrupt + bit WTSR:
          • 0: WTSR interrupt is disabled.
          • 1: + WTSR interrupt is enabled.
          */ + __IOM uint32_t MTDM : 1; /*!< [19..19] Master Transaction done mask. MTDM enables the interrupt + bit MTD:
          • 0: MTD interrupt is disabled.
          • 1: + MTD interrupt is enabled.
          */ + __IOM uint32_t STDM : 1; /*!< [20..20] Slave Transaction done mask. STDM enables the interrupt + bit STD:
          • 0: STDM interrupt is disabled.
          • 1: + STDM interrupt is enabled.
          */ + __IM uint32_t : 3; + __IOM uint32_t MALM : 1; /*!< [24..24] Master Arbitration lost mask. MALM enables the interrupt + bit MAL:
          • 0: MAL interrupt is disabled.
          • 1: + MAL interrupt is enabled.
          */ + __IOM uint32_t BERRM : 1; /*!< [25..25] Bus Error mask. BERRM enables the interrupt bit BERR:
          • 0: + BERR interrupt is disabled.
          • 1: BERR interrupt is + enabled.
          */ + __IM uint32_t : 2; + __IOM uint32_t MTDWSM : 1; /*!< [28..28] Master Transaction done without stop mask. MTDWSM enables + the interrupt bit MTDWS:
          • 0: MTDWS interrupt is disabled.
          • 1 + MTDWS interrupt is enabled.
          */ + } IMSCR_b; + } ; + + union { + __IM uint32_t RISR; /*!< (@ 0x00000030) I2C raw interrupt status register */ + + struct { + __IM uint32_t TXFE : 1; /*!< [0..0] TX FIFO empty. TXFE is set when TX FIFO is empty. This + bit is self-cleared by writing in TX FIFO.
          • 0: TX + FIFO is not empty.
          • 1: TX FIFO is empty.
          */ + __IM uint32_t TXFNE : 1; /*!< [1..1] TX FIFO nearly empty. TXFNE is set when the number of + entries in TX FIFO is less than or equal to the threshold + value programmed in the I2C_TFTR:THRESHOLD_TX register. + It is self-cleared when the threshold level is over the + programmed threshold.
          • 0: Number of entries in TX + FIFO greater than the TFTR:THRESHOLD_TX register.
          • 1: + Number of entries in TX FIFO less than or equal to the + TFTR:THRESHOLD_TX register.
          */ + __IM uint32_t TXFF : 1; /*!< [2..2] TX FIFO full. TXFF is set when a full condition occurs + in TX FIFO. This bit is self-cleared when the TX FIFO is + not full:
          • 0: TX FIFO is not full.
          • 1: TX + FIFO is full.
          */ + __IM uint32_t TXFOVR : 1; /*!< [3..3] TX FIFO overrun. TXFOVR is set when a write operation + in TX FIFO is performed and TX FIFO is full. The application + must avoid an overflow condition by a proper data flow + control. Anyway in case of overrun, the application shall + flush the transmitter (CR:FTX bit to set) because the TX + FIFO content is corrupted (at least one word has been lost + in FIFO). This interrupt is cleared by setting the related + bit of the ICR register:
          • 0: No overrun condition + occurred in TX FIFO.
          • 1: Overrun condition oc */ + __IM uint32_t RXFE : 1; /*!< [4..4] RX FIFO empty. RXFE is set when the RX FIFO is empty. + This bit is self-cleared when the slave RX FIFO is not + empty:
            • 0: RX FIFO is not empty..
            • 1: RX FIFO + is empty..
            */ + __IM uint32_t RXFNF : 1; /*!< [5..5] RX FIFO nearly full. RXFNF is set when the number of + entries in RX FIFO is greater than or equal to the threshold + value programmed in the RFTR:THRESHOLD_RX register. Its + self-cleared when the threshold level is under the programmed + threshold:
            • 0: Number of entries in the RX FIFO less + than the RFTR:THRESHOLD_RX register.
            • 1: Number + of entries in the RX FIFO greater than or equal to the + RFTR:THRESHOLD_RX register.
            */ + __IM uint32_t RXFF : 1; /*!< [6..6] RX FIFO full. RXFF is set when a full condition occurs + in RX FIFO. This bit is self-cleared when the data are + read from the RX FIFO.
            • 0: RX FIFO is not full.
            • 1: + RX FIFO is full.
            */ + __IM uint32_t : 8; + __IM uint32_t LBR : 1; /*!< [15..15] Length number of bytes received. LBR is set in case + of MR or WTS and when the number of bytes received is equal + to the transaction length programmed in the MCR:LENGTH + (master mode) or SMB_SCR:LENGTH (slave mode). On the assertion + of this interrupt and when the bit CR:FRC_STRTCH is set, + the hardware starts clock stretching, the CPU shall download + the data byte (Command code, Byte Count, Data...) from + RX FIFO, re-set the expected length of the transaction + in SMB_SCR:LENGTH and clear the interrupt. When clear */ + __IM uint32_t RFSR : 1; /*!< [16..16] Read-from-slave request. RFSR is set when a read-from-slave + Slavetransmitter request is received (I2C slave is addressed) + from the I2C line. On the assertion of this interrupt the + TX FIFO is flushed (pending data are cleared) and the CPU + shall put the data in TX FIFO. This bit is self-cleared + by writing data in FIFO. In case the FIFO is empty before + the completion of the read operation, the RISR:RFSE interrupt + bit is set.This interrupt is cleared by setting the related + bit of the ICR register.
            • 0: Re */ + __IM uint32_t RFSE : 1; /*!< [17..17] Read-from-Slave empty. RFSE is set when a read-from-slave + operation is in progress and TX FIFO is empty. On the assertion + of this interrupt, the CPU shall download in TX FIFO the + data required for the slave operation. This bit is self-cleared + by writing in TX FIFO. At the end of the read-from-slave + operation this bit is cleared although the TX FIFO is empty.
              • 0: + TX FIFO is not empty.
              • 1: TX FIFO is empty with + the read-from-slave operation in progress.
              */ + __IM uint32_t WTSR : 1; /*!< [18..18] Write-to-Slave request. WTSR is set when a write-to-slave + operation is received (I2C slave is addressed) from the + I2C line. This notification can be used by the application + to program the DMA descriptor when required. This interrupt + is cleared by setting the related bit of the ICR register:
              • 0: + No write-to-slave request pending.
              • 1: Write-to-slave + request is pending.
              */ + __IM uint32_t MTD : 1; /*!< [19..19] Master Transaction done. MTD is set when a master operation + (master write or master read) has been executed after a + stop condition. The application shall read the related + transaction status (SR register), the pending data in the + RX FIFO (only for a master read operation) and clear this + interrupt (transaction acknowledgment). A subsequent master + operation can be issued (writing the MCR register) after + the clearing of this interrupt. A subsequent slave operation + will be notified (RISR:WTSR and RISR:RFSR inte */ + __IM uint32_t STD : 1; /*!< [20..20] Slave Transaction done. STD is set when a slave operation + (write-to-slave or read-from-slave) has been executed. + The application shall read the related transaction status + (SR register), the pending data in the RX FIFO (only for + a write-to-slave operation) and clear this interrupt (transaction + acknowledgment). A subsequent slave operation will be notified + (RISR:WTSR and RISR:RFSR interrupt bits assertion) after + clearing this interrupt, meanwhile the I2C clock line will + be stretched low. A subsequent master */ + __IM uint32_t : 2; + __IM uint32_t SAL : 1; /*!< [23..23] Slave Arbitration lost. SAL is set when the slave loses + the arbitration during the data phase. A collision occurs + when 2 devices transmit simultaneously 2 opposite values + on the serial data line. The device that is pulling up + the line, identifies the collision reading a 0 value on + the sda_in signal, stops the transmission, releases the + bus and waits for the idle state (STOP condition received) + on the bus line. The device which transmits the first unique + zero wins the bus arbitration. This interrupt is clea */ + __IM uint32_t MAL : 1; /*!< [24..24] Master arbitration lost. MAL is set when the master + loses the arbitration. The status code word in the SR contains + a specific error tag (CAUSE field) for this error condition. + A collision occurs when 2 stations transmit simultaneously + 2 opposite values on the serial line. The station that + is pulling up the line, identifies the collision reading + a 0 value on the sda_in signal, stops the transmission, + leaves the bus and waits for the idle state (STOP condition + received) on the bus line before retrying the sa */ + __IM uint32_t BERR : 1; /*!< [25..25] Bus Error. BERR is set when an unexpected Start/Stop + condition occurs during a transaction. The related actions + are different, depending on the type of operation in progress.The + status code word in the SR contains a specific error tag + (CAUSE field) for this error condition. This interrupt + is cleared by setting the related bit of the ICR register.
              • 0: + No bus error detection.
              • 1: Bus error detection.
              */ + __IM uint32_t : 2; + __IM uint32_t MTDWS : 1; /*!< [28..28] Master transaction done without stop. MTDWS is set + when a master operation (write or read) has been executed + and a stop (MCR:P field) is not programmed. The application + shall read the related transaction status (SR register), + the pending data in the RX FIFO (only for a master read + operation) and clear this interrupt (transaction acknowledgment). + A subsequent master operation can be issued (by writing + the MCR register) after clearing this interrupt. A subsequent + slave operation will be notified (RISR:WTSR a */ + } RISR_b; + } ; + + union { + __IM uint32_t MISR; /*!< (@ 0x00000034) I2C masked interrupt status register */ + + struct { + __IM uint32_t TXFEMIS : 1; /*!< [0..0] TX FIFO empty masked interrupt status.
              • 0: TX FIFO + is not empty.
              • 1: TX FIFO is empty.
              */ + __IM uint32_t TXFNEMIS : 1; /*!< [1..1] TX FIFO nearly empty masked interrupt status.
              • 0: + Number of entries in TX FIFO greater than the TFTR:THRESHOLD_TX + register.
              • 1: Number of entries in TX FIFO less + than or equal to the TFTR:THRESHOLD_TX register.
              */ + __IM uint32_t TXFFMIS : 1; /*!< [2..2] Tx FIFO full masked interrupt status.
              • 0: TX FIFO + is not full.
              • 1: TX FIFO is full.
              */ + __IM uint32_t TXFOVRMIS : 1; /*!< [3..3] Tx FIFO overrun masked interrupt status.
              • 0: No + overrun condition occurred in TX FIFO.
              • 1: Overrun + condition occurred in TX FIFO.
              */ + __IM uint32_t RXFEMIS : 1; /*!< [4..4] RX FIFO empty masked interrupt status.
              • 0: RX FIFO + is not empty.
              • 1: RX FIFO is empty..
              */ + __IM uint32_t RXFNFMIS : 1; /*!< [5..5] RX FIFO nearly full masked interrupt status.
              • 0: + Number of entries in the RX FIFO less than the RFTR:THRESHOLD_RX + register.
              • 1: Number of entries in the RX FIFO greater + than or equal to the RFTR:THRESHOLD_RX register.
              */ + __IM uint32_t RXFFMIS : 1; /*!< [6..6] RX FIFO full masked interrupt status.
              • 0: RX FIFO + is not full.
              • 1: RX FIFO is full.
              */ + __IM uint32_t : 9; + __IM uint32_t RFSRMIS : 1; /*!< [16..16] Read-from-Slave request masked interrupt status.
              • 0: + Read-from-slave request has been served.
              • 1: Read-from-slave + request is pending.
              */ + __IM uint32_t RFSEMIS : 1; /*!< [17..17] Read-from-Slave empty masked interrupt status.
              • 0: + TX FIFO is not empty.
              • 1: TX FIFO is empty with + the read-from-slave operation in progress.
              */ + __IM uint32_t WTSRMIS : 1; /*!< [18..18] Write-to-Slave request masked interrupt status.
              • 0: + No write-to-slave request pending.
              • 1: Write-to-slave + request is pending.
              */ + __IM uint32_t MTDMIS : 1; /*!< [19..19] Master Transaction done masked interrupt status.
              • 0: + Master transaction acknowledged.
              • 1: Master transaction + done (ready for acknowledgment).
              */ + __IM uint32_t STDMIS : 1; /*!< [20..20] Slave Transaction done masked interrupt status.
              • 0: + Slave transaction acknowledged.
              • 1: Slave transaction + done (ready for acknowledgment).
              */ + __IM uint32_t : 3; + __IM uint32_t MALMIS : 1; /*!< [24..24] Master Arbitration lost masked interrupt status.
              • 0: + No master arbitration lost.
              • 1: Master arbitration + lost.
              */ + __IM uint32_t BERRMIS : 1; /*!< [25..25] Bus Error masked interrupt status.
              • 0: No bus + error detection.
              • 1: Bus error detection.
              */ + __IM uint32_t : 2; + __IM uint32_t MTDWSMIS : 1; /*!< [28..28] Master Transaction done without stop masked interrupt + status.
              • 0: Master transaction acknowledged.
              • 1: + Master transaction done (ready for acknowledgment) and + stop is not applied into the I2C bus.
              */ + } MISR_b; + } ; + + union { + __IOM uint32_t ICR; /*!< (@ 0x00000038) I2C interrupt clear register */ + + struct { + __IM uint32_t : 3; + __IOM uint32_t TXFOVRIC : 1; /*!< [3..3] Tx FIFO overrun interrupt clear.
              • 0: Has no effect.
              • 1: + Clears interrupt pending.
              */ + __IM uint32_t : 12; + __IOM uint32_t RFSRIC : 1; /*!< [16..16] Read-from-Slave request interrupt clear.
              • 0: + Has no effect.
              • 1: Clears interrupt pending.
              */ + __IOM uint32_t RFSEIC : 1; /*!< [17..17] Read-from-Slave empty interrupt clear.
              • 0: Has + no effect.
              • 1: Clears interrupt pending.
              */ + __IOM uint32_t WTSRIC : 1; /*!< [18..18] Write-to-Slave request interrupt clear.
              • 0: Has + no effect.
              • 1: Clears interrupt pending.
              */ + __IOM uint32_t MTDIC : 1; /*!< [19..19] Master Transaction done interrupt clear.
              • 0: + Has no effect.
              • 1: Clears interrupt pending.
              */ + __IOM uint32_t STDIC : 1; /*!< [20..20] Slave Transaction done interrupt clear.
              • 0: Has + no effect.
              • 1: Clears interrupt pending.
              */ + __IM uint32_t : 3; + __IOM uint32_t MALIC : 1; /*!< [24..24] Master Arbitration lost interrupt clear.
              • 0: + Has no effect.
              • 1: Clears interrupt pending.
              */ + __IOM uint32_t BERRIC : 1; /*!< [25..25] Bus Error interrupt clear.
              • 0: Has no effect.
              • 1: + Clears interrupt pending.
              */ + __IM uint32_t : 2; + __IOM uint32_t MTDWSIC : 1; /*!< [28..28] Master Transaction done without stop interrupt clear.
              • 0: + Has no effect.
              • 1: Clears interrupt pending.
              */ + __IM uint32_t : 1; + __IOM uint32_t TIMEOUTIC : 1; /*!< [30..30] Timeout or Tlow error interrupt clear.
              • 0: Has + no effect.
              • 1: Clears interrupt pending.
              */ + } ICR_b; + } ; + __IM uint32_t RESERVED9[4]; + + union { + __IOM uint16_t THDDAT; /*!< (@ 0x0000004C) I2C hold time data */ + + struct { + __IOM uint16_t THDDAT : 9; /*!< [8..0] Hold time data value. In master or slave mode, when the + I2C controller detects a falling edge in the SCL line, + the counter, which is loaded by the THDDAT, is launched. + Once the THDDAT value is reached, the data is transferred. */ + } THDDAT_b; + } ; + __IM uint16_t RESERVED10; + + union { + __IOM uint32_t THDSTA_FST_STD; /*!< (@ 0x00000050) I2C hold time start condition F/S */ + + struct { + __IOM uint32_t THDSTA_STD : 9; /*!< [8..0] Hold time start condition value for standard mode. When + the start condition is asserted, the decimeter loads the + value of THDSTA_STD for standard mode, once the THDSTA_STD + value is reached, the SCL line asserts low. */ + __IM uint32_t : 7; + __IOM uint32_t THDSTA_FST : 9; /*!< [24..16] Hold time start condition value for fast mode. When + the start condition is asserted, the decimeter loads the + value of THDSTA_FST for fast mode, once the THDSTA_FST + value is reached, the SCL line assert slow. */ + } THDSTA_FST_STD_b; + } ; + __IM uint32_t RESERVED11; + + union { + __IOM uint32_t TSUSTA_FST_STD; /*!< (@ 0x00000058) I2C setup time start condition F/S */ + + struct { + __IOM uint32_t TSUSTA_STD : 9; /*!< [8..0] Setup time start condition value for standard mode. After + a non-stop on the SCL line the decimeter loads the value + of TSUSTA_STD according to standard mode. Once the counter + is expired, the start condition is generated. */ + __IM uint32_t : 7; + __IOM uint32_t TSUSTA_FST : 9; /*!< [24..16] Setup time start condition value for fast mode. After + a non-stop on the SCL line the decimeter loads the value + of TSUSTA_FST according to fast mode. Once the counter + is expired the start condition is generated. */ + } TSUSTA_FST_STD_b; + } ; +} I2C_Type; /*!< Size = 92 (0x5c) */ + + + +/* =========================================================================================================================== */ +/* ================ AHBUPCONV ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief AHB up/down converter converter (AHBUPCONV) + */ + +typedef struct { /*!< (@ 0x40C00000) AHBUPCONV Structure */ + __IOM uint8_t COMMAND; /*!< (@ 0x00000000) AHB up/down converter command register */ + __IM uint8_t RESERVED[3]; + __IM uint8_t STATUS; /*!< (@ 0x00000004) Status register */ +} AHBUPCONV_Type; /*!< Size = 5 (0x5) */ + + + +/* =========================================================================================================================== */ +/* ================ MFT1 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief MFT1 (MFT1) + */ + +typedef struct { /*!< (@ 0x40D00000) MFT1 Structure */ + __IOM uint16_t TNCNT1; /*!< (@ 0x00000000) The Timer/Counter 1 register is a 16-bit RW register + that is not altered by reset and thus contains + random data upon power-up. Reading the register + returns the current value of the Timer/Counter + 1. TnCNT1 can only be written by the software + when MFT is enabled (TnEN = 1). When MFT + is disabled (TnEN = 0), write operations + on TnCNT1 register are ignored. */ + __IM uint16_t RESERVED; + __IOM uint16_t TNCRA; /*!< (@ 0x00000004) The Capture/Reload A register is a 16-bit RW + register that is not affected by reset and + thus contains random data upon power-up. + The software may read the register at any + time. However, the register can only be + written by the software when MFT is enabled + (TnEN = 1). When MFT is disabled (TnEN = + 0), write operations on TnCRA register are + ignored. */ + __IM uint16_t RESERVED1; + __IOM uint16_t TNCRB; /*!< (@ 0x00000008) The Capture/Reload B register is a 16-bit RW + register that is not affected by reset and + thus contains random data upon power-up. + The software may read the register at any + time. However, the register can only be + written by the software when MFT is enabled + (TnEN = 1). When MFT is disabled (TnEN = + 0), write operations on TnCRB register are + ignored. */ + __IM uint16_t RESERVED2; + __IOM uint16_t TNCNT2; /*!< (@ 0x0000000C) The Timer/Counter 2 register is a 16-bit RW register + that is not altered by reset and thus contains + random data upon power-up. Reading the register + returns the current value of the Timer/Counter + 2. TnCNT2 can only be written by the software + when MFT is enabled (TnEN = 1). When MFT + is disabled (TnEN = 0), write operations + on TnCNT2 register are ignored. */ + __IM uint16_t RESERVED3; + __IOM uint8_t TNPRSC; /*!< (@ 0x00000010) It contains the current value of the clock prescaler, + which determines the timer clock prescaler + ratio. The register value can be changed + at any time. The timer clock is generated + by dividing the system clock by TnPRSC + + 1. Therefore, the maximum timer clock frequency + is equal to the frequency of the system + clock (TnPRSC = 0x00), and the minimum timer + clock is the frequency of the system clock + divided by 256 (TnPRSC = 0xFF). */ + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + + union { + __IOM uint8_t TNCKC; /*!< (@ 0x00000014) Clock unit control register */ + + struct { + __IOM uint8_t TNC1CSEL : 3; /*!< [2..0] Define the clock mode for Timer/Counter 1:
              • 000b: + No clock (Timer/Counter 1 stopped).
              • 001b: System + clock with configurable prescaler (register TnPRSC).
              • 010b: + External event on TnB (mode 1 and 3 only).
              • 011b: + Pulse accumulate (mode 1 and 3 only).
              • 100b: 16 + MHz clock without prescaler (only when the system clock + is 32 MHz).
              */ + __IOM uint8_t TNC2CSEL : 3; /*!< [5..3] Define the clock mode for Timer/Counter 2:
              • 000b: + No clock (Timer/Counter 2 stopped).
              • 001b: System + clock with configurable prescaler (register TnPRSC).
              • 010b: + External event on TnB (mode 1 and 3 only).
              • 011b: + Pulse accumulate (mode 1 and 3 only).
              • 100b: 16 + MHz clock without prescaler (only when the system clock + is 32 MHz).
              */ + } TNCKC_b; + } ; + __IM uint8_t RESERVED6; + __IM uint16_t RESERVED7; + + union { + __IOM uint16_t TNMCTRL; /*!< (@ 0x00000018) Timer mode control register */ + + struct { + __IOM uint16_t TNMDSEL : 2; /*!< [1..0] MFTX mode select:
              • 00b: Mode 1 or 1a: PWM mode + and system timer or pulse train.
              • 01b: Mode 2: Dual-input + capture and system timer.
              • 10b: Mode 3: Dual independent + Timer/Counter.
              • 11b: Mode 4: Single timer and single + input capture.
              */ + __IOM uint16_t TNAEDG : 1; /*!< [2..2] Configure the TnA edge polarity for trigging an action:
              • 0: + Input is sensitive to falling edges.
              • 1: Input is + sensitive to rising edges.
              */ + __IOM uint16_t TNBEDG : 1; /*!< [3..3] Configure the TnB edge polarity for trigging an action:
              • 0: + Input is sensitive to falling edges.
              • 1: Input is + sensitive to rising edges.
              */ + __IOM uint16_t TNAEN : 1; /*!< [4..4] Enables TnA to either function as a preset input or as + a PWM output depending on the mode of operation. If the + bit is set (1) while operating in the dual-input capture + mode (mode 2), a transition on TnA causes TnCNT1 to be + preset to 0xFFFF. In the remaining modes of operation, + setting TnAEN enables TnA to function as a PWM output:
              • 0: + TnA input disable.
              • 1: TnA input enable.
              */ + __IOM uint16_t TNBEN : 1; /*!< [5..5] TnB Enable: If set (1) and while operating in dual-input + capture mode (mode 2) or input capture and timer mode (mode + 4), a transition on TnB will cause the corresponding Timer/Counter + to be preset to 0xFFFF. In mode 2, TnCNT1 will be preset + to 0xFFFF, while in mode 4, TnCNT2 is preset to 0xFFFF. + The bit has no effect while operating in any other modes + than mode 2 or mode 4:
              • 0: TnB input disable.
              • 1: + TnB input enable.
              */ + __IOM uint16_t TNAOUT : 1; /*!< [6..6] It contains the value of the TnA when used as PWM output. + The bit will be set and cleared by the hardware and thus + reflects the status of TnA. The bit can be read or written + by software at any time. If the hardware is attempting + to toggle the bit at the same time that software writes + to the bit, the software write will take precedence over + the hardware update. The bit has no effect when TnA is + used as an input or when the module is disabled:
              • 0: + TnA pin is low.
              • 1: TnA pin is high.
              */ + __IOM uint16_t TNEN : 1; /*!< [7..7] MFT is enabled if the bit is set (1), otherwise it is + disabled. When MFT is disabled, all clocks to the counter + unit are stopped, thus decreasing power consumption to + a minimum. For that reason, the Timer/Counter registers + (TnCNT1, TnCNT2), the Capture/Reload registers (TnCRA, + TnCRB) and the interrupt-pending bits (TnXPND) cannot be + written by software. Furthermore, the 8-bit clock prescaler + and the interrupt-pending bits are reset and the TnA I/O + pin becomes an input. */ + __IOM uint16_t TNPTEN : 1; /*!< [8..8] This bitfield enable the mode 1a. If set (1) while TnMDSEL + is set to 00b, the Timer/Counter 1 operates in PWM pulse-train + mode (mode 1a). The bit has no effect while TnMDSEL is + set to any value other than 00b:
              • 0: Mode 1a not + selected.
              • 1: Mode 1a selected (if TnMDSEL = 00b).
              */ + __IOM uint16_t TNPTSE : 1; /*!< [9..9] Tn Pulse-Train software trigger enable: if set (1) while + operating in PWM pulse-train mode (mode 1a), the pulse-train + generation can only be triggered by setting the TnPTET + to 1. If the TnPTSE bit is reset (0), pulses are generated + only if a transition occurs on TnB. The bit has no effect + while operating in any other modes than timer mode 1a:
              • 0: + No effect.
              • 1: Pulse-train generation trigger (in + mode 1a)
              */ + __IOM uint16_t TNPTET : 1; /*!< [10..10] Tn Pulse-Train event trigger: if set (1) while operating + in pulse-train mode (mode 1a) and the TnPTSE bit is set + (1), pulse-train generation is triggered. When Timer/Counter + 2 (TnCNT2) reaches its underflow condition, this bit is + reset (0). If the TnPTSE bit is not set (0) while operating + in mode 1a, the TnPTET bit cannot be written.
              • 0: + No pulse-train event trigger occurred.
              • 1: Pulse-train + event trigger occurred (in mode 1a).
              */ + } TNMCTRL_b; + } ; + __IM uint16_t RESERVED8; + + union { + __IOM uint8_t TNICTRL; /*!< (@ 0x0000001C) Timer interrupt control register */ + + struct { + __IM uint8_t TNAPND : 1; /*!< [0..0] Timer interrupt A pending:
              • 0: No interrupt source + pending.
              • 1: Interrupt source pending.
              */ + __IM uint8_t TNBPND : 1; /*!< [1..1] Timer interrupt B pending:
              • 0: No interrupt source + pending.
              • 1: Interrupt source pending.
              */ + __IM uint8_t TNCPND : 1; /*!< [2..2] Timer interrupt C pending:
              • 0: No interrupt source + pending.
              • 1: Interrupt source pending.
              */ + __IM uint8_t TNDPND : 1; /*!< [3..3] Timer interrupt D pending:
              • 0: No interrupt source + pending.
              • 1: Interrupt source pending.
              */ + __IOM uint8_t TNAIEN : 1; /*!< [4..4] Timer interrupt A enable:
              • 0: Interrupt disabled.
              • 1: + Interrupt enabled.
              */ + __IOM uint8_t TNBIEN : 1; /*!< [5..5] Timer interrupt B enable:
              • 0: Interrupt disabled.
              • 1: + Interrupt enabled.
              */ + __IOM uint8_t TNCIEN : 1; /*!< [6..6] Timer interrupt C enable:
              • 0: Interrupt disabled.
              • 1: + Interrupt enabled.
              */ + __IOM uint8_t TNDIEN : 1; /*!< [7..7] Timer interrupt D enable:
              • 0: Interrupt disabled.
              • 1: + Interrupt enabled.
              */ + } TNICTRL_b; + } ; + __IM uint8_t RESERVED9; + __IM uint16_t RESERVED10; + + union { + __OM uint8_t TNICLR; /*!< (@ 0x00000020) Timer interrupt clear register */ + + struct { + __OM uint8_t TNACLR : 1; /*!< [0..0] 1: clear the timer pending flag A. */ + __OM uint8_t TNBCLR : 1; /*!< [1..1] 1: clear the timer pending flag B. */ + __OM uint8_t TNCCLR : 1; /*!< [2..2] 1: clear the timer pending flag C. */ + __OM uint8_t TNDCLR : 1; /*!< [3..3] 1: clear the timer pending flag D. */ + } TNICLR_b; + } ; + __IM uint8_t RESERVED11; + __IM uint16_t RESERVED12; +} MFT_Type; /*!< Size = 36 (0x24) */ + + + +/* =========================================================================================================================== */ +/* ================ RTC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Real-Time Counter (RTC) + */ + +typedef struct { /*!< (@ 0x40F00000) RTC Structure */ + + union { + __IM uint32_t CWDR; /*!< (@ 0x00000000) Clockwatch Data Register */ + + struct { + __IM uint32_t CWSEC : 6; /*!< [5..0] RTC clockwatch second value. Clockwatch seconds: 0 to + 59 (max 0x3B). */ + __IM uint32_t CWMIN : 6; /*!< [11..6] RTC clockwatch minute value. Clockwatch seconds: 0 to + 59 (max 0x3B). */ + __IM uint32_t CWHOUR : 5; /*!< [16..12] RTC clockwatch hour value. Clockwatch seconds: 0 to + 23 (max 0x17). */ + __IM uint32_t CWDAYW : 3; /*!< [19..17] RTC clockwatch day of week value. Clockwatch day of + week:
              • 001b: Sunday.
              • 010b: Monday.
              • 011b: + Tuesday.
              • 100b: Wednesday.
              • 101b: Thursday.
              • 110b: + Friday.
              • 111b: Saturday.
              */ + __IM uint32_t CWDAYM : 5; /*!< [24..20] RTC clockwatch day of month value: 1 to 28/29/30 or + 31. Range of value to program depends on the month:
              • 1 + to 28: February month, non-leap year.
              • 1 to 29: + February month, leap year.
              • 1 to 30: April, June, + September, November month.
              • 1 to 31: January, March, + May, August, October, December month.
              */ + __IM uint32_t CWMONTH : 4; /*!< [28..25] RTC clockwatch month value:
              • 0001b: January.
              • ...
              • 1100: December.
              */ + } CWDR_b; + } ; + + union { + __IOM uint32_t CWDMR; /*!< (@ 0x00000004) Clockwatch Data Match Register */ + + struct { + __IOM uint32_t CWSECM : 6; /*!< [5..0] RTC clockwatch second match value:
              • 00 0000 to + 11 1011: (0 to 59 or 0x00 to 0x3B) clockwatch seconds.
              • 11 + 1100 to 11 1111 - (60 to 63 or 0x3C to 0x3F).
              Non-valid + data, match never occurs. */ + __IOM uint32_t CWMINM : 6; /*!< [11..6] RTC clockwatch minute match value:
              • 00 0000 to + 11 1011: (0 to 59 or 0x00 to 0x3B) clockwatch minutes.
              • 11 + 1100 to 11 1111 - (60 to 63 or 0x3C to 0x3F).
              Non-valid + data, match never occurs. */ + __IOM uint32_t CWHOURM : 5; /*!< [16..12] RTC clockwatch hour match value:
              • 00000b to 10111b: + (0 to 23 or 0x00 to 0x17) hour match value.
              • 11000b + to 11111b - (24 to 31 or 0x18 to 0x1F).
              Non-valid + data, match never occurs. */ + __IOM uint32_t CWDAYWM : 3; /*!< [19..17] RTC clockwatch day of week match value:
              • 000b: + day of week is don't care in the comparison. (Default value + after PORn).
              • 001b to 111b: (1 to 7) day of week + match value.
              */ + __IOM uint32_t CWDAYMM : 5; /*!< [24..20] RTC clockwatch day of month match value:
              • 0000b: + (month is don't care in the comparison. Default value after + PORn).
              • 1 to 31: day of month match value.
              */ + __IOM uint32_t CWMONTHM : 4; /*!< [28..25] RTC clockwatch month match value:
              • 0000b: (day + of month is don't care in the comparison. Default value + after PORn).
              • 0001b to 1100b: (1 to 12) month match + value.
              • 1101b (13, 0xD) to 1111b (0xF) non-valid + data, match never occurs.
              */ + } CWDMR_b; + } ; + + union { + __IOM uint32_t CWDLR; /*!< (@ 0x00000008) Clockwatch Data Load Register */ + + struct { + __IOM uint32_t CWSECL : 6; /*!< [5..0] RTC clockwatch second load value. Clockwatch seconds + from 0 to 59 (0x3B). Other values must not be used. */ + __IOM uint32_t CWMINL : 6; /*!< [11..6] RTC clockwatch minute load value. Clockwatch minutes + from 0 to 59 (0x3B). Other values must not be used. */ + __IOM uint32_t CWHOURL : 5; /*!< [16..12] RTC clockwatch hour load value. Clockwatch hours from + 0 to 23 (0x17). Other values must not be used. */ + __IOM uint32_t CWDAYWL : 3; /*!< [19..17] RTC clockwatch day of week load value. Clockwatch day + of week:
              • 000b: Must not be used.
              • 001b: Sunday.
              • 010 + : Monday.
              • 011b: Tuesday.
              • 100b: Wednesday.
              • 101b: + Thursday.
              • 110b: Friday.
              • 111b: Saturday.
              */ + __IOM uint32_t CWDAYML : 5; /*!< [24..20] RTC clockwatch day of month load value. 1 to 28/29/30 + or 31 depending on month:
              • 1 to 28: February month, + non-leap year.
              • 1 to 29: February month, leap year.
              • 1 + to 30: April, June, September, November month.
              • 1 + to 31: January, March, May, August, October, December month.
              • Othe + values must not be used.
              */ + __IOM uint32_t CWMONTHL : 4; /*!< [28..25] RTC clockwatch month load value:
              • 0001b: January.
              • ...
              • 1100: December.
              Other values must not be + used. */ + } CWDLR_b; + } ; + + union { + __IM uint16_t CWYR; /*!< (@ 0x0000000C) Clockwatch Year Register */ + + struct { + __IM uint16_t CWYEAR : 14; /*!< [13..0] RTC clockwatch year value. Clockwatch year, in BCD format + is from 0 to 3999. */ + } CWYR_b; + } ; + __IM uint16_t RESERVED; + + union { + __IOM uint16_t CWYMR; /*!< (@ 0x00000010) Clockwatch Year Match Register */ + + struct { + __IOM uint16_t CWYEARM : 14; /*!< [13..0] RTC clockwatch year match value. Clockwatch year match + value is in BCD format from 0 to 3999. */ + } CWYMR_b; + } ; + __IM uint16_t RESERVED1; + + union { + __IOM uint16_t CWYLR; /*!< (@ 0x00000014) Clockwatch Year Load Register */ + + struct { + __IOM uint16_t CWYEARL : 14; /*!< [13..0] RTC clockwatch year load value. Clockwatch year load + value is in BCD format from 0 to 3999. */ + } CWYLR_b; + } ; + __IM uint16_t RESERVED2; + + union { + __IOM uint32_t CTCR; /*!< (@ 0x00000018) Control Trim and Counter Register */ + + struct { + __IOM uint32_t CKDIV : 15; /*!< [14..0] Clock divider factor. This value plus one represents + the integer part of the CLK32K clock divider used to produce + the reference 1 Hz clock.
              • 0x000: CLK1HZ clock is + similar to CLK32K for RTC timer and stopped for RTC clockwatch.
              • 0 + 0001: 2 CLK32K clock cycles per CLK1HZ clock cycle.
              • ...
              • 0 + 7FFF: 32768 CLK32K clock cycles per CLK1HZ clock cycle + (default value after PORn reset).
              • ...
              • 0xFFFF: + CLK32K clock cycles per CLK1HZ clock cycle.
              Writing + to this bit-fie */ + __IM uint32_t : 1; + __IOM uint32_t CKDEL : 10; /*!< [25..16] Trim delete count. This value represents the number + of CLK32K clock pulses to delete every 1023 CLK32K clock + cycles to get a better reference 1 Hz clock for incrementing + the RTC counter.
              • 0x000: No CLK32K clock cycle is + deleted every 1023 CLK1HZ clock cycles (default value after + PORn reset).
              • 0x001: 1 CLK32K clock cycle is deleted + every 1023 CLK1HZ clock cycles.
              • ...
              • 0x3FF: + 1023 CLK32K clock cycles are deleted every 1023 CLK1HZ + clock cycles.
              Writing to this bit-field wi */ + __IOM uint32_t CWEN : 1; /*!< [26..26] Clockwatch enable bit. When set to 1, the clockwatch + is enabled. Once it is enabled, any write to this register + has no effect until a power-on reset. A read returns the + value of the CWEN bit value. */ + } CTCR_b; + } ; + + union { + __IOM uint8_t IMSC; /*!< (@ 0x0000001C) RTC interrupt mask register */ + + struct { + __IOM uint8_t WIMSC : 1; /*!< [0..0] RTC clock watch interrupt enable bit:
              • When set + to 0, clears the interrupt mask (default after PORn reset). + The interrupt is disabled.
              • When set to 1, the interrupt + for RTC clockwatch interrupt is enabled.
              */ + __IOM uint8_t TIMSC : 1; /*!< [1..1] RTC timer interrupt enable bit:
              • When set to 0, + sets the mask for RTC timer interrupt (default after PORn + reset). The interrupt is disabled.
              • When set to + 1, clears this mask and enables the interrupt.
              */ + } IMSC_b; + } ; + __IM uint8_t RESERVED3; + __IM uint16_t RESERVED4; + + union { + __IM uint8_t RIS; /*!< (@ 0x00000020) RTC raw interrupt status register */ + + struct { + __IM uint8_t WRIS : 1; /*!< [0..0] RTC clock watch raw interrupt status bit. Gives the raw + interrupt state (prior to masking) of the RTC clock watch + interrupt. */ + __IM uint8_t TRIS : 1; /*!< [1..1] RTC timer raw interrupt status bit. Gives the raw interrupt + state (prior to masking) of the RTC timer interrupt. */ + } RIS_b; + } ; + __IM uint8_t RESERVED5; + __IM uint16_t RESERVED6; + + union { + __IM uint8_t MIS; /*!< (@ 0x00000024) RTC masked interrupt status register */ + + struct { + __IM uint8_t WMIS : 1; /*!< [0..0] RTC clock watch interrupt status bit. Gives the masked + interrupt status (after masking) of the RTC clock watch + interrupt WINTR. */ + __IM uint8_t TMIS : 1; /*!< [1..1] RTC timer interrupt status bit. Gives the masked interrupt + status (after masking) of the RTC timer interrupt TINTR. */ + } MIS_b; + } ; + __IM uint8_t RESERVED7; + __IM uint16_t RESERVED8; + + union { + __OM uint8_t ICR; /*!< (@ 0x00000028) RTC interrupt clear register */ + + struct { + __OM uint8_t WIC : 1; /*!< [0..0] RTC clock watch interrupt clear register bit. Clears + the RTC clock watch interrupt WINTR.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint8_t TIC : 1; /*!< [1..1] RTC timer interrupt clear register bit. Clears the RTC + timer interrupt TINTR.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + } ICR_b; + } ; + __IM uint8_t RESERVED9; + __IM uint16_t RESERVED10; + __IM uint32_t TDR; /*!< (@ 0x0000002C) RTC timer load value */ + + union { + __IOM uint16_t TCR; /*!< (@ 0x00000030) RTC timer control register */ + + struct { + __IOM uint16_t OS : 1; /*!< [0..0] RTC Timer one shot count.
              • 0: Periodic mode (default). + When reaching zero, the RTC timer raises its interrupt + and is reloaded from the LD content.
              • 1: One-shot + mode. When reaching zero, the RTC timer raise its interrupt + and stops.
              */ + __IOM uint16_t EN : 1; /*!< [1..1] RTC Timer enable bit.
              • 0: The RTC timer is stopped + on the next CLK32K cycle.
              • 1: The RTC timer is enabled + on the next CLK32K cycle.
              When the RTC timer is + stopped, the content of the counter is frozen. A read returns + the value of the EN bit. This bit set by hardware when + the TLR register is written to while the counter is stopped. + When the device is active, this bit is cleared by hardware + when the counter reaches zero in one-shot mode. */ + __IOM uint16_t S : 1; /*!< [2..2] RTC Timer self start bit. When written to 1b, each write + in a load register or a pattern will set EN to 1b, so, + start the counter in the next CLK32K cycle. */ + __IM uint16_t : 1; + __IOM uint16_t SP : 7; /*!< [10..4] RTC Timer Pattern size. Number of pattern bits crossed + by the pointer. It defines the useful pattern size. */ + __IOM uint16_t CLK : 1; /*!< [11..11] RTC Timer clock.
              • 0: The RTC timer is clocked + by CLK32K.
              • 1: The RTC timer is clocked by the trimmed + clock.
              */ + __IOM uint16_t BYPASS_GATED : 1; /*!< [12..12] Enable or disable the internal clock gating:
              • 0: + The internal clock gating is activated.
              • 1: No clock + gating, clock is always enabled.
              */ + } TCR_b; + } ; + __IM uint16_t RESERVED11; + __IOM uint32_t TLR1; /*!< (@ 0x00000034) RTC Timer first Load Register */ + __IOM uint32_t TLR2; /*!< (@ 0x00000038) RTC Timer second Load Register */ + __IOM uint32_t TPR1; /*!< (@ 0x0000003C) RTC Timer Pattern Register (pattern[31:0]) */ + __IOM uint32_t TPR2; /*!< (@ 0x00000040) RTC Timer Pattern Register (pattern[63:32]) */ + __IOM uint32_t TPR3; /*!< (@ 0x00000044) RTC Timer Pattern Register (pattern[95:64]) */ + __IOM uint32_t TPR4; /*!< (@ 0x00000048) RTC Timer Pattern Register (pattern[127:96]) */ + __IOM uint32_t TIN; /*!< (@ 0x0000004C) RTC Timer Interrupt Number Register */ +} RTC_Type; /*!< Size = 80 (0x50) */ + + + +/* =========================================================================================================================== */ +/* ================ BLUE_CTRL ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief BLUE Controller (BLUE_CTRL) + */ + +typedef struct { /*!< (@ 0x48000000) BLUE_CTRL Structure */ + __IOM uint32_t INTERRUPT; /*!< (@ 0x00000000) Interrupt status and clear register */ + __IOM uint32_t TIMEOUT; /*!< (@ 0x00000004) Timeout programming register */ + __IM uint32_t TIMER_CAPTURE; /*!< (@ 0x00000008) Captured timer value register */ + __IOM uint32_t RADIO_CONFIG; /*!< (@ 0x0000000C) Radio configuration register */ + __IM uint32_t CURRENT_TIME; /*!< (@ 0x00000010) Timer current value register */ + __IM uint32_t STATUS; /*!< (@ 0x00000014) Status register */ + __IOM uint32_t AES_KEY0; /*!< (@ 0x00000018) AES key bit [127:96] */ + __IOM uint32_t AES_KEY1; /*!< (@ 0x0000001C) AES key bit [95:64] */ + __IOM uint32_t AES_KEY2; /*!< (@ 0x00000020) AES key bit [63:32] */ + __IOM uint32_t AES_KEY3; /*!< (@ 0x00000024) AES key bit [31:0] */ + __IOM uint32_t CLEAR_TEXT0; /*!< (@ 0x00000028) AES clear text bit [127:96] */ + __IOM uint32_t CLEAR_TEXT1; /*!< (@ 0x0000002C) AES clear text bit [95:64] */ + __IOM uint32_t CLEAR_TEXT2; /*!< (@ 0x00000030) AES clear text bit [63:32] */ + __IOM uint32_t CLEAR_TEXT3; /*!< (@ 0x00000034) AES clear text bit [31:0]. Writing in this register + starts an encryption */ + __IM uint32_t AES_CYPHERTEXT0; /*!< (@ 0x00000038) AES cypher text bit [127:96] */ + __IM uint32_t AES_CYPHERTEXT1; /*!< (@ 0x0000003C) AES cypher text bit [95:64] */ + __IM uint32_t AES_CYPHERTEXT2; /*!< (@ 0x00000040) AES cypher text bit [63:32] */ + __IM uint32_t AES_CYPHERTEXT3; /*!< (@ 0x00000044) AES cypher text bit [31:0] */ + __IOM uint32_t HOST_WKUP_TIMER; /*!< (@ 0x00000048) Host wakeup timer register */ +} BLUE_CTRL_Type; /*!< Size = 76 (0x4c) */ + + + +/* =========================================================================================================================== */ +/* ================ CKGEN_BLE ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Clock Gen BLE (CKGEN_BLE) + */ + +typedef struct { /*!< (@ 0x48100000) CKGEN_BLE Structure */ + __IM uint32_t RESERVED[2]; + + union { + __IM uint16_t REASON_RST; /*!< (@ 0x00000008) Indicates the reset reason from BLE */ + + struct { + __IM uint16_t : 1; + __IM uint16_t BOR : 1; /*!< [1..1] Reset from BOR */ + __IM uint16_t POR : 1; /*!< [2..2] Reset from POR */ + __IM uint16_t WKP_IO9 : 1; /*!< [3..3] Wakeup from external IO9 */ + __IM uint16_t WKP_IO10 : 1; /*!< [4..4] Wakeup from external IO10 */ + __IM uint16_t WKP_IO11 : 1; /*!< [5..5] Wakeup from external IO11 */ + __IM uint16_t WKP_IO12 : 1; /*!< [6..6] Wakeup from external IO12 */ + __IM uint16_t WKP_IO13 : 1; /*!< [7..7] Wakeup from external IO13 */ + __IM uint16_t WKP_BLUE : 1; /*!< [8..8] Wakeup coms from the timer 1 expiration in the wakeup + control block of the BLE radio */ + __IM uint16_t : 1; + __IM uint16_t WKP2_BLUE : 1; /*!< [10..10] Wakeup coms from the timer 2 expiration in the wakeup + control block of the BLE radio */ + } REASON_RST_b; + } ; + __IM uint16_t RESERVED1; + + union { + __IOM uint16_t CLK32K_COUNT; /*!< (@ 0x0000000C) Counter of 32 kHz clock */ + + struct { + __IOM uint16_t SLOW_COUNT : 9; /*!< [8..0] Program the window length (in slow clock period unit) + for slow clock measurement */ + } CLK32K_COUNT_b; + } ; + __IM uint16_t RESERVED2; + + union { + __IOM uint32_t CLK32K_PERIOD; /*!< (@ 0x00000010) Period of 32 kHz clock */ + + struct { + __IM uint32_t SLOW_PERIOD : 19; /*!< [18..0] Indicates slow clock period information. The result + provided in this field corresponds to the length of SLOW_COUNT + periods of the slow clock (32 kHz) measured in 16 MHz half-period + unit. The measurement is done automatically each time the + device enters in active2 mode using SLOW_COUNT = 16. A + new calculation can be launched by writing zero in CLK32K_PERIOD + register. In this case, the time window uses the value + programmed in SLOW_COUNT field. */ + } CLK32K_PERIOD_b; + } ; + + union { + __IM uint32_t CLK32K_FREQ; /*!< (@ 0x00000014) Measurement of frequency of 32 kHz clock */ + + struct { + __IM uint32_t SLOW_FREQ : 27; /*!< [26..0] Value equal to 2^33 / SLOW_PERIOD */ + } CLK32K_FREQ_b; + } ; + + union { + __IOM uint16_t CLK32K_IT; /*!< (@ 0x00000018) Interrupt event for 32 kHz clock measurement */ + + struct { + __IOM uint16_t CLK32K_MEAS_IRQ : 1; /*!< [0..0] When read, provides the status of the interrupt indicating + slow lock measurement is finished:
              • 0: No pending + interrupt.
              • 1: Pending interrupt.
              When + written, clears the interrupt:
              • 0: No effect.
              • 1: + Clear the interrupt.
              */ + } CLK32K_IT_b; + } ; + __IM uint16_t RESERVED3; +} CKGEN_BLE_Type; /*!< Size = 28 (0x1c) */ + + + +/* =========================================================================================================================== */ +/* ================ DMA ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DMA (DMA) + */ + +typedef struct { /*!< (@ 0xA0000000) DMA Structure */ + + union { + __IM uint32_t ISR; /*!< (@ 0x00000000) DMA interrupt status register */ + + struct { + __IM uint32_t GIF0 : 1; /*!< [0..0] Channel 0 global interrupt flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No TE, HT or TC event + on channel 0.
              • 1: A TE, HT or TC event occurred + on channel 0.
              */ + __IM uint32_t TCIF0 : 1; /*!< [1..1] Channel 0 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer complete + (TC) on channel 0.
              • 1: A transfer complete (TC) + occurred on channel 0.
              */ + __IM uint32_t HTIF0 : 1; /*!< [2..2] Channel 0 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No half transfer (HT) + event on channel 0.
              • 1: A half transfer (HT) event + occurred on channel 0.
              */ + __IM uint32_t TEIF0 : 1; /*!< [3..3] Channel 0 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer error (TE) + event on channel 0.
              • 1: A transfer error (TE) occurred + on channel 0.
              */ + __IM uint32_t GIF1 : 1; /*!< [4..4] Channel 1 global interrupt flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No TE, HT or TC event + on channel 1.
              • 1: A TE, HT or TC event occurred + on channel 1.
              */ + __IM uint32_t TCIF1 : 1; /*!< [5..5] Channel 1 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer complete + (TC) on channel 1.
              • 1: A transfer complete (TC) + occurred on channel 1.
              */ + __IM uint32_t HTIF1 : 1; /*!< [6..6] Channel 1 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No half transfer (HT) + event on channel 1.
              • 1: A half transfer (HT) event + occurred on channel 1.
              */ + __IM uint32_t TEIF1 : 1; /*!< [7..7] Channel 1 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer error (TE) + event on channel 1.
              • 1: A transfer error (TE) occurred + on channel 1.
              */ + __IM uint32_t GIF2 : 1; /*!< [8..8] Channel 2 global interrupt flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No TE, HT or TC event + on channel 2.
              • 1: A TE, HT or TC event occurred + on channel 2.
              */ + __IM uint32_t TCIF2 : 1; /*!< [9..9] Channel 2 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer complete + (TC) on channel 2.
              • 1: A transfer complete (TC) + occurred on channel 2.
              */ + __IM uint32_t HTIF2 : 1; /*!< [10..10] Channel 2 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No half transfer (HT) + event on channel 2.
              • 1: A half transfer (HT) event + occurred on channel 2.
              */ + __IM uint32_t TEIF2 : 1; /*!< [11..11] Channel 2 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer error (TE) + event on channel 2.
              • 1: A transfer error (TE) occurred + on channel 2.
              */ + __IM uint32_t GIF3 : 1; /*!< [12..12] Channel 3 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No TE, HT or TC event + on channel 3.
              • 1: A TE, HT or TC event occurred + on channel 3.
              */ + __IM uint32_t TCIF3 : 1; /*!< [13..13] Channel 3 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer complete + (TC) on channel 3.
              • 1: A transfer complete (TC) + occurred on channel 3.
              */ + __IM uint32_t HTIF3 : 1; /*!< [14..14] Channel 3 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No half transfer (HT) + event on channel 3.
              • 1: A half transfer (HT) event + occurred on channel 3.
              */ + __IM uint32_t TEIF3 : 1; /*!< [15..15] Channel 3 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer error (TE) + event on channel 3.
              • 1: A transfer error (TE) occurred + on channel 3.
              */ + __IM uint32_t GIF4 : 1; /*!< [16..16] Channel 4 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No TE, HT or TC event + on channel 4.
              • 1: A TE, HT or TC event occurred + on channel 4.
              */ + __IM uint32_t TCIF4 : 1; /*!< [17..17] Channel 4 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer complete + (TC) on channel 4.
              • 1: A transfer complete (TC) + occurred on channel 4.
              */ + __IM uint32_t HTIF4 : 1; /*!< [18..18] Channel 4 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No half transfer (HT) + event on channel 4.
              • 1: A half transfer (HT) event + occurred on channel 4.
              */ + __IM uint32_t TEIF4 : 1; /*!< [19..19] Channel 4 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer error (TE) + event on channel 4.
              • 1: A transfer error (TE) occurred + on channel 4.
              */ + __IM uint32_t GIF5 : 1; /*!< [20..20] Channel 5 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No TE, HT or TC event + on channel 5.
              • 1: A TE, HT or TC event occurred + on channel 5.
              */ + __IM uint32_t TCIF5 : 1; /*!< [21..21] Channel 5 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer complete + (TC) on channel 5.
              • 1: A transfer complete (TC) + occurred on channel 5.
              */ + __IM uint32_t HTIF5 : 1; /*!< [22..22] Channel 5 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No half transfer (HT) + event on channel 5.
              • 1: A half transfer (HT) event + occurred on channel 5.
              */ + __IM uint32_t TEIF5 : 1; /*!< [23..23] Channel 5 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer error (TE) + event on channel 5.
              • 1: A transfer error (TE) occurred + on channel 5.
              */ + __IM uint32_t GIF6 : 1; /*!< [24..24] Channel 6 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No TE, HT or TC event + on channel 6.
              • 1: A TE, HT or TC event occurred + on channel 6.
              */ + __IM uint32_t TCIF6 : 1; /*!< [25..25] Channel 6 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer complete + (TC) on channel 6.
              • 1: A transfer complete (TC) + occurred on channel 6.
              */ + __IM uint32_t HTIF6 : 1; /*!< [26..26] Channel 6 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No half transfer (HT) + event on channel 6.
              • 1: A half transfer (HT) event + occurred on channel 6.
              */ + __IM uint32_t TEIF6 : 1; /*!< [27..27] Channel 6 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer error (TE) + event on channel 6.
              • 1: A transfer error (TE) occurred + on channel 6.
              */ + __IM uint32_t GIF7 : 1; /*!< [28..28] Channel 7 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No TE, HT or TC event + on channel 7.
              • 1: A TE, HT or TC event occurred + on channel 7.
              */ + __IM uint32_t TCIF7 : 1; /*!< [29..29] Channel 7 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer complete + (TC) on channel 7.
              • 1: A transfer complete (TC) + occurred on channel 7.
              */ + __IM uint32_t HTIF7 : 1; /*!< [30..30] Channel 7 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No half transfer (HT) + event on channel 7.
              • 1: A half transfer (HT) event + occurred on channel 7.
              */ + __IM uint32_t TEIF7 : 1; /*!< [31..31] Channel 7 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
              • 0: No transfer error (TE) + event on channel 7.
              • 1: A transfer error (TE) occurred + on channel 7.
              */ + } ISR_b; + } ; + + union { + __OM uint32_t IFCR; /*!< (@ 0x00000004) DMA interrupt flag clear register */ + + struct { + __OM uint32_t CGIF0 : 1; /*!< [0..0] Channel 0 global interrupt flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the GIF, TEIF, HTIF and TCIF + flags in the ISR register.
              */ + __OM uint32_t CTCIF0 : 1; /*!< [1..1] Channel 0 transfer complete flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the corresponding + TCIF flag in the ISR register.
              */ + __OM uint32_t CHTIF0 : 1; /*!< [2..2] Channel 0 half transfer flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding HTIF flag + in the ISR register.
              */ + __OM uint32_t CTEIF0 : 1; /*!< [3..3] Channel 0 transfer error flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding TEIF flag + in the ISR register.
              */ + __OM uint32_t CGIF1 : 1; /*!< [4..4] Channel 1 global interrupt flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the GIF, TEIF, HTIF and TCIF + flags in the ISR register.
              */ + __OM uint32_t CTCIF1 : 1; /*!< [5..5] Channel 1 transfer complete flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the corresponding + TCIF flag in the ISR register.
              */ + __OM uint32_t CHTIF1 : 1; /*!< [6..6] Channel 1 half transfer flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding HTIF flag + in the ISR register.
              */ + __OM uint32_t CTEIF1 : 1; /*!< [7..7] Channel 1 transfer error flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding TEIF flag + in the ISR register.
              */ + __OM uint32_t CGIF2 : 1; /*!< [8..8] Channel 2 global interrupt flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the GIF, TEIF, HTIF and TCIF + flags in the ISR register.
              */ + __OM uint32_t CTCIF2 : 1; /*!< [9..9] Channel 2 transfer complete flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the corresponding + TCIF flag in the ISR register.
              */ + __OM uint32_t CHTIF2 : 1; /*!< [10..10] Channel 2 half transfer flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding HTIF flag + in the ISR register.
              */ + __OM uint32_t CTEIF2 : 1; /*!< [11..11] Channel 2 transfer error flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding TEIF flag + in the ISR register.
              */ + __OM uint32_t CGIF3 : 1; /*!< [12..12] Channel 3 global interrupt flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
              */ + __OM uint32_t CTCIF3 : 1; /*!< [13..13] Channel 3 transfer complete flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the corresponding + TCIF flag in the ISR register.
              */ + __OM uint32_t CHTIF3 : 1; /*!< [14..14] Channel 3 half transfer flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding HTIF flag + in the ISR register.
              */ + __OM uint32_t CTEIF3 : 1; /*!< [15..15] Channel 3 transfer error flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding TEIF flag + in the ISR register.
              */ + __OM uint32_t CGIF4 : 1; /*!< [16..16] Channel 4 global interrupt flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
              */ + __OM uint32_t CTCIF4 : 1; /*!< [17..17] Channel 4 transfer complete flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the corresponding + TCIF flag in the ISR register.
              */ + __OM uint32_t CHTIF4 : 1; /*!< [18..18] Channel 4 half transfer flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding HTIF flag + in the ISR register.
              */ + __OM uint32_t CTEIF4 : 1; /*!< [19..19] Channel 4 transfer error flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding TEIF flag + in the ISR register.
              */ + __OM uint32_t CGIF5 : 1; /*!< [20..20] Channel 5 global interrupt flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
              */ + __OM uint32_t CTCIF5 : 1; /*!< [21..21] Channel 5 transfer complete flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the corresponding + TCIF flag in the ISR register.
              */ + __OM uint32_t CHTIF5 : 1; /*!< [22..22] Channel 5 half transfer flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding HTIF flag + in the ISR register.
              */ + __OM uint32_t CTEIF5 : 1; /*!< [23..23] Channel 5 transfer error flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding TEIF flag + in the ISR register.
              */ + __OM uint32_t CGIF6 : 1; /*!< [24..24] Channel 6 global interrupt flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
              */ + __OM uint32_t CTCIF6 : 1; /*!< [25..25] Channel 6 transfer complete flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the corresponding + TCIF flag in the ISR register.
              */ + __OM uint32_t CHTIF6 : 1; /*!< [26..26] Channel 6 half transfer flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding HTIF flag + in the ISR register.
              */ + __OM uint32_t CTEIF6 : 1; /*!< [27..27] Channel 6 transfer error flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding TEIF flag + in the ISR register.
              */ + __OM uint32_t CGIF7 : 1; /*!< [28..28] Channel 7 global interrupt flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
              */ + __OM uint32_t CTCIF7 : 1; /*!< [29..29] Channel 7 transfer complete flag. This bit is set by + software.
              • 0: No effect.
              • 1: Clears the corresponding + TCIF flag in the ISR register.
              */ + __OM uint32_t CHTIF7 : 1; /*!< [30..30] Channel 7 half transfer flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding HTIF flag + in the ISR register.
              */ + __OM uint32_t CTEIF7 : 1; /*!< [31..31] Channel 7 transfer error flag. This bit is set by software.
              • 0: + No effect.
              • 1: Clears the corresponding TEIF flag + in the ISR register.
              */ + } IFCR_b; + } ; +} DMA_Type; /*!< Size = 8 (0x8) */ + + + +/* =========================================================================================================================== */ +/* ================ DMA_CH0 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DMA channel (DMA_CH0) + */ + +typedef struct { /*!< (@ 0xA0000008) DMA_CH0 Structure */ + + union { + __IOM uint32_t CCR; /*!< (@ 0x00000000) DMA channel configuration register */ + + struct { + __IOM uint32_t EN : 1; /*!< [0..0] DMA channel enable.
              • 0: DMA channel disabled.
              • 1: + DMA channel enabled.
              */ + __IOM uint32_t TCIE : 1; /*!< [1..1] Transfer complete interrupt enable.
              • 0: TC interrupt + disabled.
              • 1: TC interrupt enabled.
              */ + __IOM uint32_t HTIE : 1; /*!< [2..2] Half transfer interrupt enable.
              • 0: HT interrupt + disabled.
              • 1: HT interrupt enabled.
              */ + __IOM uint32_t TEIE : 1; /*!< [3..3] Transfer error interrupt enable.
              • 0: TE interrupt + disabled.
              • 1: TE interrupt enabled.
              */ + __IOM uint32_t DIR : 1; /*!< [4..4] Data transfer direction.
              • 0: Read from peripheral.
              • 1: + Read from memory.
              */ + __IOM uint32_t CIRC : 1; /*!< [5..5] Circular mode.
              • 0: Circular mode disabled.
              • 1: + Circular mode enabled.
              */ + __IOM uint32_t PINC : 1; /*!< [6..6] Peripheral increment mode.
              • 0: Peripheral increment + disabled.
              • 1: Peripheral increment enabled.
              */ + __IOM uint32_t MINC : 1; /*!< [7..7] Memory increment mode.
              • 0: Memory increment disabled.
              • 1: + Memory increment enabled.
              */ + __IOM uint32_t PSIZE : 2; /*!< [9..8] Peripheral size.
              • 00b: Size 8 bits.
              • 01b: + Size 16 bits.
              • 10b: Size 32 bits.
              */ + __IOM uint32_t MSIZE : 2; /*!< [11..10] Memory size.
              • 00b: Size 8 bits.
              • 01b: + Size 16 bits.
              • 10b: Size 32 bits.
              */ + __IOM uint32_t PL : 2; /*!< [13..12] Channel priority level.
              • 00b: Low priority.
              • 01b: + Medium priority.
              • 10b: High priority.
              • 11b: + Very high priority.
              */ + __IOM uint32_t MEM2MEM : 1; /*!< [14..14] Memory to memory mode.
              • 0: Memory to memory mode + disabled.
              • 0: Memory to memory mode enabled.
              */ + __IM uint32_t CCR_RESERVED : 17; /*!< [31..15] CCR not used bitfield. */ + } CCR_b; + } ; + + union { + __IOM uint32_t CNDTR; /*!< (@ 0x00000004) DMA channel number of data register. */ + + struct { + __IOM uint32_t NDT : 16; /*!< [15..0] Number of data to be transferred (0 up to 65535). This + register can only be written when the channel is disabled. + Once the channel is enabled, this register is read-only, + indicating the remaining bytes to be transmitted. This + register decrements after each DMA transfer. Once the transfer + is completed, this register can either stay at zero or + be reloaded automatically by the value previously programmed + if the channel is configured in auto-reload mode. If this + register is zero, no transaction can be served w */ + __IM uint32_t CNDTR_RESERVED : 16; /*!< [31..16] CNDTR not used bitfield. */ + } CNDTR_b; + } ; + + union { + __IOM uint32_t CPAR; /*!< (@ 0x00000008) DMA channel peripheral address register */ + + struct { + __IOM uint32_t PA : 32; /*!< [31..0] Base address of the peripheral data register from/to + which the data will be read/written. When PSIZE is 01 (16-bit), + the PA[0] bit is ignored. Access is automatically aligned + to a halfword address. When PSIZE is 10 (32-bit), PA[1:0] + are ignored. Access is automatically aligned to a word + address. */ + } CPAR_b; + } ; + + union { + __IOM uint32_t CMAR; /*!< (@ 0x0000000C) DMA channel memory address register */ + + struct { + __IOM uint32_t MA : 32; /*!< [31..0] Base address of the memory area from/to which the data + will be read/written. When MSIZE is 01 (16-bit), the MA[0] + bit is ignored. Access is automatically aligned to a halfword + address. When MSIZE is 10 (32-bit), MA[1:0] are ignored. + Access is automatically aligned to a word address. */ + } CMAR_b; + } ; +} DMA_CH_Type; /*!< Size = 16 (0x10) */ + + + +/* =========================================================================================================================== */ +/* ================ RNG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief RNG (RNG) + */ + +typedef struct { /*!< (@ 0xB0000000) RNG Structure */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000000) RNG configuration register */ + + struct { + __IM uint32_t : 2; + __IOM uint32_t DIS : 1; /*!< [2..2] Set the state of the random number generator.
              • 0: + RNG is enable.
              • 1: RNG is disabled. The internal + free-running oscillators are put in power-down mode and + the RNG clock is stopped at the input of the block.
              */ + __IM uint32_t : 1; + __IM uint32_t CR_RESERVED : 28; /*!< [31..4] CR not used bitfield. */ + } CR_b; + } ; + + union { + __IM uint32_t SR; /*!< (@ 0x00000004) RNG status register */ + + struct { + __IM uint32_t RDY : 1; /*!< [0..0] New random value ready.
              • 0: The RNG_VAL register + value is not yet valid. If performing a read access to + VAL, the host will be put on hold (by wait-states insertion + on the AHB bus) until a random value is available.
              • 1: + The VAL register contains a valid random number.
              This + bit remains at 0 when the RNG is disabled (RNGDIS bit = + 1b in CR) */ + __IM uint32_t : 2; + __IM uint32_t SR_RESERVED : 29; /*!< [31..3] SR not used bitfield. */ + } SR_b; + } ; + __IM uint32_t VAL; /*!< (@ 0x00000008) RNG 16 bit random value */ +} RNG_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ PKA ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief PKA (PKA) + */ + +typedef struct { /*!< (@ 0xC0000000) PKA Structure */ + + union { + __IOM uint32_t CSR; /*!< (@ 0x00000000) Command and status register */ + + struct { + __OM uint32_t GO : 1; /*!< [0..0] PKA start processing command:
              • 0: has no effect.
              • 1: + starts the processing.
              After this bitfield is + written to 1, it must be written back to zero manually. */ + __IM uint32_t READY : 1; /*!< [1..1] PKA readiness status:
              • 0: the PKA is computing. + It is not ready.
              • 1: the PKA is ready to start a + new processing.
              The rising edge of the READY bit + set the PROC_END flag in the ISR register. */ + __IM uint32_t : 5; + __OM uint32_t SFT_RST : 1; /*!< [7..7] PKA software reset:
              • 0: has no effect.
              • 1: + reset the PKA peripheral.
              After this bitfield + is written to 1, it must be written back to zero manually. */ + __IM uint32_t CSR_RESERVED : 24; /*!< [31..8] CSR not used bitfield. */ + } CSR_b; + } ; + + union { + __IOM uint32_t ISR; /*!< (@ 0x00000004) Interrupt status register */ + + struct { + __IOM uint32_t PROC_END : 1; /*!< [0..0] PKA process ending interrupt. When read:
              • 0: no + event.
              • 1: PKA process is ended.
              When written:
              • 0: + no effect.
              • 1: clears the PKA process ending interrupt.
              */ + __IM uint32_t : 1; + __IOM uint32_t RAM_ERR : 1; /*!< [2..2] RAM read / write access error interrupt. When read:
              • 0: + All AHB read or write access to the PKA RAM occurred while + the PKA was stopped.
              • 1: All the AHB read or write + access to the PKA RAM occurred while the PKA was operating + and using the internal RAM. Those read or write could not + succeed as the PKA internal RAM is disconnected from the + AHB bus when the PKA is operating (READY bit low).
              When + written:
              • 0: no effect.
              • 1: clears the RAM + access error interrupt.
              */ + __IOM uint32_t ADD_ERR : 1; /*!< [3..3] AHB address error interrupt. When read:
              • 0: All + AHB read or write access to the PKA RAM occurred in a mapped + address range.
              • 1: All AHB read or write access + to the PKA RAM occurred in an unmapped address range.
              When + written:
              • 0: no effect.
              • 1: clears the AHB + Address error interrupt.
              */ + __IM uint32_t ISR_RESERVED : 28; /*!< [31..4] ISR not used bitfield. */ + } ISR_b; + } ; + + union { + __IOM uint32_t IEN; /*!< (@ 0x00000008) Interrupt enable register */ + + struct { + __IOM uint32_t PROCEND_EN : 1; /*!< [0..0] Process ended interrupt enable.
              • 0: interrupt disabled.
              • 1 + interrupt enabled.
              */ + __IM uint32_t : 1; + __IOM uint32_t RAMERR_EN : 1; /*!< [2..2] RAM access error interrupt enable.
              • 0: interrupt + disabled.
              • 1: interrupt enabled.
              */ + __IOM uint32_t ADDERR_EN : 1; /*!< [3..3] AHB address error interrupt enable.
              • 0: interrupt + disabled.
              • 1: interrupt enabled.
              */ + __IM uint32_t ISR_RESERVED : 28; /*!< [31..4] ISR not used bitfield. */ + } IEN_b; + } ; +} PKA_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ ROM_INFO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief ROM information (ROM_INFO) + */ + +typedef struct { /*!< (@ 0x10000000) ROM_INFO Structure */ + __IM uint32_t RESERVED[4]; + __IM uint32_t BOOTLOADER_VERSION; /*!< (@ 0x00000010) Bootloader Version */ + __IM uint32_t RESERVED1[3]; + __IM uint32_t BOOTLOADER; /*!< (@ 0x00000020) Bootloader entry point */ + __IM uint32_t RESERVED2[483]; + __IM uint32_t BLD_TRIM; /*!< (@ 0x000007B0) BLD trimming value */ + __IM uint32_t ADC_BLD_1V8_OFFSET; /*!< (@ 0x000007B4) ADC BLD 1V8 OFFSET */ + __IM uint32_t ADC_BLD_1V8_VALUE; /*!< (@ 0x000007B8) ADC BLD 1V8 VALUE */ + __IM uint32_t ADC_BLD_2V7_OFFSET; /*!< (@ 0x000007BC) ADC BLD 2V7 OFFSET */ + __IM uint32_t ADC_BLD_2V7_VALUE; /*!< (@ 0x000007C0) ADC BLD 2V7 VALUE */ + __IM uint32_t ADC_BLD_3V6_OFFSET; /*!< (@ 0x000007C4) ADC BLD 3V6 OFFSET */ + __IM uint32_t ADC_BLD_3V6_VALUE; /*!< (@ 0x000007C8) ADC BLD 3V6 VALUE */ + __IM uint32_t ADC_SE2_0V_OFFSET; /*!< (@ 0x000007CC) ADC SE2 0V OFFSET */ + __IM uint32_t ADC_SE2_0V_VALUE; /*!< (@ 0x000007D0) ADC SE2 0V VALUE */ + __IM uint32_t ADC_SE2_1V8_OFFSET; /*!< (@ 0x000007D4) ADC SE2 1V8 OFFSET */ + __IM uint32_t ADC_SE2_1V8_VALUE; /*!< (@ 0x000007D8) ADC SE2 1V8 VALUE */ + __IM uint32_t ADC_SE2_3V6_OFFSET; /*!< (@ 0x000007DC) ADC SE2 3V6 OFFSET */ + __IM uint32_t ADC_SE2_3V6_VALUE; /*!< (@ 0x000007E0) ADC SE2 3V6 VALUE */ + __IM uint16_t LDO1V2_TRIMM_CODE; /*!< (@ 0x000007E4) LDO 1V2 trimming code */ + __IM uint16_t LDO1V2_TRIMMING_CODE_CHECK_BYTES;/*!< (@ 0x000007E6) LDO 1V2 trimming code check bytes */ + __IM uint16_t RCO_TRIMMING_CODE; /*!< (@ 0x000007E8) RCO trimming code */ + __IM uint16_t RCO_TRIMMING_CODE_CHECK_BYTES;/*!< (@ 0x000007EA) RCO trimming code check bytes */ + __IM uint32_t RESERVED3[2]; + __IM uint8_t UNIQUE_ID_1; /*!< (@ 0x000007F4) Unique ID 1st byte */ + __IM uint8_t UNIQUE_ID_2; /*!< (@ 0x000007F5) Unique ID 2nd byte */ + __IM uint8_t UNIQUE_ID_3; /*!< (@ 0x000007F6) Unique ID 3rd byte */ + __IM uint8_t UNIQUE_ID_4; /*!< (@ 0x000007F7) Unique ID 4th byte */ + __IM uint8_t UNIQUE_ID_5; /*!< (@ 0x000007F8) Unique ID 5th byte */ + __IM uint8_t UNIQUE_ID_6; /*!< (@ 0x000007F9) Unique ID 6th byte */ + __IM uint16_t UNIQUE_ID_CHECK_CODE; /*!< (@ 0x000007FA) Unique ID check code */ + __IM uint32_t FLASH_PROTECTION_DISABLED; /*!< (@ 0x000007FC) ROM Lock Protection (not locked) */ +} ROM_INFO_Type; /*!< Size = 2048 (0x800) */ + + +/** @} */ /* End of group Device_Peripheral_peripherals */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripheralAddr + * @{ + */ + +#define GPIO_BASE 0x40000000UL +#define FLASH_BASE 0x40100000UL +#define SYSTEM_CTRL_BASE 0x40200000UL +#define UART_BASE 0x40300000UL +#define SPI_BASE 0x40400000UL +#define WDG_BASE 0x40700000UL +#define ADC_BASE 0x40800000UL +#define CKGEN_SOC_BASE 0x40900000UL +#define I2C2_BASE 0x40A00000UL +#define I2C1_BASE 0x40B00000UL +#define AHBUPCONV_BASE 0x40C00000UL +#define MFT1_BASE 0x40D00000UL +#define MFT2_BASE 0x40E00000UL +#define RTC_BASE 0x40F00000UL +#define BLUE_CTRL_BASE 0x48000000UL +#define CKGEN_BLE_BASE 0x48100000UL +#define DMA_BASE 0xA0000000UL +#define DMA_CH0_BASE 0xA0000008UL +#define DMA_CH1_BASE 0xA000001CUL +#define DMA_CH2_BASE 0xA0000030UL +#define DMA_CH3_BASE 0xA0000044UL +#define DMA_CH4_BASE 0xA0000058UL +#define DMA_CH5_BASE 0xA000006CUL +#define DMA_CH6_BASE 0xA0000080UL +#define DMA_CH7_BASE 0xA0000094UL +#define RNG_BASE 0xB0000000UL +#define PKA_BASE 0xC0000000UL +#define ROM_INFO_BASE 0x10000000UL + +/** @} */ /* End of group Device_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_declaration + * @{ + */ + +#define GPIO ((GPIO_Type*) GPIO_BASE) +#define FLASH ((FLASH_Type*) FLASH_BASE) +#define SYSTEM_CTRL ((SYSTEM_CTRL_Type*) SYSTEM_CTRL_BASE) +#define UART ((UART_Type*) UART_BASE) +#define SPI ((SPI_Type*) SPI_BASE) +#define WDG ((WDG_Type*) WDG_BASE) +#define ADC ((ADC_Type*) ADC_BASE) +#define CKGEN_SOC ((CKGEN_SOC_Type*) CKGEN_SOC_BASE) +#define I2C2 ((I2C_Type*) I2C2_BASE) +#define I2C1 ((I2C_Type*) I2C1_BASE) +#define AHBUPCONV ((AHBUPCONV_Type*) AHBUPCONV_BASE) +#define MFT1 ((MFT_Type*) MFT1_BASE) +#define MFT2 ((MFT_Type*) MFT2_BASE) +#define RTC ((RTC_Type*) RTC_BASE) +#define BLUE_CTRL ((BLUE_CTRL_Type*) BLUE_CTRL_BASE) +#define CKGEN_BLE ((CKGEN_BLE_Type*) CKGEN_BLE_BASE) +#define DMA ((DMA_Type*) DMA_BASE) +#define DMA_CH0 ((DMA_CH_Type*) DMA_CH0_BASE) +#define DMA_CH1 ((DMA_CH_Type*) DMA_CH1_BASE) +#define DMA_CH2 ((DMA_CH_Type*) DMA_CH2_BASE) +#define DMA_CH3 ((DMA_CH_Type*) DMA_CH3_BASE) +#define DMA_CH4 ((DMA_CH_Type*) DMA_CH4_BASE) +#define DMA_CH5 ((DMA_CH_Type*) DMA_CH5_BASE) +#define DMA_CH6 ((DMA_CH_Type*) DMA_CH6_BASE) +#define DMA_CH7 ((DMA_CH_Type*) DMA_CH7_BASE) +#define RNG ((RNG_Type*) RNG_BASE) +#define PKA ((PKA_Type*) PKA_BASE) +#define ROM_INFO ((ROM_INFO_Type*) ROM_INFO_BASE) + +/** @} */ /* End of group Device_Peripheral_declaration */ + + +/* ========================================= End of section using anonymous unions ========================================= */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning restore +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG1_H */ + + +/** @} */ /* End of group BlueNRG1 */ + +/** @} */ /* End of group STMicroelectronics */ diff --git a/soc/inc/BlueNRG2.h b/soc/inc/BlueNRG2.h new file mode 100644 index 0000000..427c37d --- /dev/null +++ b/soc/inc/BlueNRG2.h @@ -0,0 +1,3478 @@ +/* + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLI + * ED 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 L + * IABLE 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 LI + * ABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTW + * ARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file BlueNRG2.h + * @brief CMSIS HeaderFile + * @version 1.2.1 + * @date 04. December 2018 + * @note Generated by SVDConv V3.3.21 on Tuesday, 04.12.2018 12:11:03 + * from File 'BlueNRG2.svd', + * last modified on Tuesday, 04.12.2018 11:11:02 + */ + + + +/** @addtogroup STMicroelectronics + * @{ + */ + + +/** @addtogroup BlueNRG2 + * @{ + */ + + +#ifndef BLUENRG2_H +#define BLUENRG2_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ Interrupt Number Definition ================ */ +/* =========================================================================================================================== */ + +typedef enum { +/* ======================================= ARM Cortex-M0 Specific Interrupt Numbers ======================================== */ + Reset_IRQn = -15, /*!< -15 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< -14 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< -13 Hard Fault, all classes of Fault */ + SVCall_IRQn = -5, /*!< -5 System Service Call via SVC instruction */ + PendSV_IRQn = -2, /*!< -2 Pendable request for system service */ + SysTick_IRQn = -1, /*!< -1 System Tick Timer */ +/* ========================================== BlueNRG2 Specific Interrupt Numbers ========================================== */ + GPIO_IRQn = 0, /*!< 0 GPIO bus interrupt */ + NVM_IRQn = 1, /*!< 1 Non-volatile memory (Flash) controller interrupt */ + UART_IRQn = 4, /*!< 4 UART interrupt */ + SPI_IRQn = 5, /*!< 5 SPI interrupt */ + BLUE_CTRL_IRQn = 6, /*!< 6 BLUE controller interrupt */ + WDG_IRQn = 7, /*!< 7 Watchdog interrupt */ + ADC_IRQn = 13, /*!< 13 ADC interrupt */ + I2C2_IRQn = 14, /*!< 14 I2C 2 interrupt */ + I2C1_IRQn = 15, /*!< 15 I2C 1 interrupt */ + MFT1A_IRQn = 17, /*!< 17 Multi functional timer MFT1 interrupt A */ + MFT1B_IRQn = 18, /*!< 18 Multi functional timer MFT1 interrupt B */ + MFT2A_IRQn = 19, /*!< 19 Multi functional timer MFT2 interrupt A */ + MFT2B_IRQn = 20, /*!< 20 Multi functional timer MFT2 interrupt B */ + RTC_IRQn = 21, /*!< 21 RTC interrupt */ + PKA_IRQn = 22, /*!< 22 PKA interrupt */ + DMA_IRQn = 23 /*!< 23 DMA interrupt */ +} IRQn_Type; + + + +/* =========================================================================================================================== */ +/* ================ Processor and Core Peripheral Section ================ */ +/* =========================================================================================================================== */ + +/* =========================== Configuration of the ARM Cortex-M0 Processor and Core Peripherals =========================== */ +#define __CM0_REV 0x0000U /*!< CM0 Core Revision */ +#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __FPU_PRESENT 0 /*!< FPU present or not */ + + +/** @} */ /* End of group Configuration_of_CMSIS */ + +#include "core_cm0.h" /*!< ARM Cortex-M0 processor and core peripherals */ +#include "system_BlueNRG2.h" /*!< BlueNRG2 System */ + +#ifndef __IM /*!< Fallback for older CMSIS versions */ + #define __IM __I +#endif +#ifndef __OM /*!< Fallback for older CMSIS versions */ + #define __OM __O +#endif +#ifndef __IOM /*!< Fallback for older CMSIS versions */ + #define __IOM __IO +#endif + + +/* ======================================== Start of section using anonymous unions ======================================== */ +#if defined (__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined (__ICCARM__) + #pragma language=extended +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" + #pragma clang diagnostic ignored "-Wgnu-anonymous-struct" + #pragma clang diagnostic ignored "-Wnested-anon-types" +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning 586 +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief GPIO Controller (GPIO) + */ + +typedef struct { /*!< (@ 0x40000000) GPIO Structure */ + __IOM uint32_t DATA; /*!< (@ 0x00000000) IO0 to IO14 data value.

              Writing to a bit will + drive the written value on the corresponding + IO when it is configured in GPIO mode and + the output direction. Reading a bit indicates + the pin value

              */ + __IOM uint32_t OEN; /*!< (@ 0x00000004) GPIO output enable register (1 bit per GPIO).
              • 0: + input mode.
              • 1: output mode
              */ + __IOM uint32_t PE; /*!< (@ 0x00000008) Pull enable (1 bit per IO).
              • 0: pull disabled.
              • 1: + pull enabled
              */ + __IOM uint32_t DS; /*!< (@ 0x0000000C) IO driver strength (1 bit per IO).
              • 0: + 2mA.
              • 1: 4 mA
              */ + __IOM uint32_t IS; /*!< (@ 0x00000010) Interrupt sense register (1 bit per IO).
              • 0: + edge detection.
              • 1: level detection
              */ + __IOM uint32_t IBE; /*!< (@ 0x00000014) Interrupt edge register (1 bit per IO).
              • 0: + single edge.
              • 1: both edges
              */ + __IOM uint32_t IEV; /*!< (@ 0x00000018) Interrupt event register (1 bit per IO).
              • 0: + falling edge or low level.
              • 1: rising + edge or high level
              */ + __IOM uint32_t IE; /*!< (@ 0x0000001C) Interrupt mask register (1 bit per IO).
              • 0: + interrupt disabled.
              • 1: interrupt + enabled.
              */ + __IM uint32_t RIS; /*!< (@ 0x00000020) Raw interrupt status register (1 bit per IO) */ + __IM uint32_t MIS; /*!< (@ 0x00000024) Masked interrupt status register (1 bit per IO) */ + __OM uint32_t IC; /*!< (@ 0x00000028) Interrupt clear register (1 bit per IO).
              • 0: + no effect.
              • 1: clear interrupt
              */ + + union { + __IOM uint32_t MODE0; /*!< (@ 0x0000002C) Select mode for IO0 to IO7.
              • 000b: GPIO + mode.
              • 001b: Serial1 mode.
              • 100b: + Serial0 mode.
              • 101b: Microphone/ADC + mode.
              */ + + struct { + __IOM uint32_t IO0 : 3; /*!< [2..0] IO0 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO1 : 3; /*!< [6..4] IO1 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO2 : 3; /*!< [10..8] IO2 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO3 : 3; /*!< [14..12] IO3 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO4 : 3; /*!< [18..16] IO4 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO5 : 3; /*!< [22..20] IO5 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO6 : 3; /*!< [26..24] IO6 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO7 : 3; /*!< [30..28] IO7 mode */ + } MODE0_b; + } ; + + union { + __IOM uint32_t MODE1; /*!< (@ 0x00000030) Select mode for IO8 to IO15.
              • 000b: GPIO + mode.
              • 001b: Serial1 mode.
              • 100b: + Serial0 mode.
              • 101b: Microphone/ADC + mode.
              */ + + struct { + __IOM uint32_t IO8 : 3; /*!< [2..0] IO8 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO9 : 3; /*!< [6..4] IO9 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO10 : 3; /*!< [10..8] IO10 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO11 : 3; /*!< [14..12] IO11 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO12 : 3; /*!< [18..16] IO12 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO13 : 3; /*!< [22..20] IO13 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO14 : 3; /*!< [26..24] IO14 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO15 : 3; /*!< [30..28] IO15 mode */ + } MODE1_b; + } ; + + union { + __IOM uint32_t MODE2; /*!< (@ 0x00000034) Select mode for IO16 to IO23 */ + + struct { + __IOM uint32_t IO16 : 3; /*!< [2..0] IO16 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO17 : 3; /*!< [6..4] IO17 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO18 : 3; /*!< [10..8] IO18 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO19 : 3; /*!< [14..12] IO19 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO20 : 3; /*!< [18..16] IO20 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO21 : 3; /*!< [22..20] IO21 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO22 : 3; /*!< [26..24] IO22 mode */ + __IM uint32_t : 1; + __IOM uint32_t IO23 : 3; /*!< [30..28] IO23 mode */ + } MODE2_b; + } ; + + union { + __IOM uint16_t MODE3; /*!< (@ 0x00000038) Select mode for IO24 to IO25 */ + + struct { + __IOM uint16_t IO24 : 3; /*!< [2..0] IO24 mode */ + __IM uint16_t : 1; + __IOM uint16_t IO25 : 3; /*!< [6..4] IO25 mode */ + } MODE3_b; + } ; + __IM uint16_t RESERVED; + __IOM uint32_t DATS; /*!< (@ 0x0000003C) Set some bits of DATA when in GPIO mode without + affecting the others (1 bit per IO).
              • 0: + no effect.
              • 1: set at 1 the bit
              */ + __IOM uint32_t DATC; /*!< (@ 0x00000040) Clear some bits of DATA when in GPIO mode without + affecting the others (1 bit per IO).
              • 0: + no effect.
              • 1: clear at 0 the bit
              */ + + union { + __IOM uint32_t MFTX; /*!< (@ 0x00000044) Select the IO to be used as capture input for + the MFTX timers */ + + struct { + __IOM uint32_t MFT1_TIMER_A : 8; /*!< [7..0] Selects which IO must be used as input pin TnA for the + MFT1 peripheral. Only mode 2 and mode 4.
              • 0x00: IO0.
              • 0x01: + IO1
              • 0x02: IO2
              • ...
              • 0x0E: IO14
              */ + __IOM uint32_t MFT1_TIMER_B : 8; /*!< [15..8] Selects which IO must be used as input pin TnB for the + MFT1 peripheral. Only mode 2 and mode 4.
              • 0x00: IO0.
              • 0x01: + IO1
              • 0x02: IO2
              • ...
              • 0x0E: IO14
              */ + __IOM uint32_t MFT2_TIMER_A : 8; /*!< [23..16] Selects which IO must be used as input pin TnA for + the MFT2 peripheral. Only mode 2 and mode 4.
              • 0x00: + IO0.
              • 0x01: IO1
              • 0x02: IO2
              • ...
              • 0x0E: + IO14
              */ + __IOM uint32_t MFT2_TIMER_B : 8; /*!< [31..24] Selects which IO must be used as input pin TnB for + the MFT2 peripheral. Only mode 2 and mode 4.
              • 0x00: + IO0.
              • 0x01: IO1
              • 0x02: IO2
              • ...
              • 0x0E: + IO14
              */ + } MFTX_b; + } ; +} GPIO_Type; /*!< Size = 72 (0x48) */ + + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Flash Controller (FLASH) + */ + +typedef struct { /*!< (@ 0x40100000) FLASH Structure */ + __IOM uint16_t COMMAND; /*!< (@ 0x00000000) Commands for the module */ + __IM uint16_t RESERVED; + __IOM uint16_t CONFIG; /*!< (@ 0x00000004) Configure the wrapper */ + __IM uint16_t RESERVED1; + + union { + __IOM uint16_t IRQSTAT; /*!< (@ 0x00000008) Flash status interrupt (masked) */ + + struct { + __IOM uint16_t CMDDONE : 1; /*!< [0..0] Command is done. 1: clear the interrupt pending bit. */ + __IOM uint16_t CMDSTART : 1; /*!< [1..1] Command is started. 1: clear the interrupt pending bit. */ + __IOM uint16_t CMDERR : 1; /*!< [2..2] Command written while BUSY. 1: clear the interrupt pending + bit. */ + __IOM uint16_t ILLCMD : 1; /*!< [3..3] Illegal command written. 1: clear the interrupt pending + bit. */ + __IOM uint16_t READOK : 1; /*!< [4..4] Mass read was OK. 1: clear the interrupt pending bit. */ + __IOM uint16_t FLNREADY : 1; /*!< [5..5] Flash not ready (sleep). 1: clear the interrupt pending + bit. */ + } IRQSTAT_b; + } ; + __IM uint16_t RESERVED2; + + union { + __IOM uint16_t IRQMASK; /*!< (@ 0x0000000C) Mask for interrupts */ + + struct { + __IOM uint16_t CMDDONE : 1; /*!< [0..0] Command is done. */ + __IOM uint16_t CMDSTART : 1; /*!< [1..1] Command is started. */ + __IOM uint16_t CMDERR : 1; /*!< [2..2] Command written while BUSY */ + __IOM uint16_t ILLCMD : 1; /*!< [3..3] Illegal command written */ + __IOM uint16_t READOK : 1; /*!< [4..4] Mass read was OK. */ + __IOM uint16_t FLNREADY : 1; /*!< [5..5] Flash not ready (sleep). */ + } IRQMASK_b; + } ; + __IM uint16_t RESERVED3; + + union { + __IOM uint16_t IRQRAW; /*!< (@ 0x00000010) Status interrupts (unmasked) */ + + struct { + __IOM uint16_t CMDDONE : 1; /*!< [0..0] Command is done. */ + __IOM uint16_t CMDSTART : 1; /*!< [1..1] Command is started. */ + __IOM uint16_t CMDERR : 1; /*!< [2..2] Command written while BUSY */ + __IOM uint16_t ILLCMD : 1; /*!< [3..3] Illegal command written */ + __IOM uint16_t READOK : 1; /*!< [4..4] Mass read was OK. */ + __IOM uint16_t FLNREADY : 1; /*!< [5..5] Flash not ready (sleep). */ + } IRQRAW_b; + } ; + __IM uint16_t RESERVED4; + __IM uint16_t SIZE; /*!< (@ 0x00000014) Indicates the size of the main Flash */ + __IM uint16_t RESERVED5; + __IOM uint32_t ADDRESS; /*!< (@ 0x00000018) Address for programming Flash, will auto-increment */ + __IM uint32_t RESERVED6[9]; + __IOM uint32_t DATA0; /*!< (@ 0x00000040) Program cycle data */ + __IOM uint32_t DATA1; /*!< (@ 0x00000044) Program cycle data */ + __IOM uint32_t DATA2; /*!< (@ 0x00000048) Program cycle data */ + __IOM uint32_t DATA3; /*!< (@ 0x0000004C) Program cycle data */ +} FLASH_Type; /*!< Size = 80 (0x50) */ + + + +/* =========================================================================================================================== */ +/* ================ SYSTEM_CTRL ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief System controller (SYSTEM_CTRL) + */ + +typedef struct { /*!< (@ 0x40200000) SYSTEM_CTRL Structure */ + __IOM uint8_t WKP_IO_IS; /*!< (@ 0x00000000) Level selection for wakeup IO (1 bit for IO) + IO[13:9].
              • 0: The system wakes up + when IO is low.
              • 1: The system wakes + up when IO is high.
              */ + __IM uint8_t RESERVED[3]; + __IOM uint8_t WKP_IO_IE; /*!< (@ 0x00000004) Enables the IO that wakes up the device (1 bit + for IO) IO[13:9].
              • 0: The wakes up + feature on the IO is disabled.
              • 1: + The wakes up feature on the IO is enabled.
              */ + __IM uint8_t RESERVED1[3]; + + union { + __IOM uint8_t CTRL; /*!< (@ 0x00000008) XO frequency indication to provide by the application */ + + struct { + __IOM uint8_t MHZ32_SEL : 1; /*!< [0..0] Indicates the crystal frequency used in the application.
              • 0: + The 16 MHz is selected.
              • 1: The 32 MHz is selected.
              */ + } CTRL_b; + } ; + __IM uint8_t RESERVED2[3]; + __IOM uint8_t SLEEPIO_OEN; /*!< (@ 0x0000000C) IO output enable register for low power modes. + It is 1 bit for IO: bit0 for IO9, bit1 for + IO10, bit2 for IO9.
              • 0: IO output + disabled.
              • 1: IO output is enabled.
              */ + __IM uint8_t RESERVED3[3]; + __IOM uint8_t SLEEPIO_OUT; /*!< (@ 0x00000010) IO data output value register for low power modes. + It is 1 bit for IO: bit0 for IO9, bit1 for + IO10, bit2 for IO9.
              • 0: put the IO + low.
              • 1: put the IO high.
              */ + __IM uint8_t RESERVED4[3]; + __IOM uint8_t SLEEPIO_DS; /*!< (@ 0x00000014) IO drive strength control register for low power + modes. It is 1 bit for IO: bit0 for IO9, + bit1 for IO10, bit2 for IO9.
              • 0: drive + up to 2 mA.
              • 1: drive up to 4 mA.
              */ + __IM uint8_t RESERVED5[3]; + __IOM uint8_t SLEEPIO_PE; /*!< (@ 0x00000018) IO pull enable register for low power modes. + It is 1 bit for IO: bit0 for IO9, bit1 for + IO10, bit2 for IO9.
              • 0: pull disabled.
              • 1: + pull enabled.
              */ +} SYSTEM_CTRL_Type; /*!< Size = 25 (0x19) */ + + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief UART (UART) + */ + +typedef struct { /*!< (@ 0x40300000) UART Structure */ + + union { + __IOM uint16_t DR; /*!< (@ 0x00000000) Data Register */ + + struct { + __IOM uint16_t DATA : 8; /*!< [7..0] UART data register:
              • Receive: read data character.
              • Trans + it: write data character.
              */ + __IM uint16_t FE : 1; /*!< [8..8] Frame error. This bit is set to 1 if the received character + did not have a valid stop bit. In FIFO mode, this error + is associated with the character at the top of the FIFO. */ + __IM uint16_t PE : 1; /*!< [9..9] Parity error. This bit is set to 1 if the parity of the + received data character does not match the parity selected + as defined by bits 2 and 7 of the LCRH_RX register. In + FIFO mode, this error is associated with the character + at the top of the FIFO. */ + __IM uint16_t BE : 1; /*!< [10..10] Break error. This bit is set to 1 if a break condition + was detected, indicating that the received data input was + held low for longer than a full-word transmission time + (defined as start, data, parity and stop bits). In FIFO + mode, this error is associated with the character at the + top of the FIFO. When a break occurs, only one 0 character + is loaded into the FIFO. The next character is only enabled + after the receive data input goes to HIGH (marking state), + and the next valid start bit is received */ + __IM uint16_t OE : 1; /*!< [11..11] Overrun error. This bit is set to 1 if data is received + and the receive FIFO is already full. This is cleared to + 0b once there is an empty space in the FIFO and a new character + can be written to it. The FIFO content remains valid since + no further data is written when the FIFO is full, only + the content of the shift register is overwritten. */ + } DR_b; + } ; + __IM uint16_t RESERVED; + + union { + union { + __IM uint32_t RSR; /*!< (@ 0x00000004) Receive Status Register */ + + struct { + __IM uint32_t FE : 1; /*!< [0..0] Frame error. This bit is set to 1 if the received character + did not have a valid stop bit (a valid stop bit is 1).This + bit is cleared to 0b after a write to ECR. In FIFO mode, + this error is associated with the character at the top + of the FIFO. */ + __IM uint32_t PE : 1; /*!< [1..1] Parity error. This bit is set to 1 if the parity of the + received data character does not match the parity selected + as defined by bits 2 and 7 of the LCRH_RX register.This + bit is cleared to 0b after a write to ECR. In FIFO mode, + this error is associated with the character at the top + of the FIFO. */ + __IM uint32_t BE : 1; /*!< [2..2] Break error. This bit is set to 1 if a break condition + was detected, indicating that the received data input was + held low for longer than a full-word transmission time + (defined as start, data, parity and stop bits). This bit + is cleared to 0b after a write to ECR. In FIFO mode, this + error is associated with the character at the top of the + FIFO. When a break occurs, only one 0 character is loaded + into the FIFO. The next character is only enabled after + the receive data input goes to HIGH (marking state), and + */ + __IM uint32_t OE : 1; /*!< [3..3] Overrun error. This bit is set to 1 if data is received + and the receive FIFO is already full. This is cleared to + 0 by a write to ECR (data value is not important). The + FIFO contents remain valid since no further data is written + when the FIFO is full, only the content of the shift register + are overwritten. The CPU or DMA must now read the data + in order to empty the FIFO. */ + } RSR_b; + } ; + __IOM uint32_t ECR; /*!< (@ 0x00000004) Error Clear Register. A write to this register + clears the framing (FE), parity (PE), break + (BE), and overrun (OE) errors. */ + }; + __IM uint32_t RESERVED1; + + union { + __IOM uint32_t TIMEOUT; /*!< (@ 0x0000000C) Timeout Register */ + + struct { + __IOM uint32_t PERIOD : 22; /*!< [21..0] Timeout period configuration. This bit field contains + the timeout period for the UART timeout interrupt assertion. + The receive timeout interrupt is asserted when the receive + FIFO is not empty and no further data is received over + a programmed timeout period. The duration before the timeout + interrupt will assert is calculated by the following formula:

              Timeout_D + ration = (TIMEOUT_PERIOD) / (OVSP * Baud_Rate)

              or

              Timeout_Duration + = (TIMEOUT_PERIOD) * Baud_Divisor * Tuartclk

              */ + } TIMEOUT_b; + } ; + __IM uint32_t RESERVED2[2]; + + union { + __IM uint16_t FR; /*!< (@ 0x00000018) Flag Register */ + + struct { + __IM uint16_t CTS : 1; /*!< [0..0] Clear to send. */ + __IM uint16_t : 2; + __IM uint16_t BUSY : 1; /*!< [3..3] UART Busy. If this bit is set to 1, the UART is busy + transmitting data. This bit remains set until the complete + byte, including all the stop bits, has been sent from the + shift register. However, if the transmit section of the + UART is disabled in the middle of a transmission, the BUSY + bit gets cleared. This bit is set again once the transmit + section is re-enabled to complete the remaining transmission.This + bit is set as soon as the transmit FIFO becomes nonempty + (regardless of whether the UART is enabled or */ + __IM uint16_t RXFE : 1; /*!< [4..4] Receive FIFO empty. If the FIFO is disabled (bit FEN + = 0b), this bit is set when the receive holding register + is empty. If the FIFO is enabled (FEN = 1b), the RXFE bit + is set when the receive FIFO is empty. */ + __IM uint16_t TXFF : 1; /*!< [5..5] Transmit FIFO full. If the FIFO is disabled (bit FEN + = 0b), this bit is set when the transmit holding register + is full. If the FIFO is enabled (FEN = 1b), the TXFF bit + is set when the transmit FIFO is full. */ + __IM uint16_t RXFF : 1; /*!< [6..6] Receive FIFO full. If the FIFO is disabled (bit FEN = + 0b), this bit is set when the receive holding register + is full. If the FIFO is enabled (FEN = 1b), the RXFF bit + is set when the receive FIFO is full. */ + __IM uint16_t TXFE : 1; /*!< [7..7] Transmit FIFO empty. If the FIFO is disabled (bit FEN + = 0b), this bit is set when the transmit holding register + is empty. If the FIFO is enabled (FEN = 1b), the TXFE bit + is set when the transmit FIFO is empty. */ + __IM uint16_t : 1; + __IM uint16_t DCTS : 1; /*!< [9..9] Delta Clear To Send. This bit is set CTS changes since + the last read of the FR register. */ + __IM uint16_t : 3; + __IM uint16_t RTXDIS : 1; /*!< [13..13] Remote Transmitter Disabled (software flow control). + This bit indicates an Xoff character was sent to the remote + transmitter to stop it after the received FIFO has passed + over its trigger limit. This bit is cleared when a Xon + character is sent to the remote transmitter. */ + } FR_b; + } ; + __IM uint16_t RESERVED3; + + union { + __IOM uint8_t LCRH_RX; /*!< (@ 0x0000001C) Receive Line Control Register */ + + struct { + __IM uint8_t : 1; + __IOM uint8_t PEN_RX : 1; /*!< [1..1] RX parity enable:
              • 0: Parity disabled.
              • 1: + Parity enabled.
              */ + __IOM uint8_t EPS_RX : 1; /*!< [2..2] RX even parity selection, when the parity is enabled.
              • 0: + Odd parity generation and checking is performed during + reception, which check for an odd number of 1s in data + and parity bits.
              • 1: Even parity generation and + checking is performed during reception, which check for + an even number of 1s in data and parity bits.
              */ + __IOM uint8_t STP2_RX : 1; /*!< [3..3] RX two stop bits select. This bit enables the check for + two stop bits being received:
              • 0: 1 stop bit received.
              • 1: + 2 stop bits received.
              */ + __IOM uint8_t FEN_RX : 1; /*!< [4..4] RX enable FIFOs. This bit enables/disables the receive + RX FIFO buffer:
              • 0: RX FIFO is disabled (character + mode).
              • 1: RX FIFO is enabled.
              */ + __IOM uint8_t WLEN_RX : 2; /*!< [6..5] RX Word length. This bit field indicates the number of + data bits received in a frame as follows:
              • 00b: 5 + bits.
              • 01b: 6 bits.
              • 10b: 7 bits.
              • 11b: + 8 bits.
              */ + __IOM uint8_t SPS_RX : 1; /*!< [7..7] RX stick parity select:
              • 0: stick parity is disabled.
              • 1: + when PEN_RX = 1b (parity enabled) and EPS_RX = 1b (even + parity), the parity is checked as a 0. When PEN_RX = 1b + and EPS_RX = 0b (odd parity), the parity bit is checked + as a 1.
              */ + } LCRH_RX_b; + } ; + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + __IM uint32_t RESERVED6; + + union { + __IOM uint16_t IBRD; /*!< (@ 0x00000024) Integer Baud Rate Register */ + + struct { + __IOM uint16_t DIVINT : 16; /*!< [15..0] Baud rate integer. The baud rate divisor is calculated + as follows:

              When OVSFACT = 0b in the CR register: Baud + rate divisor = (Frequency (UARTCLK)/(16*Baud rate))

              When + OVSFACT = 1b in CR register: Baud rate divisor = (Frequency + (UARTCLK)/(8*Baud rate))

              where Frequency (UARTCLK) is + the UART reference clock frequency. The baud rate divisor + comprises the integer value (DIVINT) and the fractional + value (DIVFRAC). The contents of the IBRD and FBRD registers + are not updated until transmission or recept */ + } IBRD_b; + } ; + __IM uint16_t RESERVED7; + + union { + __IOM uint8_t FBRD; /*!< (@ 0x00000028) Fractional Baud Rate Register */ + + struct { + __IOM uint8_t DIVFRAC : 6; /*!< [5..0] Baud rate fraction. Baud rate integer. The baud rate + divisor is calculated as follows:

              When OVSFACT = 0b in + the CR register: Baud rate divisor = (Frequency (UARTCLK)/(16*Baud + rate))

              When OVSFACT = 1b in CR register: Baud rate + divisor = (Frequency (UARTCLK)/(8*Baud rate))

              where + Frequency (UARTCLK) is the UART reference clock frequency. + The baud rate divisor comprises the integer value (DIVINT) + and the fractional value (DIVFRAC). The contents of the + IBRD and FBRD registers are not updated until tr */ + } FBRD_b; + } ; + __IM uint8_t RESERVED8; + __IM uint16_t RESERVED9; + + union { + __IOM uint8_t LCRH_TX; /*!< (@ 0x0000002C) Transmit Line Control Register */ + + struct { + __IOM uint8_t BRK : 1; /*!< [0..0] Send break. This bit allows a continuous low-level to + be forced on TX output, after completion of the current + character. This bit must be asserted for at least one complete + frame transmission time in order to generate a break condition. + The transmit FIFO contents remain unaffected during a break + condition.
              • 0: Normal transmission.
              • 1: Break + condition transmission.
              */ + __IOM uint8_t PEN_TX : 1; /*!< [1..1] TX parity enable:
              • 0: Parity disabled.
              • 1: + Parity Enable.
              */ + __IOM uint8_t EPS_TX : 1; /*!< [2..2] TX even parity select. This bit selects the parity generation, + when the parity is enabled (PEN_TX =1b). This bit has no + effect when parity is disabled (PEN_TX = 0b).
              • 0: + Odd parity generation and checking is performed during + transmission, which check for an odd number of 1s in data + and parity bits.
              • 1: Even parity generation and + checking is performed during transmission, which check + for an even number of 1s in data and parity bits.
              */ + __IOM uint8_t STP2_TX : 1; /*!< [3..3] TX two stop bits select. This bit enables the check for + two stop bits being received:
              • 0: 1 stop bit received.
              • 1: + 2 stop bits received.
              */ + __IOM uint8_t FEN_TX : 1; /*!< [4..4] TX Enable FIFO. This bit enables/disables the transmit + TX FIFO buffer:
              • 0: TX FIFO is disabled (character + mode), i.e. the TX FIFO becomes a 1-byte deep holding register.
              • 1 + TX FIFO is enabled.
              */ + __IOM uint8_t WLEN_TX : 2; /*!< [6..5] TX word length. This bit field indicates the number of + data bits transmitted in a frame as follows:
              • 00b: + 5 bits.
              • 01b: 6 bits.
              • 10b: 7 bits.
              • 11b: + 8 bits.
              */ + __IOM uint8_t SPS_TX : 1; /*!< [7..7] TX Stick parity check:
              • 0: stick parity disable.
              • 1: + when PEN_TX = 1b (parity enabled) and EPS_TX = 1b (even + parity), the parity is transmitted as a 0. When PEN_TX + = 1b and EPS_TX = 0b (odd parity), the parity bit is transmitted + as a 1.
              */ + } LCRH_TX_b; + } ; + __IM uint8_t RESERVED10; + __IM uint16_t RESERVED11; + + union { + __IOM uint32_t CR; /*!< (@ 0x00000030) Control Register */ + + struct { + __IOM uint32_t EN : 1; /*!< [0..0] UART enable. This bit enables the UART.
              • 0: UART + is disabled.
              • 1: UART is enabled. Data transmission + and reception can occur. When the UART is disabled in the + middle of transmission or reception, it completes the current + character before stopping.
              */ + __IM uint32_t : 2; + __IOM uint32_t OVSFACT : 1; /*!< [3..3] UART oversampling factor.This bit enables the UART oversampling + factor. If UARTCLK is 16 MHz thus max. baud-rate is 1 Mbaud + when OVSFACT = 0b, and 2 Mbaud when OVSFACT = 1b.
              • 0: + UART it is 16 UARTCLK clock cycles.
              • 1: UART it + is 8 UARTCLK clock cycles.
              */ + __IM uint32_t : 4; + __IOM uint32_t TXE : 1; /*!< [8..8] Transmit enable.
              • 0b: UART TX disabled.
              • 1b: + UART TX enabled.
              */ + __IOM uint32_t RXE : 1; /*!< [9..9] Receive enable.
              • 0b: UART RX disabled.
              • 1b: + UART RX enabled.
              */ + __IM uint32_t : 1; + __IOM uint32_t RTS : 1; /*!< [11..11] Request to send.
              • 0: RTS is high.
              • 1: + RTS is low.
              */ + __IM uint32_t : 2; + __IOM uint32_t RTSEN : 1; /*!< [14..14] RTS hardware flow control enable.
              • 0b: RTS disabled.
              • 1b + RTS enabled. Data is only requested when there is space + in the receive FIFO for it to be received.
              */ + __IOM uint32_t CTSEN : 1; /*!< [15..15] CTS hardware flow control enable.
              • 0b: CTS disabled.
              • 1b + CTS enabled. Data is only transmitted when the CTS is asserted.
              + */ + __IOM uint32_t STA_B_DURATION : 4; /*!< [19..16] START bit duration Receiver state. These bits can be + used to configure the START bit duration (in clock cycles) + to get the bit sampled in the middle of the UART receiver. + These bits can be used only when using high baud rates + (IBRD = 1, FBRD >= 0 and OVSFACT = 1). Below the formula + to calculate the START bit duration receiver state:

              STA_B_DURATION + = Integer(Fuartclk/(2* BAUD RATE)) - 1

              Example: when + UARTCLK = 16 MHz and BAUD RATE = 2.0 Mbps then STA_B_DURATION + = 4 - 1 = 3. STA_B_DURATION field should */ + } CR_b; + } ; + + union { + __IOM uint8_t IFLS; /*!< (@ 0x00000034) Interrupt FIFO level select register */ + + struct { + __IOM uint8_t TXIFLSEL : 3; /*!< [2..0] Transmit interrupt FIFO level select. This bit field + selects the trigger points for TX FIFO interrupt:
              • 000b: + Interrupt when FIFO >= 1/64 empty.
              • 001b: Interrupt + when FIFO >= 1/32 empty.
              • 010b: Interrupt when FIFO + >= 1/16 empty.
              • 011b: Interrupt when FIFO >= 1/8 + empty.
              • 100b: Interrupt when FIFO >= 1/4 empty.
              • 101b: + Interrupt when FIFO >= 1/2 empty.
              • 110b: Interrupt + when FIFO >= 3/4 empty.
              */ + __IOM uint8_t RXIFLSEL : 3; /*!< [5..3] Receive interrupt FIFO level select. This bit field selects + the trigger points for RX FIFO interrupt:
              • 000b: + Interrupt when FIFO >= 1/64 full.
              • 001b: Interrupt + when FIFO >= 1/32 full.
              • 010b: Interrupt when FIFO + >= 1/16 full.
              • 011b: Interrupt when FIFO >= 1/8 + full.
              • 100b: Interrupt when FIFO >= 1/4 full.
              • 101b: + Interrupt when FIFO >= 1/2 full.
              • 110b: Interrupt + when FIFO >= 3/4 full.
              */ + } IFLS_b; + } ; + __IM uint8_t RESERVED12; + __IM uint16_t RESERVED13; + + union { + __IOM uint16_t IMSC; /*!< (@ 0x00000038) Interrupt Mask Set/Clear Register */ + + struct { + __IM uint16_t : 1; + __IOM uint16_t CTSMIM : 1; /*!< [1..1] Clear to send modem interrupt mask. On a read, the current + mask for the CTSMIM interrupt is returned.
              • 0: Clears + the mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + __IM uint16_t : 2; + __IOM uint16_t RXIM : 1; /*!< [4..4] Receive interrupt mask. On a read, the current mask for + the RXIM interrupt is returned.
              • 0: Clears the mask + (interrupt is disabled).
              • 1: Sets the mask (interrupt + is enabled).
              */ + __IOM uint16_t TXIM : 1; /*!< [5..5] Transmit interrupt mask. On a read, the current mask + for the TXIM interrupt is returned.
              • 0: Clears the + mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + __IOM uint16_t RTIM : 1; /*!< [6..6] Receive timeout interrupt mask. On a read, the current + mask for the RTIM interrupt is returned.
              • 0: Clears + the mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + __IOM uint16_t FEIM : 1; /*!< [7..7] Framing error interrupt mask. On a read, the current + mask for the FEIM interrupt is returned.
              • 0: Clears + the mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + __IOM uint16_t PEIM : 1; /*!< [8..8] Parity error interrupt mask. On a read, the current mask + for the PEIM interrupt is returned.
              • 0: Clears the + mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + __IOM uint16_t BEIM : 1; /*!< [9..9] Break error interrupt mask. On a read, the current mask + for the BEIM interrupt is returned.
              • 0: Clears the + mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + __IOM uint16_t OEIM : 1; /*!< [10..10] Overrun error interrupt mask. On a read, the current + mask for the OEIM interrupt is returned.
              • 0: Clears + the mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + __IOM uint16_t XOFFIM : 1; /*!< [11..11] XOFF interrupt mask. On a read, the current mask for + the XOFFIM interrupt is returned.
              • 0: Clears the + mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + __IOM uint16_t TXFEIM : 1; /*!< [12..12] TX FIFO empty interrupt mask. On a read, the current + mask for the TXFEIM interrupt is returned.
              • 0: Clears + the mask (interrupt is disabled).
              • 1: Sets the mask + (interrupt is enabled).
              */ + } IMSC_b; + } ; + __IM uint16_t RESERVED14; + + union { + __IM uint16_t RIS; /*!< (@ 0x0000003C) Raw Interrupt Status Register */ + + struct { + __IM uint16_t : 1; + __IM uint16_t CTSMIS : 1; /*!< [1..1] Clear to send interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t : 2; + __IM uint16_t RXIS : 1; /*!< [4..4] Receive interrupt status.
              • 0: The interrupt is + not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t TXIM : 1; /*!< [5..5] Transmit interrupt status.
              • 0: The interrupt is + not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t RTIS : 1; /*!< [6..6] Receive timeout interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t FEIS : 1; /*!< [7..7] Framing error interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t PEIS : 1; /*!< [8..8] Parity error interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t BEIS : 1; /*!< [9..9] Break error interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t OEIS : 1; /*!< [10..10] Overrun error interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t XOFFIS : 1; /*!< [11..11] XOFF interrupt status.
              • 0: The interrupt is not + pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t TXFEIS : 1; /*!< [12..12] TX FIFO empty interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + } RIS_b; + } ; + __IM uint16_t RESERVED15; + + union { + __IM uint16_t MIS; /*!< (@ 0x00000040) Masked Interrupt Status Register */ + + struct { + __IM uint16_t : 1; + __IM uint16_t CTSMMIS : 1; /*!< [1..1] Clear to send masked interrupt status.
              • 0: The + interrupt is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t : 2; + __IM uint16_t RXMIS : 1; /*!< [4..4] Receive masked interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t TXMIS : 1; /*!< [5..5] Transmit masked interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t RTMIS : 1; /*!< [6..6] Receive timeout masked interrupt status.
              • 0: The + interrupt is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t FEMIS : 1; /*!< [7..7] Framing error masked interrupt status.
              • 0: The + interrupt is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t PEMIS : 1; /*!< [8..8] Parity error masked interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t BEMIS : 1; /*!< [9..9] Break error masked interrupt status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t OEMIS : 1; /*!< [10..10] Overrun error masked interrupt status.
              • 0: The + interrupt is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t XOFFMIS : 1; /*!< [11..11] XOFF interrupt masked status.
              • 0: The interrupt + is not pending.
              • 1: The interrupt is pending.
              */ + __IM uint16_t TXFEMIS : 1; /*!< [12..12] TX FIFO empty masked interrupt status.
              • 0: The + interrupt is not pending.
              • 1: The interrupt is pending.
              */ + } MIS_b; + } ; + __IM uint16_t RESERVED16; + + union { + __OM uint16_t ICR; /*!< (@ 0x00000044) Interrupt Clear Register */ + + struct { + __IM uint16_t : 1; + __OM uint16_t CTSMIC : 1; /*!< [1..1] Clear to send modem interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __IM uint16_t : 2; + __OM uint16_t RXIC : 1; /*!< [4..4] Receive interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint16_t TXIC : 1; /*!< [5..5] Transmit interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint16_t RTIC : 1; /*!< [6..6] Receive timeout interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint16_t FEIC : 1; /*!< [7..7] Framing error interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint16_t PEIC : 1; /*!< [8..8] Parity error interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint16_t BEIC : 1; /*!< [9..9] Break error interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint16_t OEIC : 1; /*!< [10..10] Overrun error interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint16_t XOFFIC : 1; /*!< [11..11] XOFF interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + __OM uint16_t TXFEIC : 1; /*!< [12..12] TX FIFO empty interrupt clear.
              • 0: No effect.
              • 1: + Clears the interrupt.
              */ + } ICR_b; + } ; + __IM uint16_t RESERVED17; + + union { + __IOM uint8_t DMACR; /*!< (@ 0x00000048) DMA control register */ + + struct { + __IOM uint8_t RXDMAE : 1; /*!< [0..0] Receive DMA enable bit.
              • 0: DMA mode is disabled + for reception.
              • 1: DMA mode is enabled for reception.
              */ + __IOM uint8_t TXDMAE : 1; /*!< [1..1] Transmit DMA enable bit.
              • 0: DMA mode is disabled + for transmit.
              • 1: DMA mode is enabled for transmit.
              */ + __IM uint8_t : 1; + __IOM uint8_t DMAONERR : 1; /*!< [3..3] DMA on error.
              • 0: UART error interrupt status has + no impact in receive DMA mode.
              • 1: DMA receive requests + are disabled when the UART error interrupt is asserted.
              */ + } DMACR_b; + } ; + __IM uint8_t RESERVED18; + __IM uint16_t RESERVED19; + __IM uint32_t RESERVED20; + + union { + __IOM uint8_t XFCR; /*!< (@ 0x00000050) XON/XOFF Control Register */ + + struct { + __IOM uint8_t SFEN : 1; /*!< [0..0] Software flow control enable.
              • 0: Software flow + control disable.
              • 1: software flow control enable.
              */ + __IOM uint8_t SFRMOD : 2; /*!< [2..1] Software receive flow control mode:
              • 00b: Receive + flow control is disabled.
              • 01b: Xon1, Xoff1 characters + are used in receiving software flow control.
              • 10b: + Xon2, Xoff2 characters are used in receiving software flow + control.
              • 11b: Xon1 and Xon2, Xoff1 and Xoff2 characters + are used in receiving software flow control.
              */ + __IOM uint8_t SFTMOD : 2; /*!< [4..3] Software transmit flow control mode:
              • 00b: Transmit + flow control is disabled.
              • 01b: Xon1, Xoff1 characters + are used in transmitting software flow control.
              • 10b: + Xon2, Xoff2 characters are used in transmitting software + flow control.
              • 11b: Xon1 and Xon2, Xoff1 and Xoff2 + characters are used in transmitting software flow control.
              */ + __IOM uint8_t XONANY : 1; /*!< [5..5] Xon-any bit:
              • 0: Incoming character must match + Xon programmed value(s) to be a valid Xon.
              • 1: Any + incoming character is considered as a valid Xon.
              */ + __IOM uint8_t SPECHAR : 1; /*!< [6..6] Special character detection bit.
              • 0: Special character + detection disabled.
              • 1: Special character detection + enabled.
              */ + } XFCR_b; + } ; + __IM uint8_t RESERVED21; + __IM uint16_t RESERVED22; + + union { + __IOM uint8_t XON1; /*!< (@ 0x00000054) Register used to store the Xon1 character used + for software flow control */ + + struct { + __IOM uint8_t XON1 : 8; /*!< [7..0] Value of Xon1 character used in the software flow control */ + } XON1_b; + } ; + __IM uint8_t RESERVED23; + __IM uint16_t RESERVED24; + + union { + __IOM uint8_t XON2; /*!< (@ 0x00000058) Register used to store the Xon2 character used + for software flow control */ + + struct { + __IOM uint8_t XON2 : 8; /*!< [7..0] Value of Xon2 character used in the software flow control */ + } XON2_b; + } ; + __IM uint8_t RESERVED25; + __IM uint16_t RESERVED26; + + union { + __IOM uint8_t XOFF1; /*!< (@ 0x0000005C) Register used to store the Xoff1 character used + for software flow control */ + + struct { + __IOM uint8_t XOFF1 : 8; /*!< [7..0] Value of Xoff1 character used in the software flow control */ + } XOFF1_b; + } ; + __IM uint8_t RESERVED27; + __IM uint16_t RESERVED28; + + union { + __IOM uint8_t XOFF2; /*!< (@ 0x00000060) Register used to store the Xoff2 character used + for software flow control */ + + struct { + __IOM uint8_t XOFF2 : 8; /*!< [7..0] Value of Xoff2 character used in the software flow control */ + } XOFF2_b; + } ; + __IM uint8_t RESERVED29; + __IM uint16_t RESERVED30; +} UART_Type; /*!< Size = 100 (0x64) */ + + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Serial peripheral interface (SPI) + */ + +typedef struct { /*!< (@ 0x40400000) SPI Structure */ + + union { + __IOM uint32_t CR0; /*!< (@ 0x00000000) Control Register 0 */ + + struct { + __IOM uint32_t DSS : 5; /*!< [4..0] Data size select. (DSS+1) defines the number of bits:
              • 0x00: + Reserved.
              • 0x01: Reserved.
              • 0x02: Reserved.
              • 0x03: + 4-bit data.
              • 0x04: 5-bit data.
              • ...
              • 0x1F: + 32-bit data.
              */ + __IM uint32_t : 1; + __IOM uint32_t SPO : 1; /*!< [6..6] Clock polarity.
              • 0: Steady state of clock polarity + is low.
              • 1: Steady state of clock polarity is high.
              */ + __IOM uint32_t SPH : 1; /*!< [7..7] Clock phase.
              • 0: Steady state of clock phase is + low.
              • 1: Steady state of clock phase is high.
              */ + __IOM uint32_t SCR : 8; /*!< [15..8] Serial Clock Rate.

              The SRC value is used to generate + the transmit and receive bit rate of the SPI. The bit rate + is: f_SPICLK / (CPSDVR * (1 + SCR)), where CPSDVR is an + even value from 2 to 254 and SCR is a value from 0 to 255.

              */ + __IOM uint32_t CSS : 5; /*!< [20..16] Command Size Select (in MicroWire mode). (CSS+1) defines + the number of bits:
              • 0x00: Reserved.
              • 0x01: + Reserved.
              • 0x02: Reserved.
              • 0x03: 4-bit data.
              • 0x04: + 5-bit data.
              • ...
              • 0x1F: 32-bit data.
              */ + __IOM uint32_t FRF : 2; /*!< [22..21] Frame format.
              • 00b: Motorola SPI frame format.
              • 10b: + National MicroWire frame format.
              */ + __IOM uint32_t SPIM : 2; /*!< [24..23] SPI transmission mode.
              • 00b: Full duplex mode.
              • 01b: + Transmit mode.
              • 10b: Receive mode.
              • 11b: + Combined mode.
              */ + __IM uint32_t : 1; + __IOM uint32_t CS1 : 1; /*!< [26..26] Chip Selection for slave one
              • 0: the slave 1 + is selected.
              • 1: the slave 1 is not selected.
              */ + } CR0_b; + } ; + + union { + __IOM uint32_t CR1; /*!< (@ 0x00000004) Control Register 1 */ + + struct { + __IM uint32_t : 1; + __IOM uint32_t SSE : 1; /*!< [1..1] SPI enable.
              • 0: SPI disable.
              • 1: SPI enable.
              */ + __IOM uint32_t MS : 1; /*!< [2..2] Master or slave mode select.
              • 0: Master mode.
              • 1: + Slave mode.
              */ + __IOM uint32_t SOD : 1; /*!< [3..3] Slave mode output disable (slave mode only).
              • 0: + SPI can drive the MISO signal in slave mode.
              • 1: + SPI must not drive the MISO signal in slave mode.
              In + multiple slave system, it is possible for a SPI master + to broadcast a message to all slaves in the system while + ensuring only one slave drives data onto the serial output + line MISO. */ + __IOM uint32_t RENDN : 2; /*!< [5..4] Receive endian format.
              • 00b: The element is received + MSByte-first and MSbit-first.
              • 01b: The element + is received LSByte-first and MSbit-first.
              • 10b: + The element is received MSByte-first and LSbit-first.
              • 11b: + The element is received LSByte-first and LSbit-first.
              The + cases 00b and 11b are set for data frame size from 4 to + 32 bits. The cases 01b and 10b are set only for data frame + size 16, 24 and 32 bits. */ + __IOM uint32_t MWAIT : 1; /*!< [6..6] MicroWire Wait Sate Bit Enable */ + __IOM uint32_t RXIFLSEL : 3; /*!< [9..7] Receive interrupt FIFO level select. This bit field selects + the trigger points to receive FIFO interrupt:
              • 000b: + RX FIFO contains 1 element or more.
              • 001b: RX FIFO + contains 4 elements or more.
              • 010b: RX FIFO contains + 8 elements or more.
              • Others: Reserved.
              */ + __IOM uint32_t TXIFLSEL : 3; /*!< [12..10] Transmit interrupt FIFO level select. This bit field + selects the trigger points to transmit FIFO interrupt:
              • 000b: + TX FIFO contains 1 element or more.
              • 001b: TX FIFO + contains 4 elements or more.
              • 010b: TX FIFO contains + 8 elements or more.
              • Others: Reserved.
              */ + __IM uint32_t : 1; + __IOM uint32_t MSPIWAIT : 4; /*!< [17..14] SPI Wait mode. This value is used to insert a wait + state between frames. */ + __IOM uint32_t TENDN : 2; /*!< [19..18] Transmit endian format.
              • 00b: The element is + transmitted MSByte-first and MSbit-first.
              • 01b: + The element is transmitted LSByte-first and MSbit-first.
              • 10b: + The element is transmitted MSByte-first and LSbit-first.
              • 11b: + The element is transmitted LSByte-first and LSbit-first.
              The + cases 00b and 11b are set for data frame size from 4 to + 32 bits. The cases 01b and 10b are set only for data frame + size 16, 24 and 32 bits. */ + __IM uint32_t : 1; + __IOM uint32_t DATAINDEL : 1; /*!< [21..21] Data input delay.
              • 0: No delay is inserted in + data input.
              • 1: A delay of 2 clock cycles is inserted + in the data input path.
              */ + } CR1_b; + } ; + + union { + __IOM uint32_t DR; /*!< (@ 0x00000008) Data Register */ + + struct { + __IOM uint32_t DATA : 32; /*!< [31..0] Transmit/Receive data:
              • Read: RX FIFO is read.
              • Write: + TX FIFO is written.
              Data must be right-justified + when a data size of less than 32-bit is programmed. Unused + bits are ignored by the transmit logic. The receive logic + automatically right-justifies data. */ + } DR_b; + } ; + + union { + __IM uint8_t SR; /*!< (@ 0x0000000C) Status Register */ + + struct { + __IM uint8_t TFE : 1; /*!< [0..0] Transmit FIFO empty:
              • 0: TX FIFO is not empty.
              • 1: + TX FIFO is empty.
              */ + __IM uint8_t TNF : 1; /*!< [1..1] Transmit FIFO not full:
              • 0: TX FIFO is full.
              • 1: + TX FIFO is not full.
              */ + __IM uint8_t RNE : 1; /*!< [2..2] Receive FIFO not empty:
              • 0: RX FIFO is empty.
              • 1: + RX FIFO is not empty.
              */ + __IM uint8_t RFF : 1; /*!< [3..3] Receive FIFO full:
              • 0: RX FIFO is not full.
              • 1: + RX FIFO is full.
              */ + __IM uint8_t BSY : 1; /*!< [4..4] SPI busy flag:
              • 0: SPI is idle.
              • 1: SPI + is currently transmitting and/or receiving a frame or the + TX FIFO is not empty.
              */ + } SR_b; + } ; + __IM uint8_t RESERVED; + __IM uint16_t RESERVED1; + + union { + __IOM uint8_t CPSR; /*!< (@ 0x00000010) Clock prescale register */ + + struct { + __IOM uint8_t CPSDVSR : 8; /*!< [7..0] Clock prescale divisor.It must be an even number from + 2 to 254. The value is used to generate the transmit and + receive bit rate of the SPI. The bit rate is:

              FSSPCLK + / [CPSDVR x (1+SCR)]

              where SCR is a value from 0 to + 255, programmed through the SSP_CR0 register. */ + } CPSR_b; + } ; + __IM uint8_t RESERVED2; + __IM uint16_t RESERVED3; + + union { + __IOM uint8_t IMSC; /*!< (@ 0x00000014) Interrupt mask set or clear register */ + + struct { + __IOM uint8_t RORIM : 1; /*!< [0..0] Receive overrun interrupt mask:
              • 0: RX FIFO written + to while full condition interrupt is masked (irq disabled).
              • 1: + RX FIFO written to while full condition interrupt is not + masked (irq enabled).
              */ + __IOM uint8_t RTIM : 1; /*!< [1..1] Receive timeout interrupt mask:
              • 0: RX FIFO not + empty or no read prior to the timeout period interrupt + is masked (irq disabled).
              • 1: RX FIFO not empty + or no read prior to the timeout period interrupt is not + masked (irq enabled).
              */ + __IOM uint8_t RXIM : 1; /*!< [2..2] Receive FIFO interrupt mask:
              • 0: Receive interrupt + is masked (irq disabled).
              • 1: Receive interrupt + is not masked (irq enabled).
              */ + __IOM uint8_t TXIM : 1; /*!< [3..3] Transmit FIFO interrupt mask:
              • 0: Transmit interrupt + is masked (irq disabled).
              • 1: Transmit interrupt + is not masked (irq enabled).
              */ + __IOM uint8_t TURIM : 1; /*!< [4..4] Transmit underrun interrupt mask:
              • 0: Transmit + underrun interrupt is masked (irq disabled).
              • 1: + Transmit underrun interrupt is not masked (irq enabled).
              */ + __IOM uint8_t TEIM : 1; /*!< [5..5] Transmit FIFO empty interrupt mask:
              • 0: TX FIFO + empty interrupt is masked (irq disabled).
              • 1: TX + FIFO empty interrupt is not masked (irq enabled).
              */ + } IMSC_b; + } ; + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + + union { + __IM uint8_t RIS; /*!< (@ 0x00000018) Raw interrupt status register */ + + struct { + __IM uint8_t RORRIS : 1; /*!< [0..0] Receive overrun raw interrupt status */ + __IM uint8_t RTRIS : 1; /*!< [1..1] Receive time out raw interrupt status */ + __IM uint8_t RXRIS : 1; /*!< [2..2] Receive raw interrupt status */ + __IM uint8_t TXRIS : 1; /*!< [3..3] Transmit raw interrupt status */ + __IM uint8_t TURRIS : 1; /*!< [4..4] Transmit underrun raw interrupt Status */ + __IM uint8_t TERIS : 1; /*!< [5..5] Transmit FIFO Empty Raw Interrupt Status */ + } RIS_b; + } ; + __IM uint8_t RESERVED6; + __IM uint16_t RESERVED7; + + union { + __IM uint8_t MIS; /*!< (@ 0x0000001C) Masked Interrupt Status Register */ + + struct { + __IM uint8_t RORMIS : 1; /*!< [0..0] Receive Overrun Masked Interrupt Status: gives the interrupt + status after masking of the receive overrun interrupt. */ + __IM uint8_t RTMIS : 1; /*!< [1..1] Receive Time Out Masked Interrupt Status: gives the interrupt + status after masking of receive timeout interrupt. */ + __IM uint8_t RXMIS : 1; /*!< [2..2] Receive Masked Interrupt Status: gives the interrupt + status after masking of the receive interrupt. */ + __IM uint8_t TXMIS : 1; /*!< [3..3] Transmit Masked Interrupt Status: gives the interrupt + status after masking of the transmit interrupt. */ + __IM uint8_t TURMIS : 1; /*!< [4..4] Transmit Underrun Masked Interrupt Status: gives the + interrupt status after masking of the transmit underrun + interrupt. */ + __IM uint8_t TEMIS : 1; /*!< [5..5] Transmit FIFO Empty Masked Interrupt Status: gives the + interrupt status after masking of the transmit FIFO empty + interrupt. */ + } MIS_b; + } ; + __IM uint8_t RESERVED8; + __IM uint16_t RESERVED9; + + union { + __OM uint8_t ICR; /*!< (@ 0x00000020) Interrupt clear register */ + + struct { + __OM uint8_t RORIC : 1; /*!< [0..0] Receive Overrun Clear Interrupt: writing 1 clears the + receive overrun interrupt. */ + __OM uint8_t RTIC : 1; /*!< [1..1] Receive Time Out Clear Interrupt: writing 1 clears the + receive timeout interrupt. */ + __OM uint8_t TURIC : 1; /*!< [2..2] Transmit Underrun Clear Interrupt: writing 1 clears the + transmit overrun interrupt. */ + } ICR_b; + } ; + __IM uint8_t RESERVED10; + __IM uint16_t RESERVED11; + + union { + __IOM uint8_t DMACR; /*!< (@ 0x00000024) SPI DMA control register */ + + struct { + __IOM uint8_t RXDMASE : 1; /*!< [0..0] Single receive DMA request.
              • 0: Single transfer + DMA in receive disable.
              • 1: Single transfer DMA + in receive enable.
              */ + __IM uint8_t : 1; + __IOM uint8_t TXDMASE : 1; /*!< [2..2] Signle transmit DMA request.
              • 0: Single transfer + DMA in transmit disable.
              • 1: Single transfer DMA + in transmit enable.
              */ + } DMACR_b; + } ; + __IM uint8_t RESERVED12; + __IM uint16_t RESERVED13; + __IOM uint16_t RXFRM; /*!< (@ 0x00000028) SPI Receive Frame register. Indicates the number + of frames to receive from the slave. */ + __IM uint16_t RESERVED14; + __IOM uint32_t CHN; /*!< (@ 0x0000002C) Dummy character register */ + __IOM uint16_t WDTXF; /*!< (@ 0x00000030) SPI transmit FIFO receive frame number. Indicates + the number of frames to receive from the + transmit FIFO. */ + __IM uint16_t RESERVED15; + __IM uint32_t RESERVED16[19]; + + union { + __IOM uint8_t ITCR; /*!< (@ 0x00000080) Integration test control register */ + + struct { + __IM uint8_t : 1; + __IOM uint8_t SWAPFIFO : 1; /*!< [1..1] FIFO control mode:
              • 0: FIFO normal mode. Write + in TDR register puts data in TX FIFO and read from TDR + register read data from RX FIFO.
              • 1: FIFO swapped + mode. Write in TDR register puts data in RX FIFO and read + from TDR register read data from TX FIFO.
              */ + } ITCR_b; + } ; + __IM uint8_t RESERVED17; + __IM uint16_t RESERVED18; + __IM uint32_t RESERVED19[2]; + __IOM uint32_t TDR; /*!< (@ 0x0000008C) FIFO Test Data Register */ +} SPI_Type; /*!< Size = 144 (0x90) */ + + + +/* =========================================================================================================================== */ +/* ================ WDG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Watchdog (WDG) + */ + +typedef struct { /*!< (@ 0x40700000) WDG Structure */ + + union { + __IOM uint32_t LR; /*!< (@ 0x00000000) Watchdog Load Register */ + + struct { + __IOM uint32_t LOAD : 32; /*!< [31..0] Watchdog load value. Value from which the counter is + to decrement. When this register is written to, the count + is immediately restarted from the new value. */ + } LR_b; + } ; + + union { + __IM uint32_t VAL; /*!< (@ 0x00000004) Watchdog Value Register */ + + struct { + __IM uint32_t WDTVAL : 32; /*!< [31..0] Watchdog load value. When read, returns the current + value of the decrementing watchdog counter. A write has + no effect. */ + } VAL_b; + } ; + + union { + __IOM uint8_t CR; /*!< (@ 0x00000008) Watchdog Control Register */ + + struct { + __IOM uint8_t INTEN : 1; /*!< [0..0] Watchdog interrupt enable. Enable the interrupt event:
              • 0: + watchdog interrupt is disabled.
              • 1: watchdog interrupt + is enabled.
              */ + __IOM uint8_t RESEN : 1; /*!< [1..1] Watchdog reset enable. Enable the watchdog reset output:
              • 0: + watchdog reset is disabled.
              • 1: watchdog reset is + enabled.
              */ + } CR_b; + } ; + __IM uint8_t RESERVED; + __IM uint16_t RESERVED1; + + union { + __IOM uint32_t ICR; /*!< (@ 0x0000000C) Watchdog Interrupt Clear Register */ + + struct { + __IOM uint32_t WDTICLR : 32; /*!< [31..0] Watchdog interrupt enable:
              • Writing any value + will clear the watchdog interrupt and reloads the counter + from the LR register.
              • A read returns zero.
              */ + } ICR_b; + } ; + + union { + __IM uint8_t RIS; /*!< (@ 0x00000010) Watchdog Raw Interrupt Status Register */ + + struct { + __IM uint8_t RIS : 1; /*!< [0..0] Watchdog raw interrupt status bit. Reflects the status + of the interrupt status from the watchdog:
              • 0: watchdog + interrupt is not active.
              • 1: watchdog interrupt + is active.
              Read-only bit. A write has no effect. */ + } RIS_b; + } ; + __IM uint8_t RESERVED2; + __IM uint16_t RESERVED3; + + union { + __IM uint8_t MIS; /*!< (@ 0x00000014) Watchdog Masked Interrupt Status Register */ + + struct { + __IM uint8_t MIS : 1; /*!< [0..0] Watchdog masked interrupt status bit. Masked value of + watchdog interrupt status:
              • 0: watchdog interrupt + is not active.
              • 1: watchdog interrupt is active.
              Read-onl + bit. A write has no effect. */ + } MIS_b; + } ; + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + __IM uint32_t RESERVED6[762]; + + union { + __IOM uint32_t LOCK; /*!< (@ 0x00000C00) Watchdog Lock Register */ + + struct { + __IOM uint32_t LOCKVAL : 32; /*!< [31..0] Watchdog lock value. When read, returns the lock status:
              • 0: + Write access to all watchdog other registers is enabled.
              • 1: + Write access to all watchdog other registers is disabled.
              When + written, allows enabling or disabling write access to all + other watchdog registers:
              • Writing 0x1ACCE551: Write + access to all other registers is enabled.
              • Writing + any other value: Write access to all other registers is + disabled.
              */ + } LOCK_b; + } ; +} WDG_Type; /*!< Size = 3076 (0xc04) */ + + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief ADC (ADC) + */ + +typedef struct { /*!< (@ 0x40800000) ADC Structure */ + + union { + __IOM uint16_t CTRL; /*!< (@ 0x00000000) ADC control register */ + + struct { + __IOM uint16_t ON : 1; /*!< [0..0] Starts ADC analog subsystem. This bit must be set before + starting a conversion.
              • 0: ADC is OFF.
              • 1: + ADC is ON.
              This bit works for all the mode except + the microphone mode. */ + __IOM uint16_t CALEN : 1; /*!< [1..1] The automatic calibration routine is enabled if both + AUTO_OFFSET and CALEN bitfields are set. The result of + the calibration is placed in the OFFSET register according + to the SKIP bitfield value.
              • 0: disable the automatic + calibration.
              • 1: enable the automatic calibration.
              This + bitfield can be set to 0 only by setting to 1 the bitfield + RSTCALEN. */ + __IOM uint16_t SWSTART : 1; /*!< [2..2] Starts the ADC conversion phase when set. This bit works + for all the mode except the microphone mode. */ + __IOM uint16_t RESET : 1; /*!< [3..3] Reset all the ADC APB registers when set (CTRL, CONF, + DATA_CONV_THRESHOLD_HI, THRESHOLD_LO). */ + __IOM uint16_t STOP : 1; /*!< [4..4] Permits to stop the continuous conversion. 1: stop the + continuous conversion and switch off the ADC. The bitfields + SWSTART, ON, DMA_EN and MIC_ON are auto-cleared if set. + This bit is auto-cleared by the hardware so it is always + read at 0. */ + __IOM uint16_t ENAB_COMP : 1; /*!< [5..5] Enables the window comparator when set to 1. WDOG flag + is ADC_SR register is set if the converted value is between + ADCTHRESHOLD_HI and ADCTHRESHOLD_LO value. */ + __IOM uint16_t RSTCALEN : 1; /*!< [6..6] Disable the calibration phase when set to 1. This bit + has to be set to disable the calibration each time calibration + is enabled. */ + __IOM uint16_t AUTO_OFFSET : 1; /*!< [7..7] The automatic calibration routine is enabled if both + AUTO_OFFSET and CALEN bitfields are set. The result of + the calibration is placed in the OFFSET register according + to the SKIP bitfield value.
              • 0: disable the automatic + calibration.
              • 1: enable the automatic calibration.
              This + bitfield can be set to 0 only by setting to 1 the bitfield + RSTCALEN. */ + __IOM uint16_t MIC_ON : 1; /*!< [8..8] Starts ADC analog subsystem only for microphone mode.
              • 0: + ADC is OFF.
              • 1: ADC is ON.
              */ + __IOM uint16_t DMA_EN : 1; /*!< [9..9] Enables the DMA.
              • 0: DMA is disabled.
              • 1: + DMA is enabled.
              */ + } CTRL_b; + } ; + __IM uint16_t RESERVED; + + union { + __IOM uint32_t CONF; /*!< (@ 0x00000004) ADC configuration register */ + + struct { + __IM uint32_t : 1; + __IOM uint32_t CHSEL : 3; /*!< [3..1] Select the input channel:
              • 000b: All switches open.
              • 001b: + Single ended through ADC2 pin. InP=VREF (internal), InN=ADC2 + pin.
              • 010b: Single ended through ADC1 pin. InP=ADC1 + pin, InN=VREF (internal).
              • 011b: Differential ADC1 + pin - ADC2 pin, InP=ADC1 pin, InN=ADC2 pin.
              • 101b: + Battery level detector. InP=0.6V (internal), InN=VBATSENS.
              • 110b: + Short InN=InP=0.6V (internal).
              */ + __IOM uint32_t REFSEL : 2; /*!< [5..4] Set the VREF for single ended conversion:
              • 00b: + 0.0V.
              • 10b: 0.6V.
              */ + __IOM uint32_t OSR : 2; /*!< [7..6] Set the ADC resolution:
              • 00b: Set the oversampling + ratio to 200.
              • 01b: Set the oversampling ratio to + 100.
              • 10b: Set the oversampling ratio to 64.
              • 11b: + Set the oversampling ratio to 32.
              */ + __IOM uint32_t PGASEL : 2; /*!< [9..8] Set the input attenuator value:
              • 000b: Input attenuator + at 0 dB.
              • 001b: Input attenuator at 6.02 dB.
              • 010b: + Input attenuator at 9.54 dB.
              */ + __IM uint32_t : 1; + __IOM uint32_t CONT : 1; /*!< [11..11] Enable the continuous conversion mode:
              • 0: Single + conversion.
              • 1: Continuous conversion.
              */ + __IM uint32_t : 6; + __IOM uint32_t SKIP : 1; /*!< [18..18] It permits to bypass the filter COMP to speed up the + conversion for signal at low frequency:
              • 0: Filter + not bypassed.
              • 1: Filter bypassed.
              According + to the value of this bitfield, the behaviour of the ADC + changes as follows: if SKIP is 0: the first 10 converted + samples in ADC mode continuous should be discarded by the + user (3 if SKIP is 1). The converted date are in DATA_CONV_MSB + (DATA_CONV_LSB if SKIP is 1). The calibration result is + in OFFSET_MSB (OFFSET_LSB if SKIP is 1). */ + __IM uint32_t : 1; + __IOM uint32_t DIG_FILT_CLK : 1; /*!< [20..20] Frequency clock selection value on GPIO0 when MIC_SEL=1:
              • 0: + 0.8 MHz.
              • 1: 1.6 MHz.
              */ + __IM uint32_t : 1; + __IOM uint32_t MIC_SEL : 1; /*!< [22..22] Provides the clock on GPIO:
              • 0: Do not provided + any external clock source.
              • 1: Provide clock source + from GPIO.
              */ + } CONF_b; + } ; + + union { + __IM uint8_t IRQSTAT; /*!< (@ 0x00000008) IRQ masked status register */ + + struct { + __IM uint8_t ENDCAL : 1; /*!< [0..0] 1: when the calibration is completed. Clear on register + read. */ + __IM uint8_t : 1; + __IM uint8_t EOC : 1; /*!< [2..2] 1: when the conversion is completed. Clear on register + read. */ + __IM uint8_t WDOG : 1; /*!< [3..3] 1: when the data is within the thresholds. Clear on register + read. */ + } IRQSTAT_b; + } ; + __IM uint8_t RESERVED1; + __IM uint16_t RESERVED2; + + union { + __IOM uint8_t IRQMASK; /*!< (@ 0x0000000C) It sets the mask for ADC interrupt */ + + struct { + __IOM uint8_t ENDCAL : 1; /*!< [0..0] Interrupt mask for the end of calibration event:
              • 0: + Interrupt is enabled.
              • 1: Interrupt is disabled.
              */ + __IM uint8_t : 1; + __IOM uint8_t EOC : 1; /*!< [2..2] Interrupt mask for the end of conversion event:
              • 0: + Interrupt is enabled.
              • 1: Interrupt is disabled.
              */ + __IOM uint8_t WDOG : 1; /*!< [3..3] Interrupt mask for the within the threhsold event:
              • 0: + Interrupt is enabled.
              • 1: Interrupt is disabled.
              */ + } IRQMASK_b; + } ; + __IM uint8_t RESERVED3; + __IM uint16_t RESERVED4; + + union { + __IM uint8_t IRQRAW; /*!< (@ 0x00000010) IRQ status raw register */ + + struct { + __IM uint8_t ENDCAL : 1; /*!< [0..0] 1: when the calibration is completed. Clear on register + read. */ + __IM uint8_t : 1; + __IM uint8_t EOC : 1; /*!< [2..2] 1: when the conversion is completed. Clear on register + read. */ + __IM uint8_t WDOG : 1; /*!< [3..3] 1: when the data is inside the thresholds. Clear on register + read. */ + } IRQRAW_b; + } ; + __IM uint8_t RESERVED5; + __IM uint16_t RESERVED6; + __IM uint16_t DATA_CONV_LSB; /*!< (@ 0x00000014) Result of the conversion LSB in two complement + format. If the filter is bypassed, the bitfield + SKIP is 1, the DATA_CONV_MSB is negligible + and the ADC converted data is the DATA_CONV_LSB + * 1.08 (corrective factor). If the filter + is not bypassed, the bitfield SKIP is 0, + the DATA_CONV_LSB is negligeble. */ + __IM uint16_t DATA_CONV_MSB; /*!< (@ 0x00000016) Result of the conversion MSB in two complement + format. If the filter is not bypassed, the + bitfield SKIP is 0, the DATA_CONV_LSB is + negligible and the ADC converted data is + the DATA_CONV_MSB. If the filter is bypassed, + the bitfield SKIP is 1, the DATA_CONV_MSB + is negligeble. */ + __IOM uint16_t OFFSET_LSB; /*!< (@ 0x00000018) Offset for correction of converted data. If the + bitfield SKIP is 0, the 16-bit offset is + in OFFSET_MSB, while if the bitfield SKIP + is 1, the 16-bit offset is in OFFSET_LSB. */ + __IOM uint16_t OFFSET_MSB; /*!< (@ 0x0000001A) Offset for correction of converted data. If the + bitfield SKIP is 0, the 16-bit offset is + in OFFSET_MSB, while if the bitfield SKIP + is 1, the 16-bit offset is in OFFSET_LSB. */ + __IM uint32_t RESERVED7; + + union { + __IOM uint8_t SR_REG; /*!< (@ 0x00000020) ADC status register */ + + struct { + __IM uint8_t : 1; + __IOM uint8_t BUSY : 1; /*!< [1..1] 1: during conversion. */ + __IM uint8_t : 1; + __IOM uint8_t WDOG : 1; /*!< [3..3] If ENAB_COMP=1, this bit indicates the result of the + conversion is between high and low threshold:
              • 0: + DATAOUT[31:0] is NOT between THRESHOLD_HI and THRESHOLD_LO + values.
              • 1: DATAOUT[31:0] is between THRESHOLD_HI + and THRESHOLD_LO values.
              */ + } SR_REG_b; + } ; + __IM uint8_t RESERVED8; + __IM uint16_t RESERVED9; + __IOM uint32_t THRESHOLD_HI; /*!< (@ 0x00000024) High threshold for window comparator */ + __IOM uint32_t THRESHOLD_LO; /*!< (@ 0x00000028) Low threshold for window comparator */ +} ADC_Type; /*!< Size = 44 (0x2c) */ + + + +/* =========================================================================================================================== */ +/* ================ CKGEN_SOC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Clock Gen SOC (CKGEN_SOC) + */ + +typedef struct { /*!< (@ 0x40900000) CKGEN_SOC Structure */ + __IM uint32_t RESERVED[2]; + + union { + __IM uint8_t REASON_RST; /*!< (@ 0x00000008) Indicates the reset reason from Cortex-M0 */ + + struct { + __IM uint8_t : 1; + __IM uint8_t SYSREQ : 1; /*!< [1..1] Reset caused by Cortex-M0 debug asserting SYSRESETREQ */ + __IM uint8_t WDG : 1; /*!< [2..2] Reset caused by assertion of watchdog reset */ + __IM uint8_t LOCKUP : 1; /*!< [3..3] Reset caused by Cortex-M0 asserting LOCKUP signal */ + } REASON_RST_b; + } ; + __IM uint8_t RESERVED1; + __IM uint16_t RESERVED2; + __IM uint32_t RESERVED3[4]; + + union { + __IM uint32_t DIE_ID; /*!< (@ 0x0000001C) Identification information of the device */ + + struct { + __IM uint32_t REV : 4; /*!< [3..0] Cut revision */ + __IM uint32_t VERSION : 4; /*!< [7..4] Cut version */ + __IM uint32_t PRODUCT : 4; /*!< [11..8] Product */ + } DIE_ID_b; + } ; + + union { + __IOM uint32_t CLOCK_EN; /*!< (@ 0x00000020) Enable or gates the APB clock of the peripherals */ + + struct { + __IOM uint32_t GPIO : 1; /*!< [0..0] GPIO clock */ + __IOM uint32_t NVM : 1; /*!< [1..1] Flash controller clock */ + __IOM uint32_t SYSCTRL : 1; /*!< [2..2] System controller clock */ + __IOM uint32_t UART : 1; /*!< [3..3] UART clock */ + __IOM uint32_t SPI : 1; /*!< [4..4] SPI clock */ + __IM uint32_t : 2; + __IOM uint32_t WDOG : 1; /*!< [7..7] Watchdog clock */ + __IOM uint32_t ADC : 1; /*!< [8..8] ADC clock */ + __IOM uint32_t I2C1 : 1; /*!< [9..9] I2C1 clock */ + __IOM uint32_t I2C2 : 1; /*!< [10..10] I2C2 clock */ + __IOM uint32_t MFT1 : 1; /*!< [11..11] MFT1 clock */ + __IOM uint32_t MFT2 : 1; /*!< [12..12] MFT2 clock */ + __IOM uint32_t RTC : 1; /*!< [13..13] RTC clock */ + __IM uint32_t : 2; + __IOM uint32_t DMA : 1; /*!< [16..16] DMA AHB clock */ + __IOM uint32_t RNG : 1; /*!< [17..17] RNG AHB clock */ + __IOM uint32_t PKA : 2; /*!< [19..18] PKA AHB clock and RAM */ + } CLOCK_EN_b; + } ; + + union { + __IOM uint8_t DMA_CONFIG; /*!< (@ 0x00000024) DMA config */ + + struct { + __IOM uint8_t ADC_CH0 : 1; /*!< [0..0] Select ADC on DMA channel 0 instead of peripheral */ + __IOM uint8_t ADC_CH1 : 1; /*!< [1..1] Select ADC on DMA channel 1 instead of peripheral */ + __IOM uint8_t ADC_CH2 : 1; /*!< [2..2] Select ADC on DMA channel 2 instead of peripheral */ + __IOM uint8_t ADC_CH3 : 1; /*!< [3..3] Select ADC on DMA channel 3 instead of peripheral */ + __IOM uint8_t ADC_CH4 : 1; /*!< [4..4] Select ADC on DMA channel 4 instead of peripheral */ + __IOM uint8_t ADC_CH5 : 1; /*!< [5..5] Select ADC on DMA channel 5 instead of peripheral */ + __IOM uint8_t ADC_CH6 : 1; /*!< [6..6] Select ADC on DMA channel 6 instead of peripheral */ + __IOM uint8_t ADC_CH7 : 1; /*!< [7..7] Select ADC on DMA channel 7 instead of peripheral */ + } DMA_CONFIG_b; + } ; + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + + union { + __IM uint32_t JTAG_IDCODE; /*!< (@ 0x00000028) JTAG ID code */ + + struct { + __IM uint32_t : 1; + __IM uint32_t MANUF_ID : 11; /*!< [11..1] Manufacturer ID */ + __IM uint32_t PART_NUMBER : 16; /*!< [27..12] Part number */ + __IM uint32_t VERSION_NUM : 4; /*!< [31..28] Version */ + } JTAG_IDCODE_b; + } ; +} CKGEN_SOC_Type; /*!< Size = 44 (0x2c) */ + + + +/* =========================================================================================================================== */ +/* ================ I2C2 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief I2C2 (I2C2) + */ + +typedef struct { /*!< (@ 0x40A00000) I2C2 Structure */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000000) I2C Control register */ + + struct { + __IOM uint32_t PE : 1; /*!< [0..0] I2C enable disable:
              • 0: I2C disable.
              • 1: + I2C enable.
              This bit when deasserted works as + software reset for I2C peripheral. */ + __IOM uint32_t OM : 2; /*!< [2..1] Select the operating mode:
              • 00b: Slave mode. The + peripheral can only respond (transmit/receive) when addressed + by a master device
              • 01b: Master mode. The peripheral + works in a multi-master system where itself cannot be addressed + by another master device. It can only initiate a new transfer + as master device.
              • 10b: Master/slave mode. The peripheral + works in a multi-master system where itself can be addressed + by another master device, besides to initiate a transfer + as master device.
              • 0: 7-bit addressing mode.
              • 1: + 10-bit addressing mode.
              */ + __IOM uint32_t SM : 2; /*!< [5..4] Speed mode. SM defines the speed mode related to the + serial bit rate:
              • 0: Standard mode (up to 100 K/s).
              • 1: + Fast mode (up to 400 K/s).
              */ + __IOM uint32_t SGCM : 1; /*!< [6..6] Slave general call mode defines the operating mode of + the slave controller when a general call is received. This + setting does not affect the hardware general call that + is always managed in transparent mode.
              • 0: transparent + mode, the slave receiver recognizes the general call but + any action is taken by the hardware after the decoding + of the message included in the Rx FIFO.
              • 1: direct + mode, the slave receiver recognizes the general call and + executes directly (without software intervention) the r */ + __IOM uint32_t FTX : 1; /*!< [7..7] FTX flushes the transmit circuitry (FIFO, fsm). The configuration + of the I2C node (register setting) is not affected by the + flushing operation. The flushing operation is performed + on modules working on different clock domains (system and + I2C clocks) and needs several system clock cycles before + being completed. Upon completion, the I2C node (internal + logic) clears this bit. The application must not access + the Tx FIFO during the flushing operation and should poll + on this bit waiting for completion.
                • 0: */ + __IOM uint32_t FRX : 1; /*!< [8..8] FRX flushes the receive circuitry (FIFO, fsm).The configuration + of the I2C node (register setting) is not affected by the + flushing operation. The flushing operation is performed + on modules working on different clock domains (system and + I2C clocks) and needs several system clock cycles before + to be completed. Upon completion, the I2C node (internal + logic) clears this bit. The application must not access + the Rx FIFO during the flushing operation and should poll + on this bit waiting for the completion.
                  • */ + __IOM uint32_t DMA_TX_EN : 1; /*!< [9..9] Enables the DMA TX interface.
                    • 0: Idle state, the + DMA TX interface is disabled.
                    • 1: Run state, the + DMA TX interface is enabled.
                    On the completion + of the DMA transfer, the DMA TX interface is automatically + turned off clearing this bit when the end of transfer signal + coming from the DMA is raised. DMA_TX_EN and DMA_RX_EN + must not enabled at the same time. */ + __IOM uint32_t DMA_RX_EN : 1; /*!< [10..10] Enables the DMA RX interface.
                    • 0: Idle state, + the DMA RX interface is disabled.
                    • 1: Run state, + the DMA RX interface is enabled.
                    On the completion + of the DMA transfer, the DMA RX interface is automatically + turned off clearing this bit when the end of transfer signal + coming from the DMA is raised. DMA_TX_EN and DMA_RX_EN + must not enabled at the same time. */ + __IM uint32_t : 2; + __IOM uint32_t FON : 2; /*!< [14..13] Filtering on sets the digital filters on the SDA, SCL + line, according to the I2C bus requirements, when standard + open-drain pads are used:
                    • 00b: No digital filters + are inserted.
                    • 01b: Digital filters (filter 1 ck + wide spikes) are inserted.
                    • 10b: Digital filters + (filter 2 ck wide spikes) are inserted.
                    • 11b: Digital + filters (filter 4 ck wide spikes) are inserted.
                    */ + __IOM uint32_t FS_1 : 1; /*!< [15..15] Force stop enable bit. When set to 1b, the STOP condition + is generated.
                    • 0: Force stop disabled.
                    • 1: + Enable force stop.
                    */ + } CR_b; + } ; + + union { + __IOM uint32_t SCR; /*!< (@ 0x00000004) I2C Slave Control register */ + + struct { + __IOM uint32_t SA7 : 7; /*!< [6..0] Slave address 7-bit. SA7 includes the slave address 7-bit + or the LSB bits of the slave address 10-bit */ + __IOM uint32_t ESA10 : 3; /*!< [9..7] Extended slave address 10-bit. ESA10 includes the extension + (MSB bits) to the SA7 register field in case of slave addressing + mode set to 10-bit */ + __IM uint32_t : 6; + __IOM uint32_t SLSU : 16; /*!< [31..16] Slave data setup time. SLSU defines the data setup + time after SCL clock stretching in terms of i2c_clk cycles. + Data setup time is actually equal to SLSU-1 clock cycles. + The typical values for i2c_clk of 16 MHz are SLSU = 5 in + standard mode and SLSU = 3 in fast modes. */ + } SCR_b; + } ; + __IM uint32_t RESERVED; + + union { + __IOM uint32_t MCR; /*!< (@ 0x0000000C) I2C master control register */ + + struct { + __IOM uint32_t OP : 1; /*!< [0..0] Operation
                    • 0: Indicates a master write operation.
                    • 1: + Indicates a master read operation.
                    */ + __IOM uint32_t A7 : 7; /*!< [7..1] Address. Includes the 7-bit address or the LSB bits of + the10-bit address used to initiate the current transaction */ + __IOM uint32_t EA10 : 3; /*!< [10..8] Extended address. Includes the extension (MSB bits) + of the field A7 used to initiate the current transaction */ + __IOM uint32_t SB : 1; /*!< [11..11] Start byte:
                    • 0: The start byte procedure is not + applied to the current transaction.
                    • 1: The start + byte procedure is prefixed to the current transaction.
                    */ + __IOM uint32_t AM : 2; /*!< [13..12] Address type:
                    • 00b: The transaction is initiated + by a general call command. In this case the fields OP, + A7, EA10 are don't care.
                    • 01b: The transaction is + initiated by the 7-bit address included in the A7 field.
                    • 10b: + The transaction is initiated by the 10-bit address included + in the EA10 and A7 fields.
                    */ + __IOM uint32_t P : 1; /*!< [14..14] Stop condition:
                    • 0: The current transaction is + not terminated by a STOP condition. A repeated START condition + is generated on the next operation which is required to + avoid to stall the I2C line.
                    • 1: The current transaction + is terminated by a STOP condition.
                    */ + __IOM uint32_t LENGTH : 11; /*!< [25..15] Transaction length. Defines the length, in terms of + the number of bytes to be transmitted (MW) or received + (MR). In case of write operation, the payload is stored + in the Tx FIFO. A transaction can be larger than the Tx + FIFO size. In case of read operation the length refers + to the number of bytes to be received before generating + a not-acknowledge response. A transaction can be larger + than the Rx FIFO size. The I2C clock line is stretched + low until the data in Rx FIFO are consumed. */ + } MCR_b; + } ; + + union { + __IOM uint8_t TFR; /*!< (@ 0x00000010) I2C transmit FIFO register */ + + struct { + __IOM uint8_t TDATA : 8; /*!< [7..0] Transmission Data. TDATA contains the payload related + to a master write or read-from-slave operation to be written + in the Tx FIFO. TDATA(0) is the first LSB bit transmitted + over the I2C line.

                    In case of master write operation, + the Tx FIFO shall be preloaded otherwise the I2C controller + cannot start the operation until data are available.

                    In + case of read-from-slave operation, when the slave is addressed, + the interrupt RISR:RFSR bit is asserted and the CPU shall + download the data in the FIFO. If the */ + } TFR_b; + } ; + __IM uint8_t RESERVED1; + __IM uint16_t RESERVED2; + + union { + __IM uint32_t SR; /*!< (@ 0x00000014) I2C status register */ + + struct { + __IM uint32_t OP : 2; /*!< [1..0] Operation:

                    • 00b: MW: master write operation.
                    • 01b: + MR: master read operation.
                    • 10b: WTS: write-to-slave + operation.
                    • 11b: RFS: read-from-slave operation.
                    */ + __IM uint32_t STATUS : 2; /*!< [3..2] Controller status. Valid for the operations MW, MR, WTS + RFS:
                    • 00b: NOP: No operation is in progress.
                    • 01b: + ON_GOING: An operation is ongoing.
                    • 10b: OK: The + operation (OP field) has been completed successfully.
                    • 11b: + ABORT: The operation (OP field) has been aborted due to + the occurrence of the event described in the CAUSE field.
                    */ + __IM uint32_t CAUSE : 3; /*!< [6..4] Abort cause. This field is valid only when the STATUS + field contains the ABORT tag. Others: reserved.
                    • 000b: + NACK_ADDR: The master receives a not-acknowledge after + the transmission of the address. Valid for the operation + MW, MR.
                    • 001b: NACK_DATA: The master receives a + not-acknowledge during the data phase of a MW operation. + Valid for the operation MW.
                    • 011b: ARB_LOST: The + master loses the arbitration during a MW or MR operation. + Valid for the operation MW, MR.
                    • 100b: BERR_START: */ + __IM uint32_t TYPE : 2; /*!< [8..7] Receive type. Valid only for the operation WTS:
                      • 00b: + FRAME: The slave has received a normal frame.
                      • 01b: + GCALL: The slave has received a general call. If the it + I2C_CR:SGCM is set to 1, the general call is directly executed + without software intervention and only the control code + word is reported in FIFO (LENGTH =0).
                      • 10b: HW_GCALL: + The slave has received a hardware general call.
                      */ + __IM uint32_t LENGTH : 10; /*!< [18..9] Transfer length. For an MR, WTS operation the LENGTH + field defines the actual size of the subsequent payload, + in terms of number of bytes. For an MW, RFS operation the + LENGTH field defines the actual number of bytes transferred + by the master/slave device. For a WTS operation if the + transfer length exceeds 2047 bytes, the operation is stopped + by the slave returning a NACK handshake and the flag OVFL + is set. For an RFS operation if the transfer length exceeds + 2047 bytes, the operation continues normally but */ + __IM uint32_t : 10; + __IM uint32_t DUALF : 1; /*!< [29..29] Dual flag (slave mode):
                      • 0: Received address + matched with slave address (SA7).
                      • 1: Received address + matched with dual slave address (DSA7).
                      Cleared + by hardware after a Stop condition or repeated Start condition, + bus error or when PE=0. */ + } SR_b; + } ; + + union { + __IM uint8_t RFR; /*!< (@ 0x00000018) I2C receive FIFO register */ + + struct { + __IM uint8_t RDATA : 8; /*!< [7..0] Receive data. RDATA contains the received payload, related + to a master read or write-to-slave operation, to be read + from the Rx FIFO. The RDATA(0) is the first LSB bit received + over the I2C line. In case the FIFO is full, the I2C controller + stretches automatically the I2C clock line until a new + entry is available.

                      For a write-to-slave operation, when + the slave is addressed, the interrupt I2C_RISR:WTSR bit + is asserted for notification to the CPU. In CPU mode the + FIFO management shall be based on the asser */ + } RFR_b; + } ; + __IM uint8_t RESERVED3; + __IM uint16_t RESERVED4; + + union { + __IOM uint16_t TFTR; /*!< (@ 0x0000001C) I2C transmit FIFO threshold register */ + + struct { + __IOM uint16_t THRESH_TX : 10; /*!< [9..0] Threshold TX, contains the threshold value, in terms + of number of bytes, of the Tx FIFO.

                      When the number of + entries of the Tx FIFO is less or equal than the threshold + value, the interrupt bit I2C_RISR:TXFNE is set in order + to request the loading of data to the application.

                      */ + } TFTR_b; + } ; + __IM uint16_t RESERVED5; + + union { + __IOM uint16_t RFTR; /*!< (@ 0x00000020) I2C receive FIFO threshold register */ + + struct { + __IOM uint16_t THRESH_RX : 10; /*!< [9..0] Threshold RX, contains the threshold value, in terms + of number of bytes, of the Rx FIFO.

                      When the number of + entries of the RX FIFO is greater than or equal to the + threshold value, the interrupt bit RISR:RXFNF is set in + order to request the download of received data to the application. + The application shall download the received data based + on the threshold. (RISR:RXFNF).

                      */ + } RFTR_b; + } ; + __IM uint16_t RESERVED6; + + union { + __IOM uint16_t DMAR; /*!< (@ 0x00000024) I2C DMA register */ + + struct { + __IM uint16_t : 8; + __IOM uint16_t DBSIZE_TX : 3; /*!< [10..8] Destination burst size. This register field is valid + only if the BURST_TX bit is set to '1'. If burst size is + smaller than the transaction length, only single request + are generated. */ + __IOM uint16_t BURST_TX : 1; /*!< [11..11] Defines the type of DMA request generated by the DMA + TX interface.
                      • 0: Single request mode. Transfers + a single data (one byte) in the TX FIFO.
                      • 1: Burst + request mode. Transfers a programmed burst of data according + to DBSIZE_TX field.
                      When the burst mode is programmed, + the DMA transfer can be completed by one or more single + requests as required. */ + } DMAR_b; + } ; + __IM uint16_t RESERVED7; + + union { + __IOM uint16_t BRCR; /*!< (@ 0x00000028) I2C Baud-rate counter register */ + + struct { + __IOM uint16_t BRCNT : 16; /*!< [15..0] Baud rate counter. BRCNT defines the counter value used + to set up the I2C baud rate in standard and fast mode, + when the peripheral is operating in master mode. */ + } BRCR_b; + } ; + __IM uint16_t RESERVED8; + + union { + __IOM uint32_t IMSCR; /*!< (@ 0x0000002C) I2C interrupt mask set/clear register */ + + struct { + __IOM uint32_t TXFEM : 1; /*!< [0..0] TX FIFO empty mask. TXFEM enables the interrupt bit TXFE:
                      • 0: + TXFE interrupt is disabled.
                      • 1: TXFE interrupt is + enabled.
                      */ + __IOM uint32_t TXFNEM : 1; /*!< [1..1] TX FIFO nearly empty mask. TXFNEM enables the interrupt + bit TXFNE:
                      • 0: TXFNE interrupt is disabled.
                      • 1: + TXFNE interrupt is enabled.
                      */ + __IOM uint32_t TXFFM : 1; /*!< [2..2] TX FIFO full mask. TXFFM enables the interrupt bit TXFF:
                      • 0: + TXFF interrupt is disabled.
                      • 1: TXFF interrupt is + enabled.
                      */ + __IOM uint32_t TXFOVRM : 1; /*!< [3..3] TX FIFO overrun mask. TXOVRM enables the interrupt bit + TXOVR:
                      • 0: TXOVR interrupt is disabled.
                      • 1: + TXOVR interrupt is enabled.
                      */ + __IOM uint32_t RXFEM : 1; /*!< [4..4] RX FIFO empty mask. RXFEM enables the interrupt bit RXFE:
                      • 0: + RXFE interrupt is disabled.
                      • 1: RXFE interrupt is + enabled.
                      */ + __IOM uint32_t RXFNFM : 1; /*!< [5..5] RX FIFO nearly full mask. RXNFM enables the interrupt + bit RXNF:
                      • 0: RXNF interrupt is disabled.
                      • 1: + RXNF interrupt is enabled
                      */ + __IOM uint32_t RXFFM : 1; /*!< [6..6] RX FIFO full mask. RXFFM enables the interrupt bit RXFF:
                      • 0: + RXFF interrupt is disabled.
                      • 1: RXFF interrupt is + enabled.
                      */ + __IM uint32_t : 9; + __IOM uint32_t RFSRM : 1; /*!< [16..16] Read-from-Slave request mask. RFSRM enables the interrupt + bit RFSR:
                      • 0: RFSR interrupt is disabled.
                      • 1: + RFSR interrupt is enabled.
                      */ + __IOM uint32_t RFSEM : 1; /*!< [17..17] Read-from-Slave empty mask. RFSEM enables the interrupt + bit RFSE:
                      • 0: RFSE interrupt is disabled.
                      • 1: + RFSE interrupt is enabled.
                      */ + __IOM uint32_t WTSRM : 1; /*!< [18..18] Write-to-Slave request mask. WTSRM enables the interrupt + bit WTSR:
                      • 0: WTSR interrupt is disabled.
                      • 1: + WTSR interrupt is enabled.
                      */ + __IOM uint32_t MTDM : 1; /*!< [19..19] Master Transaction done mask. MTDM enables the interrupt + bit MTD:
                      • 0: MTD interrupt is disabled.
                      • 1: + MTD interrupt is enabled.
                      */ + __IOM uint32_t STDM : 1; /*!< [20..20] Slave Transaction done mask. STDM enables the interrupt + bit STD:
                      • 0: STDM interrupt is disabled.
                      • 1: + STDM interrupt is enabled.
                      */ + __IM uint32_t : 3; + __IOM uint32_t MALM : 1; /*!< [24..24] Master Arbitration lost mask. MALM enables the interrupt + bit MAL:
                      • 0: MAL interrupt is disabled.
                      • 1: + MAL interrupt is enabled.
                      */ + __IOM uint32_t BERRM : 1; /*!< [25..25] Bus Error mask. BERRM enables the interrupt bit BERR:
                      • 0: + BERR interrupt is disabled.
                      • 1: BERR interrupt is + enabled.
                      */ + __IM uint32_t : 2; + __IOM uint32_t MTDWSM : 1; /*!< [28..28] Master Transaction done without stop mask. MTDWSM enables + the interrupt bit MTDWS:
                      • 0: MTDWS interrupt is disabled.
                      • 1 + MTDWS interrupt is enabled.
                      */ + } IMSCR_b; + } ; + + union { + __IM uint32_t RISR; /*!< (@ 0x00000030) I2C raw interrupt status register */ + + struct { + __IM uint32_t TXFE : 1; /*!< [0..0] TX FIFO empty. TXFE is set when TX FIFO is empty. This + bit is self-cleared by writing in TX FIFO.
                      • 0: TX + FIFO is not empty.
                      • 1: TX FIFO is empty.
                      */ + __IM uint32_t TXFNE : 1; /*!< [1..1] TX FIFO nearly empty. TXFNE is set when the number of + entries in TX FIFO is less than or equal to the threshold + value programmed in the I2C_TFTR:THRESHOLD_TX register. + It is self-cleared when the threshold level is over the + programmed threshold.
                      • 0: Number of entries in TX + FIFO greater than the TFTR:THRESHOLD_TX register.
                      • 1: + Number of entries in TX FIFO less than or equal to the + TFTR:THRESHOLD_TX register.
                      */ + __IM uint32_t TXFF : 1; /*!< [2..2] TX FIFO full. TXFF is set when a full condition occurs + in TX FIFO. This bit is self-cleared when the TX FIFO is + not full:
                      • 0: TX FIFO is not full.
                      • 1: TX + FIFO is full.
                      */ + __IM uint32_t TXFOVR : 1; /*!< [3..3] TX FIFO overrun. TXFOVR is set when a write operation + in TX FIFO is performed and TX FIFO is full. The application + must avoid an overflow condition by a proper data flow + control. Anyway in case of overrun, the application shall + flush the transmitter (CR:FTX bit to set) because the TX + FIFO content is corrupted (at least one word has been lost + in FIFO). This interrupt is cleared by setting the related + bit of the ICR register:
                      • 0: No overrun condition + occurred in TX FIFO.
                      • 1: Overrun condition oc */ + __IM uint32_t RXFE : 1; /*!< [4..4] RX FIFO empty. RXFE is set when the RX FIFO is empty. + This bit is self-cleared when the slave RX FIFO is not + empty:
                        • 0: RX FIFO is not empty..
                        • 1: RX FIFO + is empty..
                        */ + __IM uint32_t RXFNF : 1; /*!< [5..5] RX FIFO nearly full. RXFNF is set when the number of + entries in RX FIFO is greater than or equal to the threshold + value programmed in the RFTR:THRESHOLD_RX register. Its + self-cleared when the threshold level is under the programmed + threshold:
                        • 0: Number of entries in the RX FIFO less + than the RFTR:THRESHOLD_RX register.
                        • 1: Number + of entries in the RX FIFO greater than or equal to the + RFTR:THRESHOLD_RX register.
                        */ + __IM uint32_t RXFF : 1; /*!< [6..6] RX FIFO full. RXFF is set when a full condition occurs + in RX FIFO. This bit is self-cleared when the data are + read from the RX FIFO.
                        • 0: RX FIFO is not full.
                        • 1: + RX FIFO is full.
                        */ + __IM uint32_t : 8; + __IM uint32_t LBR : 1; /*!< [15..15] Length number of bytes received. LBR is set in case + of MR or WTS and when the number of bytes received is equal + to the transaction length programmed in the MCR:LENGTH + (master mode) or SMB_SCR:LENGTH (slave mode). On the assertion + of this interrupt and when the bit CR:FRC_STRTCH is set, + the hardware starts clock stretching, the CPU shall download + the data byte (Command code, Byte Count, Data...) from + RX FIFO, re-set the expected length of the transaction + in SMB_SCR:LENGTH and clear the interrupt. When clear */ + __IM uint32_t RFSR : 1; /*!< [16..16] Read-from-slave request. RFSR is set when a read-from-slave + Slavetransmitter request is received (I2C slave is addressed) + from the I2C line. On the assertion of this interrupt the + TX FIFO is flushed (pending data are cleared) and the CPU + shall put the data in TX FIFO. This bit is self-cleared + by writing data in FIFO. In case the FIFO is empty before + the completion of the read operation, the RISR:RFSE interrupt + bit is set.This interrupt is cleared by setting the related + bit of the ICR register.
                        • 0: Re */ + __IM uint32_t RFSE : 1; /*!< [17..17] Read-from-Slave empty. RFSE is set when a read-from-slave + operation is in progress and TX FIFO is empty. On the assertion + of this interrupt, the CPU shall download in TX FIFO the + data required for the slave operation. This bit is self-cleared + by writing in TX FIFO. At the end of the read-from-slave + operation this bit is cleared although the TX FIFO is empty.
                          • 0: + TX FIFO is not empty.
                          • 1: TX FIFO is empty with + the read-from-slave operation in progress.
                          */ + __IM uint32_t WTSR : 1; /*!< [18..18] Write-to-Slave request. WTSR is set when a write-to-slave + operation is received (I2C slave is addressed) from the + I2C line. This notification can be used by the application + to program the DMA descriptor when required. This interrupt + is cleared by setting the related bit of the ICR register:
                          • 0: + No write-to-slave request pending.
                          • 1: Write-to-slave + request is pending.
                          */ + __IM uint32_t MTD : 1; /*!< [19..19] Master Transaction done. MTD is set when a master operation + (master write or master read) has been executed after a + stop condition. The application shall read the related + transaction status (SR register), the pending data in the + RX FIFO (only for a master read operation) and clear this + interrupt (transaction acknowledgment). A subsequent master + operation can be issued (writing the MCR register) after + the clearing of this interrupt. A subsequent slave operation + will be notified (RISR:WTSR and RISR:RFSR inte */ + __IM uint32_t STD : 1; /*!< [20..20] Slave Transaction done. STD is set when a slave operation + (write-to-slave or read-from-slave) has been executed. + The application shall read the related transaction status + (SR register), the pending data in the RX FIFO (only for + a write-to-slave operation) and clear this interrupt (transaction + acknowledgment). A subsequent slave operation will be notified + (RISR:WTSR and RISR:RFSR interrupt bits assertion) after + clearing this interrupt, meanwhile the I2C clock line will + be stretched low. A subsequent master */ + __IM uint32_t : 2; + __IM uint32_t SAL : 1; /*!< [23..23] Slave Arbitration lost. SAL is set when the slave loses + the arbitration during the data phase. A collision occurs + when 2 devices transmit simultaneously 2 opposite values + on the serial data line. The device that is pulling up + the line, identifies the collision reading a 0 value on + the sda_in signal, stops the transmission, releases the + bus and waits for the idle state (STOP condition received) + on the bus line. The device which transmits the first unique + zero wins the bus arbitration. This interrupt is clea */ + __IM uint32_t MAL : 1; /*!< [24..24] Master arbitration lost. MAL is set when the master + loses the arbitration. The status code word in the SR contains + a specific error tag (CAUSE field) for this error condition. + A collision occurs when 2 stations transmit simultaneously + 2 opposite values on the serial line. The station that + is pulling up the line, identifies the collision reading + a 0 value on the sda_in signal, stops the transmission, + leaves the bus and waits for the idle state (STOP condition + received) on the bus line before retrying the sa */ + __IM uint32_t BERR : 1; /*!< [25..25] Bus Error. BERR is set when an unexpected Start/Stop + condition occurs during a transaction. The related actions + are different, depending on the type of operation in progress.The + status code word in the SR contains a specific error tag + (CAUSE field) for this error condition. This interrupt + is cleared by setting the related bit of the ICR register.
                          • 0: + No bus error detection.
                          • 1: Bus error detection.
                          */ + __IM uint32_t : 2; + __IM uint32_t MTDWS : 1; /*!< [28..28] Master transaction done without stop. MTDWS is set + when a master operation (write or read) has been executed + and a stop (MCR:P field) is not programmed. The application + shall read the related transaction status (SR register), + the pending data in the RX FIFO (only for a master read + operation) and clear this interrupt (transaction acknowledgment). + A subsequent master operation can be issued (by writing + the MCR register) after clearing this interrupt. A subsequent + slave operation will be notified (RISR:WTSR a */ + } RISR_b; + } ; + + union { + __IM uint32_t MISR; /*!< (@ 0x00000034) I2C masked interrupt status register */ + + struct { + __IM uint32_t TXFEMIS : 1; /*!< [0..0] TX FIFO empty masked interrupt status.
                          • 0: TX FIFO + is not empty.
                          • 1: TX FIFO is empty.
                          */ + __IM uint32_t TXFNEMIS : 1; /*!< [1..1] TX FIFO nearly empty masked interrupt status.
                          • 0: + Number of entries in TX FIFO greater than the TFTR:THRESHOLD_TX + register.
                          • 1: Number of entries in TX FIFO less + than or equal to the TFTR:THRESHOLD_TX register.
                          */ + __IM uint32_t TXFFMIS : 1; /*!< [2..2] Tx FIFO full masked interrupt status.
                          • 0: TX FIFO + is not full.
                          • 1: TX FIFO is full.
                          */ + __IM uint32_t TXFOVRMIS : 1; /*!< [3..3] Tx FIFO overrun masked interrupt status.
                          • 0: No + overrun condition occurred in TX FIFO.
                          • 1: Overrun + condition occurred in TX FIFO.
                          */ + __IM uint32_t RXFEMIS : 1; /*!< [4..4] RX FIFO empty masked interrupt status.
                          • 0: RX FIFO + is not empty.
                          • 1: RX FIFO is empty..
                          */ + __IM uint32_t RXFNFMIS : 1; /*!< [5..5] RX FIFO nearly full masked interrupt status.
                          • 0: + Number of entries in the RX FIFO less than the RFTR:THRESHOLD_RX + register.
                          • 1: Number of entries in the RX FIFO greater + than or equal to the RFTR:THRESHOLD_RX register.
                          */ + __IM uint32_t RXFFMIS : 1; /*!< [6..6] RX FIFO full masked interrupt status.
                          • 0: RX FIFO + is not full.
                          • 1: RX FIFO is full.
                          */ + __IM uint32_t : 9; + __IM uint32_t RFSRMIS : 1; /*!< [16..16] Read-from-Slave request masked interrupt status.
                          • 0: + Read-from-slave request has been served.
                          • 1: Read-from-slave + request is pending.
                          */ + __IM uint32_t RFSEMIS : 1; /*!< [17..17] Read-from-Slave empty masked interrupt status.
                          • 0: + TX FIFO is not empty.
                          • 1: TX FIFO is empty with + the read-from-slave operation in progress.
                          */ + __IM uint32_t WTSRMIS : 1; /*!< [18..18] Write-to-Slave request masked interrupt status.
                          • 0: + No write-to-slave request pending.
                          • 1: Write-to-slave + request is pending.
                          */ + __IM uint32_t MTDMIS : 1; /*!< [19..19] Master Transaction done masked interrupt status.
                          • 0: + Master transaction acknowledged.
                          • 1: Master transaction + done (ready for acknowledgment).
                          */ + __IM uint32_t STDMIS : 1; /*!< [20..20] Slave Transaction done masked interrupt status.
                          • 0: + Slave transaction acknowledged.
                          • 1: Slave transaction + done (ready for acknowledgment).
                          */ + __IM uint32_t : 3; + __IM uint32_t MALMIS : 1; /*!< [24..24] Master Arbitration lost masked interrupt status.
                          • 0: + No master arbitration lost.
                          • 1: Master arbitration + lost.
                          */ + __IM uint32_t BERRMIS : 1; /*!< [25..25] Bus Error masked interrupt status.
                          • 0: No bus + error detection.
                          • 1: Bus error detection.
                          */ + __IM uint32_t : 2; + __IM uint32_t MTDWSMIS : 1; /*!< [28..28] Master Transaction done without stop masked interrupt + status.
                          • 0: Master transaction acknowledged.
                          • 1: + Master transaction done (ready for acknowledgment) and + stop is not applied into the I2C bus.
                          */ + } MISR_b; + } ; + + union { + __IOM uint32_t ICR; /*!< (@ 0x00000038) I2C interrupt clear register */ + + struct { + __IM uint32_t : 3; + __IOM uint32_t TXFOVRIC : 1; /*!< [3..3] Tx FIFO overrun interrupt clear.
                          • 0: Has no effect.
                          • 1: + Clears interrupt pending.
                          */ + __IM uint32_t : 12; + __IOM uint32_t RFSRIC : 1; /*!< [16..16] Read-from-Slave request interrupt clear.
                          • 0: + Has no effect.
                          • 1: Clears interrupt pending.
                          */ + __IOM uint32_t RFSEIC : 1; /*!< [17..17] Read-from-Slave empty interrupt clear.
                          • 0: Has + no effect.
                          • 1: Clears interrupt pending.
                          */ + __IOM uint32_t WTSRIC : 1; /*!< [18..18] Write-to-Slave request interrupt clear.
                          • 0: Has + no effect.
                          • 1: Clears interrupt pending.
                          */ + __IOM uint32_t MTDIC : 1; /*!< [19..19] Master Transaction done interrupt clear.
                          • 0: + Has no effect.
                          • 1: Clears interrupt pending.
                          */ + __IOM uint32_t STDIC : 1; /*!< [20..20] Slave Transaction done interrupt clear.
                          • 0: Has + no effect.
                          • 1: Clears interrupt pending.
                          */ + __IM uint32_t : 3; + __IOM uint32_t MALIC : 1; /*!< [24..24] Master Arbitration lost interrupt clear.
                          • 0: + Has no effect.
                          • 1: Clears interrupt pending.
                          */ + __IOM uint32_t BERRIC : 1; /*!< [25..25] Bus Error interrupt clear.
                          • 0: Has no effect.
                          • 1: + Clears interrupt pending.
                          */ + __IM uint32_t : 2; + __IOM uint32_t MTDWSIC : 1; /*!< [28..28] Master Transaction done without stop interrupt clear.
                          • 0: + Has no effect.
                          • 1: Clears interrupt pending.
                          */ + __IM uint32_t : 1; + __IOM uint32_t TIMEOUTIC : 1; /*!< [30..30] Timeout or Tlow error interrupt clear.
                          • 0: Has + no effect.
                          • 1: Clears interrupt pending.
                          */ + } ICR_b; + } ; + __IM uint32_t RESERVED9[4]; + + union { + __IOM uint16_t THDDAT; /*!< (@ 0x0000004C) I2C hold time data */ + + struct { + __IOM uint16_t THDDAT : 9; /*!< [8..0] Hold time data value. In master or slave mode, when the + I2C controller detects a falling edge in the SCL line, + the counter, which is loaded by the THDDAT, is launched. + Once the THDDAT value is reached, the data is transferred. */ + } THDDAT_b; + } ; + __IM uint16_t RESERVED10; + + union { + __IOM uint32_t THDSTA_FST_STD; /*!< (@ 0x00000050) I2C hold time start condition F/S */ + + struct { + __IOM uint32_t THDSTA_STD : 9; /*!< [8..0] Hold time start condition value for standard mode. When + the start condition is asserted, the decimeter loads the + value of THDSTA_STD for standard mode, once the THDSTA_STD + value is reached, the SCL line asserts low. */ + __IM uint32_t : 7; + __IOM uint32_t THDSTA_FST : 9; /*!< [24..16] Hold time start condition value for fast mode. When + the start condition is asserted, the decimeter loads the + value of THDSTA_FST for fast mode, once the THDSTA_FST + value is reached, the SCL line assert slow. */ + } THDSTA_FST_STD_b; + } ; + __IM uint32_t RESERVED11; + + union { + __IOM uint32_t TSUSTA_FST_STD; /*!< (@ 0x00000058) I2C setup time start condition F/S */ + + struct { + __IOM uint32_t TSUSTA_STD : 9; /*!< [8..0] Setup time start condition value for standard mode. After + a non-stop on the SCL line the decimeter loads the value + of TSUSTA_STD according to standard mode. Once the counter + is expired, the start condition is generated. */ + __IM uint32_t : 7; + __IOM uint32_t TSUSTA_FST : 9; /*!< [24..16] Setup time start condition value for fast mode. After + a non-stop on the SCL line the decimeter loads the value + of TSUSTA_FST according to fast mode. Once the counter + is expired the start condition is generated. */ + } TSUSTA_FST_STD_b; + } ; +} I2C_Type; /*!< Size = 92 (0x5c) */ + + + +/* =========================================================================================================================== */ +/* ================ AHBUPCONV ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief AHB up/down converter converter (AHBUPCONV) + */ + +typedef struct { /*!< (@ 0x40C00000) AHBUPCONV Structure */ + __IOM uint8_t COMMAND; /*!< (@ 0x00000000) AHB up/down converter command register */ + __IM uint8_t RESERVED[3]; + __IM uint8_t STATUS; /*!< (@ 0x00000004) Status register */ +} AHBUPCONV_Type; /*!< Size = 5 (0x5) */ + + + +/* =========================================================================================================================== */ +/* ================ MFT1 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief MFT1 (MFT1) + */ + +typedef struct { /*!< (@ 0x40D00000) MFT1 Structure */ + __IOM uint16_t TNCNT1; /*!< (@ 0x00000000) The Timer/Counter 1 register is a 16-bit RW register + that is not altered by reset and thus contains + random data upon power-up. Reading the register + returns the current value of the Timer/Counter + 1. TnCNT1 can only be written by the software + when MFT is enabled (TnEN = 1). When MFT + is disabled (TnEN = 0), write operations + on TnCNT1 register are ignored. */ + __IM uint16_t RESERVED; + __IOM uint16_t TNCRA; /*!< (@ 0x00000004) The Capture/Reload A register is a 16-bit RW + register that is not affected by reset and + thus contains random data upon power-up. + The software may read the register at any + time. However, the register can only be + written by the software when MFT is enabled + (TnEN = 1). When MFT is disabled (TnEN = + 0), write operations on TnCRA register are + ignored. */ + __IM uint16_t RESERVED1; + __IOM uint16_t TNCRB; /*!< (@ 0x00000008) The Capture/Reload B register is a 16-bit RW + register that is not affected by reset and + thus contains random data upon power-up. + The software may read the register at any + time. However, the register can only be + written by the software when MFT is enabled + (TnEN = 1). When MFT is disabled (TnEN = + 0), write operations on TnCRB register are + ignored. */ + __IM uint16_t RESERVED2; + __IOM uint16_t TNCNT2; /*!< (@ 0x0000000C) The Timer/Counter 2 register is a 16-bit RW register + that is not altered by reset and thus contains + random data upon power-up. Reading the register + returns the current value of the Timer/Counter + 2. TnCNT2 can only be written by the software + when MFT is enabled (TnEN = 1). When MFT + is disabled (TnEN = 0), write operations + on TnCNT2 register are ignored. */ + __IM uint16_t RESERVED3; + __IOM uint8_t TNPRSC; /*!< (@ 0x00000010) It contains the current value of the clock prescaler, + which determines the timer clock prescaler + ratio. The register value can be changed + at any time. The timer clock is generated + by dividing the system clock by TnPRSC + + 1. Therefore, the maximum timer clock frequency + is equal to the frequency of the system + clock (TnPRSC = 0x00), and the minimum timer + clock is the frequency of the system clock + divided by 256 (TnPRSC = 0xFF). */ + __IM uint8_t RESERVED4; + __IM uint16_t RESERVED5; + + union { + __IOM uint8_t TNCKC; /*!< (@ 0x00000014) Clock unit control register */ + + struct { + __IOM uint8_t TNC1CSEL : 3; /*!< [2..0] Define the clock mode for Timer/Counter 1:
                          • 000b: + No clock (Timer/Counter 1 stopped).
                          • 001b: System + clock with configurable prescaler (register TnPRSC).
                          • 010b: + External event on TnB (mode 1 and 3 only).
                          • 011b: + Pulse accumulate (mode 1 and 3 only).
                          • 100b: 16 + MHz clock without prescaler (only when the system clock + is 32 MHz).
                          */ + __IOM uint8_t TNC2CSEL : 3; /*!< [5..3] Define the clock mode for Timer/Counter 2:
                          • 000b: + No clock (Timer/Counter 2 stopped).
                          • 001b: System + clock with configurable prescaler (register TnPRSC).
                          • 010b: + External event on TnB (mode 1 and 3 only).
                          • 011b: + Pulse accumulate (mode 1 and 3 only).
                          • 100b: 16 + MHz clock without prescaler (only when the system clock + is 32 MHz).
                          */ + } TNCKC_b; + } ; + __IM uint8_t RESERVED6; + __IM uint16_t RESERVED7; + + union { + __IOM uint16_t TNMCTRL; /*!< (@ 0x00000018) Timer mode control register */ + + struct { + __IOM uint16_t TNMDSEL : 2; /*!< [1..0] MFTX mode select:
                          • 00b: Mode 1 or 1a: PWM mode + and system timer or pulse train.
                          • 01b: Mode 2: Dual-input + capture and system timer.
                          • 10b: Mode 3: Dual independent + Timer/Counter.
                          • 11b: Mode 4: Single timer and single + input capture.
                          */ + __IOM uint16_t TNAEDG : 1; /*!< [2..2] Configure the TnA edge polarity for trigging an action:
                          • 0: + Input is sensitive to falling edges.
                          • 1: Input is + sensitive to rising edges.
                          */ + __IOM uint16_t TNBEDG : 1; /*!< [3..3] Configure the TnB edge polarity for trigging an action:
                          • 0: + Input is sensitive to falling edges.
                          • 1: Input is + sensitive to rising edges.
                          */ + __IOM uint16_t TNAEN : 1; /*!< [4..4] Enables TnA to either function as a preset input or as + a PWM output depending on the mode of operation. If the + bit is set (1) while operating in the dual-input capture + mode (mode 2), a transition on TnA causes TnCNT1 to be + preset to 0xFFFF. In the remaining modes of operation, + setting TnAEN enables TnA to function as a PWM output:
                          • 0: + TnA input disable.
                          • 1: TnA input enable.
                          */ + __IOM uint16_t TNBEN : 1; /*!< [5..5] TnB Enable: If set (1) and while operating in dual-input + capture mode (mode 2) or input capture and timer mode (mode + 4), a transition on TnB will cause the corresponding Timer/Counter + to be preset to 0xFFFF. In mode 2, TnCNT1 will be preset + to 0xFFFF, while in mode 4, TnCNT2 is preset to 0xFFFF. + The bit has no effect while operating in any other modes + than mode 2 or mode 4:
                          • 0: TnB input disable.
                          • 1: + TnB input enable.
                          */ + __IOM uint16_t TNAOUT : 1; /*!< [6..6] It contains the value of the TnA when used as PWM output. + The bit will be set and cleared by the hardware and thus + reflects the status of TnA. The bit can be read or written + by software at any time. If the hardware is attempting + to toggle the bit at the same time that software writes + to the bit, the software write will take precedence over + the hardware update. The bit has no effect when TnA is + used as an input or when the module is disabled:
                          • 0: + TnA pin is low.
                          • 1: TnA pin is high.
                          */ + __IOM uint16_t TNEN : 1; /*!< [7..7] MFT is enabled if the bit is set (1), otherwise it is + disabled. When MFT is disabled, all clocks to the counter + unit are stopped, thus decreasing power consumption to + a minimum. For that reason, the Timer/Counter registers + (TnCNT1, TnCNT2), the Capture/Reload registers (TnCRA, + TnCRB) and the interrupt-pending bits (TnXPND) cannot be + written by software. Furthermore, the 8-bit clock prescaler + and the interrupt-pending bits are reset and the TnA I/O + pin becomes an input. */ + __IOM uint16_t TNPTEN : 1; /*!< [8..8] This bitfield enable the mode 1a. If set (1) while TnMDSEL + is set to 00b, the Timer/Counter 1 operates in PWM pulse-train + mode (mode 1a). The bit has no effect while TnMDSEL is + set to any value other than 00b:
                          • 0: Mode 1a not + selected.
                          • 1: Mode 1a selected (if TnMDSEL = 00b).
                          */ + __IOM uint16_t TNPTSE : 1; /*!< [9..9] Tn Pulse-Train software trigger enable: if set (1) while + operating in PWM pulse-train mode (mode 1a), the pulse-train + generation can only be triggered by setting the TnPTET + to 1. If the TnPTSE bit is reset (0), pulses are generated + only if a transition occurs on TnB. The bit has no effect + while operating in any other modes than timer mode 1a:
                          • 0: + No effect.
                          • 1: Pulse-train generation trigger (in + mode 1a)
                          */ + __IOM uint16_t TNPTET : 1; /*!< [10..10] Tn Pulse-Train event trigger: if set (1) while operating + in pulse-train mode (mode 1a) and the TnPTSE bit is set + (1), pulse-train generation is triggered. When Timer/Counter + 2 (TnCNT2) reaches its underflow condition, this bit is + reset (0). If the TnPTSE bit is not set (0) while operating + in mode 1a, the TnPTET bit cannot be written.
                          • 0: + No pulse-train event trigger occurred.
                          • 1: Pulse-train + event trigger occurred (in mode 1a).
                          */ + } TNMCTRL_b; + } ; + __IM uint16_t RESERVED8; + + union { + __IOM uint8_t TNICTRL; /*!< (@ 0x0000001C) Timer interrupt control register */ + + struct { + __IM uint8_t TNAPND : 1; /*!< [0..0] Timer interrupt A pending:
                          • 0: No interrupt source + pending.
                          • 1: Interrupt source pending.
                          */ + __IM uint8_t TNBPND : 1; /*!< [1..1] Timer interrupt B pending:
                          • 0: No interrupt source + pending.
                          • 1: Interrupt source pending.
                          */ + __IM uint8_t TNCPND : 1; /*!< [2..2] Timer interrupt C pending:
                          • 0: No interrupt source + pending.
                          • 1: Interrupt source pending.
                          */ + __IM uint8_t TNDPND : 1; /*!< [3..3] Timer interrupt D pending:
                          • 0: No interrupt source + pending.
                          • 1: Interrupt source pending.
                          */ + __IOM uint8_t TNAIEN : 1; /*!< [4..4] Timer interrupt A enable:
                          • 0: Interrupt disabled.
                          • 1: + Interrupt enabled.
                          */ + __IOM uint8_t TNBIEN : 1; /*!< [5..5] Timer interrupt B enable:
                          • 0: Interrupt disabled.
                          • 1: + Interrupt enabled.
                          */ + __IOM uint8_t TNCIEN : 1; /*!< [6..6] Timer interrupt C enable:
                          • 0: Interrupt disabled.
                          • 1: + Interrupt enabled.
                          */ + __IOM uint8_t TNDIEN : 1; /*!< [7..7] Timer interrupt D enable:
                          • 0: Interrupt disabled.
                          • 1: + Interrupt enabled.
                          */ + } TNICTRL_b; + } ; + __IM uint8_t RESERVED9; + __IM uint16_t RESERVED10; + + union { + __OM uint8_t TNICLR; /*!< (@ 0x00000020) Timer interrupt clear register */ + + struct { + __OM uint8_t TNACLR : 1; /*!< [0..0] 1: clear the timer pending flag A. */ + __OM uint8_t TNBCLR : 1; /*!< [1..1] 1: clear the timer pending flag B. */ + __OM uint8_t TNCCLR : 1; /*!< [2..2] 1: clear the timer pending flag C. */ + __OM uint8_t TNDCLR : 1; /*!< [3..3] 1: clear the timer pending flag D. */ + } TNICLR_b; + } ; + __IM uint8_t RESERVED11; + __IM uint16_t RESERVED12; +} MFT_Type; /*!< Size = 36 (0x24) */ + + + +/* =========================================================================================================================== */ +/* ================ RTC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Real-Time Counter (RTC) + */ + +typedef struct { /*!< (@ 0x40F00000) RTC Structure */ + + union { + __IM uint32_t CWDR; /*!< (@ 0x00000000) Clockwatch Data Register */ + + struct { + __IM uint32_t CWSEC : 6; /*!< [5..0] RTC clockwatch second value. Clockwatch seconds: 0 to + 59 (max 0x3B). */ + __IM uint32_t CWMIN : 6; /*!< [11..6] RTC clockwatch minute value. Clockwatch seconds: 0 to + 59 (max 0x3B). */ + __IM uint32_t CWHOUR : 5; /*!< [16..12] RTC clockwatch hour value. Clockwatch seconds: 0 to + 23 (max 0x17). */ + __IM uint32_t CWDAYW : 3; /*!< [19..17] RTC clockwatch day of week value. Clockwatch day of + week:
                          • 001b: Sunday.
                          • 010b: Monday.
                          • 011b: + Tuesday.
                          • 100b: Wednesday.
                          • 101b: Thursday.
                          • 110b: + Friday.
                          • 111b: Saturday.
                          */ + __IM uint32_t CWDAYM : 5; /*!< [24..20] RTC clockwatch day of month value: 1 to 28/29/30 or + 31. Range of value to program depends on the month:
                          • 1 + to 28: February month, non-leap year.
                          • 1 to 29: + February month, leap year.
                          • 1 to 30: April, June, + September, November month.
                          • 1 to 31: January, March, + May, August, October, December month.
                          */ + __IM uint32_t CWMONTH : 4; /*!< [28..25] RTC clockwatch month value:
                          • 0001b: January.
                          • ...
                          • 1100: December.
                          */ + } CWDR_b; + } ; + + union { + __IOM uint32_t CWDMR; /*!< (@ 0x00000004) Clockwatch Data Match Register */ + + struct { + __IOM uint32_t CWSECM : 6; /*!< [5..0] RTC clockwatch second match value:
                          • 00 0000 to + 11 1011: (0 to 59 or 0x00 to 0x3B) clockwatch seconds.
                          • 11 + 1100 to 11 1111 - (60 to 63 or 0x3C to 0x3F).
                          Non-valid + data, match never occurs. */ + __IOM uint32_t CWMINM : 6; /*!< [11..6] RTC clockwatch minute match value:
                          • 00 0000 to + 11 1011: (0 to 59 or 0x00 to 0x3B) clockwatch minutes.
                          • 11 + 1100 to 11 1111 - (60 to 63 or 0x3C to 0x3F).
                          Non-valid + data, match never occurs. */ + __IOM uint32_t CWHOURM : 5; /*!< [16..12] RTC clockwatch hour match value:
                          • 00000b to 10111b: + (0 to 23 or 0x00 to 0x17) hour match value.
                          • 11000b + to 11111b - (24 to 31 or 0x18 to 0x1F).
                          Non-valid + data, match never occurs. */ + __IOM uint32_t CWDAYWM : 3; /*!< [19..17] RTC clockwatch day of week match value:
                          • 000b: + day of week is don't care in the comparison. (Default value + after PORn).
                          • 001b to 111b: (1 to 7) day of week + match value.
                          */ + __IOM uint32_t CWDAYMM : 5; /*!< [24..20] RTC clockwatch day of month match value:
                          • 0000b: + (month is don't care in the comparison. Default value after + PORn).
                          • 1 to 31: day of month match value.
                          */ + __IOM uint32_t CWMONTHM : 4; /*!< [28..25] RTC clockwatch month match value:
                          • 0000b: (day + of month is don't care in the comparison. Default value + after PORn).
                          • 0001b to 1100b: (1 to 12) month match + value.
                          • 1101b (13, 0xD) to 1111b (0xF) non-valid + data, match never occurs.
                          */ + } CWDMR_b; + } ; + + union { + __IOM uint32_t CWDLR; /*!< (@ 0x00000008) Clockwatch Data Load Register */ + + struct { + __IOM uint32_t CWSECL : 6; /*!< [5..0] RTC clockwatch second load value. Clockwatch seconds + from 0 to 59 (0x3B). Other values must not be used. */ + __IOM uint32_t CWMINL : 6; /*!< [11..6] RTC clockwatch minute load value. Clockwatch minutes + from 0 to 59 (0x3B). Other values must not be used. */ + __IOM uint32_t CWHOURL : 5; /*!< [16..12] RTC clockwatch hour load value. Clockwatch hours from + 0 to 23 (0x17). Other values must not be used. */ + __IOM uint32_t CWDAYWL : 3; /*!< [19..17] RTC clockwatch day of week load value. Clockwatch day + of week:
                          • 000b: Must not be used.
                          • 001b: Sunday.
                          • 010 + : Monday.
                          • 011b: Tuesday.
                          • 100b: Wednesday.
                          • 101b: + Thursday.
                          • 110b: Friday.
                          • 111b: Saturday.
                          */ + __IOM uint32_t CWDAYML : 5; /*!< [24..20] RTC clockwatch day of month load value. 1 to 28/29/30 + or 31 depending on month:
                          • 1 to 28: February month, + non-leap year.
                          • 1 to 29: February month, leap year.
                          • 1 + to 30: April, June, September, November month.
                          • 1 + to 31: January, March, May, August, October, December month.
                          • Othe + values must not be used.
                          */ + __IOM uint32_t CWMONTHL : 4; /*!< [28..25] RTC clockwatch month load value:
                          • 0001b: January.
                          • ...
                          • 1100: December.
                          Other values must not be + used. */ + } CWDLR_b; + } ; + + union { + __IM uint16_t CWYR; /*!< (@ 0x0000000C) Clockwatch Year Register */ + + struct { + __IM uint16_t CWYEAR : 14; /*!< [13..0] RTC clockwatch year value. Clockwatch year, in BCD format + is from 0 to 3999. */ + } CWYR_b; + } ; + __IM uint16_t RESERVED; + + union { + __IOM uint16_t CWYMR; /*!< (@ 0x00000010) Clockwatch Year Match Register */ + + struct { + __IOM uint16_t CWYEARM : 14; /*!< [13..0] RTC clockwatch year match value. Clockwatch year match + value is in BCD format from 0 to 3999. */ + } CWYMR_b; + } ; + __IM uint16_t RESERVED1; + + union { + __IOM uint16_t CWYLR; /*!< (@ 0x00000014) Clockwatch Year Load Register */ + + struct { + __IOM uint16_t CWYEARL : 14; /*!< [13..0] RTC clockwatch year load value. Clockwatch year load + value is in BCD format from 0 to 3999. */ + } CWYLR_b; + } ; + __IM uint16_t RESERVED2; + + union { + __IOM uint32_t CTCR; /*!< (@ 0x00000018) Control Trim and Counter Register */ + + struct { + __IOM uint32_t CKDIV : 15; /*!< [14..0] Clock divider factor. This value plus one represents + the integer part of the CLK32K clock divider used to produce + the reference 1 Hz clock.
                          • 0x000: CLK1HZ clock is + similar to CLK32K for RTC timer and stopped for RTC clockwatch.
                          • 0 + 0001: 2 CLK32K clock cycles per CLK1HZ clock cycle.
                          • ...
                          • 0 + 7FFF: 32768 CLK32K clock cycles per CLK1HZ clock cycle + (default value after PORn reset).
                          • ...
                          • 0xFFFF: + CLK32K clock cycles per CLK1HZ clock cycle.
                          Writing + to this bit-fie */ + __IM uint32_t : 1; + __IOM uint32_t CKDEL : 10; /*!< [25..16] Trim delete count. This value represents the number + of CLK32K clock pulses to delete every 1023 CLK32K clock + cycles to get a better reference 1 Hz clock for incrementing + the RTC counter.
                          • 0x000: No CLK32K clock cycle is + deleted every 1023 CLK1HZ clock cycles (default value after + PORn reset).
                          • 0x001: 1 CLK32K clock cycle is deleted + every 1023 CLK1HZ clock cycles.
                          • ...
                          • 0x3FF: + 1023 CLK32K clock cycles are deleted every 1023 CLK1HZ + clock cycles.
                          Writing to this bit-field wi */ + __IOM uint32_t CWEN : 1; /*!< [26..26] Clockwatch enable bit. When set to 1, the clockwatch + is enabled. Once it is enabled, any write to this register + has no effect until a power-on reset. A read returns the + value of the CWEN bit value. */ + } CTCR_b; + } ; + + union { + __IOM uint8_t IMSC; /*!< (@ 0x0000001C) RTC interrupt mask register */ + + struct { + __IOM uint8_t WIMSC : 1; /*!< [0..0] RTC clock watch interrupt enable bit:
                          • When set + to 0, clears the interrupt mask (default after PORn reset). + The interrupt is disabled.
                          • When set to 1, the interrupt + for RTC clockwatch interrupt is enabled.
                          */ + __IOM uint8_t TIMSC : 1; /*!< [1..1] RTC timer interrupt enable bit:
                          • When set to 0, + sets the mask for RTC timer interrupt (default after PORn + reset). The interrupt is disabled.
                          • When set to + 1, clears this mask and enables the interrupt.
                          */ + } IMSC_b; + } ; + __IM uint8_t RESERVED3; + __IM uint16_t RESERVED4; + + union { + __IM uint8_t RIS; /*!< (@ 0x00000020) RTC raw interrupt status register */ + + struct { + __IM uint8_t WRIS : 1; /*!< [0..0] RTC clock watch raw interrupt status bit. Gives the raw + interrupt state (prior to masking) of the RTC clock watch + interrupt. */ + __IM uint8_t TRIS : 1; /*!< [1..1] RTC timer raw interrupt status bit. Gives the raw interrupt + state (prior to masking) of the RTC timer interrupt. */ + } RIS_b; + } ; + __IM uint8_t RESERVED5; + __IM uint16_t RESERVED6; + + union { + __IM uint8_t MIS; /*!< (@ 0x00000024) RTC masked interrupt status register */ + + struct { + __IM uint8_t WMIS : 1; /*!< [0..0] RTC clock watch interrupt status bit. Gives the masked + interrupt status (after masking) of the RTC clock watch + interrupt WINTR. */ + __IM uint8_t TMIS : 1; /*!< [1..1] RTC timer interrupt status bit. Gives the masked interrupt + status (after masking) of the RTC timer interrupt TINTR. */ + } MIS_b; + } ; + __IM uint8_t RESERVED7; + __IM uint16_t RESERVED8; + + union { + __OM uint8_t ICR; /*!< (@ 0x00000028) RTC interrupt clear register */ + + struct { + __OM uint8_t WIC : 1; /*!< [0..0] RTC clock watch interrupt clear register bit. Clears + the RTC clock watch interrupt WINTR.
                          • 0: No effect.
                          • 1: + Clears the interrupt.
                          */ + __OM uint8_t TIC : 1; /*!< [1..1] RTC timer interrupt clear register bit. Clears the RTC + timer interrupt TINTR.
                          • 0: No effect.
                          • 1: + Clears the interrupt.
                          */ + } ICR_b; + } ; + __IM uint8_t RESERVED9; + __IM uint16_t RESERVED10; + __IM uint32_t TDR; /*!< (@ 0x0000002C) RTC timer load value */ + + union { + __IOM uint16_t TCR; /*!< (@ 0x00000030) RTC timer control register */ + + struct { + __IOM uint16_t OS : 1; /*!< [0..0] RTC Timer one shot count.
                          • 0: Periodic mode (default). + When reaching zero, the RTC timer raises its interrupt + and is reloaded from the LD content.
                          • 1: One-shot + mode. When reaching zero, the RTC timer raise its interrupt + and stops.
                          */ + __IOM uint16_t EN : 1; /*!< [1..1] RTC Timer enable bit.
                          • 0: The RTC timer is stopped + on the next CLK32K cycle.
                          • 1: The RTC timer is enabled + on the next CLK32K cycle.
                          When the RTC timer is + stopped, the content of the counter is frozen. A read returns + the value of the EN bit. This bit set by hardware when + the TLR register is written to while the counter is stopped. + When the device is active, this bit is cleared by hardware + when the counter reaches zero in one-shot mode. */ + __IOM uint16_t S : 1; /*!< [2..2] RTC Timer self start bit. When written to 1b, each write + in a load register or a pattern will set EN to 1b, so, + start the counter in the next CLK32K cycle. */ + __IM uint16_t : 1; + __IOM uint16_t SP : 7; /*!< [10..4] RTC Timer Pattern size. Number of pattern bits crossed + by the pointer. It defines the useful pattern size. */ + __IOM uint16_t CLK : 1; /*!< [11..11] RTC Timer clock.
                          • 0: The RTC timer is clocked + by CLK32K.
                          • 1: The RTC timer is clocked by the trimmed + clock.
                          */ + __IOM uint16_t BYPASS_GATED : 1; /*!< [12..12] Enable or disable the internal clock gating:
                          • 0: + The internal clock gating is activated.
                          • 1: No clock + gating, clock is always enabled.
                          */ + } TCR_b; + } ; + __IM uint16_t RESERVED11; + __IOM uint32_t TLR1; /*!< (@ 0x00000034) RTC Timer first Load Register */ + __IOM uint32_t TLR2; /*!< (@ 0x00000038) RTC Timer second Load Register */ + __IOM uint32_t TPR1; /*!< (@ 0x0000003C) RTC Timer Pattern Register (pattern[31:0]) */ + __IOM uint32_t TPR2; /*!< (@ 0x00000040) RTC Timer Pattern Register (pattern[63:32]) */ + __IOM uint32_t TPR3; /*!< (@ 0x00000044) RTC Timer Pattern Register (pattern[95:64]) */ + __IOM uint32_t TPR4; /*!< (@ 0x00000048) RTC Timer Pattern Register (pattern[127:96]) */ + __IOM uint32_t TIN; /*!< (@ 0x0000004C) RTC Timer Interrupt Number Register */ +} RTC_Type; /*!< Size = 80 (0x50) */ + + + +/* =========================================================================================================================== */ +/* ================ BLUE_CTRL ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief BLUE Controller (BLUE_CTRL) + */ + +typedef struct { /*!< (@ 0x48000000) BLUE_CTRL Structure */ + __IOM uint32_t INTERRUPT; /*!< (@ 0x00000000) Interrupt status and clear register */ + __IOM uint32_t TIMEOUT; /*!< (@ 0x00000004) Timeout programming register */ + __IM uint32_t TIMER_CAPTURE; /*!< (@ 0x00000008) Captured timer value register */ + __IOM uint32_t RADIO_CONFIG; /*!< (@ 0x0000000C) Radio configuration register */ + __IM uint32_t CURRENT_TIME; /*!< (@ 0x00000010) Timer current value register */ + __IM uint32_t STATUS; /*!< (@ 0x00000014) Status register */ + __IOM uint32_t AES_KEY0; /*!< (@ 0x00000018) AES key bit [127:96] */ + __IOM uint32_t AES_KEY1; /*!< (@ 0x0000001C) AES key bit [95:64] */ + __IOM uint32_t AES_KEY2; /*!< (@ 0x00000020) AES key bit [63:32] */ + __IOM uint32_t AES_KEY3; /*!< (@ 0x00000024) AES key bit [31:0] */ + __IOM uint32_t CLEAR_TEXT0; /*!< (@ 0x00000028) AES clear text bit [127:96] */ + __IOM uint32_t CLEAR_TEXT1; /*!< (@ 0x0000002C) AES clear text bit [95:64] */ + __IOM uint32_t CLEAR_TEXT2; /*!< (@ 0x00000030) AES clear text bit [63:32] */ + __IOM uint32_t CLEAR_TEXT3; /*!< (@ 0x00000034) AES clear text bit [31:0]. Writing in this register + starts an encryption */ + __IM uint32_t AES_CYPHERTEXT0; /*!< (@ 0x00000038) AES cypher text bit [127:96] */ + __IM uint32_t AES_CYPHERTEXT1; /*!< (@ 0x0000003C) AES cypher text bit [95:64] */ + __IM uint32_t AES_CYPHERTEXT2; /*!< (@ 0x00000040) AES cypher text bit [63:32] */ + __IM uint32_t AES_CYPHERTEXT3; /*!< (@ 0x00000044) AES cypher text bit [31:0] */ + __IOM uint32_t HOST_WKUP_TIMER; /*!< (@ 0x00000048) Host wakeup timer register */ +} BLUE_CTRL_Type; /*!< Size = 76 (0x4c) */ + + + +/* =========================================================================================================================== */ +/* ================ CKGEN_BLE ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Clock Gen BLE (CKGEN_BLE) + */ + +typedef struct { /*!< (@ 0x48100000) CKGEN_BLE Structure */ + __IM uint32_t RESERVED[2]; + + union { + __IM uint16_t REASON_RST; /*!< (@ 0x00000008) Indicates the reset reason from BLE */ + + struct { + __IM uint16_t : 1; + __IM uint16_t BOR : 1; /*!< [1..1] Reset from BOR */ + __IM uint16_t POR : 1; /*!< [2..2] Reset from POR */ + __IM uint16_t WKP_IO9 : 1; /*!< [3..3] Wakeup from external IO9 */ + __IM uint16_t WKP_IO10 : 1; /*!< [4..4] Wakeup from external IO10 */ + __IM uint16_t WKP_IO11 : 1; /*!< [5..5] Wakeup from external IO11 */ + __IM uint16_t WKP_IO12 : 1; /*!< [6..6] Wakeup from external IO12 */ + __IM uint16_t WKP_IO13 : 1; /*!< [7..7] Wakeup from external IO13 */ + __IM uint16_t WKP_BLUE : 1; /*!< [8..8] Wakeup coms from the timer 1 expiration in the wakeup + control block of the BLE radio */ + __IM uint16_t : 1; + __IM uint16_t WKP2_BLUE : 1; /*!< [10..10] Wakeup coms from the timer 2 expiration in the wakeup + control block of the BLE radio */ + } REASON_RST_b; + } ; + __IM uint16_t RESERVED1; + + union { + __IOM uint16_t CLK32K_COUNT; /*!< (@ 0x0000000C) Counter of 32 kHz clock */ + + struct { + __IOM uint16_t SLOW_COUNT : 9; /*!< [8..0] Program the window length (in slow clock period unit) + for slow clock measurement */ + } CLK32K_COUNT_b; + } ; + __IM uint16_t RESERVED2; + + union { + __IOM uint32_t CLK32K_PERIOD; /*!< (@ 0x00000010) Period of 32 kHz clock */ + + struct { + __IM uint32_t SLOW_PERIOD : 19; /*!< [18..0] Indicates slow clock period information. The result + provided in this field corresponds to the length of SLOW_COUNT + periods of the slow clock (32 kHz) measured in 16 MHz half-period + unit. The measurement is done automatically each time the + device enters in active2 mode using SLOW_COUNT = 16. A + new calculation can be launched by writing zero in CLK32K_PERIOD + register. In this case, the time window uses the value + programmed in SLOW_COUNT field. */ + } CLK32K_PERIOD_b; + } ; + + union { + __IM uint32_t CLK32K_FREQ; /*!< (@ 0x00000014) Measurement of frequency of 32 kHz clock */ + + struct { + __IM uint32_t SLOW_FREQ : 27; /*!< [26..0] Value equal to 2^33 / SLOW_PERIOD */ + } CLK32K_FREQ_b; + } ; + + union { + __IOM uint16_t CLK32K_IT; /*!< (@ 0x00000018) Interrupt event for 32 kHz clock measurement */ + + struct { + __IOM uint16_t CLK32K_MEAS_IRQ : 1; /*!< [0..0] When read, provides the status of the interrupt indicating + slow lock measurement is finished:
                          • 0: No pending + interrupt.
                          • 1: Pending interrupt.
                          When + written, clears the interrupt:
                          • 0: No effect.
                          • 1: + Clear the interrupt.
                          */ + } CLK32K_IT_b; + } ; + __IM uint16_t RESERVED3; +} CKGEN_BLE_Type; /*!< Size = 28 (0x1c) */ + + + +/* =========================================================================================================================== */ +/* ================ DMA ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DMA (DMA) + */ + +typedef struct { /*!< (@ 0xA0000000) DMA Structure */ + + union { + __IM uint32_t ISR; /*!< (@ 0x00000000) DMA interrupt status register */ + + struct { + __IM uint32_t GIF0 : 1; /*!< [0..0] Channel 0 global interrupt flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No TE, HT or TC event + on channel 0.
                          • 1: A TE, HT or TC event occurred + on channel 0.
                          */ + __IM uint32_t TCIF0 : 1; /*!< [1..1] Channel 0 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer complete + (TC) on channel 0.
                          • 1: A transfer complete (TC) + occurred on channel 0.
                          */ + __IM uint32_t HTIF0 : 1; /*!< [2..2] Channel 0 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No half transfer (HT) + event on channel 0.
                          • 1: A half transfer (HT) event + occurred on channel 0.
                          */ + __IM uint32_t TEIF0 : 1; /*!< [3..3] Channel 0 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer error (TE) + event on channel 0.
                          • 1: A transfer error (TE) occurred + on channel 0.
                          */ + __IM uint32_t GIF1 : 1; /*!< [4..4] Channel 1 global interrupt flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No TE, HT or TC event + on channel 1.
                          • 1: A TE, HT or TC event occurred + on channel 1.
                          */ + __IM uint32_t TCIF1 : 1; /*!< [5..5] Channel 1 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer complete + (TC) on channel 1.
                          • 1: A transfer complete (TC) + occurred on channel 1.
                          */ + __IM uint32_t HTIF1 : 1; /*!< [6..6] Channel 1 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No half transfer (HT) + event on channel 1.
                          • 1: A half transfer (HT) event + occurred on channel 1.
                          */ + __IM uint32_t TEIF1 : 1; /*!< [7..7] Channel 1 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer error (TE) + event on channel 1.
                          • 1: A transfer error (TE) occurred + on channel 1.
                          */ + __IM uint32_t GIF2 : 1; /*!< [8..8] Channel 2 global interrupt flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No TE, HT or TC event + on channel 2.
                          • 1: A TE, HT or TC event occurred + on channel 2.
                          */ + __IM uint32_t TCIF2 : 1; /*!< [9..9] Channel 2 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer complete + (TC) on channel 2.
                          • 1: A transfer complete (TC) + occurred on channel 2.
                          */ + __IM uint32_t HTIF2 : 1; /*!< [10..10] Channel 2 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No half transfer (HT) + event on channel 2.
                          • 1: A half transfer (HT) event + occurred on channel 2.
                          */ + __IM uint32_t TEIF2 : 1; /*!< [11..11] Channel 2 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer error (TE) + event on channel 2.
                          • 1: A transfer error (TE) occurred + on channel 2.
                          */ + __IM uint32_t GIF3 : 1; /*!< [12..12] Channel 3 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No TE, HT or TC event + on channel 3.
                          • 1: A TE, HT or TC event occurred + on channel 3.
                          */ + __IM uint32_t TCIF3 : 1; /*!< [13..13] Channel 3 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer complete + (TC) on channel 3.
                          • 1: A transfer complete (TC) + occurred on channel 3.
                          */ + __IM uint32_t HTIF3 : 1; /*!< [14..14] Channel 3 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No half transfer (HT) + event on channel 3.
                          • 1: A half transfer (HT) event + occurred on channel 3.
                          */ + __IM uint32_t TEIF3 : 1; /*!< [15..15] Channel 3 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer error (TE) + event on channel 3.
                          • 1: A transfer error (TE) occurred + on channel 3.
                          */ + __IM uint32_t GIF4 : 1; /*!< [16..16] Channel 4 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No TE, HT or TC event + on channel 4.
                          • 1: A TE, HT or TC event occurred + on channel 4.
                          */ + __IM uint32_t TCIF4 : 1; /*!< [17..17] Channel 4 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer complete + (TC) on channel 4.
                          • 1: A transfer complete (TC) + occurred on channel 4.
                          */ + __IM uint32_t HTIF4 : 1; /*!< [18..18] Channel 4 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No half transfer (HT) + event on channel 4.
                          • 1: A half transfer (HT) event + occurred on channel 4.
                          */ + __IM uint32_t TEIF4 : 1; /*!< [19..19] Channel 4 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer error (TE) + event on channel 4.
                          • 1: A transfer error (TE) occurred + on channel 4.
                          */ + __IM uint32_t GIF5 : 1; /*!< [20..20] Channel 5 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No TE, HT or TC event + on channel 5.
                          • 1: A TE, HT or TC event occurred + on channel 5.
                          */ + __IM uint32_t TCIF5 : 1; /*!< [21..21] Channel 5 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer complete + (TC) on channel 5.
                          • 1: A transfer complete (TC) + occurred on channel 5.
                          */ + __IM uint32_t HTIF5 : 1; /*!< [22..22] Channel 5 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No half transfer (HT) + event on channel 5.
                          • 1: A half transfer (HT) event + occurred on channel 5.
                          */ + __IM uint32_t TEIF5 : 1; /*!< [23..23] Channel 5 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer error (TE) + event on channel 5.
                          • 1: A transfer error (TE) occurred + on channel 5.
                          */ + __IM uint32_t GIF6 : 1; /*!< [24..24] Channel 6 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No TE, HT or TC event + on channel 6.
                          • 1: A TE, HT or TC event occurred + on channel 6.
                          */ + __IM uint32_t TCIF6 : 1; /*!< [25..25] Channel 6 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer complete + (TC) on channel 6.
                          • 1: A transfer complete (TC) + occurred on channel 6.
                          */ + __IM uint32_t HTIF6 : 1; /*!< [26..26] Channel 6 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No half transfer (HT) + event on channel 6.
                          • 1: A half transfer (HT) event + occurred on channel 6.
                          */ + __IM uint32_t TEIF6 : 1; /*!< [27..27] Channel 6 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer error (TE) + event on channel 6.
                          • 1: A transfer error (TE) occurred + on channel 6.
                          */ + __IM uint32_t GIF7 : 1; /*!< [28..28] Channel 7 global interrupt flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No TE, HT or TC event + on channel 7.
                          • 1: A TE, HT or TC event occurred + on channel 7.
                          */ + __IM uint32_t TCIF7 : 1; /*!< [29..29] Channel 7 transfer complete flag. This bit is set by + hardware. It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer complete + (TC) on channel 7.
                          • 1: A transfer complete (TC) + occurred on channel 7.
                          */ + __IM uint32_t HTIF7 : 1; /*!< [30..30] Channel 7 half transfer flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No half transfer (HT) + event on channel 7.
                          • 1: A half transfer (HT) event + occurred on channel 7.
                          */ + __IM uint32_t TEIF7 : 1; /*!< [31..31] Channel 7 transfer error flag. This bit is set by hardware. + It is cleared by software writing 1 to the corresponding + bit in the IFCR register.
                          • 0: No transfer error (TE) + event on channel 7.
                          • 1: A transfer error (TE) occurred + on channel 7.
                          */ + } ISR_b; + } ; + + union { + __OM uint32_t IFCR; /*!< (@ 0x00000004) DMA interrupt flag clear register */ + + struct { + __OM uint32_t CGIF0 : 1; /*!< [0..0] Channel 0 global interrupt flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the GIF, TEIF, HTIF and TCIF + flags in the ISR register.
                          */ + __OM uint32_t CTCIF0 : 1; /*!< [1..1] Channel 0 transfer complete flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the corresponding + TCIF flag in the ISR register.
                          */ + __OM uint32_t CHTIF0 : 1; /*!< [2..2] Channel 0 half transfer flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding HTIF flag + in the ISR register.
                          */ + __OM uint32_t CTEIF0 : 1; /*!< [3..3] Channel 0 transfer error flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding TEIF flag + in the ISR register.
                          */ + __OM uint32_t CGIF1 : 1; /*!< [4..4] Channel 1 global interrupt flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the GIF, TEIF, HTIF and TCIF + flags in the ISR register.
                          */ + __OM uint32_t CTCIF1 : 1; /*!< [5..5] Channel 1 transfer complete flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the corresponding + TCIF flag in the ISR register.
                          */ + __OM uint32_t CHTIF1 : 1; /*!< [6..6] Channel 1 half transfer flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding HTIF flag + in the ISR register.
                          */ + __OM uint32_t CTEIF1 : 1; /*!< [7..7] Channel 1 transfer error flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding TEIF flag + in the ISR register.
                          */ + __OM uint32_t CGIF2 : 1; /*!< [8..8] Channel 2 global interrupt flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the GIF, TEIF, HTIF and TCIF + flags in the ISR register.
                          */ + __OM uint32_t CTCIF2 : 1; /*!< [9..9] Channel 2 transfer complete flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the corresponding + TCIF flag in the ISR register.
                          */ + __OM uint32_t CHTIF2 : 1; /*!< [10..10] Channel 2 half transfer flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding HTIF flag + in the ISR register.
                          */ + __OM uint32_t CTEIF2 : 1; /*!< [11..11] Channel 2 transfer error flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding TEIF flag + in the ISR register.
                          */ + __OM uint32_t CGIF3 : 1; /*!< [12..12] Channel 3 global interrupt flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
                          */ + __OM uint32_t CTCIF3 : 1; /*!< [13..13] Channel 3 transfer complete flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the corresponding + TCIF flag in the ISR register.
                          */ + __OM uint32_t CHTIF3 : 1; /*!< [14..14] Channel 3 half transfer flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding HTIF flag + in the ISR register.
                          */ + __OM uint32_t CTEIF3 : 1; /*!< [15..15] Channel 3 transfer error flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding TEIF flag + in the ISR register.
                          */ + __OM uint32_t CGIF4 : 1; /*!< [16..16] Channel 4 global interrupt flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
                          */ + __OM uint32_t CTCIF4 : 1; /*!< [17..17] Channel 4 transfer complete flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the corresponding + TCIF flag in the ISR register.
                          */ + __OM uint32_t CHTIF4 : 1; /*!< [18..18] Channel 4 half transfer flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding HTIF flag + in the ISR register.
                          */ + __OM uint32_t CTEIF4 : 1; /*!< [19..19] Channel 4 transfer error flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding TEIF flag + in the ISR register.
                          */ + __OM uint32_t CGIF5 : 1; /*!< [20..20] Channel 5 global interrupt flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
                          */ + __OM uint32_t CTCIF5 : 1; /*!< [21..21] Channel 5 transfer complete flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the corresponding + TCIF flag in the ISR register.
                          */ + __OM uint32_t CHTIF5 : 1; /*!< [22..22] Channel 5 half transfer flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding HTIF flag + in the ISR register.
                          */ + __OM uint32_t CTEIF5 : 1; /*!< [23..23] Channel 5 transfer error flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding TEIF flag + in the ISR register.
                          */ + __OM uint32_t CGIF6 : 1; /*!< [24..24] Channel 6 global interrupt flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
                          */ + __OM uint32_t CTCIF6 : 1; /*!< [25..25] Channel 6 transfer complete flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the corresponding + TCIF flag in the ISR register.
                          */ + __OM uint32_t CHTIF6 : 1; /*!< [26..26] Channel 6 half transfer flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding HTIF flag + in the ISR register.
                          */ + __OM uint32_t CTEIF6 : 1; /*!< [27..27] Channel 6 transfer error flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding TEIF flag + in the ISR register.
                          */ + __OM uint32_t CGIF7 : 1; /*!< [28..28] Channel 7 global interrupt flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the GIF, + TEIF, HTIF and TCIF flags in the ISR register.
                          */ + __OM uint32_t CTCIF7 : 1; /*!< [29..29] Channel 7 transfer complete flag. This bit is set by + software.
                          • 0: No effect.
                          • 1: Clears the corresponding + TCIF flag in the ISR register.
                          */ + __OM uint32_t CHTIF7 : 1; /*!< [30..30] Channel 7 half transfer flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding HTIF flag + in the ISR register.
                          */ + __OM uint32_t CTEIF7 : 1; /*!< [31..31] Channel 7 transfer error flag. This bit is set by software.
                          • 0: + No effect.
                          • 1: Clears the corresponding TEIF flag + in the ISR register.
                          */ + } IFCR_b; + } ; +} DMA_Type; /*!< Size = 8 (0x8) */ + + + +/* =========================================================================================================================== */ +/* ================ DMA_CH0 ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DMA channel (DMA_CH0) + */ + +typedef struct { /*!< (@ 0xA0000008) DMA_CH0 Structure */ + + union { + __IOM uint32_t CCR; /*!< (@ 0x00000000) DMA channel configuration register */ + + struct { + __IOM uint32_t EN : 1; /*!< [0..0] DMA channel enable.
                          • 0: DMA channel disabled.
                          • 1: + DMA channel enabled.
                          */ + __IOM uint32_t TCIE : 1; /*!< [1..1] Transfer complete interrupt enable.
                          • 0: TC interrupt + disabled.
                          • 1: TC interrupt enabled.
                          */ + __IOM uint32_t HTIE : 1; /*!< [2..2] Half transfer interrupt enable.
                          • 0: HT interrupt + disabled.
                          • 1: HT interrupt enabled.
                          */ + __IOM uint32_t TEIE : 1; /*!< [3..3] Transfer error interrupt enable.
                          • 0: TE interrupt + disabled.
                          • 1: TE interrupt enabled.
                          */ + __IOM uint32_t DIR : 1; /*!< [4..4] Data transfer direction.
                          • 0: Read from peripheral.
                          • 1: + Read from memory.
                          */ + __IOM uint32_t CIRC : 1; /*!< [5..5] Circular mode.
                          • 0: Circular mode disabled.
                          • 1: + Circular mode enabled.
                          */ + __IOM uint32_t PINC : 1; /*!< [6..6] Peripheral increment mode.
                          • 0: Peripheral increment + disabled.
                          • 1: Peripheral increment enabled.
                          */ + __IOM uint32_t MINC : 1; /*!< [7..7] Memory increment mode.
                          • 0: Memory increment disabled.
                          • 1: + Memory increment enabled.
                          */ + __IOM uint32_t PSIZE : 2; /*!< [9..8] Peripheral size.
                          • 00b: Size 8 bits.
                          • 01b: + Size 16 bits.
                          • 10b: Size 32 bits.
                          */ + __IOM uint32_t MSIZE : 2; /*!< [11..10] Memory size.
                          • 00b: Size 8 bits.
                          • 01b: + Size 16 bits.
                          • 10b: Size 32 bits.
                          */ + __IOM uint32_t PL : 2; /*!< [13..12] Channel priority level.
                          • 00b: Low priority.
                          • 01b: + Medium priority.
                          • 10b: High priority.
                          • 11b: + Very high priority.
                          */ + __IOM uint32_t MEM2MEM : 1; /*!< [14..14] Memory to memory mode.
                          • 0: Memory to memory mode + disabled.
                          • 0: Memory to memory mode enabled.
                          */ + __IM uint32_t CCR_RESERVED : 17; /*!< [31..15] CCR not used bitfield. */ + } CCR_b; + } ; + + union { + __IOM uint32_t CNDTR; /*!< (@ 0x00000004) DMA channel number of data register. */ + + struct { + __IOM uint32_t NDT : 16; /*!< [15..0] Number of data to be transferred (0 up to 65535). This + register can only be written when the channel is disabled. + Once the channel is enabled, this register is read-only, + indicating the remaining bytes to be transmitted. This + register decrements after each DMA transfer. Once the transfer + is completed, this register can either stay at zero or + be reloaded automatically by the value previously programmed + if the channel is configured in auto-reload mode. If this + register is zero, no transaction can be served w */ + __IM uint32_t CNDTR_RESERVED : 16; /*!< [31..16] CNDTR not used bitfield. */ + } CNDTR_b; + } ; + + union { + __IOM uint32_t CPAR; /*!< (@ 0x00000008) DMA channel peripheral address register */ + + struct { + __IOM uint32_t PA : 32; /*!< [31..0] Base address of the peripheral data register from/to + which the data will be read/written. When PSIZE is 01 (16-bit), + the PA[0] bit is ignored. Access is automatically aligned + to a halfword address. When PSIZE is 10 (32-bit), PA[1:0] + are ignored. Access is automatically aligned to a word + address. */ + } CPAR_b; + } ; + + union { + __IOM uint32_t CMAR; /*!< (@ 0x0000000C) DMA channel memory address register */ + + struct { + __IOM uint32_t MA : 32; /*!< [31..0] Base address of the memory area from/to which the data + will be read/written. When MSIZE is 01 (16-bit), the MA[0] + bit is ignored. Access is automatically aligned to a halfword + address. When MSIZE is 10 (32-bit), MA[1:0] are ignored. + Access is automatically aligned to a word address. */ + } CMAR_b; + } ; +} DMA_CH_Type; /*!< Size = 16 (0x10) */ + + + +/* =========================================================================================================================== */ +/* ================ RNG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief RNG (RNG) + */ + +typedef struct { /*!< (@ 0xB0000000) RNG Structure */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000000) RNG configuration register */ + + struct { + __IM uint32_t : 2; + __IOM uint32_t DIS : 1; /*!< [2..2] Set the state of the random number generator.
                          • 0: + RNG is enable.
                          • 1: RNG is disabled. The internal + free-running oscillators are put in power-down mode and + the RNG clock is stopped at the input of the block.
                          */ + __IM uint32_t : 1; + __IM uint32_t CR_RESERVED : 28; /*!< [31..4] CR not used bitfield. */ + } CR_b; + } ; + + union { + __IM uint32_t SR; /*!< (@ 0x00000004) RNG status register */ + + struct { + __IM uint32_t RDY : 1; /*!< [0..0] New random value ready.
                          • 0: The RNG_VAL register + value is not yet valid. If performing a read access to + VAL, the host will be put on hold (by wait-states insertion + on the AHB bus) until a random value is available.
                          • 1: + The VAL register contains a valid random number.
                          This + bit remains at 0 when the RNG is disabled (RNGDIS bit = + 1b in CR) */ + __IM uint32_t : 2; + __IM uint32_t SR_RESERVED : 29; /*!< [31..3] SR not used bitfield. */ + } SR_b; + } ; + __IM uint32_t VAL; /*!< (@ 0x00000008) RNG 16 bit random value */ +} RNG_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ PKA ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief PKA (PKA) + */ + +typedef struct { /*!< (@ 0xC0000000) PKA Structure */ + + union { + __IOM uint32_t CSR; /*!< (@ 0x00000000) Command and status register */ + + struct { + __OM uint32_t GO : 1; /*!< [0..0] PKA start processing command:
                          • 0: has no effect.
                          • 1: + starts the processing.
                          After this bitfield is + written to 1, it must be written back to zero manually. */ + __IM uint32_t READY : 1; /*!< [1..1] PKA readiness status:
                          • 0: the PKA is computing. + It is not ready.
                          • 1: the PKA is ready to start a + new processing.
                          The rising edge of the READY bit + set the PROC_END flag in the ISR register. */ + __IM uint32_t : 5; + __OM uint32_t SFT_RST : 1; /*!< [7..7] PKA software reset:
                          • 0: has no effect.
                          • 1: + reset the PKA peripheral.
                          After this bitfield + is written to 1, it must be written back to zero manually. */ + __IM uint32_t CSR_RESERVED : 24; /*!< [31..8] CSR not used bitfield. */ + } CSR_b; + } ; + + union { + __IOM uint32_t ISR; /*!< (@ 0x00000004) Interrupt status register */ + + struct { + __IOM uint32_t PROC_END : 1; /*!< [0..0] PKA process ending interrupt. When read:
                          • 0: no + event.
                          • 1: PKA process is ended.
                          When written:
                          • 0: + no effect.
                          • 1: clears the PKA process ending interrupt.
                          */ + __IM uint32_t : 1; + __IOM uint32_t RAM_ERR : 1; /*!< [2..2] RAM read / write access error interrupt. When read:
                          • 0: + All AHB read or write access to the PKA RAM occurred while + the PKA was stopped.
                          • 1: All the AHB read or write + access to the PKA RAM occurred while the PKA was operating + and using the internal RAM. Those read or write could not + succeed as the PKA internal RAM is disconnected from the + AHB bus when the PKA is operating (READY bit low).
                          When + written:
                          • 0: no effect.
                          • 1: clears the RAM + access error interrupt.
                          */ + __IOM uint32_t ADD_ERR : 1; /*!< [3..3] AHB address error interrupt. When read:
                          • 0: All + AHB read or write access to the PKA RAM occurred in a mapped + address range.
                          • 1: All AHB read or write access + to the PKA RAM occurred in an unmapped address range.
                          When + written:
                          • 0: no effect.
                          • 1: clears the AHB + Address error interrupt.
                          */ + __IM uint32_t ISR_RESERVED : 28; /*!< [31..4] ISR not used bitfield. */ + } ISR_b; + } ; + + union { + __IOM uint32_t IEN; /*!< (@ 0x00000008) Interrupt enable register */ + + struct { + __IOM uint32_t PROCEND_EN : 1; /*!< [0..0] Process ended interrupt enable.
                          • 0: interrupt disabled.
                          • 1 + interrupt enabled.
                          */ + __IM uint32_t : 1; + __IOM uint32_t RAMERR_EN : 1; /*!< [2..2] RAM access error interrupt enable.
                          • 0: interrupt + disabled.
                          • 1: interrupt enabled.
                          */ + __IOM uint32_t ADDERR_EN : 1; /*!< [3..3] AHB address error interrupt enable.
                          • 0: interrupt + disabled.
                          • 1: interrupt enabled.
                          */ + __IM uint32_t ISR_RESERVED : 28; /*!< [31..4] ISR not used bitfield. */ + } IEN_b; + } ; +} PKA_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ ROM_INFO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief ROM information (ROM_INFO) + */ + +typedef struct { /*!< (@ 0x10000000) ROM_INFO Structure */ + __IM uint32_t RESERVED[4]; + __IM uint32_t BOOTLOADER_VERSION; /*!< (@ 0x00000010) Bootloader Version */ + __IM uint32_t RESERVED1; + __IM uint32_t FLASH_WRITE; /*!< (@ 0x00000018) FLASH write function */ + __IM uint32_t FLASH_ERASE; /*!< (@ 0x0000001C) FLASH erase function */ + __IM uint32_t BOOTLOADER; /*!< (@ 0x00000020) Bootloader entry point */ + __IM uint32_t RESERVED2[483]; + __IM uint32_t BLD_TRIM; /*!< (@ 0x000007B0) BLD trimming value */ + __IM uint32_t ADC_BLD_1V8_OFFSET; /*!< (@ 0x000007B4) ADC BLD 1V8 OFFSET */ + __IM uint32_t ADC_BLD_1V8_VALUE; /*!< (@ 0x000007B8) ADC BLD 1V8 VALUE */ + __IM uint32_t ADC_BLD_2V7_OFFSET; /*!< (@ 0x000007BC) ADC BLD 2V7 OFFSET */ + __IM uint32_t ADC_BLD_2V7_VALUE; /*!< (@ 0x000007C0) ADC BLD 2V7 VALUE */ + __IM uint32_t ADC_BLD_3V6_OFFSET; /*!< (@ 0x000007C4) ADC BLD 3V6 OFFSET */ + __IM uint32_t ADC_BLD_3V6_VALUE; /*!< (@ 0x000007C8) ADC BLD 3V6 VALUE */ + __IM uint32_t ADC_SE2_0V_OFFSET; /*!< (@ 0x000007CC) ADC SE2 0V OFFSET */ + __IM uint32_t ADC_SE2_0V_VALUE; /*!< (@ 0x000007D0) ADC SE2 0V VALUE */ + __IM uint32_t ADC_SE2_1V8_OFFSET; /*!< (@ 0x000007D4) ADC SE2 1V8 OFFSET */ + __IM uint32_t ADC_SE2_1V8_VALUE; /*!< (@ 0x000007D8) ADC SE2 1V8 VALUE */ + __IM uint32_t ADC_SE2_3V6_OFFSET; /*!< (@ 0x000007DC) ADC SE2 3V6 OFFSET */ + __IM uint32_t ADC_SE2_3V6_VALUE; /*!< (@ 0x000007E0) ADC SE2 3V6 VALUE */ + __IM uint16_t LDO1V2_TRIMM_CODE; /*!< (@ 0x000007E4) LDO 1V2 trimming code */ + __IM uint16_t LDO1V2_TRIMMING_CODE_CHECK_BYTES;/*!< (@ 0x000007E6) LDO 1V2 trimming code check bytes */ + __IM uint16_t RCO_TRIMMING_CODE; /*!< (@ 0x000007E8) RCO trimming code */ + __IM uint16_t RCO_TRIMMING_CODE_CHECK_BYTES;/*!< (@ 0x000007EA) RCO trimming code check bytes */ + __IM uint32_t RESERVED3[2]; + __IM uint8_t UNIQUE_ID_1; /*!< (@ 0x000007F4) Unique ID 1st byte */ + __IM uint8_t UNIQUE_ID_2; /*!< (@ 0x000007F5) Unique ID 2nd byte */ + __IM uint8_t UNIQUE_ID_3; /*!< (@ 0x000007F6) Unique ID 3rd byte */ + __IM uint8_t UNIQUE_ID_4; /*!< (@ 0x000007F7) Unique ID 4th byte */ + __IM uint8_t UNIQUE_ID_5; /*!< (@ 0x000007F8) Unique ID 5th byte */ + __IM uint8_t UNIQUE_ID_6; /*!< (@ 0x000007F9) Unique ID 6th byte */ + __IM uint16_t UNIQUE_ID_CHECK_CODE; /*!< (@ 0x000007FA) Unique ID check code */ + __IM uint32_t FLASH_PROTECTION_DISABLED; /*!< (@ 0x000007FC) ROM Lock Protection (not locked) */ +} ROM_INFO_Type; /*!< Size = 2048 (0x800) */ + + +/** @} */ /* End of group Device_Peripheral_peripherals */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripheralAddr + * @{ + */ + +#define GPIO_BASE 0x40000000UL +#define FLASH_BASE 0x40100000UL +#define SYSTEM_CTRL_BASE 0x40200000UL +#define UART_BASE 0x40300000UL +#define SPI_BASE 0x40400000UL +#define WDG_BASE 0x40700000UL +#define ADC_BASE 0x40800000UL +#define CKGEN_SOC_BASE 0x40900000UL +#define I2C2_BASE 0x40A00000UL +#define I2C1_BASE 0x40B00000UL +#define AHBUPCONV_BASE 0x40C00000UL +#define MFT1_BASE 0x40D00000UL +#define MFT2_BASE 0x40E00000UL +#define RTC_BASE 0x40F00000UL +#define BLUE_CTRL_BASE 0x48000000UL +#define CKGEN_BLE_BASE 0x48100000UL +#define DMA_BASE 0xA0000000UL +#define DMA_CH0_BASE 0xA0000008UL +#define DMA_CH1_BASE 0xA000001CUL +#define DMA_CH2_BASE 0xA0000030UL +#define DMA_CH3_BASE 0xA0000044UL +#define DMA_CH4_BASE 0xA0000058UL +#define DMA_CH5_BASE 0xA000006CUL +#define DMA_CH6_BASE 0xA0000080UL +#define DMA_CH7_BASE 0xA0000094UL +#define RNG_BASE 0xB0000000UL +#define PKA_BASE 0xC0000000UL +#define ROM_INFO_BASE 0x10000000UL + +/** @} */ /* End of group Device_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_declaration + * @{ + */ + +#define GPIO ((GPIO_Type*) GPIO_BASE) +#define FLASH ((FLASH_Type*) FLASH_BASE) +#define SYSTEM_CTRL ((SYSTEM_CTRL_Type*) SYSTEM_CTRL_BASE) +#define UART ((UART_Type*) UART_BASE) +#define SPI ((SPI_Type*) SPI_BASE) +#define WDG ((WDG_Type*) WDG_BASE) +#define ADC ((ADC_Type*) ADC_BASE) +#define CKGEN_SOC ((CKGEN_SOC_Type*) CKGEN_SOC_BASE) +#define I2C2 ((I2C_Type*) I2C2_BASE) +#define I2C1 ((I2C_Type*) I2C1_BASE) +#define AHBUPCONV ((AHBUPCONV_Type*) AHBUPCONV_BASE) +#define MFT1 ((MFT_Type*) MFT1_BASE) +#define MFT2 ((MFT_Type*) MFT2_BASE) +#define RTC ((RTC_Type*) RTC_BASE) +#define BLUE_CTRL ((BLUE_CTRL_Type*) BLUE_CTRL_BASE) +#define CKGEN_BLE ((CKGEN_BLE_Type*) CKGEN_BLE_BASE) +#define DMA ((DMA_Type*) DMA_BASE) +#define DMA_CH0 ((DMA_CH_Type*) DMA_CH0_BASE) +#define DMA_CH1 ((DMA_CH_Type*) DMA_CH1_BASE) +#define DMA_CH2 ((DMA_CH_Type*) DMA_CH2_BASE) +#define DMA_CH3 ((DMA_CH_Type*) DMA_CH3_BASE) +#define DMA_CH4 ((DMA_CH_Type*) DMA_CH4_BASE) +#define DMA_CH5 ((DMA_CH_Type*) DMA_CH5_BASE) +#define DMA_CH6 ((DMA_CH_Type*) DMA_CH6_BASE) +#define DMA_CH7 ((DMA_CH_Type*) DMA_CH7_BASE) +#define RNG ((RNG_Type*) RNG_BASE) +#define PKA ((PKA_Type*) PKA_BASE) +#define ROM_INFO ((ROM_INFO_Type*) ROM_INFO_BASE) + +/** @} */ /* End of group Device_Peripheral_declaration */ + + +/* ========================================= End of section using anonymous unions ========================================= */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning restore +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG2_H */ + + +/** @} */ /* End of group BlueNRG2 */ + +/** @} */ /* End of group STMicroelectronics */ diff --git a/soc/inc/bluenrg_x_device.h b/soc/inc/bluenrg_x_device.h new file mode 100644 index 0000000..157bffb --- /dev/null +++ b/soc/inc/bluenrg_x_device.h @@ -0,0 +1,99 @@ +/** + ****************************************************************************** + * @file BlueNRG_x_device.h + * @author VMA Application Team + * @version V1.0.0 + * @date 23-January-2017 + * @brief This file is used to select the BlueNRG-1 or BlueNRG-2 device. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

                          © COPYRIGHT 2017 STMicroelectronics

                          + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLUENRG_X_DEVICE_H +#define BLUENRG_X_DEVICE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup BlueNRG_x_device BlueNRG_x_device + * @{ + */ + +#ifdef BLUENRG2_DEVICE /* Reserved for Future Use: Do Not Enable it */ +#include "BlueNRG2.h" +#else +#include "BlueNRG1.h" +#endif + + + +/** @addtogroup BlueNRG_x_device_configuration Configuration + * @{ + */ + +/** + * @} + */ + +/** @addtogroup BlueNRG_x_device_Exported_Constants Exported Constants + * @{ + */ + + + + +/** + * @} + */ + +/** @addtogroup BlueNRG_x_device_Exported_Macros Exported Macros + * @{ + */ + + + +/** + * @} + */ + +/** @addtogroup BlueNRG_x_device_Exported_Typedefs Exported Typedefs + * @{ + */ + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* BLUENRG_X_DEVICE_H */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/soc/inc/system_bluenrg.h b/soc/inc/system_bluenrg.h new file mode 100644 index 0000000..2c520e8 --- /dev/null +++ b/soc/inc/system_bluenrg.h @@ -0,0 +1,296 @@ +/** + ****************************************************************************** + * @file system_bluenrg.h + * @author AMS RF-Application Team + * @version V1.2.0 + * @date 21-November-2018 + * @brief This file contains all the functions prototypes for the CRMU firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

                          © COPYRIGHT 2014 STMicroelectronics

                          + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SYSTEM_BLUENRG_H +#define SYSTEM_BLUENRG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup system_bluenrg system bluenrg + * @{ + */ + +/** @addtogroup system_bluenrg_device_configuration Device Configuration Constants + * @{ + */ + +/** + * @brief High Speed crystal 32 MHz + */ +#define HS_SPEED_XTAL_32MHZ 1 + +/** + * @brief High Speed crystal 16 MHz + */ +#define HS_SPEED_XTAL_16MHZ 2 + +/** + * @brief High Speed Internal RO + * Not useful when radio operation are needed + * or in any case when accurate ref clock is needed. + */ +#define HS_SPEED_XTAL_INTERNAL_RO 3 + + +/** + * @brief Low Speed Internal RO + */ +#define LS_SOURCE_INTERNAL_RO 1 + +/** + * @brief Low Speed External 32 KHz + */ +#define LS_SOURCE_EXTERNAL_32KHZ 2 + +/** + * @brief SMPS Inductor 10 uH + */ +#define SMPS_INDUCTOR_10uH 1 + +/** + * @brief SMPS Inductor 4.7 uH + */ +#define SMPS_INDUCTOR_4_7uH 2 + +/** + * @brief SMPS Inductor None + */ +#define SMPS_INDUCTOR_NONE 3 + +/** + * @brief BOR OFF + */ +#define BOR_OFF 1 + +/** + * @brief BOR ON + */ +#define BOR_ON 2 + +/*Device version to apply the BOR/BLD settings*/ +#define WA_DEVICE_VERSION 0x12 + +/** + * @brief Word to unlock the flash operation + */ +#define FLASH_UNLOCK_WORD 0xFCECBCCC + +/** + * @brief Word to lock the flash operation + */ +#define FLASH_LOCK_WORD 0 + + /** + * @brief High Speed Crystal default configuration + */ +#ifndef HS_SPEED_XTAL +#define HS_SPEED_XTAL HS_SPEED_XTAL_16MHZ +#endif + +/** + * @brief BOR default configuration + */ +#ifndef BOR_CONFIG +#define BOR_CONFIG BOR_ON +#endif + +/** + * @} + */ + + +/** @addtogroup system_bluenrg_Exported_Macros Exported Macros + * @{ + */ + + + +#define SET_BIT(REG, BIT) ((REG) |= (BIT)) + +#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) + +#define READ_BIT(REG, BIT) ((REG) & (BIT)) + +#define CLEAR_REG(REG) ((REG) = (0x0)) + +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) + +#define READ_REG(REG) ((REG)) + +#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) + +#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL))) + + +/* Uncomment the line below to expanse the "assert_param" macro in the + Standard Peripheral Library drivers code */ +/* #define USE_FULL_ASSERT 1 */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT + +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function which reports + * the name of the source file and the source line number of the call + * that failed. If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0) +#endif /* USE_FULL_ASSERT */ + + +/** + * @} + */ + +/** @addtogroup system_bluenrg_Exported_Typedefs Exported Typedefs + * @{ + */ + +typedef void( *intfunc )( void ); +typedef union { intfunc __fun; void * __ptr; } intvec_elem; + + +typedef uint16_t BlueTransBlueStrctPtr_t; +typedef uint16_t BlueTransBlueDataPtr_t; + +typedef struct +{ + volatile uint16_t Config; // 1:0 + volatile uint16_t period_slow; // 3:2 + volatile uint8_t unused; // 4 + volatile uint8_t TxDelay; // 5 + volatile uint8_t RcvDelay; // 6 + volatile uint8_t TxDelay1; // 7 + volatile uint8_t RcvDelay1; // 8 + volatile uint8_t wakeup_time_offset; // 9 + volatile BlueTransBlueDataPtr_t RadioConfigPtr; // 10:11 +} BlueGlob; + +typedef struct +{ + volatile uint8_t Pack_count_Tx[5]; // 4:0 + volatile uint8_t Pack_count_Rcv[5]; // 9:5 + volatile uint8_t stat_config; // 10 + /*volatile uint8_t rcv_fail_count;*/ + volatile uint8_t unmapped_chan; // 11 + volatile BlueTransBlueStrctPtr_t txpoint_prev; // 13:12 + volatile BlueTransBlueStrctPtr_t rcvpoint_prev; // 15:14 + volatile BlueTransBlueStrctPtr_t txpoint; // 17:16 + volatile BlueTransBlueStrctPtr_t rcvpoint; // 19:18 + volatile BlueTransBlueStrctPtr_t txpoint_next; // 21:20 + volatile uint8_t remap_chan; // 22 + volatile uint8_t config; // 23 + volatile uint32_t access_address; // 27:24 + volatile uint32_t crc_init; // 31:28 + /* volatile uint8_t rcv_fail_trig;*/ + volatile uint8_t hop_incr; // 32 + volatile uint8_t chan_remap[5]; // 37:33 + volatile uint8_t enc_iv[8]; // 45:38 + volatile uint8_t enc_key[16]; // 61:46 + volatile uint8_t conf_byte5; // 62 + volatile uint8_t unused; // 63 +} BlueGlobPerMaster; + + +typedef struct +{ + BlueGlob BlueGlobVar; + BlueGlobPerMaster BlueGlobPerMasterVar[8]; + +} __blue_RAM_struct; + + +/** + * @} + */ + + +/** @addtogroup system_bluenrg_Exported_Variables Exported Variables + * @{ + */ + + +extern __blue_RAM_struct __blue_RAM; +extern const intvec_elem __vector_table[]; +extern uint32_t savedICSR; +extern uint32_t savedSHCSR; +extern uint32_t savedNVIC_ISPR; +extern volatile uint8_t wakeupFromSleepFlag; +extern volatile uint32_t ota_sw_activation; +extern volatile uint32_t flash_sw_lock; +extern volatile uint32_t rfTimeout; + +/** + * @} + */ + + +/** @addtogroup system_bluenrg_Exported_Functions Exported Functions + * @{ + */ + +/* Important note: The __low_level_init() function is critical for waking up from + deep sleep and it should not use more that 20 stack positions + otherwise a stack corruption will occur when waking up from deep sleep. + For this reason we are saving and restoring the first 20 words of the stack that + will be corrupted during the wake-up procedure from deep sleep. + If the __low_level_init() will be modified, this define shall be modifed according + the new function implementation +*/ +#define CSTACK_PREAMBLE_NUMBER 20 + + +void SystemInit(void); +void DeviceConfiguration(BOOL coldStart, BOOL waitLS_Ready); +void BOR_ConfigSave(uint8_t pmu_ana_user_conf); +void SET_BORconfigStatus(uint8_t enabled); +void Set_RF_FrontEnd(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_BLUENRG_H */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/soc/inc/system_bluenrg1.h b/soc/inc/system_bluenrg1.h new file mode 100644 index 0000000..035d851 --- /dev/null +++ b/soc/inc/system_bluenrg1.h @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * @file system_bluenrg1.h + * @author AMS RF-Application Team + * @version V1.1.0 + * @date 6-April-2018 + * @brief This file contains all the functions prototypes for the CRMU firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

                          © COPYRIGHT 2018 STMicroelectronics

                          + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SYSTEM_BLUENRG1_H +#define SYSTEM_BLUENRG1_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup system_bluenrg1 system bluenrg1 + * @{ + */ + +#include "compiler.h" +#include "hal_types.h" +#include +#include "system_bluenrg.h" + + +/** @addtogroup system_bluenrg1_Exported_Constants Exported Constants + * @{ + */ + + +/** + * @brief RAM base address + */ +#define _MEMORY_RAM_BEGIN_ 0x20000000 +#define _MEMORY_RAM_SIZE_ 0x6000 /* 24KB */ +#define _MEMORY_RAM_END_ 0x20005FFF + +/** + * @brief User FLASH base address + */ +#define _MEMORY_FLASH_BEGIN_ 0x10040000 +#define _MEMORY_FLASH_SIZE_ 0x28000 /* 160KB */ +#define _MEMORY_FLASH_END_ 0x10067FFF +#define _MEMORY_BYTES_PER_PAGE_ (2048) + +/** + * @brief ROM base address + */ +#define _MEMORY_ROM_BEGIN_ 0x10000000 +#define _MEMORY_ROM_SIZE_ 0x800 /* 2KB */ +#define _MEMORY_ROM_END_ 0x100007FF + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_BLUENRG1_H */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/soc/inc/system_bluenrg2.h b/soc/inc/system_bluenrg2.h new file mode 100644 index 0000000..4eba0df --- /dev/null +++ b/soc/inc/system_bluenrg2.h @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * @file system_bluenrg2.h + * @author AMS RF-Application Team + * @version V1.1.0 + * @date 6-April-2018 + * @brief This file contains all the functions prototypes for the CRMU firmware + * library. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

                          © COPYRIGHT 2018 STMicroelectronics

                          + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SYSTEM_BLUENRG2_H +#define SYSTEM_BLUENRG2_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup system_bluenrg2 system bluenrg2 + * @{ + */ + +#include "compiler.h" +#include "hal_types.h" +#include +#include "system_bluenrg.h" + + +/** @addtogroup system_bluenrg2_Exported_Constants Exported Constants + * @{ + */ + + +/** + * @brief RAM base address + */ +#define _MEMORY_RAM_BEGIN_ 0x20000000 +#define _MEMORY_RAM_SIZE_ 0x6000 /* 24KB */ +#define _MEMORY_RAM_END_ 0x20005FFF + +/** + * @brief User FLASH base address + */ +#define _MEMORY_FLASH_BEGIN_ 0x10040000 +#define _MEMORY_FLASH_SIZE_ 0x40000 /* 256KB */ +#define _MEMORY_FLASH_END_ 0x1007FFFF +#define _MEMORY_BYTES_PER_PAGE_ (2048) + +/** + * @brief ROM base address + */ +#define _MEMORY_ROM_BEGIN_ 0x10000000 +#define _MEMORY_ROM_SIZE_ 0x800 /* 2KB */ +#define _MEMORY_ROM_END_ 0x100007FF + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* SYSTEM_BLUENRG2_H */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/soc/src/system_bluenrg1.c b/soc/src/system_bluenrg1.c new file mode 100644 index 0000000..245b921 --- /dev/null +++ b/soc/src/system_bluenrg1.c @@ -0,0 +1,989 @@ +/******************** (C) COPYRIGHT 2018 STMicroelectronics ******************** +* File Name : system_bluenrg1.c +* Author : AMS - RF Application team +* Version : V1.2.0 +* Date : 21-November-2018 +* Description : BlueNRG-1,BlueNRG-2 Low Level Init function +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file system_bluenrg1.c + * @brief BlueNRG-1,2 Low Level Init functions + * + +* \section SystemInit System Initialization + + - The SystemInit() function is called on BlueNRG-1, BlueNRG-2 main application as first operation required for properly initialize the device: + - It remaps the vector table and it configures all the device interrrupt priorities giving the + highest one to the Pendable request for system service and to the BLE radio BLUE Controller ones. + - It calls the DeviceConfiguration(TRUE,TRUE) function for performing the proper application configuration steps. + - It disables all the peripherals clock except NVM, SYSCTR, PKA and RNG + - It's up to user application to enables the other peripherals clock according to his needs. + - It clear PRIMASK to reenable global interrupt operations. + +* \section DeviceConfiguration_Cold Define Application Configurations + + - During the device initialization phase, some specific parameters must be set + on BLE device controller registers, in order to define the following configurations: + - Application mode: user or test mode + - High speed crystal configuration: 32 or 16 MHz + - Low speed crystal source: external 32 kHz oscillator, internal RO + - SMPS: on or off (if on: 4.7 uH or 10 uH SMPS inductor) + - BOR configuration. + - The BlueNRG-1, BlueNRG-2 controller registers values are defined on file system_bluenrg1.c through the configuration table: + - COLD_START_CONFIGURATION. + - This table defines the default configurations as follows: + - User mode: ATB0_ANA_ENG_REG = USER_MODE_ATB0 (0x00), ATB1_ANA_ENG_REG = USER_MODE_ATB (0x30) + - SMPS ON, 10 uH inductor: CLOCK_LOW_ENG_REG = SMPS_ON, RM1_DIG_ENG_REG = SMPS_10uH_RM1 + - 16 MHz high speed crystal: CLOCK_HIGH_ENG_REG = HIGH_FREQ_16M + - External 32 kHz oscillator: CLOCK_ANA_USER_REG = LOW_FREQ_XO + - BOR (brown-out threshold): it is enabled by default. + - At device initialization, on reset/power-on, the function SystemInit() sets the + starting parameters defined on the COLD_START_CONFIGURATION table within + the cold_start_config[] array by calling the DeviceConfiguration(BOOL coldStart, BOOL waitLS_Ready) function with coldStart = TRUE and waitLS_Ready = TRUE. + As consequence, user application must define the following preprocessor options, based on specific application configuration PCB: + - HS_SPEED_XTAL (high speed cystal: HS_SPEED_XTAL_16MHZ or HS_SPEED_XTAL_32MHZ) + - LS_SOURCE (Low speed crystal source: LS_SOURCE_EXTERNAL_32kHZ, LS_SOURCE_INTERNAL_RO) + - SMPS_INDUCTOR (SPMS inductor disabled: SMPS_INDUCTOR_NONE or SPMS inductor enabled with 10uH: SMPS_INDUCTOR_10uH or SPMS inductor enabled with 4.7uH: SMPS_INDUCTOR_4_7uH). + + - NOTE: BOR_CONFIG preprocessor option is set to BOR_ON by default (brown-out threshold enabled). + + - Regarding the ATB0_ANA_ENG_REG, ATB1_ANA_ENG_REG registers settings, some test modes are also available in order to address some test scenarios. + + WARNING: when using one of the test modes DIO14 cannot be used and must be kept configured as an input pin. + + User should sets such registers as follows: + + - Low speed crystal oscillator test mode: + + - cold_start_config[2] = LS_XTAL_MEAS_ATB0 (0x37) + - cold_start_config[5] = LS_XTAL_MEAS_ATB1 (0x34) + + - High speed start-up time test mode: + + - cold_start_config[2] = HS_STARTUP_TIME_MEAS_ATB0 (0x04) + - cold_start_config[5] = HS_STARTUP_TIME_MEAS_ATB1 (0x34) + + - TX/RX event alert enabling: + + - cold_start_config[2] = TX_RX_START_STOP_MEAS_ATB0 (0x38) + - cold_start_config[5] = TX_RX_START_STOP_MEAS_ATB1 (0x34) + + - Internal RO time test mode: + + - cold_start_config[2] = LS_RO_MEAS_ATB0 (0x36) + - cold_start_config[5] = LS_RO_MEAS_ATB1 (0x34) + + - Please notice that the default user mode register setting must be restored for typical user mode application scenarios: + + - cold_start_config[2] = USER_MODE_ATB0 (0x00) + - cold_start_config[5] = USER_MODE_ATB1 (0x30) + +* \section General_Configuration General Device Configuration + + - Beyond the application configuration performed only at device reset/power-on by calling the DeviceConfiguration() function with + coldStart = TRUE, this function performs the following general configuration operations: + + - Setup RCO32K trimming value in PMU_ANA_USER_REG + - Setup LDO1V2 trimming value in ATB1_ANA_ENG_REG + +* \section DeviceConfiguration_ALL How to set Device Configuration Parameters? + + - The selected device configuration parameters are set within the BLE device controller, Radio configuration register, through the + following instructions executed on DeviceConfiguration() function: + + BLUE_CTRL->RADIO_CONFIG = 0x10000U | (uint16_t)((uint32_t)cold_start_config + & 0x0000FFFFU); + while ((BLUE_CTRL->RADIO_CONFIG & 0x10000) != 0); + + - Once the device configuration parameters are set, the DeviceConfiguration() function must wait until the High Speed (HS) crystal is ready. + Since the slow clock period measurement is done automatically each time the device enters in active2 state and the HS cystal is ready, the + related Clock Gen interrupt signals that a slow clock period measurement has been done: + + while(CKGEN_BLE->CLK32K_IT == 0); //Interrupt event for 32 kHz clock measurement + +**/ + +#include "bluenrg_x_device.h" +#include "BluenRG1_flash.h" +#include "misc.h" +#include "miscutil.h" +#include "hal_types.h" +#include "BlueNRG1_sysCtrl.h" + +#define RESET_WAKE_DEEPSLEEP_REASONS 0x05 +#define CRITICAL_PRIORITY 0 +/* OTA tag used to tag a valid application on interrupt vector table*/ +#if ST_OTA_SERVICE_MANAGER_APPLICATION +#define OTA_VALID_APP_TAG (0xAABBCCDD) /* OTA Service Manager has a special valid tag */ +#else +#define OTA_VALID_APP_TAG (0xAA5555AA) +#endif + +#define BLUE_FLAG_TAG (0x424C5545) + +#define HOT_TABLE_RADIO_SIZE 32 + +WEAK_FUNCTION(void NMI_Handler(void) {}); +WEAK_FUNCTION(void HardFault_Handler(void) {}); +WEAK_FUNCTION(void SVC_Handler(void) {}); +WEAK_FUNCTION(void PendSV_Handler(void) {}); +WEAK_FUNCTION(void SysTick_Handler(void) {}); +WEAK_FUNCTION(void GPIO_Handler(void) {}); +WEAK_FUNCTION(void NVM_Handler(void) {}); +WEAK_FUNCTION(void UART_Handler(void) {}); +WEAK_FUNCTION(void SPI_Handler(void) {}); +WEAK_FUNCTION(void Blue_Handler(void) {}); +WEAK_FUNCTION(void MFT1A_Handler(void) {}); +WEAK_FUNCTION(void MFT1B_Handler(void) {}); +WEAK_FUNCTION(void MFT2A_Handler(void) {}); +WEAK_FUNCTION(void MFT2B_Handler(void) {}); +WEAK_FUNCTION(void RTC_Handler(void) {}); +WEAK_FUNCTION(void WDG_Handler(void) {}); +WEAK_FUNCTION(void ADC_Handler(void) {}); +WEAK_FUNCTION(void I2C2_Handler(void) {}); +WEAK_FUNCTION(void I2C1_Handler(void) {}); +WEAK_FUNCTION(void DMA_Handler(void) {}); +WEAK_FUNCTION(void PKA_Handler(void) {}); + +#ifndef NO_SMART_POWER_MANAGEMENT +static void nextRF_transaction(uint16_t reset_reason); +#endif + +/* ------------------------------------------------------------------------------ +* uint32_t ota_sw_activation +* +* OTA SW activation +* +* ------------------------------------------------------------------------------ */ +NO_INIT_SECTION(volatile uint32_t ota_sw_activation, ".ota_sw_activation"); + +/* ------------------------------------------------------------------------------ +* uint32_t savedMSP +* +* Private storage to hold the saved Main Stack Pointer. +* ------------------------------------------------------------------------------ */ +SECTION(".savedMSP") +REQUIRED(uint32_t savedMSP); + + +/* ------------------------------------------------------------------------------ +* uint8_t wakeupFromSleepFlag +* +* A simple flag used to indicate if the wakeup occurred from Sleep or Standby +* condition. +* If this flag is zero, an interrupt has affected the WFI instruction and the +* BlueNRG-1 doesn't enter in deep sleep state. So, no context restore is +* necessary. +* If this flag is non-zero, the WFI instruction puts the BlueNRG-1 in deep sleep. +* So, at wakeup time a context restore is necessary. +* Note: The smallest unit of storage is a single byte. +* +* NOTE: This flag must be cleared before the context restore is called +* ------------------------------------------------------------------------------ */ +SECTION(".wakeupFromSleepFlag") +REQUIRED(uint8_t volatile wakeupFromSleepFlag); + + +/* ------------------------------------------------------------------------------ +* uint32_t __blueflag_RAM +* +* __blueflag_RAM +* +* ------------------------------------------------------------------------------ */ +SECTION(".__blueflag_RAM") +REQUIRED(uint32_t __blueflag_RAM); + + +/* ------------------------------------------------------------------------------ +* volatile uint32_t flash_sw_lock; +* +* This is used to lock/unlock the flash operations in software. +* The unlock word is 0xFCECBCCC +* ------------------------------------------------------------------------------ */ +SECTION(".flash_sw_lock") +REQUIRED(uint32_t volatile flash_sw_lock); + +/* ------------------------------------------------------------------------------ +* volatile uint32_t rfTimeout; +* +* Timeout for the next RF transaction. +* +* ------------------------------------------------------------------------------ */ +SECTION(".rfTimeout") +REQUIRED(uint32_t volatile rfTimeout); + +/* ------------------------------------------------------------------------------ +* uint32_t savedICSR +* +* Private storage to save the Interrupt Control State register, to check the +* SysTick and PendSV interrupt status +* This variable is only used during the samrt power management +* procedure +* ------------------------------------------------------------------------------ */ +uint32_t savedICSR; + +/* ------------------------------------------------------------------------------ +* uint32_t savedSHCSR +* +* Private storage to save the System Handler Control and State register, +* to check the SVCall interrupt status +* This variable is only used during the samrt power management +* procedure +* ------------------------------------------------------------------------------ */ +uint32_t savedSHCSR; + +/* ------------------------------------------------------------------------------ +* uint32_t savedNVIC_ISPR +* +* Private storage to save the Interrupt Set Pending register, +* to check the NVIC interrupt status +* This variable is only used during the smart power management +* procedure +* ------------------------------------------------------------------------------ */ +uint32_t savedNVIC_ISPR; + +/* ------------------------------------------------------------------------------ +* volatile uint8_t hot_table_radio_config[HOT_TABLE_RADIO_SIZE] +* +* Hot table radio configuration storage. +* This variable is only used during the smart power management +* procedure +* ------------------------------------------------------------------------------ */ +volatile uint8_t hot_table_radio_config[HOT_TABLE_RADIO_SIZE]={0x00}; + +/* ------------------------------------------------------------------------------ +* volatile uint8_t BOR_config[7] +* +* BOR configuration storage. +* This variable is only used during the smart power management +* procedure +* ------------------------------------------------------------------------------ */ +SECTION(".BOR_config") +REQUIRED(volatile uint8_t BOR_config[7]); + + +int __low_level_init(void) +{ + uint8_t i; + volatile uint16_t reset_reason; + +#if (HS_SPEED_XTAL == HS_SPEED_XTAL_32MHZ) + SYSTEM_CTRL->CTRL_b.MHZ32_SEL = 1; +#endif + + /* Lock the flash */ + flash_sw_lock = FLASH_LOCK_WORD; + + for (i=0; i<3; i++) { + reset_reason = SysCtrl_GetWakeupResetReason(); + if (reset_reason != RESET_NONE) + break; + } + /* If the reset reason is a wakeup from sleep restore the context */ + if (reset_reason >= RESET_BLE_WAKEUP_FROM_IO9) { +#ifndef NO_SMART_POWER_MANAGEMENT + /* Verify if load the hot table from the application */ + nextRF_transaction(reset_reason); + + void CS_contextRestore(void); + wakeupFromSleepFlag = 1; /* A wakeup from Standby or Sleep occurred */ + CS_contextRestore(); /* Restore the context */ + /* if the context restore worked properly, we should never return here */ + while(1) { + NVIC_SystemReset(); + } +#else + return 0; +#endif + } + return 1; +} + +#ifdef __CC_ARM + +__attribute__((noreturn)) void RESET_HANDLER(void) +{ + if(__low_level_init()==1) + __main(); + else { + __set_MSP((uint32_t)_INITIAL_SP); + main(); + } + while(1); +} + + +#else /* __CC_ARM */ +#ifdef __GNUC__ + +extern unsigned long _etext; +extern unsigned long _sidata; /* start address for the initialization values of the .data section. Defined in linker script */ +extern unsigned long _sdata; /* start address for the .data section. Defined in linker script */ +extern unsigned long _edata; /* end address for the .data section. Defined in linker script */ +extern unsigned long _sbss; /* start address for the .bss section. Defined in linker script */ +extern unsigned long _ebss; /* end address for the .bss section. Defined in linker script */ +extern unsigned long _sbssblue; /* start address for the section reserved for the Blue controller. Defined in linker script */ +extern unsigned long _ebssblue; /* end address for the section reserved for the Blue controller. Defined in linker script */ +extern unsigned long _estack; /* init value for the stack pointer. Defined in linker script */ +extern unsigned long _sidata2; /* start address for the initialization values of the special ram_preamble */ +extern unsigned long _sdata2; /* start address the special ram_preamble defined in linker script */ +extern unsigned long _edata2; /* end address the special ram_preamble defined in linker script */ + +extern int main(void); + +void RESET_HANDLER(void) +{ + if(__low_level_init()==1) { + unsigned long *pulSrc, *pulDest; + + // Copy the data segment initializers from flash to SRAM. + pulSrc = &_sidata; + for(pulDest = &_sdata; pulDest < &_edata; ) + { + *(pulDest++) = *(pulSrc++); + } + + pulSrc = &_sidata2; + for(pulDest = &_sdata2; pulDest < &_edata2; ) + { + *(pulDest++) = *(pulSrc++); + } + + // Zero fill the bss segment. + for(pulDest = &_sbssblue; pulDest < &_ebssblue; ) + { + *(pulDest++) = 0; + } + + for(pulDest = &_sbss; pulDest < &_ebss; ) + { + *(pulDest++) = 0; + } + } + // Call the application's entry point. + __set_MSP((uint32_t)_INITIAL_SP); + main(); +} + +#endif /* __GNUC__ */ +#endif /* __CC_ARM */ + + +SECTION(".intvec") +REQUIRED(const intvec_elem __vector_table[]) = { + {.__ptr = _INITIAL_SP}, /* Stack address */ + {RESET_HANDLER}, /* Reset handler is C initialization. */ + {NMI_Handler}, /* The NMI handler */ + {HardFault_Handler}, /* The hard fault handler */ + {(intfunc) OTA_VALID_APP_TAG}, /* OTA Application */ + {(intfunc) BLUE_FLAG_TAG}, /* Reserved for blue flag DTM updater */ + {0x00000000}, /* Reserved */ + {0x00000000}, /* Reserved */ + {0x00000000}, /* Reserved */ + {0x00000000}, /* Reserved */ + {0x00000000}, /* Reserved */ + {SVC_Handler}, /* SVCall */ + {0x00000000}, /* Reserved */ + {0x00000000}, /* Reserved */ + {PendSV_Handler}, /* PendSV */ + {SysTick_Handler}, /* SysTick_Handler */ + {GPIO_Handler}, /* IRQ0: GPIO */ + {NVM_Handler}, /* IRQ1: NVM */ + {0x00000000}, /* IRQ2: */ + {0x00000000}, /* IRQ3: */ + {UART_Handler}, /* IRQ4: UART */ + {SPI_Handler}, /* IRQ5: SPI */ + {Blue_Handler}, /* IRQ6: Blue */ + {WDG_Handler}, /* IRQ7: Watchdog */ + {0x00000000}, /* IRQ8: */ + {0x00000000}, /* IRQ9: */ + {0x00000000}, /* IRQ10: */ + {0x00000000}, /* IRQ11: */ + {0x00000000}, /* IRQ12: */ + {ADC_Handler}, /* IRQ13 ADC */ + {I2C2_Handler}, /* IRQ14 I2C2 */ + {I2C1_Handler}, /* IRQ15 I2C1 */ + {0x00000000}, /* IRQ16 */ + {MFT1A_Handler}, /* IRQ17 MFT1 irq1 */ + {MFT1B_Handler}, /* IRQ18 MFT1 irq2 */ + {MFT2A_Handler}, /* IRQ19 MFT2 irq1 */ + {MFT2B_Handler}, /* IRQ20 MFT2 irq2 */ + {RTC_Handler}, /* IRQ21 RTC */ + {PKA_Handler}, /* IRQ22 PKA */ + {DMA_Handler}, /* IRQ23 DMA */ + {0x00000000}, /* IRQ24 */ + {0x00000000}, /* IRQ25 */ + {0x00000000}, /* IRQ26 */ + {0x00000000}, /* IRQ27 */ + {0x00000000}, /* IRQ28 */ + {0x00000000}, /* IRQ29 */ + {0x00000000}, /* IRQ30 */ + {0x00000000} /* IRQ31 */ +}; + + + +//------------------------------------------------------------------------------ +// uint32_t *app_base +// +// The application base address. Used by OTA IRQ stub file to determine the +// effective application base address and jump to the proper IRQ handler. +// +//------------------------------------------------------------------------------ +SECTION(".app_base") +REQUIRED(uint32_t *app_base) = (uint32_t *) __vector_table; + + +SECTION(".bss.__blue_RAM") +REQUIRED(__blue_RAM_struct __blue_RAM) = {0,}; + +/** + * @name Device Configuration Registers + *@{ + */ + +/** + *@brief Analog Test Bus 0 register + */ +#define ATB0_ANA_ENG_REG 0x3F +/** + *@brief Analog Test Bus 1 register + */ +#define ATB1_ANA_ENG_REG 0x3E +/** + *@brief Rate Multiplier 1 register + */ +#define RM1_DIG_ENG_REG 0x3C +/** + *@brief Low Frequency Clock and SMPS register + */ +#define CLOCK_LOW_ENG_REG 0x3B +/** + *@brief High Frequency Clock register + */ +#define CLOCK_HIGH_ENG_REG 0x3A +/** + *@brief Power Management register + */ +#define PMU_ANA_ENG_REG 0x39 +/** + *@brief System Clock register + */ +#define CLOCK_ANA_USER_REG 0x34 +/** + *@brief System Power Management register + */ +#define PMU_ANA_USER_REG 0x35 +/** + *@brief Modulator register + */ +#define MOD_ANA_ENG_REG 0x21 +//@} \\Device Configuration Registers + +/** + * @name Device Configuration values + *@{ + */ + +/** + * @brief Enable the low frequency RO + */ +#define LOW_FREQ_RO 0x1B +/** + * @brief Enable the external low frequency XO + */ +#define LOW_FREQ_XO 0x5B +/** + * @brief Enable the high frequency 16 MHz + */ +#define HIGH_FREQ_16M 0x40 +/** + * @brief Enable the high frequrency 32 MHz + */ +#define HIGH_FREQ_32M 0x44 +/** + * @brief Enable the SMPS + */ +#define SMPS_ON 0x4C +/** + * @brief Disable the SMPS + */ +#define SMPS_OFF 0x6C +/** + * @brief SMPS clock frequency value for 4.7 uH inductor + */ +#define SMPS_4_7uH_RM1 0x40 +/** + * @brief Power management configuration for 4.7 uH inductor + */ +#define SMPS_4_7uH_PMU 0xBE +/** + * @brief SMPS clock frequency value for 10 uH inductor + */ +#define SMPS_10uH_RM1 0x20 +/** + * @brief Power management configuration for 10 uH inductor + */ +#define SMPS_10uH_PMU 0xB2 +/** + * @brief RCO32 trimming default values + */ +#define PMU_ANA_USER_RESET_VALUE 0x0B +/** + * @brief Analog test bus 0 settings for + * normal application mode + */ +#define USER_MODE_ATB0 0x00 +/** + * @brief Analog test bus 1 settings for + * normal application mode + */ +#define USER_MODE_ATB1 0x30 +/** + * @brief Analog test bus 0 settings for + * low speed crystal measurement + */ +#define LS_XTAL_MEAS_ATB0 0x37 +/** + * @brief Analog test bus 1 settings for + * low speed crystal measurement + */ +#define LS_XTAL_MEAS_ATB1 0x34 +/** + * @brief Analog test bus 0 settings for + * high speed crystal startup time measurement + */ +#define HS_STARTUP_TIME_MEAS_ATB0 0x04 +/** + * @brief Analog test bus 1 settings for + * high speed crystal startup time measurement + */ +#define HS_STARTUP_TIME_MEAS_ATB1 0x34 +/** + * @brief Analog test bus 0 settings for + * Tx/Rx start stop signal measurement + */ +#define TX_RX_START_STOP_MEAS_ATB0 0x38 +/** + * @brief Analog test bus 1 settings for + * Tx/Rx start stop signal measurement + */ +#define TX_RX_START_STOP_MEAS_ATB1 0x34 +/** + * @brief Analog test bus 0 settings for + * internal Low Frequency Ring Oscillator + * measurement + */ +#define LS_RO_MEAS_ATB0 0x36 +/** + * @brief Analog test bus 1 settings for + * internal Low Frequency Ring Oscillator + * measurement + */ +#define LS_RO_MEAS_ATB1 0x34 +/** + * @brief Central frequency + */ +#define CENTRAL_FREQ_MOD 0x08 +//@} \\Device Configuration values + +/** + *@brief Number of configuration bytes to send over Blue SPI + */ +#define NUMBER_CONFIG_BYTE 0x02 +/** + *@brief End Configuration Tag + */ +#define END_CONFIG 0x00 + +/** + * @brief Cold start configuration register table + */ +#define COLD_START_CONFIGURATION \ +{ \ + NUMBER_CONFIG_BYTE, ATB0_ANA_ENG_REG, USER_MODE_ATB0, \ + NUMBER_CONFIG_BYTE, ATB1_ANA_ENG_REG, USER_MODE_ATB1, \ + NUMBER_CONFIG_BYTE, RM1_DIG_ENG_REG, SMPS_10uH_RM1, \ + NUMBER_CONFIG_BYTE, CLOCK_LOW_ENG_REG, SMPS_ON, \ + NUMBER_CONFIG_BYTE, CLOCK_HIGH_ENG_REG, HIGH_FREQ_16M, \ + NUMBER_CONFIG_BYTE, PMU_ANA_ENG_REG, SMPS_10uH_PMU, \ + NUMBER_CONFIG_BYTE, CLOCK_ANA_USER_REG, LOW_FREQ_XO, \ + NUMBER_CONFIG_BYTE, PMU_ANA_USER_REG, PMU_ANA_USER_RESET_VALUE, \ + END_CONFIG \ +} + +/** + * @brief RCO32K trimming value flash location + */ +#define RCO32K_TRIMMING_FLASH_ADDR 0x100007E8 +/** + * @brief LDO1V2 trimming value flash location + */ +#define LDO1V2_TRIMMING_FLASH_ADDR 0x100007E4 +/** + * @brief Battery Level Detector Threshold trimming value flash location + */ +#define SET_BLD_LVL_TRIMMING_FLASH_ADDR 0x100007B0 +/** + * @brief Check bytes tag + */ +#define CHECK_BYTES 0xAA55 + + +/* LS Stabilization state machine defines */ +#define WAIT_FREQ_MIN_STATE 0 +#define WAIT_FREQ_STABILIZATION_STATE 1 +#define LS_STABILIZATION_ENDED 2 + +/* Min Clock Period to wait. Clock period value for 20 KHz */ +#define MIN_CLOCK_PERIOD 38400 +/* Max number of iteration to wait before to exit if the clock is not stabilized */ +#define MAX_NUMBER_ITERATION 500 +/* Default slow count */ +#define SLOW_COUNT 23 + +/* Macros to calculate the time diff between two machine times */ +#define INT_ASR(X,Y) ((X) >> (Y)) +#define INT_SHIFT_R(X, Y) ((int32_t)INT_ASR((int32_t)(X),(Y))) +#define TIME24_DIFF(TA, TB) (INT_SHIFT_R((uint32_t)((uint32_t)((TA) - (TB)) << 8), 8)) +/* Timeout Threshold used to evaluate if load the hot table at application level */ +#define TIMEOUT_THRESHOLD 40 + +/* Wait the Low speed oscillator stabilization */ +void Wait_LS_Stabilization(void) +{ + uint8_t ls_state; + uint16_t number_iteration; + volatile uint32_t period1; + uint32_t period2, tick_result; + + number_iteration = 0; + ls_state = WAIT_FREQ_MIN_STATE; + CKGEN_BLE->CLK32K_COUNT = SLOW_COUNT; + + while ((ls_state != LS_STABILIZATION_ENDED) && (number_iteration <= MAX_NUMBER_ITERATION)) { + + /* Stabilization State machine */ + switch(ls_state) + { + case WAIT_FREQ_MIN_STATE: + { + /* Wait until the LS freq is minor of 20 KHz */ + CKGEN_BLE->CLK32K_IT = 1; + CKGEN_BLE->CLK32K_PERIOD = 0; + while(CKGEN_BLE->CLK32K_IT == 0); + period1 = CKGEN_BLE->CLK32K_PERIOD; + if (period1 <= MIN_CLOCK_PERIOD) { + ls_state = WAIT_FREQ_STABILIZATION_STATE; + } + } + break; + case WAIT_FREQ_STABILIZATION_STATE: + { + CKGEN_BLE->CLK32K_IT = 1; + CKGEN_BLE->CLK32K_PERIOD = 0; + while(CKGEN_BLE->CLK32K_IT == 0); + period2 = CKGEN_BLE->CLK32K_PERIOD; + if (period2 > period1) + tick_result = period2 - period1; + else + tick_result = period1 - period2; + if (tick_result <= (period1>>10)) { + ls_state = LS_STABILIZATION_ENDED; + } + period1 = period2; + } + break; + default: + /* Nothing to do */ + break; + } + number_iteration++; + } +} + +/* Configure RF FrontEnd */ +void Set_RF_FrontEnd(void) +{ + uint8_t i=0; + + /* Hot table already populated, search the first free location */ + while (hot_table_radio_config[i] != 0) + i += (hot_table_radio_config[i] + 1); + + if ((i+3) < HOT_TABLE_RADIO_SIZE) { + /* Hot table configuraiton used only for smart power management */ + hot_table_radio_config[i] = NUMBER_CONFIG_BYTE; + hot_table_radio_config[i+1] = MOD_ANA_ENG_REG; + hot_table_radio_config[i+2] = CENTRAL_FREQ_MOD; + hot_table_radio_config[i+3] = END_CONFIG; + + BLUE_CTRL->RADIO_CONFIG = 0x10000U | (uint16_t)((uint32_t)(&hot_table_radio_config[i]) & 0x0000FFFFU); + while ((BLUE_CTRL->RADIO_CONFIG & 0x10000) != 0); + } +} + +/* Function to store the BOR configuration and to populate the hot radio configuration table */ +void BOR_ConfigSave(uint8_t pmu_ana_user_conf) +{ + uint8_t i=0; + + /* Hot table already populated, search the first free location */ + while (hot_table_radio_config[i] != 0) + i += (hot_table_radio_config[i] + 1); + + if ((i+3) < HOT_TABLE_RADIO_SIZE) { + /* BOR configuration storage inside hot table used only for smart power managment */ + hot_table_radio_config[i] = NUMBER_CONFIG_BYTE; + hot_table_radio_config[i+1] = PMU_ANA_USER_REG; + hot_table_radio_config[i+2] = pmu_ana_user_conf; + hot_table_radio_config[i+3] = END_CONFIG; + } + + /* BOR configuration storage used only for smart power managment */ + BOR_config[0] = NUMBER_CONFIG_BYTE; + BOR_config[1] = PMU_ANA_USER_REG; + BOR_config[2] = pmu_ana_user_conf; + BOR_config[3] = END_CONFIG; +} + +/* Function to access the BLUE SPI registers to disable and restore the BOR configuration */ +void SET_BORconfigStatus(uint8_t enabled) +{ + uint8_t pmu_ana_conf; + + if (enabled) { + BLUE_CTRL->RADIO_CONFIG = 0x10000U | (uint16_t)((uint32_t)BOR_config & 0x0000FFFFU); + while ((BLUE_CTRL->RADIO_CONFIG & 0x10000) != 0); + }else { + pmu_ana_conf = BOR_config[2]; + BOR_config[2] &= ~(1<<2); + BLUE_CTRL->RADIO_CONFIG = 0x10000U | (uint16_t)((uint32_t)BOR_config & 0x0000FFFFU); + while ((BLUE_CTRL->RADIO_CONFIG & 0x10000) != 0); + BOR_config[2] = pmu_ana_conf; + } +} + +#ifndef NO_SMART_POWER_MANAGEMENT +/* Function to evaluate if the application has enough time to load the hot table */ +__STATIC_INLINE void nextRF_transaction(uint16_t reset_reason) +{ + uint32_t currTimeTHR; + int32_t time_diff = -1; + PartInfoType Device_partInfo; + uint8_t load_hot_table = 1; + + /* Wakeup from radio transaction. So, nothing to do */ + if (reset_reason & RESET_BLE_WAKEUP_FROM_TIMER1) { + return; + } + + /* Verify device version */ + HAL_GetPartInfo(&Device_partInfo); + if (((Device_partInfo.die_major<<4)|(Device_partInfo.die_cut)) < WA_DEVICE_VERSION) { + load_hot_table = 0; + } + + /* Verify if the BLE radio is NOT active */ + if((*(volatile uint32_t*)0x200000C0 & 8U) == 0U) { + if (load_hot_table) + SET_BORconfigStatus(TRUE); + return; + } + + /* Check if the next transaction is enough in the future */ + currTimeTHR = BLUE_CTRL->CURRENT_TIME + TIMEOUT_THRESHOLD; + time_diff = TIME24_DIFF(rfTimeout, currTimeTHR); + if (time_diff > 0) { + /* There is enough time to load the hot table */ + if (load_hot_table) + SET_BORconfigStatus(TRUE); + /* Restore the Timeout register content after wakeup */ + BLUE_CTRL->TIMEOUT = rfTimeout; + } else { + /* Nothing to do, too close to RF timeout. Wait the radio transaction */ + } + +} +#endif + +void DeviceConfiguration(BOOL coldStart, BOOL waitLS_Ready) +{ + uint32_t current_time; + uint32_t Trimm_config; + uint8_t pmu_ana_user; + PartInfoType Device_partInfo; + volatile uint8_t cold_start_config[] = COLD_START_CONFIGURATION; + + /* Get partInfo */ + HAL_GetPartInfo(&Device_partInfo); + + if (coldStart) { + /* High Speed Crystal Configuration */ +#if (HS_SPEED_XTAL == HS_SPEED_XTAL_32MHZ) + cold_start_config[14] = HIGH_FREQ_32M; + /* Set 32MHz_SEL bit in the System controller register */ + SYSTEM_CTRL->CTRL_b.MHZ32_SEL = 1; +#elif (HS_SPEED_XTAL == HS_SPEED_XTAL_16MHZ) + cold_start_config[14] = HIGH_FREQ_16M; +#else +#error "No definition for High Speed Crystal" +#endif + + /* SMPS configuration */ +#if (SMPS_INDUCTOR == SMPS_INDUCTOR_10uH) + cold_start_config[11] = SMPS_ON; + cold_start_config[8] = SMPS_10uH_RM1; + cold_start_config[17] = SMPS_10uH_PMU; +#elif (SMPS_INDUCTOR == SMPS_INDUCTOR_4_7uH) + cold_start_config[11] = SMPS_ON; + cold_start_config[8] = SMPS_4_7uH_RM1; + cold_start_config[17] = SMPS_4_7uH_PMU; +#elif (SMPS_INDUCTOR == SMPS_INDUCTOR_NONE) + cold_start_config[11] = SMPS_OFF; +#else +#warning "No definition for SMPS Configuration" +#endif + + /* Low Speed Crystal Source */ +#if (LS_SOURCE == LS_SOURCE_EXTERNAL_32KHZ) + cold_start_config[20] = LOW_FREQ_XO; +#elif (LS_SOURCE == LS_SOURCE_INTERNAL_RO) + cold_start_config[20] = LOW_FREQ_RO; +#else +#warning "No definition for Low Speed Crystal Source" +#endif + + /* Setup RCO32K trimming value in PMU_ANA_USER_REG */ + Trimm_config = *(volatile uint32_t*)RCO32K_TRIMMING_FLASH_ADDR; + if ((Trimm_config >> 16) == CHECK_BYTES) { + cold_start_config[23] &= ~0x70; // Clear the register content bit 4-5-6 + cold_start_config[23] |= (Trimm_config&0x7)<<4; // Store the RCO32K trimming value in bit 4-5-6 + } + + /* Setup LDO1V2 trimming value in ATB1_ANA_ENG_REG */ + Trimm_config = *(volatile uint32_t*)LDO1V2_TRIMMING_FLASH_ADDR; + if ((Trimm_config >> 16) == CHECK_BYTES) { + cold_start_config[5] &= ~0x30; // Clear the register content of bit 4 and 5 + cold_start_config[5] |= (Trimm_config&0x3)<<4; // Store the LDO1V2 trimming value in bit 4 and 5 + } + + /* Setup Battery Level Detector Threshold value in PMU_ANA_USER_REG */ + Trimm_config = *(volatile uint32_t*)SET_BLD_LVL_TRIMMING_FLASH_ADDR; + if ((Trimm_config >> 16) == CHECK_BYTES) { + cold_start_config[23] &= ~0x03; // Clear the register content of bit 0 and 1 + cold_start_config[23] |= (Trimm_config&0x3); // Store the BLD_LVL trimming value in bit 0 and 1 + } + + /* BOR configuration. Note: this setup shall be executed after the SMPS configuration*/ +#if (BOR_CONFIG == BOR_ON) + /* Clear the 3 bit of the CLOCK_LOW_ENG_REG register */ + cold_start_config[11] &= ~(1<<2); + if (((Device_partInfo.die_major<<4)|(Device_partInfo.die_cut)) >= WA_DEVICE_VERSION) { + /* Set the 3 bit of the PMU_ANA_USER register */ + cold_start_config[23] |= (1<<2); + pmu_ana_user = cold_start_config[23]; + BOR_ConfigSave(pmu_ana_user); + } +#elif (BOR_CONFIG == BOR_OFF) + /* Set the 3 bit of the CLOCK_LOW_ENG_REG register */ + cold_start_config[11] |= (1<<2); + if (((Device_partInfo.die_major<<4)|(Device_partInfo.die_cut)) >= WA_DEVICE_VERSION) { + /* Clear the 3 bit of the PMU_ANA_USER register */ + cold_start_config[23] &= ~(1<<2); + pmu_ana_user = cold_start_config[23]; + BOR_ConfigSave(pmu_ana_user); + } +#else +#error "No definition for BOR Configuration" +#endif + + /* Cold start configuration device */ + BLUE_CTRL->RADIO_CONFIG = 0x10000U | (uint16_t)((uint32_t)cold_start_config & 0x0000FFFFU); + while ((BLUE_CTRL->RADIO_CONFIG & 0x10000) != 0); + + /* Configure RF FrontEnd */ + if (((Device_partInfo.die_major<<4)|(Device_partInfo.die_cut)) >= WA_DEVICE_VERSION) { + Set_RF_FrontEnd(); + } + + } + + /* Wait until HS is ready. The slow clock period + * measurement is done automatically each time the + * device enters in active2 state and the HS is ready. + * The interrupt signals that a measurement is done. + */ + while(CKGEN_BLE->CLK32K_IT == 0); + CKGEN_BLE->CLK32K_IT = 1; + CKGEN_BLE->CLK32K_COUNT = 23; //Restore the window length for slow clock measurement. + CKGEN_BLE->CLK32K_PERIOD = 0; + + + /* Wait until the RO or 32KHz is ready */ + if (waitLS_Ready) { + current_time = BLUE_CTRL->CURRENT_TIME; + while(((BLUE_CTRL->CURRENT_TIME)&0x10) == (current_time&0x10)); +#if (LS_SOURCE == LS_SOURCE_INTERNAL_RO) + /* Wait the LS stabilization */ + Wait_LS_Stabilization(); +#endif + } + + if (coldStart) { +#if (HS_SPEED_XTAL == HS_SPEED_XTAL_32MHZ) +#ifndef FORCE_CORE_TO_16MHZ + /* AHB up converter command register write*/ + AHBUPCONV->COMMAND = 0x15; +#endif +#endif + } + + /* Unlock the Flash */ + flash_sw_lock = FLASH_UNLOCK_WORD; +} + +void SystemInit(void) +{ + /* Remap the vector table */ + FLASH->CONFIG = FLASH_PREMAP_MAIN; + + /* Configure all the interrupts priority. + * The application can modify the interrupts priority. + * The PendSV_IRQn and BLUE_CTRL_IRQn SHALL maintain the highest priority + */ + NVIC_SetPriority(PendSV_IRQn, LOW_PRIORITY); + NVIC_SetPriority(SysTick_IRQn, LOW_PRIORITY); + NVIC_SetPriority(GPIO_IRQn, LOW_PRIORITY); + NVIC_SetPriority(NVM_IRQn, LOW_PRIORITY); + NVIC_SetPriority(UART_IRQn, LOW_PRIORITY); + NVIC_SetPriority(SPI_IRQn, LOW_PRIORITY); + NVIC_SetPriority(BLUE_CTRL_IRQn, CRITICAL_PRIORITY); + NVIC_SetPriority(WDG_IRQn, LOW_PRIORITY); + NVIC_SetPriority(ADC_IRQn, LOW_PRIORITY); + NVIC_SetPriority(I2C2_IRQn, LOW_PRIORITY); + NVIC_SetPriority(I2C1_IRQn, LOW_PRIORITY); + NVIC_SetPriority(MFT1A_IRQn, LOW_PRIORITY); + NVIC_SetPriority(MFT1B_IRQn, LOW_PRIORITY); + NVIC_SetPriority(MFT2A_IRQn, LOW_PRIORITY); + NVIC_SetPriority(MFT2B_IRQn, LOW_PRIORITY); + NVIC_SetPriority(RTC_IRQn, LOW_PRIORITY); + NVIC_SetPriority(PKA_IRQn, LOW_PRIORITY); + NVIC_SetPriority(DMA_IRQn, LOW_PRIORITY); + + /* Device Configuration */ + DeviceConfiguration(TRUE, TRUE); + /* Disable all the peripherals clock except NVM, SYSCTR, PKA and RNG */ + CKGEN_SOC->CLOCK_EN = 0xE0066; + __enable_irq(); +} + + +/******************* (C) COPYRIGHT 2017 STMicroelectronics *****END OF FILE****/ diff --git a/zephyr/module.yml b/zephyr/module.yml new file mode 100644 index 0000000..eb317c3 --- /dev/null +++ b/zephyr/module.yml @@ -0,0 +1,2 @@ +build: + cmake: .