From 9d2055dc95cd92128a28b51708519195903ad7dd Mon Sep 17 00:00:00 2001 From: Nikos Oikonomou Date: Thu, 28 Jan 2021 17:39:48 +0200 Subject: [PATCH 1/3] strf: added subg1 cube expansion package Added ST Microelectronics SUBG1 (s2lp) cube expansion package Signed-off-by: Nikos Oikonomou --- CMakeLists.txt | 3 + README | 3 + strf/README | 37 + strf/s2lp/CMakeLists.txt | 25 + strf/s2lp/S2LP_Library/Inc/MCU_Interface.h | 166 ++ .../S2LP_Library/Inc/MCU_Interface_template.h | 157 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h | 201 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Config.h | 141 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Csma.h | 199 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Fifo.h | 138 ++ strf/s2lp/S2LP_Library/Inc/S2LP_General.h | 142 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Gpio.h | 364 ++++ .../S2LP_Library/Inc/S2LP_PacketHandler.h | 234 ++ strf/s2lp/S2LP_Library/Inc/S2LP_PktBasic.h | 283 +++ strf/s2lp/S2LP_Library/Inc/S2LP_PktStack.h | 286 +++ strf/s2lp/S2LP_Library/Inc/S2LP_PktWMbus.h | 181 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Qi.h | 180 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Radio.h | 277 +++ strf/s2lp/S2LP_Library/Inc/S2LP_Regs.h | 1875 +++++++++++++++++ strf/s2lp/S2LP_Library/Inc/S2LP_Timer.h | 201 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Timer_ex.h | 118 ++ strf/s2lp/S2LP_Library/Inc/S2LP_Types.h | 236 +++ strf/s2lp/S2LP_Library/Src/S2LP_Commands.c | 159 ++ strf/s2lp/S2LP_Library/Src/S2LP_Csma.c | 546 +++++ strf/s2lp/S2LP_Library/Src/S2LP_Fifo.c | 338 +++ strf/s2lp/S2LP_Library/Src/S2LP_General.c | 210 ++ strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c | 472 +++++ .../S2LP_Library/Src/S2LP_PacketHandler.c | 891 ++++++++ strf/s2lp/S2LP_Library/Src/S2LP_PktBasic.c | 457 ++++ strf/s2lp/S2LP_Library/Src/S2LP_PktStack.c | 530 +++++ strf/s2lp/S2LP_Library/Src/S2LP_PktWMbus.c | 367 ++++ strf/s2lp/S2LP_Library/Src/S2LP_Qi.c | 305 +++ strf/s2lp/S2LP_Library/Src/S2LP_Radio.c | 1596 ++++++++++++++ strf/s2lp/S2LP_Library/Src/S2LP_Timer.c | 815 +++++++ strf/s2lp/S2LP_Library/Src/S2LP_Timer_ex.c | 121 ++ strf/s2lp/S2LP_Library/Src/S2LP_Types.c | 196 ++ 36 files changed, 12450 insertions(+) create mode 100644 strf/README create mode 100644 strf/s2lp/CMakeLists.txt create mode 100644 strf/s2lp/S2LP_Library/Inc/MCU_Interface.h create mode 100644 strf/s2lp/S2LP_Library/Inc/MCU_Interface_template.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Config.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Csma.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Fifo.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_General.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Gpio.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_PacketHandler.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_PktBasic.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_PktStack.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_PktWMbus.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Qi.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Radio.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Regs.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Timer.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Timer_ex.h create mode 100644 strf/s2lp/S2LP_Library/Inc/S2LP_Types.h create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Commands.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Csma.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Fifo.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_General.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_PktBasic.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_PktStack.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_PktWMbus.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Qi.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Radio.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Timer.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Timer_ex.c create mode 100644 strf/s2lp/S2LP_Library/Src/S2LP_Types.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 95d23314..57f151e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,3 +40,6 @@ endif() # STMEMSC - Hardware Abstraction Layer for ST sensor add_subdirectory_ifdef(CONFIG_HAS_STMEMSC sensor/stmemsc) + +# STRF - S2LP +add_subdirectory_ifdef(CONFIG_IEEE802154_S2LP strf/s2lp) \ No newline at end of file diff --git a/README b/README index 82c65df2..5e36e690 100644 --- a/README +++ b/README @@ -5,4 +5,7 @@ Available libs: * sensor/vl53l0x: allows to drive the vl53l0x sensor full information can be found here : http://www.st.com/en/embedded-software/stsw-img005.html + * strf/subg1: + provides support for the s2lp radio transceiver. + full information can be found here : https://www.st.com/en/embedded-software/x-cube-subg1.html *... diff --git a/strf/README b/strf/README new file mode 100644 index 00000000..35a2b2f9 --- /dev/null +++ b/strf/README @@ -0,0 +1,37 @@ +STM32CubeSUBG1 +############## + +Origin: + ST Microelectronics + https://www.st.com/en/embedded-software/x-cube-subg1.html + +Status: + version 3.2.0 + +Purpose: + ST Microelectronics official software package for SUBG1 radio series. + +Description: + This package is an extract of the official STM32CubeSUBG1 expansion package + written by ST Microelectronics. It contains the software library for the + s2-lp 802.15.4 radio. + +Dependencies: + None. + +URL: + https://www.st.com/en/embedded-software/x-cube-subg1.html + +commit: + version 3.2.0 + +Maintained-by: + External + +License: + BSD-3-Clause + +License Link: + https://opensource.org/licenses/BSD-3-Clause + +Patch List: diff --git a/strf/s2lp/CMakeLists.txt b/strf/s2lp/CMakeLists.txt new file mode 100644 index 00000000..cbffdfce --- /dev/null +++ b/strf/s2lp/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (c) 2021 Nikos Oikonomou +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories( + S2LP_Library/Inc + ) + +zephyr_sources( + S2LP_Library/Src/S2LP_Commands.c + S2LP_Library/Src/S2LP_Csma.c + S2LP_Library/Src/S2LP_Fifo.c + S2LP_Library/Src/S2LP_General.c + S2LP_Library/Src/S2LP_Gpio.c + S2LP_Library/Src/S2LP_PacketHandler.c + S2LP_Library/Src/S2LP_PktBasic.c + S2LP_Library/Src/S2LP_PktStack.c + S2LP_Library/Src/S2LP_PktWMbus.c + S2LP_Library/Src/S2LP_Qi.c + S2LP_Library/Src/S2LP_Radio.c + S2LP_Library/Src/S2LP_Timer_ex.c + S2LP_Library/Src/S2LP_Timer.c + S2LP_Library/Src/S2LP_Types.c + ) + diff --git a/strf/s2lp/S2LP_Library/Inc/MCU_Interface.h b/strf/s2lp/S2LP_Library/Inc/MCU_Interface.h new file mode 100644 index 00000000..61c919c5 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/MCU_Interface.h @@ -0,0 +1,166 @@ +/** +* @file MCU_Interface.h +* @author LowPower RF BU - AMG +* @version 1.1.0 +* @date July 1, 2016 +* @brief Header file for low level S2LP SPI driver. +****************************************************************************** +* @attention +* +*

© COPYRIGHT(c) 2019 STMicroelectronics

+* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name of STMicroelectronics nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +* This header file constitutes an interface to the SPI driver used to +* communicate with S2LP. +* It exports some function prototypes to write/read registers and FIFOs +* and to send command strobes. +* Since the S2LP libraries are totally platform independent, the implementation +* of these functions are not provided here. The user have to implement these functions +* taking care to keep the exported prototypes. +* +* These functions are: +* +*
    +*
  • S2LPSpiInit +*
  • S2LPSpiWriteRegisters +*
  • S2LPSpiReadRegisters +*
  • S2LPSpiCommandStrobes +*
  • S2LPSpiWriteLinearFifo +*
  • S2LPSpiReadLinearFifo +*
+* +* @note An example of SPI driver implementation is available in the Sdk_Eval library. +* +* +*

© COPYRIGHT 2019 STMicroelectronics

+*/ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MCU_INTERFACE_H +#define __MCU_INTERFACE_H + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Config.h" +#include "S2LP_Util.h" +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup S2LP_Libraries + * @{ + */ + +/** @defgroup S2LP_SPI_Driver SPI Driver + * @brief Header file for low level S2LP SPI driver. + * @details See the file @ref MCU_Interface.h for more details. + * @{ + */ + + +/** @defgroup SPI_Exported_Types SPI Exported Types + * @{ + */ + +typedef S2LPStatus StatusBytes; + +/** + * @} + */ + + +/** @defgroup SPI_Exported_Constants SPI Exported Constants + * @{ + */ + +/** + * @} + */ + + +/** @defgroup SPI_Exported_Functions SPI Exported Functions + * @{ + */ + +void RadioSpiInit(void); +void RadioSpiDeinit(void); +StatusBytes RadioSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer); +StatusBytes RadioSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer); +StatusBytes RadioSpiCommandStrobes(uint8_t cCommandCode); +StatusBytes RadioSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer); +StatusBytes RadioSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer); +//static void SPI_Error(void); + +void RadioEnterShutdown(void); +void RadioExitShutdown(void); +//SFlagStatus RadioCheckShutdown(void); + +/** + * @} + */ + + +/** @defgroup SPI_Exported_Macros SPI Exported Macros + * @{ + */ + +#define S2LPEnterShutdown RadioEnterShutdown +#define S2LPExitShutdown RadioExitShutdown +#define S2LPCheckShutdown (SFlagStatus)RadioCheckShutdown //(S2LPFlagStatus)SdkEvalCheckShutdown + +#define S2LPSpiInit RadioSpiInit +#define S2LPSpiDeinit RadioSpiDeinit +#define S2LPSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer) RadioSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer) +#define S2LPSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer) RadioSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer) +#define S2LPSpiCommandStrobes(cCommandCode) RadioSpiCommandStrobes(cCommandCode) +#define S2LPSpiWriteFifo(cNbBytes, pcBuffer) RadioSpiWriteFifo(cNbBytes, pcBuffer) +#define S2LPSpiReadFifo(cNbBytes, pcBuffer) RadioSpiReadFifo(cNbBytes, pcBuffer) +//#define SdkEvalSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer) S2LPSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer) +//#define SdkEvalSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer) S2LPSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer) +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/MCU_Interface_template.h b/strf/s2lp/S2LP_Library/Inc/MCU_Interface_template.h new file mode 100644 index 00000000..1d116706 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/MCU_Interface_template.h @@ -0,0 +1,157 @@ +/** + * @file MCU_Interface_template.h + * @author LowPower RF BU - AMG + * @version 1.1.0 + * @date July 1, 2016 + * @brief Header file for low level S2LP SPI driver. + * To be copied in the application floder and customized according to the SPI driver used. + ****************************************************************************** +* @attention +* +*

© COPYRIGHT(c) 2019 STMicroelectronics

+* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name of STMicroelectronics nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* This header file constitutes an interface to the SPI driver used to +* communicate with S2LP. +* It exports some function prototypes to write/read registers and FIFOs +* and to send command strobes. +* Since the S2LP libraries are totally platform independent, the implementation +* of these functions are not provided here. The user have to implement these functions +* taking care to keep the exported prototypes. +* +* These functions are: +* +*
    +*
  • S2LPSpiInit +*
  • S2LPSpiWriteRegisters +*
  • S2LPSpiReadRegisters +*
  • S2LPSpiCommandStrobes +*
  • S2LPSpiWriteLinearFifo +*
  • S2LPSpiReadLinearFifo +*
+* +* @note An example of SPI driver implementation is available in the Sdk_Eval library. +* +*

© COPYRIGHT 2019 STMicroelectronics

+*/ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MCU_INTERFACE_H +#define __MCU_INTERFACE_H + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Config.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup S2LP_Libraries + * @{ + */ + +/** @defgroup S2LP_SPI_Driver SPI Driver + * @brief Header file for low level S2LP SPI driver. + * @details See the file @ref MCU_Interface.h for more details. + * @{ + */ + + +/** @defgroup SPI_Exported_Types SPI Exported Types + * @{ + */ + +typedef S2LPStatus StatusBytes; + +/** + * @} + */ + + + + +/** @defgroup SPI_Exported_Functions SPI Exported Functions + * @{ + */ + + +void SdkEvalSpiInit(void); +void SdkEvalSpiDeinit(void); +StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer); +StatusBytes SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer); +StatusBytes SdkEvalSpiCommandStrobes(uint8_t cCommandCode); +StatusBytes SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer); +StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer); + +void SdkEvalEnterShutdown(void); +void SdkEvalExitShutdown(void); +SFlagStatus SdkEvalCheckShutdown(void); + +/** + * @} + */ + + +/** @defgroup SPI_Exported_Macros SPI Exported Macros + * @{ + */ + +#define S2LPEnterShutdown SdkEvalEnterShutdown +#define S2LPExitShutdown SdkEvalExitShutdown +#define S2LPCheckShutdown (S2LPFlagStatus)SdkEvalCheckShutdown + +#define S2LPSpiInit SdkEvalSpiInit +#define S2LPSpiDeinit SdkEvalSpiDeinit +#define S2LPSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer) SdkEvalSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer) +#define S2LPSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer) SdkEvalSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer) +#define S2LPSpiCommandStrobes(cCommandCode) SdkEvalSpiCommandStrobes(cCommandCode) +#define S2LPSpiWriteFifo(cNbBytes, pcBuffer) SdkEvalSpiWriteFifo(cNbBytes, pcBuffer) +#define S2LPSpiReadFifo(cNbBytes, pcBuffer) SdkEvalSpiReadFifo(cNbBytes, pcBuffer) + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h new file mode 100644 index 00000000..92b7309e --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h @@ -0,0 +1,201 @@ +/** + * @file S2LP_Commands.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date April 12, 2017 + * @brief Management of S2-LP Commands. + ****************************************************************************** +* @attention +* +*

© COPYRIGHT(c) 2019 STMicroelectronics

+* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name of STMicroelectronics nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +* In this module can be found all the API used to strobe commands to +* S2LP. +* Every command strobe is an SPI transaction with a specific command code. +* +* Example: +* @code +* ... +* +* S2LPCmdStrobeRx(); +* +* ... +* @endcode +* +*

© COPYRIGHT 2019 STMicroelectronics

+*/ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_COMMANDS_H +#define __S2LP_COMMANDS_H + + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Regs.h" +#include "S2LP_Types.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_Commands Commands + * @brief Management of S2LP Commands. + * @details See the file @ref S2LP_Commands.h for more details. + * @{ + */ + +/** + * @defgroup Commands_Exported_Types Commands Exported Types + * @{ + */ + +/** + * @brief S2LP Commands codes enumeration + */ +typedef enum +{ + CMD_TX = ((uint8_t)(0x60)), /*!< Start to transmit; valid only from READY */ + CMD_RX = ((uint8_t)(0x61)), /*!< Start to receive; valid only from READY */ + CMD_READY = ((uint8_t)(0x62)), /*!< Go to READY; valid only from STANDBY or SLEEP or LOCK */ + CMD_STANDBY = ((uint8_t)(0x63)), /*!< Go to STANDBY; valid only from READY */ + CMD_SLEEP = ((uint8_t)(0x64)), /*!< Go to SLEEP; valid only from READY */ + CMD_LOCKRX = ((uint8_t)(0x65)), /*!< Go to LOCK state by using the RX configuration of the synth; valid only from READY */ + CMD_LOCKTX = ((uint8_t)(0x66)), /*!< Go to LOCK state by using the TX configuration of the synth; valid only from READY */ + CMD_SABORT = ((uint8_t)(0x67)), /*!< Force exit form TX or RX states and go to READY state; valid only from TX or RX */ + CMD_LDC_RELOAD = ((uint8_t)(0x68)), /*!< LDC Mode: Reload the LDC timer with the value stored in the LDC_PRESCALER / COUNTER registers; valid from all states */ + CMD_RCO_CALIB = ((uint8_t)(0x69)), /*!< Start (or re-start) the RCO calibration */ + CMD_SRES = ((uint8_t)(0x70)), /*!< Reset of all digital part, except SPI registers */ + CMD_FLUSHRXFIFO = ((uint8_t)(0x71)), /*!< Clean the RX FIFO; valid from all states */ + CMD_FLUSHTXFIFO = ((uint8_t)(0x72)), /*!< Clean the TX FIFO; valid from all states */ + CMD_SEQUENCE_UPDATE = ((uint8_t)(0x73)), /*!< Autoretransmission: Reload the Packet sequence counter with the value stored in the PROTOCOL[2] register valid from all states */ +} S2LPCmd; + + +/** + * @} + */ + + +/** + * @defgroup Commands_Exported_Constants Commands Exported Constants + * @{ + */ + + +/** + * @} + */ + + +/** + * @defgroup Commands_Exported_Macros Commands Exported Macros + * @{ + */ + +/** + * @brief Sends the TX command to S2-LP. Start to transmit. + * @param None. + * @retval None. + * @note: this macro sets the SMPS switching frequency to 5.46MHz about for ETSI regulation compliancy. + */ + +#define S2LPCmdStrobeTx() {uint8_t tmp=0x9C;\ + Config_RangeExt(PA_TX,S2LPManagementGetRangeExtender());\ + S2LPSpiWriteRegisters(0x76,1,&tmp);\ + S2LPCmdStrobeCommand(CMD_TX);} + +/** + * @brief Sends the RX command to S2-LP. Start to receive. + * @param None. + * @retval None. + * @note: this macro sets the SMPS switching frequency to 3.12MHz. + */ + +#define S2LPCmdStrobeRx() {uint8_t tmp=0x90;\ + Config_RangeExt(PA_RX,S2LPManagementGetRangeExtender());\ + S2LPSpiWriteRegisters(0x76,1,&tmp);\ + S2LPCmdStrobeCommand(CMD_RX);} + +#define S2LPCmdStrobeReady() S2LPCmdStrobeCommand(CMD_READY) +#define S2LPCmdStrobeStandby() S2LPCmdStrobeCommand(CMD_STANDBY) +#define S2LPCmdStrobeSleep() S2LPCmdStrobeCommand(CMD_SLEEP) +#define S2LPCmdStrobeLockRx() S2LPCmdStrobeCommand(CMD_LOCKRX) +#define S2LPCmdStrobeLockTx() S2LPCmdStrobeCommand(CMD_LOCKTX) +#define S2LPCmdStrobeSabort() S2LPCmdStrobeCommand(CMD_SABORT) +#define S2LPCmdStrobeLdcReload() S2LPCmdStrobeCommand(CMD_LDC_RELOAD) +#define S2LPCmdStrobeSequenceUpdate() S2LPCmdStrobeCommand(CMD_SEQUENCE_UPDATE) +#define S2LPCmdStrobeSres() S2LPCmdStrobeCommand(CMD_SRES) +#define S2LPCmdStrobeFlushRxFifo() S2LPCmdStrobeCommand(CMD_FLUSHRXFIFO) +#define S2LPCmdStrobeFlushTxFifo() S2LPCmdStrobeCommand(CMD_FLUSHTXFIFO) + + +/** + * @} + */ + + +/** + * @defgroup Commands_Exported_Functions Commands Exported Functions + * @{ + */ + +void S2LPCmdStrobeCommand(S2LPCmd xCommandCode); + + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + + + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Config.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Config.h new file mode 100644 index 00000000..15fc161c --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Config.h @@ -0,0 +1,141 @@ +/** + * @file S2LP_Config.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief S2LP Configuration and useful defines . + ****************************************************************************** +* @attention +* +*

© COPYRIGHT(c) 2019 STMicroelectronics

+* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name of STMicroelectronics nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* This file is used to include all or a part of the S2LP +* libraries into the application program which will be used. +* Moreover some important parameters are defined here and the +* user is allowed to edit them. +* +*

© COPYRIGHT 2015 STMicroelectronics

+*/ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_CONFIG_H +#define __S2LP_CONFIG_H + + + /* Includes ------------------------------------------------------------------*/ +#include "S2LP_Regs.h" +#include "S2LP_Commands.h" +#include "S2LP_Csma.h" +#include "S2LP_General.h" +#include "S2LP_Gpio.h" +#include "S2LP_Timer.h" +#include "S2LP_Fifo.h" +#include "S2LP_PacketHandler.h" +#include "S2LP_PktBasic.h" +#include "S2LP_PktWMbus.h" +#include "S2LP_PktStack.h" +#include "S2LP_Radio.h" +#include "S2LP_Qi.h" +#include "MCU_Interface.h" +#include "S2LP_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup S2LP_Libraries S2LP Libraries + * @brief This firmware implements libraries which allow the user + * to manage the features of S2LP without knowing the hardware details. + * @details The S2LP_Libraries modules are totally platform independent. The library provides one + * module for each device feature. Each module refers to some functions whose prototypes are located in the + * header file @ref MCU_Interface.h. The user who want to use these libraries on a particular + * platform has to implement these functions respecting them signatures. + * @{ + */ + +/** @defgroup S2LP_Configuration Configuration + * @brief S2LP Configuration and useful defines. + * @details See the file @ref S2LP_Config.h for more details. + * @{ + */ + + +/** @defgroup Configuration_Exported_Types Configuration Exported Types + * @{ + */ + +/** + * @} + */ + + +/** @defgroup Configuration_Exported_Constants Configuration Exported Constants + * @{ + */ +#define DIG_DOMAIN_XTAL_THRESH 30000000 /*!< Digital domain logic threshold for XTAL in MHz */ + +/** + * @} + */ + + +/** @defgroup Configuration_Exported_Macros Configuration Exported Macros + * @{ + */ + + +/** + * @} + */ + + +/** @defgroup Configuration_Exported_Functions Configuration Exported Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Csma.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Csma.h new file mode 100644 index 00000000..e1bf7d61 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Csma.h @@ -0,0 +1,199 @@ +/** + * @file S2LP_Csma.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP CSMA. + ****************************************************************************** +* @attention +* +*

© COPYRIGHT(c) 2019 STMicroelectronics

+* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name of STMicroelectronics nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +* Example: +* @code +* +* CsmaInit csmaInit={ +* S_DISABLE, // persistent mode +* TBIT_TIME_64, // Tbit time +* TCCA_TIME_3, // Tcca time +* 5, // max number of backoffs +* 0xFA21, // BU counter seed +* 32 // CU prescaler +* }; +* +* ... +* +* S2LPCsmaInit(&csmaInit); +* S2LPCsma(S_ENABLE); +* +* +* @endcode +* +* @note The CS status depends of the RSSI threshold set. Please see the S2LP_Qi +* module for details. +*

© COPYRIGHT 2019 STMicroelectronics

+*/ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_CSMA_H +#define __S2LP_CSMA_H + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Types.h" +#include "S2LP_Regs.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_Csma CSMA + * @brief Configuration and management of S2LP CSMA. + * @details See the file @ref S2LP_Csma.h for more details. + * @{ + */ + +/** + * @defgroup Csma_Exported_Types CSMA Exported Types + * @{ + */ + + +/** + * @brief Multiplier for Tcca time enumeration (Tcca = Multiplier*Tbit). + */ + +typedef enum { + CSMA_PERIOD_64TBIT, /*!< CSMA/CA: Sets CCA period to 64*TBIT */ + CSMA_PERIOD_128TBIT, /*!< CSMA/CA: Sets CCA period to 128*TBIT */ + CSMA_PERIOD_256TBIT, /*!< CSMA/CA: Sets CCA period to 256*TBIT */ + CSMA_PERIOD_512TBIT /*!< CSMA/CA: Sets CCA period to 512*TBIT */ +}SCsmaPeriod; + + +/** + * @brief S2LP CSMA Init structure definition + */ +typedef struct { + SFunctionalState xCsmaPersistentMode; /*!< Enable the CSMA persistent mode */ + SCsmaPeriod xMultiplierTbit; /*!< Set the Tbit multiplier to obtain the Tcca. @ref CcaPeriod */ + uint8_t xCcaLength; /*!< Set the Tcca multiplier to determinate the Tlisten. From 0 to 15. */ + uint8_t cMaxNb; /*!< Specifies the max number of backoff cycles. From 0 to 7. */ + uint16_t nBuCounterSeed; /*!< Specifies the BU counter seed. */ + uint8_t cBuPrescaler; /*!< Specifies the BU prescaler. From 0 to 63. */ +} SCsmaInit; + + +/** + *@} + */ + + +/** + * @defgroup Csma_Exported_Constants CSMA Exported Constants + * @{ + */ + +/** + * @defgroup Csma_Parameters CSMA Parameters + * @{ + */ + + +/** + *@} + */ + +/** + *@} + */ + + +/** + * @defgroup Csma_Exported_Macros CSMA Exported Macros + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup Csma_Exported_Functions CSMA Exported Functions + * @{ + */ + +void S2LPCsmaInit(SCsmaInit* pxSCsmaInit); +void S2LPCsmaGetInfo(SCsmaInit* pxSCsmaInit); +void S2LPCsma(SFunctionalState xNewState); +SFunctionalState S2LPCsmaGetCsma(void); +void S2LPCsmaPersistentMode(SFunctionalState xNewState); +SFunctionalState S2LPCsmaGetPersistentMode(void); +void S2LPCsmaSeedReloadMode(SFunctionalState xNewState); +SFunctionalState S2LPCsmaGetSeedReloadMode(void); +void S2LPCsmaSetBuCounterSeed(uint16_t nBuCounterSeed); +uint16_t S2LPCsmaGetBuCounterSeed(void); +void S2LPCsmaSetBuPrescaler(uint8_t cBuPrescaler); +uint8_t S2LPCsmaGetBuPrescaler(void); +void S2LPCsmaSetCcaPeriod(SCsmaPeriod xMultiplierTbit); +uint8_t S2LPCsmaGetCcaPeriod(void); +void S2LPCsmaSetCcaLength(uint8_t xCcaLength); +uint8_t S2LPCsmaGetCcaLength(void); +void S2LPCsmaSetMaxNumberBackoff(uint8_t cMaxNb); +uint8_t S2LPCsmaGetMaxNumberBackoff(void); + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Fifo.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Fifo.h new file mode 100644 index 00000000..1dc624cb --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Fifo.h @@ -0,0 +1,138 @@ +/** + * @file S2LP_Fifo.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP Fifo. + ****************************************************************************** +* @attention +* +*

© COPYRIGHT(c) 2019 STMicroelectronics

+* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name of STMicroelectronics nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* This module allows the user to manage the linear FIFO. The functions exported +* here can be used to set the thresholds for the FIFO almost full / empty alarm +* interrupts or to get the total number of elements inside the FIFO. +* +*

© COPYRIGHT 2019 STMicroelectronics

+*/ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_FIFO_H +#define __S2LP_FIFO_H + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Regs.h" +#include "S2LP_Types.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_Fifo FIFO + * @brief Configuration and management of S2LP FIFO. + * @details See the file @ref S2LP_Fifo.h for more details. + * @{ + */ + +/** + * @defgroup Fifo_Exported_Types FIFO Exported Types + * @{ + */ + + +/** + * @} + */ + + +/** + * @defgroup Fifo_Exported_Constants FIFO Exported Constants + * @{ + */ + +/** + * @} + */ + + +/** + * @defgroup Fifo_Exported_Macros FIFO Exported Macros + * @{ + */ + + +/** + * @} + */ + + +/** + * @defgroup Fifo_Exported_Functions FIFO Exported Functions + * @{ + */ + +uint8_t S2LPFifoReadNumberBytesRxFifo(void); +uint8_t S2LPFifoReadNumberBytesTxFifo(void); +void S2LPFifoSetAlmostFullThresholdRx(uint8_t cThrRxFifo); +uint8_t S2LPFifoGetAlmostFullThresholdRx(void); +void S2LPFifoSetAlmostEmptyThresholdRx(uint8_t cThrRxFifo); +uint8_t S2LPFifoGetAlmostEmptyThresholdRx(void); +void S2LPFifoSetAlmostFullThresholdTx(uint8_t cThrTxFifo); +uint8_t S2LPFifoGetAlmostFullThresholdTx(void); +void S2LPFifoSetAlmostEmptyThresholdTx(uint8_t cThrTxFifo); +uint8_t S2LPFifoGetAlmostEmptyThresholdTx(void); +void S2LPFifoMuxRxFifoIrqEnable(SFunctionalState xNewState); + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_General.h b/strf/s2lp/S2LP_Library/Inc/S2LP_General.h new file mode 100644 index 00000000..295bbd91 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_General.h @@ -0,0 +1,142 @@ +/** + * @file S2LP_General.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP General functionalities. + ****************************************************************************** +* @attention +* +*

© COPYRIGHT(c) 2019 STMicroelectronics

+* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name of STMicroelectronics nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*

© COPYRIGHT 2019 STMicroelectronics

+*/ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_GENERAL_H +#define __S2LP_GENERAL_H + + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Regs.h" +#include "S2LP_Types.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_General General + * @brief Configuration and management of S2LP General functionalities. + * @details See the file @ref S2LP_General.h for more details. + * @{ + */ + +/** + * @defgroup General_Exported_Types General Exported Types + * @{ + */ + + +/** + * @brief S2LP version type enumeration + */ + +typedef enum { + MODE_EXT_XO = 0, + MODE_EXT_XIN = 0x80, +} ModeExtRef; + + +/** + * @} + */ + + +/** + * @defgroup General_Exported_Constants General Exported Constants + * @{ + */ + + +/** + * @} + */ + + +/** + * @defgroup General_Exported_Macros General Exported Macros + * @{ + */ +#define S2LPGeneralLibraryVersion() "S2LP_Libraries_v.1.3.0" + + +/** + * @} + */ + + +/** + * @defgroup General_Exported_Functions General Exported Functions + * @{ + */ + +uint8_t S2LPGeneralGetDevicePN(void); +uint8_t S2LPGeneralGetVersion(void); +void S2LPGeneralSetExtRef(ModeExtRef xExtMode); +ModeExtRef S2LPGeneralGetExtRef(void); +void S2LPRadioSetExternalSmpsMode(SFunctionalState xNewState); +void S2LPRefreshStatus(void); + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Gpio.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Gpio.h new file mode 100644 index 00000000..de165a3b --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Gpio.h @@ -0,0 +1,364 @@ +/** + * @file S2LP_Gpio.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP GPIO. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This module can be used to configure the S2-LP GPIO pins to perform + * specific functions. + * The structure @ref gpioIRQ can be used to specify these features for + * one of the four S2-LP Gpio pin. + * The following example shows how to configure a pin (GPIO 3) to be used as an IRQ source + * for a microcontroller using the @ref S2LPGpioInit() function. + * + * Example: + * @code + * + * SGpioInit gpioIRQ={ + * S2LP_GPIO_3, + * S2LP_GPIO_MODE_DIGITAL_OUTPUT_LP, + * S2LP_GPIO_DIG_OUT_IRQ + * }; + * + * ... + * + * S2LPGpioInit(&gpioIRQ); + * + * @endcode + * + * @note Please read the functions documentation for the other GPIO features. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_GPIO_H +#define __S2LP_GPIO_H + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Regs.h" +#include "S2LP_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup S2LP_Libraries + * @{ + */ + + +/** @defgroup S2LP_Gpio GPIO + * @brief Configuration and management of S2LP GPIO. + * @details See the file @ref S2LP_Gpio.h for more details. + * @{ + */ + + + +/** @defgroup Gpio_Exported_Types GPIO Exported Types + * @{ + */ + +/** + * @brief S2LP GPIO pin enumeration. + */ +typedef enum { + S2LP_GPIO_0 = GPIO0_CONF_ADDR, /*!< GPIO_0 selected */ + S2LP_GPIO_1 = GPIO1_CONF_ADDR, /*!< GPIO_1 selected */ + S2LP_GPIO_2 = GPIO2_CONF_ADDR, /*!< GPIO_2 selected */ + S2LP_GPIO_3 = GPIO3_CONF_ADDR /*!< GPIO_3 selected */ +} S2LPGpioPin; + + +/** + * @brief S2LP GPIO mode enumeration. + */ +typedef enum { + S2LP_GPIO_MODE_DIGITAL_INPUT = 0x01, /*!< Digital Input on GPIO */ + S2LP_GPIO_MODE_DIGITAL_OUTPUT_LP , /*!< Digital Output on GPIO (low current) */ + S2LP_GPIO_MODE_DIGITAL_OUTPUT_HP /*!< Digital Output on GPIO (high current) */ +} S2LPGpioMode; + + + +/** + * @brief S2LP I/O selection enumeration. + */ +typedef enum { + S2LP_GPIO_DIG_OUT_IRQ = 0x00, /*!< nIRQ (Interrupt Request, active low) , default configuration after POR */ + S2LP_GPIO_DIG_OUT_POR_INV = 0x08, /*!< POR inverted (active low) */ + S2LP_GPIO_DIG_OUT_WUT_EXP = 0x10, /*!< Wake-Up Timer expiration: "1" when WUT has expired */ + S2LP_GPIO_DIG_OUT_LBD = 0x18, /*!< Low battery detection: "1" when battery is below threshold setting */ + S2LP_GPIO_DIG_OUT_TX_DATA = 0x20, /*!< TX data internal clock output (TX data are sampled on the rising edge of it) */ + S2LP_GPIO_DIG_OUT_TX_STATE = 0x28, /*!< TX state indication: "1" when S2LP1 is passing in the TX state */ + S2LP_GPIO_DIG_OUT_TXRX_FIFO_ALMOST_EMPTY = 0x30, /*!< TX/RX FIFO Almost Empty Flag */ + S2LP_GPIO_DIG_OUT_TXRX_FIFO_ALMOST_FULL = 0x38, /*!< TX/RX FIFO Almost Full Flag */ + S2LP_GPIO_DIG_OUT_RX_DATA = 0x40, /*!< RX data output */ + S2LP_GPIO_DIG_OUT_RX_CLOCK = 0x48, /*!< RX clock output (recovered from received data) */ + S2LP_GPIO_DIG_OUT_RX_STATE = 0x50, /*!< RX state indication: "1" when demodulator is ON */ + S2LP_GPIO_DIG_OUT_NOT_STANDBY_SLEEP = 0x58, /*!< VDD when the device is not in SLEEP or STANDBY */ + S2LP_GPIO_DIG_OUT_STANDBY = 0x60, /*!< VDD when device is in STANDBY */ + S2LP_GPIO_DIG_OUT_ANTENNA_SWITCH = 0x68, /*!< Antenna switch used for antenna diversity */ + S2LP_GPIO_DIG_OUT_VALID_PREAMBLE = 0x70, /*!< Valid Preamble Detected Flag */ + S2LP_GPIO_DIG_OUT_SYNC_DETECTED = 0x78, /*!< Sync WordSync Word Detected Flag */ + S2LP_GPIO_DIG_OUT_RSSI_THRESHOLD = 0x80, /*!< RSSI above threshold */ + S2LP_GPIO_DIG_OUT_MCU_CLOCK = 0x88, /*!< MCU Clock */ + S2LP_GPIO_DIG_OUT_TX_RX_MODE = 0x90, /*!< TX or RX mode indicator (to enable an external range extender) */ + S2LP_GPIO_DIG_OUT_VDD = 0x98, /*!< VDD (to emulate an additional GPIO of the MCU, programmable by SPI) */ + S2LP_GPIO_DIG_OUT_GND = 0xA0, /*!< GND (to emulate an additional GPIO of the MCU, programmable by SPI) */ + S2LP_GPIO_DIG_OUT_SMPS_EXT = 0xA8, /*!< External SMPS enable signal (active high) */ + S2LP_GPIO_DIG_OUT_SLEEP = 0xB0, /*!< Device in SLEEP (active high) */ + S2LP_GPIO_DIG_OUT_READY = 0xB8, /*!< Device in READY (active high) */ + S2LP_GPIO_DIG_OUT_LOCK = 0xC0, /*!< Device in LOCK (active high) */ + S2LP_GPIO_DIG_OUT_WAIT_FOR_LOCK_SIG = 0xC8, /*!< Device waiting for LOCK (active high) */ + S2LP_GPIO_DIG_OUT_TX_DATA_OOK_SIGNAL = 0xD0, + S2LP_GPIO_DIG_OUT_WAIT_FOR_READY2_SIG = 0xD8, + S2LP_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_PM_SET = 0xE0, + S2LP_GPIO_DIG_OUT_WAIT_VCO_CALIBRATION = 0xE8, + S2LP_GPIO_DIG_OUT_ENABLE_SYNTH_FULL_CIRCUIT = 0xF0, + + S2LP_GPIO_DIG_IN_TX_COMMAND = 0x00, + S2LP_GPIO_DIG_IN_RX_COMMAND = 0x08, + S2LP_GPIO_DIG_IN_TX_DATA_INPUT_FOR_DIRECTRF = 0x10, + S2LP_GPIO_DIG_IN_DATA_WAKEUP = 0x18, + S2LP_GPIO_DIG_IN_EXT_CLOCK_AT_34_7KHZ = 0x20 +} S2LPGpioIO; + + +/** + * @brief S2LP OutputLevel enumeration. + */ +typedef enum { + LOW = 0, + HIGH = !LOW +} OutputLevel; + + +/** + * @brief S2LP GPIO Init structure definition. + */ +typedef struct { + S2LPGpioPin xS2LPGpioPin; /*!< Select the GPIO pins to be configured. @ref S2LPGpioPin */ + S2LPGpioMode xS2LPGpioMode; /*!< Set the pin operating mode. @ref S2LPGpioMode */ + S2LPGpioIO xS2LPGpioIO; /*!< Set the I/O selection for the pin. @ref S2LPGpioIO */ +} SGpioInit; + + +/** + * @brief S2LP clock output XO prescaler enumeration. + */ +typedef enum { + XO_RATIO_1 = 0x00, /*!< XO Clock signal available on the GPIO divided by 1 */ + XO_RATIO_1_2 = 0x02, /*!< XO Clock signal available on the GPIO divided by 1/2 */ + XO_RATIO_1_4 = 0x04, /*!< XO Clock signal available on the GPIO divided by 1/4 */ + XO_RATIO_1_8 = 0x06, /*!< XO Clock signal available on the GPIO divided by 1/8 */ + XO_RATIO_1_16 = 0x08, /*!< XO Clock signal available on the GPIO divided by 1/16 */ + XO_RATIO_1_32 = 0x0A, /*!< XO Clock signal available on the GPIO divided by 1/32 */ + XO_RATIO_1_64 = 0x0C, /*!< XO Clock signal available on the GPIO divided by 1/64 */ + XO_RATIO_1_128 = 0x0E, /*!< XO Clock signal available on the GPIO divided by 1/128 */ + XO_RATIO_1_256 = 0x10 /*!< XO Clock signal available on the GPIO divided by 1/256 */ +} ClockOutputXOPrescaler; + + +/** + * @brief S2LP Clock Output RCO prescaler enumeration. + */ + +typedef enum { + RCO_RATIO_1 = 0x00, /*!< RCO Clock signal available on the GPIO divided by 1 */ + RCO_RATIO_1_128 /*!< RCO Clock signal available on the GPIO divided by 1/128 */ +} ClockOutputRCOPrescaler; + + +/** + * @brief S2LP ExtraClockCycles enumeration. + */ +typedef enum { +EXTRA_CLOCK_CYCLES_0 = 0x00, /*!< 0 extra clock cycles provided to the MCU before switching to STANDBY state */ +EXTRA_CLOCK_CYCLES_128 = 0x20, /*!< 128 extra clock cycles provided to the MCU before switching to STANDBY state */ +EXTRA_CLOCK_CYCLES_256 = 0x40, /*!< 256 extra clock cycles provided to the MCU before switching to STANDBY state */ +EXTRA_CLOCK_CYCLES_512 = 0x60 /*!< 512 extra clock cycles provided to the MCU before switching to STANDBY state */ +} ExtraClockCycles; + + +/** + * @brief S2LP Clock Output initialization structure definition. + */ +typedef struct { + ClockOutputXOPrescaler xClockOutputXOPrescaler; /*!< Set the XO Ratio. @ref ClockOutputXOPrescaler */ + ClockOutputRCOPrescaler xClockOutputRCOPrescaler; /*!< Set the RCO Ratio. @ref ClockOutputRCOPrescaler */ + ExtraClockCycles xExtraClockCycles; /*!< Set the Extra Clock Cycles provided before entering in Standby state. @ref ExtraClockCycles */ +} ClockOutputInit; + + +/** + * @brief IRQ bitfield structure for S2LP. This structure is used to read or write the single IRQ bit. + * During the initialization the user has to fill this structure setting to one the single field related + * to the IRQ he wants to enable, and to zero the single field related to all the IRQs he wants to disable. + * The same structure can be used to retrieve all the IRQ events from the IRQ registers IRQ_STATUS[3:0], + * and read if one or more specific IRQ raised. + * @note The fields order in the structure depends on used endianness (little or big + * endian). The actual definition is valid ONLY for LITTLE ENDIAN mode. Be sure to + * change opportunely the fields order when use a different endianness. + */ +typedef struct { + SFlagStatus IRQ_RX_DATA_READY:1; /*!< IRQ: RX data ready */ + SFlagStatus IRQ_RX_DATA_DISC:1; /*!< IRQ: RX data discarded (upon filtering) */ + SFlagStatus IRQ_TX_DATA_SENT:1; /*!< IRQ: TX data sent */ + SFlagStatus IRQ_MAX_RE_TX_REACH:1; /*!< IRQ: Max re-TX reached */ + SFlagStatus IRQ_CRC_ERROR:1; /*!< IRQ: CRC error */ + SFlagStatus IRQ_TX_FIFO_ERROR:1; /*!< IRQ: TX FIFO underflow/overflow error */ + SFlagStatus IRQ_RX_FIFO_ERROR:1; /*!< IRQ: RX FIFO underflow/overflow error */ + SFlagStatus IRQ_TX_FIFO_ALMOST_FULL:1; /*!< IRQ: TX FIFO almost full */ + + SFlagStatus IRQ_TX_FIFO_ALMOST_EMPTY:1; /*!< IRQ: TX FIFO almost empty */ + SFlagStatus IRQ_RX_FIFO_ALMOST_FULL:1; /*!< IRQ: RX FIFO almost full */ + SFlagStatus IRQ_RX_FIFO_ALMOST_EMPTY:1; /*!< IRQ: RX FIFO almost empty */ + SFlagStatus IRQ_MAX_BO_CCA_REACH:1; /*!< IRQ: Max number of back-off during CCA */ + SFlagStatus IRQ_VALID_PREAMBLE:1; /*!< IRQ: Valid preamble detected */ + SFlagStatus IRQ_VALID_SYNC:1; /*!< IRQ: Sync word detected */ + SFlagStatus IRQ_RSSI_ABOVE_TH:1; /*!< IRQ: RSSI above threshold */ + SFlagStatus IRQ_WKUP_TOUT_LDC:1; /*!< IRQ: Wake-up timeout in LDC mode */ + + SFlagStatus IRQ_READY:1; /*!< IRQ: READY state */ + SFlagStatus IRQ_STANDBY_DELAYED:1; /*!< IRQ: STANDBY state after MCU_CK_CONF_CLOCK_TAIL_X clock cycles */ + SFlagStatus IRQ_LOW_BATT_LVL:1; /*!< IRQ: Battery level below threshold*/ + SFlagStatus IRQ_POR:1; /*!< IRQ: Power On Reset */ + SFlagStatus IRQ_BOR:1; /*!< IRQ: Brown out event (both accurate and inaccurate)*/ + SFlagStatus IRQ_LOCK:1; /*!< IRQ: LOCK state */ + SFlagStatus IRQ_VCO_CALIBRATION_END:1; /*!< IRQ: End of VCO calibration procedure */ + SFlagStatus IRQ_PA_CALIBRATION_END:1; /*!< IRQ: End of PA calibration procedure */ + + SFlagStatus IRQ_PM_COUNT_EXPIRED:1; /*!< IRQ: only for debug; Power Management startup timer expiration (see reg PM_START_COUNTER, 0xB5) */ + SFlagStatus IRQ_XO_COUNT_EXPIRED:1; /*!< IRQ: only for debug; Crystal oscillator settling time counter expired */ + SFlagStatus IRQ_TX_START_TIME:1; /*!< IRQ: only for debug; TX circuitry startup time; see TX_START_COUNTER */ + SFlagStatus IRQ_RX_START_TIME:1; /*!< IRQ: only for debug; RX circuitry startup time; see TX_START_COUNTER */ + SFlagStatus IRQ_RX_TIMEOUT:1; /*!< IRQ: RX operation timeout */ + SFlagStatus IRQ_RX_SNIFF_TIMEOUT:1; /*!< IRQ: RX sniff opeartion timeout */ + SFlagStatus :2; /*!< Reserved bit */ +} S2LPIrqs; + + +/** + * @brief IRQ list enumeration for S2LP. This enumeration type can be used to address a + * specific IRQ. + */ +typedef enum { + RX_DATA_READY = 0x00000001, /*!< IRQ: RX data ready */ + RX_DATA_DISC = 0x00000002, /*!< IRQ: RX data discarded (upon filtering) */ + TX_DATA_SENT = 0x00000004, /*!< IRQ: TX data sent */ + MAX_RE_TX_REACH = 0x00000008, /*!< IRQ: Max re-TX reached */ + CRC_ERROR = 0x00000010, /*!< IRQ: CRC error */ + TX_FIFO_ERROR = 0x00000020, /*!< IRQ: TX FIFO underflow/overflow error */ + RX_FIFO_ERROR = 0x00000040, /*!< IRQ: RX FIFO underflow/overflow error */ + TX_FIFO_ALMOST_FULL = 0x00000080, /*!< IRQ: TX FIFO almost full */ + TX_FIFO_ALMOST_EMPTY = 0x00000100, /*!< IRQ: TX FIFO almost empty */ + RX_FIFO_ALMOST_FULL = 0x00000200, /*!< IRQ: RX FIFO almost full */ + RX_FIFO_ALMOST_EMPTY = 0x00000400, /*!< IRQ: RX FIFO almost empty */ + MAX_BO_CCA_REACH = 0x00000800, /*!< IRQ: Max number of back-off during CCA */ + VALID_PREAMBLE = 0x00001000, /*!< IRQ: Valid preamble detected */ + VALID_SYNC = 0x00002000, /*!< IRQ: Sync word detected */ + RSSI_ABOVE_TH = 0x00004000, /*!< IRQ: RSSI above threshold */ + WKUP_TOUT_LDC = 0x00008000, /*!< IRQ: Wake-up timeout in LDC mode */ + READY = 0x00010000, /*!< IRQ: READY state */ + STANDBY_DELAYED = 0x00020000, /*!< IRQ: STANDBY state after MCU_CK_CONF_CLOCK_TAIL_X clock cycles */ + LOW_BATT_LVL = 0x00040000, /*!< IRQ: Battery level below threshold*/ + POR = 0x00080000, /*!< IRQ: Power On Reset */ + BOR = 0x00100000, /*!< IRQ: Brown out event (both accurate and inaccurate)*/ + LOCK = 0x00200000, /*!< IRQ: LOCK state */ + VCO_CALIBRATION_END = 0x00400000, /*!< IRQ: only for debug; Power Management startup timer expiration (see reg PM_START_COUNTER, 0xB5) */ + PA_CALIBRATION_END = 0x00800000, /*!< IRQ: only for debug; Crystal oscillator settling time counter expired */ + PM_COUNT_EXPIRED = 0x01000000, /*!< IRQ: only for debug; Power Management startup timer expiration (see reg PM_START_COUNTER, 0xB5) */ + XO_COUNT_EXPIRED = 0x02000000, /*!< IRQ: only for debug; Crystal oscillator settling time counter expired */ + TX_START_TIME = 0x04000000, /*!< IRQ: only for debug; TX circuitry startup time; see TX_START_COUNTER */ + RX_START_TIME = 0x08000000, /*!< IRQ: only for debug; RX circuitry startup time; see TX_START_COUNTER */ + RX_TIMEOUT = 0x10000000, /*!< IRQ: RX operation timeout */ + RX_SNIFF_TIMEOUT = 0x20000000, /*!< IRQ: RX sniff operation timeout */ + ALL_IRQ = 0x7FFFFFFF /*!< All the above mentioned IRQs */ +} IrqList; + + +/** + * @} + */ + + + +/** @defgroup Gpio_Exported_Functions GPIO Exported Functions + * @{ + */ + +void S2LPGpioInit(SGpioInit* pxGpioInitStruct); +void S2LPGpioSetLevel(S2LPGpioPin xGpioX, OutputLevel xLevel); +OutputLevel S2LPGpioGetLevel(S2LPGpioPin xGpioX); +void S2LPGpioClockOutput(SFunctionalState xNewState); +void S2LPGpioClockOutputInit(ClockOutputInit* pxClockOutputInitStruct); +void S2LPGpioSetXOPrescaler(ClockOutputXOPrescaler xXOPrescaler); +ClockOutputXOPrescaler S2LPGpioGetXOPrescaler(void); +void S2LPGpioSetRCOPrescaler(ClockOutputRCOPrescaler xRCOPrescaler); +ClockOutputRCOPrescaler S2LPGpioGetRCOPrescaler(void); +void S2LPGpioSetExtraClockCycles(ExtraClockCycles xExtraCycles); +ExtraClockCycles S2LPGpioGetExtraClockCycles(void); + +void S2LPGpioIrqDeInit(S2LPIrqs* pxIrqInit); +void S2LPGpioIrqInit(S2LPIrqs* pxIrqInit); +void S2LPGpioIrqConfig(IrqList xIrq, SFunctionalState xNewState); +void S2LPGpioIrqGetMask(S2LPIrqs* pxIrqMask); +void S2LPGpioIrqGetStatus(S2LPIrqs* pxIrqStatus); +void S2LPGpioIrqClearStatus(void); +SBool S2LPGpioIrqCheckFlag(IrqList xFlag); + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_PacketHandler.h b/strf/s2lp/S2LP_Library/Inc/S2LP_PacketHandler.h new file mode 100644 index 00000000..4eda5048 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_PacketHandler.h @@ -0,0 +1,234 @@ +/** + * @file S2LP_PacketHandler.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of the common features of S2-LP packets. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This module provides all the common functions and definitions used by the + * packets modules. + * Here are also defined all the generic enumeration types that are redefined + * in the specific packets modules, but every enumeration value is referred + * to this module. So the user who wants to configure the preamble of a Basic, + * or a STack packet has to use the enumeration values defined here. + * + * Example: + * @code + * + * ... + * + * S2LPPktBasicSetPreambleLength(PKT_PREAMBLE_LENGTH_18BYTES); + * + * ... + * + * @endcode + * + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_PKT_COMMON_H +#define __S2LP_PKT_COMMON_H + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Regs.h" +#include "S2LP_Types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_PktCommon Pkt Common + * @brief Configuration and management of the common features of S2LP packets. + * @details See the file @ref S2LP_PktCommon.h for more details. + * @{ + */ + +/** + * @defgroup PktCommon_Exported_Types Pkt Common Exported Types + * @{ + */ + + +/** + * @brief CRC length in bytes enumeration. + */ +typedef enum { + PKT_NO_CRC = 0x00, /*!< No CRC */ + PKT_CRC_MODE_8BITS = 0x20, /*!< CRC length 8 bits - poly: 0x07 */ + PKT_CRC_MODE_16BITS_1 = 0x40, /*!< CRC length 16 bits - poly: 0x8005 */ + PKT_CRC_MODE_16BITS_2 = 0x60, /*!< CRC length 16 bits - poly: 0x1021 */ + PKT_CRC_MODE_24BITS = 0x80, /*!< CRC length 24 bits - poly: 0x864CFB */ + PKT_CRC_MODE_32BITS = 0xA0, /*!< CRC length 32 bits - poly: 0x04C011BB7 */ +} PktCrcMode; + + +/** + * @brief Direct transmission mode enumeration for SPIRIT. + */ +typedef enum +{ + NORMAL_TX_MODE = 0x00, /*!< Normal mode, no direct transmission is used */ + DIRECT_TX_FIFO_MODE = 0x04, /*!< Source is FIFO: payload bits are continuously read from the TX FIFO */ + DIRECT_TX_GPIO_MODE = 0x08, /*!< Source is GPIO: payload bits are continuously read from one of the GPIO ports and transmitted without any processing */ + PN9_TX_MODE = 0x0C /*!< A pseudorandom binary sequence is generated internally */ +} DirectTx; + + +/** + * @brief Direct receive mode enumeration for SPIRIT. + */ +typedef enum +{ + NORMAL_RX_MODE = 0x00, /*!< Normal mode, no direct reception is used */ + DIRECT_RX_FIFO_MODE = 0x10, /*!< Destination is FIFO: payload bits are continuously written to the RX FIFO and not subjected to any processing*/ + DIRECT_RX_GPIO_MODE = 0x20 /*!< Destination is GPIO: payload bits are continuously written to one of the GPIO ports and not subjected to any processing*/ +} DirectRx; + + +/** + *@} + */ + + +/** + * @defgroup PktCommon_Exported_Constants Pkt Common Exported Constants + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup PktCommon_Exported_Macros Pkt Common Exported Macros + * @{ + */ + +#define S2LPSetPreambleLengthByte(xPreambleLength) S2LPSetPreambleLength(4*xPreambleLength) +#define S2LPSetSyncLengthByte(cSyncLength) S2LPSetSyncLength(8*cSyncLength) + +#define IS_PREAMBLE_LEN(VAL) (VAL<=1024) +#define IS_SYNC_LEN(VAL) (VAL<=64) + +#define IS_PKT_LEN_FIELD_WID(LENGTH) ((LENGTH == PKT_LENGTH_FIELD_1BYTE) || \ + (LENGTH == PKT_LENGTH_FIELD_2BYTE)) + + +#define IS_PKT_CRC_MODE(MODE) ((MODE == PKT_NO_CRC) || \ + (MODE == PKT_CRC_MODE_8BITS) || \ + (MODE == PKT_CRC_MODE_16BITS_1) || \ + (MODE == PKT_CRC_MODE_16BITS_2) || \ + (MODE == PKT_CRC_MODE_24BITS)) +/** + *@} + */ + + +/** + * @defgroup PktCommon_Exported_Functions Pkt Common Exported Functions + * @{ + */ + +void S2LPSetPreambleLength(uint16_t cPreambleLength); +uint16_t S2LPGetPreambleLength(void); +void S2LPSetSyncLength(uint8_t cSyncLength); +uint8_t S2LPGetSyncLength(void); +void S2LPSetSyncWords(uint32_t lSyncWords, uint8_t xSyncLength); +void S2LPGetSyncWords(uint32_t* lSyncWords, uint8_t* cSyncLength); +void S2LPPacketHandlerWhitening(SFunctionalState xNewState); +void S2LPPacketHandlerFec(SFunctionalState xNewState); +void S2LPPacketHandler3OutOf6(SFunctionalState xNewState); +void S2LPPacketHandlerManchester(SFunctionalState xNewState); +uint8_t S2LPGetPacketFormat(void); +void S2LPPktCommonFilterOnCrc(SFunctionalState xNewState); +uint8_t S2LPGetReceivedDestinationAddress(void); +uint8_t S2LPGetReceivedSourceAddress(void); +uint8_t S2LPGetMyAddress(void); +uint8_t S2LPGetBroadcastAddress(void); +uint8_t S2LPGetMulticastAddress(void); +uint8_t S2LPGetRxSourceMask(void); +uint8_t S2LPGetRxSourceReferenceAddress(void); +void S2LPPacketHandlerSetTxMode(DirectTx xNewState); +void S2LPPacketHandlerSetRxMode(DirectRx xNewState); +DirectTx S2LPPacketHandlerGetTxMode(void); +DirectRx S2LPPacketHandlerGetRxMode(void); +void S2LPPacketHandlerSetExtendedLenField(SFunctionalState xExtendedLenField); +void S2LPPacketHandlerSwap4FSKSymbol(SFunctionalState xSwapSymbol); +void S2LPPacketHandlerSwapFifoEndianess(SFunctionalState xEnableSwap); +void S2LPPacketHandlerSwapPreamblePattern(SFunctionalState xEnableSwap); +void S2LPPacketHandlerSetCrcMode(PktCrcMode xPktCrcMode); +PktCrcMode S2LPPacketHandlerGetCrcMode(void); +void S2LPPacketHandlerSelectSecondarySync(SFunctionalState xSecondarySync); +void S2LPPacketHandlerSetAutoPcktFilter(SFunctionalState xNewState); +void S2LPPacketHandlerSetRxPersistentMode(SFunctionalState xNewState); +void S2LPPacketHandlerSetSrcAddrFlt(SFunctionalState xNewState); +void S2LPPacketHandlerSetVariableLength(SFunctionalState xVarLen); +void S2LPSetDualSyncWords(uint32_t lSyncWords); +void S2LPGetDualSyncWords(uint32_t* lSyncWords); +void S2LPSetRxSourceMask(uint8_t address); +void S2LPSetRxSourceReferenceAddress(uint8_t address); +void S2LPSetBroadcastAddress(uint8_t address); +void S2LPSetMulticastAddress(uint8_t address); +void S2LPSetMyAddress(uint8_t address); +uint8_t S2LPGetMyAddress(void); + + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_PktBasic.h b/strf/s2lp/S2LP_Library/Inc/S2LP_PktBasic.h new file mode 100644 index 00000000..0c51dffb --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_PktBasic.h @@ -0,0 +1,283 @@ +/** + * @file S2LP_PktBasic.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP Basic packets. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This module can be used to manage the configuration of S2LP Basic + * packets. + * The user can obtain a packet configuration filling the structure + * @ref PktBasicInit, defining in it some general parameters + * for the S2-LP Basic packet format. + * Another structure the user can fill is @ref PktBasicAddressesInit + * to define the addresses which will be used during the communication. + * Moreover, functions to set the payload length and the destination address + * are provided. + * + * Example: + * @code + * + * PktBasicInit basicInit={ + * 32, // preamble length in bits + * 32, // sync word length in bits + * 0x88888888, // sync word + * S_ENABLE, // variable or fixed payload length + * S_DISABLE, // extended length field width (used only for variable length) + * PKT_NO_CRC, // CRC mode + * S_ENABLE, // address field + * S_DISABLE, // FEC + * S_ENABLE // whitening + * }; + * + * PktBasicAddressesInit addressInit={ + * S_ENABLE, // enable/disable filtering on my address + * 0x34, // my address (address of the current node) + * S_DISABLE, // enable/disable filtering on multicast address + * 0xEE, // multicast address + * S_DISABLE, // enable/disable filtering on broadcast address + * 0xFF // broadcast address + * }; + * + * ... + * + * S2LPPktBasicInit(&basicInit); + * S2LPPktBasicAddressesInit(&addressInit); + * + * ... + * + * S2LPPktBasicSetPayloadLength(20); + * S2LPPktBasicSetDestinationAddress(0x44); + * + * ... + * + * @endcode + * + * The module provides some other functions that can be used to modify + * or read only some configuration parameters. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_PKT_BASIC_H +#define __S2LP_PKT_BASIC_H + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Regs.h" +#include "S2LP_Types.h" +#include "S2LP_PacketHandler.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_PktBasic Pkt Basic + * @brief Configuration and management of S2LP Basic packets. + * @details See the file @ref S2LP_PktBasic.h for more details. + * @{ + */ + +/** + * @defgroup PktBasic_Exported_Types Pkt Basic Exported Types + * @{ + */ + + +/** + * @brief CRC length in bytes enumeration. + */ +typedef PktCrcMode BasicCrcMode; + + + +/** + * @brief S2LP Basic Packet Init structure definition. + */ +typedef struct { + uint16_t xPreambleLength; /*!< Set the preamble length of packet. From 1 to 1024 chip sequence. */ + uint8_t xSyncLength; /*!< Set the sync word length of packet in bits. From 1 to 64 bits. */ + uint32_t lSyncWords; /*!< Set the sync words in MSB. */ + SFunctionalState xFixVarLength; /*!< Enable the variable length mode. */ + SFunctionalState cExtendedPktLenField; /*!< Extend the length field from 1 byte to 2 bytes. Variable length mode only. */ + BasicCrcMode xCrcMode; /*!< Set the CRC type. @ref StackCrcMode */ + SFunctionalState xAddressField; /*!< Enable the destination address field. */ + SFunctionalState xFec; /*!< Enable the FEC/Viterbi. */ + SFunctionalState xDataWhitening; /*!< Enable the data whitening. */ +} PktBasicInit; + + +/** + * @brief S2LP Basic packet address structure definition. This structure allows users to specify + * the node/multicast/broadcast addresses and the correspondent filtering options. + */ +typedef struct { + SFunctionalState xFilterOnMyAddress; /*!< If set packet is received if its destination address matches with cMyAddress. */ + uint8_t cMyAddress; /*!< Set the MyAddress. */ + SFunctionalState xFilterOnMulticastAddress; /*!< If set packet is received if its destination address matches with cMulticastAddress. */ + uint8_t cMulticastAddress; /*!< Set the Multicast address */ + SFunctionalState xFilterOnBroadcastAddress; /*!< If set packet is received if its destination address matches with cBroadcastAddress. */ + uint8_t cBroadcastAddress; /*!< Set the Broadcast address */ +} PktBasicAddressesInit; + + +/** + *@} + */ + + +/** + * @defgroup PktBasic_Exported_Macros Pkt Basic Exported Macros + * @{ + */ + +/** + * @brief Sets the PREAMBLE field length for S2LP Basic packets. + * @param xPreambleLength length of PREAMBLE field in bytes. + * This parameter can be any value of @ref BasicPreambleLength. + * @retval None. + */ +#define S2LPPktBasicSetPreambleLength(xPreambleLength) S2LPSetPreambleLength(xPreambleLength) + + +/** + * @brief Returns the PREAMBLE field length mode for S2LP Basic packets. + * @param None. + * @retval uint8_t Preamble field length in bytes. + */ +#define S2LPPktBasicGetPreambleLength() S2LPGetPreambleLength() + + +/** + * @brief Sets the SYNC field length for S2LP Basic packets. + * @param xSyncLength length of SYNC field in bytes. + * This parameter can be any value of @ref BasicSyncLength. + * @retval None. + */ +#define S2LPPktBasicSetSyncLength(xSyncLength) S2LPSetSyncLength((PktSyncLength)xSyncLength) + + +/** + * @brief Returns the SYNC field length for S2LP Basic packets. + * @param None. + * @retval uint8_t SYNC field length in bytes. + */ +#define S2LPPktBasicGetSyncLength() S2LPGetSyncLength() + + +/** + * @brief Enables or Disables the CRC filtering. + * @param xNewState new state for CRC_CHECK. + * This parameter can be S_ENABLE or S_DISABLE. + * @retval None. + */ +#define S2LPPktBasicFilterOnCrc(xNewState) S2LPPktCommonFilterOnCrc(xNewState) + + +/** + * @brief Enables or Disables WHITENING for S2LP packets. + * @param xNewState new state for WHITENING mode. + * This parameter can be S_ENABLE or S_DISABLE. + * @retval None. + */ +#define S2LPPktBasicWhitening(xNewState) S2LPWhitening(xNewState) + + +/** + * @brief Enables or Disables FEC for S2LP Basic packets. + * @param xNewState new state for FEC mode. + * This parameter can be S_ENABLE or S_DISABLE. + * @retval None. + */ +#define S2LPPktBasicFec(xNewState) S2LPFec(xNewState) + + + +/** + * @brief Sets multiple SYNC words for S2LP Basic packets. + * @param lSyncWords SYNC words to be set with format: 0x|SYNC1|SYNC2|SYNC3|SYNC4|. + * This parameter is a uint32_t. + * @param xSyncLength SYNC length in bytes. The 32bit word passed will be stored in the SYNCx registers from the MSb + * until the number of bytes in xSyncLength has been stored. + * This parameter is a @ref BasicSyncLength. + * @retval None. + */ +#define S2LPPktBasicSetSyncWords(lSyncWords, xSyncLength) S2LPSetSyncWords(lSyncWords, xSyncLength) + + +/** + *@} + */ + + +/** + * @defgroup PktBasic_Exported_Functions Pkt Basic Exported Functions + * @{ + */ + +void S2LPPktBasicInit(PktBasicInit* pxPktBasicInit); +void S2LPPktBasicGetInfo(PktBasicInit* pxPktBasicInit); +void S2LPPktBasicAddressesInit(PktBasicAddressesInit* pxPktBasicAddresses); +void S2LPPktBasicGetAddressesInfo(PktBasicAddressesInit* pxPktBasicAddresses); +void S2LPPktBasicSetFormat(void); +void S2LPPktBasicAddressField(SFunctionalState xAddressField); +SFunctionalState S2LPPktBasicGetAddressField(void); +void S2LPPktBasicSetPayloadLength(uint16_t nPayloadLength); +uint16_t S2LPPktBasicGetPayloadLength(void); +uint16_t S2LPPktBasicGetReceivedPktLength(void); + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_PktStack.h b/strf/s2lp/S2LP_Library/Inc/S2LP_PktStack.h new file mode 100644 index 00000000..d0c327a9 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_PktStack.h @@ -0,0 +1,286 @@ +/** + * @file S2LP_PktStack.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP STack packets. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * This module can be used to manage the configuration of S2LP STack + * packets, and it is quite similar to the Basic packets one since the + * STack packets can be considered an extension of Basic. + * The user can obtain a packet configuration filling the structure + * @ref PktStackInit, defining in it some general parameters + * for the S2-LP STack packet format. + * Another structure the user can fill is @ref PktStackAddressesInit + * to define the addresses which will be used during the communication. + * Moreover, functions to set the payload length and the destination address + * are provided. + * + * Example: + * @code + * + * PktStackInit stackInit={ + * 32, // preamble length in bits + * 32, // sync word length in bits + * 0x88888888, // sync word + * S_ENABLE, // variable or fixed payload length + * S_DISABLE, // extended length field width (used only for variable length) + * PKT_NO_CRC, // CRC mode + * S_DISABLE, // FEC + * S_ENABLE // whitening + * }; + * + * PktStackAddressesInit addressInit={ + * S_ENABLE, // enable/disable filtering on my address + * 0x34, // my address (address of the current node) + * S_DISABLE, // enable/disable filtering on multicast address + * 0xEE, // multicast address + * S_DISABLE, // enable/disable filtering on broadcast address + * 0xFF // broadcast address + * }; + * + * ... + * + * S2LPPktStackInit(&stackInit); + * S2LPPktStackAddressesInit(&addressInit); + * + * ... + * + * S2LPPktStackSetPayloadLength(20); + * S2LPPktStackSetDestinationAddress(0x44); + * + * ... + * + * @endcode + * + * The module provides some other functions that can be used to modify + * or read only some configuration parameters. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_PKT_STACK_H +#define __S2LP_PKT_STACK_H + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Regs.h" +#include "S2LP_Types.h" +#include "S2LP_PacketHandler.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_PktStack Pkt STack + * @brief Configuration and management of S2LP STack packets. + * @details See the file @ref S2LP_PktStack.h for more details. + * @{ + */ + +/** + * @defgroup PktStack_Exported_Types Pkt STack Exported Types + * @{ + */ + + +/** + * @brief CRC length in bytes enumeration. + */ +typedef PktCrcMode StackCrcMode; + + +/** + * @brief S2LP STack Packet Init structure definition. + */ +typedef struct { + uint16_t xPreambleLength; /*!< Set the preamble length of packet. From 1 to 1024 chip sequence. */ + uint8_t xSyncLength; /*!< Set the sync word length of packet in bits. From 1 to 64 bits. */ + uint32_t lSyncWords; /*!< Set the sync words in MSB. */ + SFunctionalState xFixVarLength; /*!< Enable the variable length mode. */ + SFunctionalState cExtendedPktLenField; /*!< Extend the length field from 1 byte to 2 bytes. Variable length mode only. */ + StackCrcMode xCrcMode; /*!< Set the CRC type. @ref StackCrcMode */ + SFunctionalState xFec; /*!< Enable the FEC/Viterbi. */ + SFunctionalState xDataWhitening; /*!< Enable the data whitening. */ +} PktStackInit; + + +/** + * @brief S2LP STack packet address structure definition. This structure allows users to specify + * the node/multicast/broadcast addresses and the correspondent filtering options. + */ +typedef struct { + SFunctionalState xFilterOnMyAddress; /*!< If set packet is received if its destination address matches with cMyAddress. */ + uint8_t cMyAddress; /*!< Set the MyAddress. */ + SFunctionalState xFilterOnMulticastAddress; /*!< If set packet is received if its destination address matches with cMulticastAddress. */ + uint8_t cMulticastAddress; /*!< Set the Multicast address */ + SFunctionalState xFilterOnBroadcastAddress; /*!< If set packet is received if its destination address matches with cBroadcastAddress. */ + uint8_t cBroadcastAddress; /*!< Set the Broadcast address */ +} PktStackAddressesInit; + + +/** + *@} + */ + + +/** + * @defgroup PktStack_Exported_Macros Pkt STack Exported Macros + * @{ + */ + +/** + * @brief Sets the PREAMBLE Length mode for S2LP STack packets. + * @param xPreambleLength length of PREAMBLE field in bytes. + * This parameter can be any value of @ref StackPreambleLength. + * @retval None. + */ +#define S2LPPktStackSetPreambleLength(xPreambleLength) S2LPSetPreambleLength(xPreambleLength) + + +/** + * @brief Returns the PREAMBLE Length mode for S2LP STack packets. + * @param None. + * @retval uint8_t Preamble length in bytes. + */ +#define S2LPPktStackGetPreambleLength() S2LPGetPreambleLength() + + +/** + * @brief Sets the SYNC Length for S2LP STack packets. + * @param xSyncLength length of SYNC field in bytes. + * This parameter can be any value of @ref StackSyncLength. + * @retval None. + */ +#define S2LPPktStackSetSyncLength(xSyncLength) S2LPSetSyncLength((PktSyncLength)xSyncLength) + + +/** + * @brief Returns the SYNC Length for S2LP STack packets. + * @param None. + * @retval uint8_t Sync length in bytes. + */ +#define S2LPPktStackGetSyncLength() S2LPGetSyncLength() + + + +/** + * @brief Enables or Disables the CRC filtering. + * @param xNewState new state for CRC_CHECK. + * This parameter can be S_ENABLE or S_DISABLE. + * @retval None. + */ +#define S2LPPktStackFilterOnCrc(xNewState) S2LPPktCommonFilterOnCrc(xNewState) + + + +/** + * @brief Enables or Disables WHITENING for S2LP STack packets. + * @param xNewState new state for WHITENING mode. + * This parameter can be S_ENABLE or S_DISABLE. + * @retval None. + */ +#define S2LPPktStackWhitening(xNewState) S2LPWhitening(xNewState) + + +/** + * @brief Enables or Disables FEC for S2LP STack packets. + * @param xNewState new state for FEC mode. + * This parameter can be S_ENABLE or S_DISABLE. + * @retval None. + */ +#define S2LPPktStackFec(xNewState) S2LPFec(xNewState) + + +/** + * @brief Sets multiple SYNC words for S2LP STack packets. + * @param lSyncWords SYNC words to be set with format: 0x|SYNC1|SYNC2|SYNC3|SYNC4|. + * This parameter is a uint32_t. + * @param xSyncLength SYNC length in bytes. The 32bit word passed will be stored in the SYNCx registers from the MSb + * until the number of bytes in xSyncLength has been stored. + * This parameter is a @ref StackSyncLength. + * @retval None. + */ +#define S2LPPktStackSetSyncWords(lSyncWords, xSyncLength) S2LPSetSyncWords(lSyncWords,xSyncLength) + + +/** + *@} + */ + + +/** + * @defgroup PktStack_Exported_Functions Pkt STack Exported Functions + * @{ + */ + +void S2LPPktStackInit(PktStackInit* pxPktStackInit); +void S2LPPktStackGetInfo(PktStackInit* pxPktStackInit); +void S2LPPktStackAddressesInit(PktStackAddressesInit* pxPktStackAddresses); +void S2LPPktStackGetAddressesInfo(PktStackAddressesInit* pxPktStackAddresses); +void S2LPPktStackSetFormat(void); +void S2LPPktStackSetPayloadLength(uint16_t nPayloadLength); +uint16_t S2LPPktStackGetPayloadLength(void); +void S2LPPktStackAckRequest(SFunctionalState xNewState); +void S2LPPktStackAutoAck(SFunctionalState xNewState); +void S2LPPktStackNRetx(uint8_t nRetx); +void S2LPPktStackPiggybacking(SFunctionalState xNewState); +SFlagStatus S2LPPktStackGetTXAckRequest(void); +uint8_t S2LPPktStackGetNReTx(void); + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_PktWMbus.h b/strf/s2lp/S2LP_Library/Inc/S2LP_PktWMbus.h new file mode 100644 index 00000000..2e5f5aef --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_PktWMbus.h @@ -0,0 +1,181 @@ +/** + * @file S2LP_PktWMbus.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP WMbus packets. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This module can be used to manage the configuration of S2-LP WMbus + * packets. + * The user can obtain a packet configuration filling the structure + * @ref PktWMbusInit, defining in it some general parameters + * for the S2-LP WMbus packet format. + * Since the WMbus protocol is a standard, the configuration of a WMbus + * packet is very simple to do. + * + * Example: + * @code + * + * PktWMbusInit mbusInit={ + * WMbus_SUBMODE_S1_S2_LONG_HEADER, // WMbus submode selection + * 36, // added "01" chips on preamble + * 16 // postamble length in "01" chips + * }; + * + * ... + * + * S2LPPktWMbusInit(&mbusInit); + * + * ... + * + * @endcode + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_PACKET_WMBUS_H +#define __S2LP_PACKET_WMBUS_H + + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Regs.h" +#include "S2LP_Types.h" +#include "S2LP_PacketHandler.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_PktWMbus Pkt WMbus + * @brief Configuration and management of S2LP WMbus packets. + * @details See the file @ref S2LP_PktWMbus.h for more details. + * @{ + */ + +/** + * @defgroup PktWMbus_Exported_Types Pkt WMbus Exported Types + * @{ + */ + + + +/** + * @brief WMbus submode enumeration. + */ + +typedef enum { + WMBUS_SUBMODE_NOT_CONFIGURED = 0, /*!< WMBUS submode S1, S2 (long header) - Header length = WMBUS_prmbl_ctrl + 279 (in "01" bit pairs) , Sync word = 0x7696 (length 18 bits) */ + WMBUS_SUBMODE_S1_S2_LONG_HEADER, /*!< WMBUS submode S1, S2 (long header) - Header length = WMBUS_prmbl_ctrl + 279 (in "01" bit pairs) , Sync word = 0x7696 (length 18 bits) */ + WMBUS_SUBMODE_S1_M_S2_T2_OTHER_TO_METER, /*!< WMBUS submode S1-m, S2, T2 (other to meter) - Header length = WMBUS_prmbl_ctrl + 15 (in "01" bit pairs) , Sync word = 0x7696 (length 18 bits)*/ + WMBUS_SUBMODE_T1_T2_METER_TO_OTHER, /*!< WMBUS submode T1, T2 (meter to other) - Header length = WMBUS_prmbl_ctrl + 19 (in "01" bit pairs) , Sync word = 0x3D (length 10 bits)*/ + WMBUS_SUBMODE_R2_SHORT_HEADER, /*!< WMBUS submode R2, short header - Header length = WMBUS_prmbl_ctrl + 39 (in "01" bit pairs) , Sync word = 0x7696 (length 18 bits)*/ +} WMbusSubmode; + + +/** + * @brief S2LP WMBUS Packet Init structure definition + */ +typedef struct { + WMbusSubmode xWMbusSubmode; /*!< Set the WMBUS submode. @ref WMbusSubmode */ + uint8_t cPreambleLength; /*!< Set the preamble length in chip sequence */ + uint8_t cPostambleLength; /*!< Set the postamble length in chip sequence */ +} PktWMbusInit; + +/** + *@} + */ + + + +/** + * @defgroup PktWMbus_Exported_Functions Pkt WMbus Exported Functions + * @{ + */ + +/** + * @brief Sets the PREAMBLE field length for S2LP Basic packets. + * @param xPreambleLength length of PREAMBLE field in bytes. + * This parameter can be any value of @ref BasicPreambleLength. + * @retval None. + */ +#define S2LPPktWMbusSetPreambleLength(xPreambleLength) S2LPPktCommonSetPreambleLength((PktPreambleLength)xPreambleLength) + + +/** + * @brief Returns the PREAMBLE field length mode for S2LP Basic packets. + * @param None. + * @retval uint8_t Preamble field length in bytes. + */ +#define S2LPPktWMbusGetPreambleLength() S2LPPktCommonGetPreambleLength() + + +void S2LPPktWMbusInit(PktWMbusInit* pxPktWMbusInit); +void S2LPPktWMbusGetInfo(PktWMbusInit* pxPktWMbusInit); +void S2LPPktWMbusSetFormat(void); +void S2LPPktWMbusSetPostamble(uint8_t cPostamble); +uint8_t S2LPPktWMbusGetPostamble(void); +void S2LPPktWMbusSetPostamblePattern(uint8_t cPostamble); +uint8_t S2LPPktWMbusGetPostamblePattern(void); +void S2LPPktWMbusSetSubmode(WMbusSubmode xWMbusSubmode); +WMbusSubmode S2LPPktWMbusGetSubmode(void); +void S2LPPktWMbusSetPayloadLength(uint16_t nPayloadLength); +uint16_t S2LPPktWMbusGetPayloadLength(void); + + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Qi.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Qi.h new file mode 100644 index 00000000..949f6782 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Qi.h @@ -0,0 +1,180 @@ +/** + * @file S2LP_Qi.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2LP QI. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This module can be used to configure and read some quality indicators + * used by S2-LP. + * API to set thresholds and to read values in raw mode or in dBm are + * provided. + * + * Example: + * @code + * + * int32_t rssiValuedBm; + * uint8_t pqiValue, sqiValue; + * + * S2LPQiPqiCheck(S_ENABLE); + * S2LPQiSqiCheck(S_ENABLE); + * + * ... + * + * rssiValueDbm = S2LPQiGetRssidBm(); + * pqiValue = S2LPQiGetPqi(); + * sqiValue = S2LPQiGetSqi(); + * + * ... + * + * @endcode + * + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_QI_H +#define __S2LP_QI_H + + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Regs.h" +#include "S2LP_Types.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_Qi QI + * @brief Configuration and management of S2LP QI. + * @details See the file @ref S2LP_Qi.h for more details. + * @{ + */ + +/** + * @defgroup Qi_Exported_Types QI Exported Types + * @{ + */ + +/** + * @brief S2LP RSSI mode enumeration + */ +typedef enum { + RSSI_STATIC_MODE = 0, /* static mode */ + RSSI_DYNAMIC_6DB_STEP_MODE, /* dynamic mode 6 dB above threshold*/ + RSSI_DYNAMIC_12DB_STEP_MODE, /* dynamic mode 12 dB above threshold */ + RSSI_DYNAMIC_18DB_STEP_MODE /* dynamic mode 18 dB above threshold */ +} SRssiMode; + + +/** + * @brief S2LP RSSI Init structure definition + */ +typedef struct { + uint8_t cRssiFlt; /*!< Set the RSSI filter gain. From 0 to 15. */ + SRssiMode xRssiMode; /*!< Set the RSSI mode. @ref SRssiMode */ + int32_t cRssiThreshdBm; /*!< Set the RSSI threshold in dBm. From -130 to -2.5 dBm. */ +} SRssiInit; + + +/** + *@} + */ + + +/** + * @defgroup Qi_Exported_Constants QI Exported Constants + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup Qi_Exported_Macros QI Exported Macros + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup Qi_Exported_Functions QI Exported Functions + * @{ + */ + +int32_t S2LPRadioGetRssidBm(void); +int32_t S2LPRadioGetRssidBmRun(void); +void S2LPRadioSetRssiThreshdBm(int32_t wRssiThrehsold); +void S2LPRadioCsBlanking(SFunctionalState xCsBlank); +void S2LPRadioRssiInit(SRssiInit* xSRssiInit); +void S2LPRadioGetRssiInfo(SRssiInit* xSRssiInit); +void S2LPRadioAntennaSwitching(SFunctionalState xAntennaSwitch); +void S2LPRadioSetPqiCheck(uint8_t cPqiLevel); +SFlagStatus S2LPQiGetCs(void); + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Radio.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Radio.h new file mode 100644 index 00000000..1385b4d9 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Radio.h @@ -0,0 +1,277 @@ +/** + * @file S2LP_Radio.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP RF Analog and Digital part. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * In order to configure the Radio main parameters, the user can + * fit SRadioInit structure the and call the S2LPRadioInit() + * function passing its pointer as an argument. + * + * Example: + * @code + * + * SRadioInit radioInit = { + * 433400000, // base frequency + * MOD_2FSK, // modulation select + * 38400, // datarate + * 20000, // frequency deviation + * 100000 // channel filter bandwidth + * }; + * + * ... + * + * S2LPRadioInit(&radioInit); + * @endcode + * + * Another important parameter for the radio configuration is the + * transmission power. + * The user is allowed to configure it using the function S2LPRadioSetPALeveldBm() + * which sets the PA LEVEL specified by the first argument to the + * power expressed in dBm by the second parameter. + * + * Example: + * @code + * + * S2LPRadioSetPALeveldBm(0 , 10.0); + * + * @endcode + * + * + * @note The effective power that is set can be a little different from the + * passed argument in dBm because the function performs an approximation. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_RADIO_H +#define __S2LP_RADIO_H + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Regs.h" +#include "S2LP_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup S2LP_Libraries + * @{ + */ + + +/** @defgroup S2LP_Radio Radio + * @brief Configuration and management of S2LP RF Analog and Digital part. + * @details See the file @ref S2LP_Radio.h for more details. + * @{ + */ + + + +/** @defgroup Radio_Exported_Types Radio Exported Types + * @{ + */ + + +/** + * @brief S2LP Modulation enumeration + */ +typedef enum { + MOD_NO_MOD = 0x70, /*!< CW modulation selected */ + MOD_2FSK = 0x00, /*!< 2-FSK modulation selected */ + MOD_4FSK = 0x10, /*!< 4-FSK modulation selected */ + MOD_2GFSK_BT05 = 0xA0, /*!< G2FSK modulation selected with BT = 0.5 */ + MOD_2GFSK_BT1 = 0x20, /*!< G2FSK modulation selected with BT = 1 */ + MOD_4GFSK_BT05 = 0xB0, /*!< G4FSK modulation selected with BT = 0.5 */ + MOD_4GFSK_BT1 = 0x30, /*!< G4FSK modulation selected with BT = 1 */ + MOD_ASK_OOK = 0x50, /*!< OOK modulation selected. */ + MOD_POLAR = 0x60, /*!< OOK modulation selected. */ +} ModulationSelect; + + +/** + * @brief S2LP Radio Init structure definition + */ +typedef struct { + uint32_t lFrequencyBase; /*!< Specifies the base carrier frequency (in Hz), + i.e. the carrier frequency of channel #0. + This parameter can be in one of the following ranges: + High_Band: from 860 MHz to 940 MHz + Middle Band: from 430 MHz to 470 MHz */ + ModulationSelect xModulationSelect; /*!< Specifies the modulation @ref ModulationSelect */ + uint32_t lDatarate; /*!< Specifies the datarate expressed in bps. + This parameter can be in the range + between 100 bps and 500 kbps */ + uint32_t lFreqDev; /*!< Specifies the frequency deviation expressed in Hz. + This parameter can be in the range: + [F_Xo*8/2^18, F_Xo*7680/2^18] Hz */ + uint32_t lBandwidth; /*!< Specifies the channel filter bandwidth + expressed in Hz. This parameter can be + in the range between 1100 and 800100 Hz */ +} SRadioInit; + + +/** + * @brief S2LP AFC mode enumeration + */ +typedef enum { + AFC_MODE_LOOP_CLOSED_ON_SLICER = 0, /* loop closed on slicer */ + AFC_MODE_LOOP_CLOSED_ON_2ND_CONV_STAGE /* loop closed on 2nd conversion stage */ +} SAfcMode; + + +/** + * @brief S2LP AFC Init structure definition + */ +typedef struct { + SFunctionalState xAfcEnable; /*!< AFC enable */ + SFunctionalState xAfcFreezeOnSync; /*!< Freeze the parameters on SYNC word detect */ + SAfcMode xAfcMode; /*!< Specify the AFC mode. @ref SAfcMode */ + uint8_t cAfcFastPeriod; /*!< Fast period duration */ + uint8_t cAfcFastGain; /*!< Gain used during fast loop */ + uint8_t cAfcSlowGain; /*!< Gain used during slow loop */ +} SAfcInit; + + +/** + * @brief S2LP ISI Equalization type enumeration + */ +typedef enum { + ISI_EQUALIZATION_DISABLED = 0, /* static mode */ + ISI_EQUALIZATION_SINGLE_PASS, /* dynamic mode 6 dB above threshold*/ + ISI_EQUALIZATION_DUAL_PASS /* dynamic mode 18 dB above threshold */ +} SIsiEqu; + + +/** + * @brief S2LP Clock Recovery mode enumeration + */ +typedef enum { + CLKREC_DLL_MODE = 0, /* DLL mode */ + CLKREC_PLL_MODE, /* PLL mode */ +} SClkRecMode; + + +/** + * @brief S2LP Clock Recovery Init structure definition + */ +typedef struct { + SClkRecMode xSClkRecMode; /*!< Select the clock recovery mode. @ref SClkRecMode */ + uint8_t cClkRecPGainSlow; /*!< Gain P for slow stage. From 0 to 7. */ + uint8_t cClkRecPGainFast; /*!< Gain P for fast stage. From 0 to 7. */ + uint8_t cClkRecIGainSlow; /*!< Gain I for slow stage. From 0 to 15. */ + uint8_t cClkRecIGainFast; /*!< Gain I for fast stage. From 0 to 15. */ + SFunctionalState cClkRec16SymPostFlt; /*!< Set the post filter to 16 symbols. Default is 8 symbols */ +} SSymClkRecInit; + + +/** + * @} + */ + + + +/** @defgroup Radio_Exported_Functions Radio Exported Functions + * @{ + */ + +uint8_t S2LPRadioInit(SRadioInit* pxSRadioInitStruct); +void S2LPRadioGetInfo(SRadioInit* pxSRadioInitStruct); +void S2LPRadioSetSynthWord(uint32_t lSynthWord); +uint32_t S2LPRadioGetSynthWord(void); +void S2LPRadioSetChannel(uint8_t cChannel); +uint8_t S2LPRadioGetChannel(void); +void S2LPRadioSetRefDiv(SFunctionalState xNewState); +SFunctionalState S2LPRadioGetRefDiv(void); +void S2LPRadioSetDigDiv(SFunctionalState xNewState); +SFunctionalState S2LPRadioGetDigDiv(void); +void S2LPRadioSetChannelSpace(uint32_t lChannelSpace); +uint32_t S2LPRadioGetChannelSpace(void); +uint8_t S2LPRadioSetFrequencyBase(uint32_t lFBase); +uint32_t S2LPRadioGetFrequencyBase(void); +void S2LPRadioSetDatarate(uint32_t lDatarate); +uint32_t S2LPRadioGetDatarate(void); +void S2LPRadioSetFrequencyDev(uint32_t lFDev); +uint32_t S2LPRadioGetFrequencyDev(void); +void S2LPRadioSetChannelBW(uint32_t lBandwidth); +uint32_t S2LPRadioGetChannelBW(void); +void S2LPRadioSetModulation(ModulationSelect xModulation); +ModulationSelect S2LPRadioGetModulation(void); +void S2LPRadioSetXtalFrequency(uint32_t lXtalFrequency); +uint32_t S2LPRadioGetXtalFrequency(void); +void S2LPRadioSetIsiEqualizationMode(SIsiEqu xSIsiMode); +SIsiEqu S2LPRadioGetIsiEqualizationMode(void); +void S2LPRadioCalibrationVco(SFunctionalState xAmplitudeCalibration, SFunctionalState xFrequencyCalibration); +void S2LPRadioSetTxCalibVcoAmpWord(uint8_t value); +void S2LPRadioSetRxCalibVcoAmpWord(uint8_t value); +void S2LPRadioSetTxCalibVcoFreqWord(uint8_t value); +void S2LPRadioSetRxCalibVcoFreqWord(uint8_t value); + +void S2LPRadioSetMaxPALevel(SFunctionalState xNewState); +void S2LPRadioSetPALeveldBm(uint8_t cIndex, int32_t wPowerdBm); +int32_t S2LPRadioGetPALeveldBm(uint8_t cIndex); +uint8_t S2LPRadioGetPALevelMaxIndex(void); +void S2LPRadioSetPALevelMaxIndex(uint8_t cIndex); +void S2LPRadioSetManualRampingMode(SFunctionalState xNewState); +void S2LPRadioSetAutoRampingMode(SFunctionalState xNewState); + +void S2LPRadioAfcInit(SAfcInit* xSAfcInit); +void S2LPRadioGetAfcInfo(SAfcInit* xSAfcInit); +void S2LPRadioSymClkRecoverInit(SSymClkRecInit* xSSymClkRecInit); +void S2LPRadioGetSymClkRecoverInfo(SSymClkRecInit* xSSymClkRecInit); + + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Regs.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Regs.h new file mode 100644 index 00000000..e6022fab --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Regs.h @@ -0,0 +1,1875 @@ +/** + * @file S2LP_Regs.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief This file contains all the registers address and masks. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + + +/** + * \brief GPIO0_CONF register + * \code + * Read and Write + * Default value: 0x0A + * 7:3 GPIO_SELECT: Specify the GPIO0 I/O signal, default setting POR. + * 2 RESERVED: - + * 1:0 GPIO_MODE: GPIO0 Mode:, 01b: Digital Input, 10b: Digital Output Low Power, 11b: Digital Output High Power + * \endcode + */ +#define GPIO0_CONF_ADDR ((uint8_t)0x00) + +#define GPIO_SELECT_REGMASK ((uint8_t)0xF8) +#define GPIO_MODE_REGMASK ((uint8_t)0x03) + + +/** + * \brief GPIO1_CONF register + * \code + * Read and Write + * Default value: 0xA2 + * 7:3 GPIO_SELECT: Specify the GPIO1 I/O signal, default setting digital GND. + * 2 RESERVED: - + * 1:0 GPIO_MODE: GPIO1 Mode:, 01b: Digital Input1, 0b: Digital Output Low Power, 11b: Digital Output High Power + * \endcode + */ +#define GPIO1_CONF_ADDR ((uint8_t)0x01) + +#define GPIO_SELECT_REGMASK ((uint8_t)0xF8) +#define GPIO_MODE_REGMASK ((uint8_t)0x03) + + +/** + * \brief GPIO2_CONF register + * \code + * Read and Write + * Default value: 0xA2 + * 7:3 GPIO_SELECT: Specify the GPIO2 I/O signal, default setting digital GND. + * 2 RESERVED: - + * 1:0 GPIO_MODE: GPIO2 Mode:, 01b: Digital Input, 10b: Digital Output Low Power, 11b: Digital Output High Power + * \endcode + */ +#define GPIO2_CONF_ADDR ((uint8_t)0x02) + +#define GPIO_SELECT_REGMASK ((uint8_t)0xF8) +#define GPIO_MODE_REGMASK ((uint8_t)0x03) + + +/** + * \brief GPIO3_CONF register + * \code + * Read and Write + * Default value: 0xA2 + * 7:3 GPIO_SELECT: Specify the GPIO3 I/O signal, default setting digital GND. + * 2 RESERVED: - + * 1:0 GPIO_MODE: GPIO3 Mode:, 00b: Analog, 01b: Digital Input, 10b: Digital Output Low Power, 11b: Digital Output High Power + * \endcode + */ +#define GPIO3_CONF_ADDR ((uint8_t)0x03) + +#define GPIO_SELECT_REGMASK ((uint8_t)0xF8) +#define GPIO_MODE_REGMASK ((uint8_t)0x03) + + +/** + * \brief MCU_CK_CONF register + * \code + * Read and Write + * Default value: 0x00 + * 7 EN_MCU_CLK: 1: The internal divider logic is running, so the MCU clock is available (but proper GPIO configuration is needed) + * 6:5 CLOCK_TAIL: Number of extra clock cycles provided to the MCU before switching to STANDBY state., 00b: 0 extra clock cycle, 01b: 64 extra clock cycles, 10b: 256 extra clock cycles, 11b: 512 extra clock cycles + * 4:1 XO_RATIO: Divider for the XO clock output + * 0 RCO_RATIO: Divider for the RCO clock output, 0: 1 , 1: 1/128 + * \endcode + */ +#define MCU_CK_CONF_ADDR ((uint8_t)0x04) + +#define EN_MCU_CLK_REGMASK ((uint8_t)0x80) +#define CLOCK_TAIL_REGMASK ((uint8_t)0x60) +#define XO_RATIO_REGMASK ((uint8_t)0x1E) +#define RCO_RATIO_REGMASK ((uint8_t)0x01) + + +/** + * \brief SYNT3 register + * \code + * Read and Write + * Default value: 0x42 + * 7:5 PLL_CP_ISEL: Set the charge pump current according to the XTAL frequency. + * 4 BS: Synthesizer band select. This parameter selects the out-of loop divide factor of the synthesizer:, 0: 4, band select factor for high band, 1: 8, band select factor for middle band. + * 3:0 SYNT_27_24: MSB bits of the PLL programmable divider. + * \endcode + */ +#define SYNT3_ADDR ((uint8_t)0x05) + +#define PLL_CP_ISEL_REGMASK ((uint8_t)0xE0) +#define BS_REGMASK ((uint8_t)0x10) +#define SYNT_27_24_REGMASK ((uint8_t)0x0F) + + +/** + * \brief SYNT2 register + * \code + * Read and Write + * Default value: 0x16 + * 7:0 SYNT[23:16]: Intermediate bits of the PLL programmable divider. + * \endcode + */ +#define SYNT2_ADDR ((uint8_t)0x06) + +#define SYNT_23_16_REGMASK ((uint8_t)0xFF) + + +/** + * \brief SYNT1 register + * \code + * Read and Write + * Default value: 0x27 + * 7:0 SYNT[15:8]: Intermediate bits of the PLL programmable divider. + * \endcode + */ +#define SYNT1_ADDR ((uint8_t)0x07) + +#define SYNT_15_8_REGMASK ((uint8_t)0xFF) + + +/** + * \brief SYNT0 register + * \code + * Read and Write + * Default value: 0x62 + * 7:0 SYNT[7:0]: LSB bits of the PLL programmable divider. + * \endcode + */ +#define SYNT0_ADDR ((uint8_t)0x08) + +#define SYNT_7_0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IF_OFFSET_ANA register + * \code + * Read and Write + * Default value: 0x2A + * 7:0 IF_OFFSET_ANA: Intermediate frequency setting for the analog RF synthesizer, default: 300 kHz. + * \endcode + */ +#define IF_OFFSET_ANA_ADDR ((uint8_t)0x09) + +#define IF_OFFSET_ANA_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IF_OFFSET_DIG register + * \code + * Read and Write + * Default value: 0xB8 + * 7:0 IF_OFFSET_DIG: Intermediate frequency setting for the digital shift-to-baseband circuits, default: 300 kHz. + * \endcode + */ +#define IF_OFFSET_DIG_ADDR ((uint8_t)0x0A) + +#define IF_OFFSET_DIG_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CH_SPACE register + * \code + * Read and Write + * Default value: 0x3F + * 7:0 CH_SPACE: Channel spacing. From ~793Hz to ~200KHz in 793Hz steps, default 100kHz. + * \endcode + */ +#define CH_SPACE_ADDR ((uint8_t)0x0C) + +#define CH_SPACE_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CHNUM register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 CH_NUM: Channel number. This value is multiplied by the channel spacing and added to the synthesizer base frequency to generate the actual RF carrier frequency. + * \endcode + */ +#define CHNUM_ADDR ((uint8_t)0x0D) + +#define CH_NUM_REGMASK ((uint8_t)0xFF) + + +/** + * \brief MOD4 register + * \code + * Read and Write + * Default value: 0x83 + * 7:0 DATARATE_M[15:8]: The MSB of the mantissa value of the data rate equation, default 38.4 ksps. + * \endcode + */ +#define MOD4_ADDR ((uint8_t)0x0E) + +#define DATARATE_M_15_8_REGMASK ((uint8_t)0xFF) + + +/** + * \brief MOD3 register + * \code + * Read and Write + * Default value: 0x2B + * 7:0 DATARATE_M[7:0]: The LSB of the mantissa value of the data rate equation, default 38.4 ksps. + * \endcode + */ +#define MOD3_ADDR ((uint8_t)0x0F) + +#define DATARATE_M_7_0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief MOD2 register + * \code + * Read and Write + * Default value: 0x77 + * 7:4 MOD_TYPE: Modulation type:, 0: 2-FSK, 1: 4-FSK, 2: 2-GFSK BT=1, 3: 4-GFSK BT=1, 5: ASK/OOK, 7: unmodulated, 10: 2-GFSK BT=0.5, 12: 4-GFSK BT=0.5 + * 3:0 DATARATE_E: The exponent value of the data rate equation, default 38.4 ksps. + * \endcode + */ +#define MOD2_ADDR ((uint8_t)0x10) + +#define MOD_TYPE_REGMASK ((uint8_t)0xF0) +#define DATARATE_E_REGMASK ((uint8_t)0x0F) + + +/** + * \brief MOD1 register + * \code + * Read and Write + * Default value: 0x03 + * 7 PA_INTERP_EN: 1: enable the power interpolator + * 6 MOD_INTERP_EN: 1: enable frequency interpolator + * 5:4 G4FSK_CONST_MAP: Select the constellation map for 4-GFSK. + * 3:0 FDEV_E: The exponent value of the frequency deviation equation, default 20 kHz. + * \endcode + */ +#define MOD1_ADDR ((uint8_t)0x11) + +#define PA_INTERP_EN_REGMASK ((uint8_t)0x80) +#define MOD_INTERP_EN_REGMASK ((uint8_t)0x40) +#define G4FSK_CONST_MAP_REGMASK ((uint8_t)0x30) +#define FDEV_E_REGMASK ((uint8_t)0x0F) + + +/** + * \brief MOD0 register + * \code + * Read and Write + * Default value: 0x93 + * 7:0 FDEV_M: The mantissa value of the frequency deviation equation, default 20 kHz. + * \endcode + */ +#define MOD0_ADDR ((uint8_t)0x12) + +#define FDEV_M_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CHFLT register + * \code + * Read and Write + * Default value: 0x23 + * 7:4 CHFLT_M: The mantissa value of the receiver channel filter, default 100 kHz. + * 3:0 CHFLT_E: The exponent value of the receiver channel filter, default 100 kHz. + * \endcode + */ +#define CHFLT_ADDR ((uint8_t)0x13) + +#define CHFLT_M_REGMASK ((uint8_t)0xF0) +#define CHFLT_E_REGMASK ((uint8_t)0x0F) + + +/** + * \brief AFC2 register + * \code + * Read and Write + * Default value: 0xC8 + * 7 AFC_FREEZE_ON_SYNC: 1: enable the freeze AFC correction upon sync word detection. + * 6 AFC_ENABLED: 1: enable the AFC correction. + * 5 AFC_MODE: Select AFC mode:, 0: AFC loop closed on slicer, 1: AFC loop closed on second conversion stage. + * 4:0 RESERVED: - + * \endcode + */ +#define AFC2_ADDR ((uint8_t)0x14) + +#define AFC_FREEZE_ON_SYNC_REGMASK ((uint8_t)0x80) +#define AFC_ENABLED_REGMASK ((uint8_t)0x40) +#define AFC_MODE_REGMASK ((uint8_t)0x20) + + +/** + * \brief AFC1 register + * \code + * Read and Write + * Default value: 0x18 + * 7:0 AFC_FAST_PERIOD: The length of the AFC fast period. + * \endcode + */ +#define AFC1_ADDR ((uint8_t)0x15) + +#define AFC_FAST_PERIOD_REGMASK ((uint8_t)0xFF) + + +/** + * \brief AFC0 register + * \code + * Read and Write + * Default value: 0x25 + * 7:4 AFC_FAST_GAIN: The AFC loop gain in fast mode (2's log). + * 3:0 AFC_SLOW_GAIN: The AFC loop gain in slow mode (2's log). + * \endcode + */ +#define AFC0_ADDR ((uint8_t)0x16) + +#define AFC_FAST_GAIN_REGMASK ((uint8_t)0xF0) +#define AFC_SLOW_GAIN_REGMASK ((uint8_t)0x0F) + + +/** + * \brief RSSI_FLT register + * \code + * Read and Write + * Default value: 0xE3 + * 7:4 RSSI_FLT: Gain of the RSSI filter. + * 3:2 CS_MODE: Carrier sense mode:, 00b: Static CS, 01b: Dynamic CS with 6dB dynamic threshold, 10b: Dynamic CS with 12dB dynamic threshold, 11b: Dynamic CS with 18dB dynamic threshold. + * 1:0 RESERVED: - + * \endcode + */ +#define RSSI_FLT_ADDR ((uint8_t)0x17) + +#define RSSI_FLT_REGMASK ((uint8_t)0xF0) +#define CS_MODE_REGMASK ((uint8_t)0x0C) + + +/** + * \brief RSSI_TH register + * \code + * Read and Write + * Default value: 0x28 + * 7:0 RSSI_TH: Signal detect threshold in 0.5 dB steps, default -120 dBm corresponds to 0x28. + * \endcode + */ +#define RSSI_TH_ADDR ((uint8_t)0x18) + +#define RSSI_TH_REGMASK ((uint8_t)0xFF) + + +/** + * \brief ANT_SELECT_CONF register + * \code + * Read and Write + * Default value: 0x45 + * 7 RESERVED: - + * 6:5 EQU_CTRL: ISI cancellation equalizer:, 00: equalization disabled, 01: single pass equalization, 10: dual pass equalization. + * 4 CS_BLANKING: Do not fill the RX FIFO with data if the CS is above threhold. + * 3 AS_ENABLE: 1: enable the antenna switching. + * 2:0 AS_MEAS_TIME: Set the measurement time. + * \endcode + */ +#define ANT_SELECT_CONF_ADDR ((uint8_t)0x1F) + +#define EQU_CTRL_REGMASK ((uint8_t)0x60) +#define CS_BLANKING_REGMASK ((uint8_t)0x10) +#define AS_ENABLE_REGMASK ((uint8_t)0x08) +#define AS_MEAS_TIME_REGMASK ((uint8_t)0x07) + + +/** + * \brief CLOCKREC1 register + * \code + * Read and Write + * Default value: 0x00 + * 7:5 CLK_REC_P_GAIN_SLOW: Clock recovery slow loop gain (log2). + * 4 CLK_REC_ALGO_SEL: Select the symbol timing recovery algorithm: 0: DLL, 1: PLL. + * 3:0 CLK_REC_I_GAIN_SLOW: Set the integral slow gain for symbol timing recovery (PLL mode only). + * \endcode + */ +#define CLOCKREC1_ADDR ((uint8_t)0x20) + +#define CLK_REC_P_GAIN_SLOW_REGMASK ((uint8_t)0xE0) +#define CLK_REC_ALGO_SEL_REGMASK ((uint8_t)0x10) +#define CLK_REC_I_GAIN_SLOW_REGMASK ((uint8_t)0x0F) + + +/** + * \brief CLOCKREC0 register + * \code + * Read and Write + * Default value: 0x58 + * 7:5 CLK_REC_P_GAIN_FAST: Clock recovery fast loop gain (log2). + * 4 PSTFLT_LEN: Select the post filter length: 0: 8 symbols, 1: 16 symbols. + * 3:0 CLK_REC_I_GAIN_FAST: Set the integral fast gain for symbol timing recovery (PLL mode only).. + * \endcode + */ +#define CLOCKREC0_ADDR ((uint8_t)0x21) + +#define CLK_REC_P_GAIN_FAST_REGMASK ((uint8_t)0xE0) +#define PSTFLT_LEN_REGMASK ((uint8_t)0x10) +#define CLK_REC_I_GAIN_FAST_REGMASK ((uint8_t)0x0F) + + +/** + * \brief PCKTCTRL6 register + * \code + * Read and Write + * Default value: 0x80 + * 7:2 SYNC_LEN: The number of bits used for the SYNC field in the packet. + * 1:0 PREAMBLE_LEN_9_8: The MSB of the number of '01 or '10' of the preamble of the packet. + * \endcode + */ +#define PCKTCTRL6_ADDR ((uint8_t)0x2B) + +#define SYNC_LEN_REGMASK ((uint8_t)0xFC) +#define PREAMBLE_LEN_9_8_REGMASK ((uint8_t)0x03) + + +/** + * \brief PCKTCTRL5 register + * \code + * Read and Write + * Default value: 0x10 + * 7:0 PREAMBLE_LEN[7:0]: The LSB of the number of '01 or '10' of the preamble of the packet. + * \endcode + */ +#define PCKTCTRL5_ADDR ((uint8_t)0x2C) + +#define PREAMBLE_LEN_7_0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief PCKTCTRL4 register + * \code + * Read and Write + * Default value: 0x00 + * 7 LEN_WID: The number of bytes used for the length field: 0: 1 byte, 1: 2 bytes. + * 6:4 RESERVED: - + * 3 ADDRESS_LEN: 1: include the ADDRESS field in the packet. + * 2:0 RESERVED: - + * \endcode + */ +#define PCKTCTRL4_ADDR ((uint8_t)0x2D) + +#define LEN_WID_REGMASK ((uint8_t)0x80) +#define ADDRESS_LEN_REGMASK ((uint8_t)0x08) + + +/** + * \brief PCKTCTRL3 register + * \code + * Read and Write + * Default value: 0x20 + * 7:6 PCKT_FRMT: Format of packet:, 0: Basic, 2: WM-Bus, 3: STack + * 5:4 RX_MODE: RX mode:, 0: normal mode, 1: direct through FIFO, 2: direct through GPIO + * 3 FSK4_SYM_SWAP: Select the symbol mapping for 4(G)FSK. + * 2 BYTE_SWAP: Select the transmission order between MSB and LSB. + * 1:0 PREAMBLE_SEL: Select the preamble pattern between '10' and '01'. + * \endcode + */ +#define PCKTCTRL3_ADDR ((uint8_t)0x2E) + +#define PCKT_FRMT_REGMASK ((uint8_t)0xC0) +#define RX_MODE_REGMASK ((uint8_t)0x30) +#define FSK4_SYM_SWAP_REGMASK ((uint8_t)0x08) +#define BYTE_SWAP_REGMASK ((uint8_t)0x04) +#define PREAMBLE_SEL_REGMASK ((uint8_t)0x03) + + +/** + * \brief PCKTCTRL2 register + * \code + * Read and Write + * Default value: 0x00 + * 7:6 RESERVED: - + * 5 FCS_TYPE_4G: FCS type in header field of 802.15.4g packet. + * 4 FEC_TYPE_4G: Select the FEC type of 802.15.4g packet: 0: NRNSC. 1: RSC. + * 3 INT_EN_4G: 1: enable the interleaving of 802.15.4g packet. + * 2 MBUS_3OF6_EN: 1: enable the 3-out-of-6 encoding/decoding. + * 1 MANCHESTER_EN: 1: enable the Manchester encoding/decoding. + * 0 FIX_VAR_LEN: Packet length mode:, 0: fixed, 1: variable (in variable mode the field LEN_WID of PCKTCTRL3 register must be configured) + * \endcode + */ +#define PCKTCTRL2_ADDR ((uint8_t)0x2F) + +#define FCS_TYPE_4G_REGMASK ((uint8_t)0x20) +#define FEC_TYPE_4G_REGMASK ((uint8_t)0x10) +#define INT_EN_4G_REGMASK ((uint8_t)0x08) +#define MBUS_3OF6_EN_REGMASK ((uint8_t)0x04) +#define MANCHESTER_EN_REGMASK ((uint8_t)0x02) +#define FIX_VAR_LEN_REGMASK ((uint8_t)0x01) + + +/** + * \brief PCKTCTRL1 register + * \code + * Read and Write + * Default value: 0x2C + * 7:5 CRC_MODE: CRC field:, 0: no CRC field, 1: CRC using poly 0x07, 2: CRC using poly 0x8005, 3: CRC using poly 0x1021, 4: CRC using poly 0x864CBF + * 4 WHIT_EN: 1: enable the whitening mode. + * 3:2 TXSOURCE: Tx source data:, 0: normal mode, 1: direct through FIFO, 2: direct through GPIO, 3: PN9 + * 1 SECOND_SYNC_SEL: In TX mode: 0 select the primary SYNC word, 1 select the secondary SYNC word., In RX mode: enable the dual SYNC word detection mode. + * 0 FEC_EN: 1: enable the FEC encoding in TX or the Viterbi decoding in RX. + * \endcode + */ +#define PCKTCTRL1_ADDR ((uint8_t)0x30) + +#define CRC_MODE_REGMASK ((uint8_t)0xE0) +#define WHIT_EN_REGMASK ((uint8_t)0x10) +#define TXSOURCE_REGMASK ((uint8_t)0x0C) +#define SECOND_SYNC_SEL_REGMASK ((uint8_t)0x02) +#define FEC_EN_REGMASK ((uint8_t)0x01) + + +/** + * \brief PCKTLEN1 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 PCKTLEN1: MSB of length of packet in bytes. + * \endcode + */ +#define PCKTLEN1_ADDR ((uint8_t)0x31) + +#define PCKTLEN1_REGMASK ((uint8_t)0xFF) + + +/** + * \brief PCKTLEN0 register + * \code + * Read and Write + * Default value: 0x14 + * 7:0 PCKTLEN0: LSB of length of packet in bytes. + * \endcode + */ +#define PCKTLEN0_ADDR ((uint8_t)0x32) + +#define PCKTLEN0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief SYNC3 register + * \code + * Read and Write + * Default value: 0x88 + * 7:0 SYNC3: SYNC word byte 4. + * \endcode + */ +#define SYNC3_ADDR ((uint8_t)0x33) + +#define SYNC3_REGMASK ((uint8_t)0xFF) + + +/** + * \brief SYNC2 register + * \code + * Read and Write + * Default value: 0x88 + * 7:0 SYNC2: SYNC word byte 3. + * \endcode + */ +#define SYNC2_ADDR ((uint8_t)0x34) + +#define SYNC2_REGMASK ((uint8_t)0xFF) + + +/** + * \brief SYNC1 register + * \code + * Read and Write + * Default value: 0x88 + * 7:0 SYNC1: SYNC word byte 1. + * \endcode + */ +#define SYNC1_ADDR ((uint8_t)0x35) + +#define SYNC1_REGMASK ((uint8_t)0xFF) + + +/** + * \brief SYNC0 register + * \code + * Read and Write + * Default value: 0x88 + * 7:0 SYNC0: SYNC word byte 0. + * \endcode + */ +#define SYNC0_ADDR ((uint8_t)0x36) + +#define SYNC0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief QI register + * \code + * Read and Write + * Default value: 0x01 + * 7:5 SQI_TH: SQI threshold. + * 4:1 PQI_TH: PQI threshold. + * 0 SQI_EN: 1: enable the SQI check. + * \endcode + */ +#define QI_ADDR ((uint8_t)0x37) + +#define SQI_TH_REGMASK ((uint8_t)0xE0) +#define PQI_TH_REGMASK ((uint8_t)0x1E) +#define SQI_EN_REGMASK ((uint8_t)0x01) + + +/** + * \brief PCKT_PSTMBL register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 PCKT_PSTMBL: Set the packet postamble length. + * \endcode + */ +#define PCKT_PSTMBL_ADDR ((uint8_t)0x38) + +#define PCKT_PSTMBL_REGMASK ((uint8_t)0xFF) + + +/** + * \brief PROTOCOL2 register + * \code + * Read and Write + * Default value: 0x40 + * 7 CS_TIMEOUT_MASK: 1: enable the CS value contributes to timeout disabling. + * 6 SQI_TIMEOUT_MASK: 1: enable the SQI value contributes to timeout disabling. + * 5 PQI_TIMEOUT_MASK: 1: enable the PQI value contributes to timeout disabling. + * 4:3 TX_SEQ_NUM_RELOAD: TX sequence number to be used when counting reset is required using the related command. + * 2 FIFO_GPIO_OUT_MUX_SEL: 1: select the almost empty/full control for TX FIFO., 0: select the almost empty/full control for RX FIFO. + * 1:0 LDC_TIMER_MULT: Set the LDC timer multiplier factor: 00b: x1, 01b: x2, 10b: x4, 11b: x8. + * \endcode + */ +#define PROTOCOL2_ADDR ((uint8_t)0x39) + +#define CS_TIMEOUT_MASK_REGMASK ((uint8_t)0x80) +#define SQI_TIMEOUT_MASK_REGMASK ((uint8_t)0x40) +#define PQI_TIMEOUT_MASK_REGMASK ((uint8_t)0x20) +#define TX_SEQ_NUM_RELOAD_REGMASK ((uint8_t)0x18) +#define FIFO_GPIO_OUT_MUX_SEL_REGMASK ((uint8_t)0x04) +#define LDC_TIMER_MULT_REGMASK ((uint8_t)0x03) + + +/** + * \brief PROTOCOL1 register + * \code + * Read and Write + * Default value: 0x00 + * 7 LDC_MODE: 1: enable the Low Duty Cycle mode. + * 6 LDC_RELOAD_ON_SYNC: 1: enable the LDC timer reload mode. + * 5 PIGGYBACKING: 1: enable the piggybacking. + * 4 FAST_CS_TERM_EN: 1: enable the RX sniff timer. + * 3 SEED_RELOAD: 1: enable the reload of the back-off random generator seed using the value written in the BU_COUNTER_SEED. + * 2 CSMA_ON: 1 enable the CSMA channel access mode. + * 1 CSMA_PERS_ON: 1: enable the CSMA persistent mode (no backoff cycles). + * 0 AUTO_PCKT_FLT: 1: enable the automatic packet filtering control. + * \endcode + */ +#define PROTOCOL1_ADDR ((uint8_t)0x3A) + +#define LDC_MODE_REGMASK ((uint8_t)0x80) +#define LDC_RELOAD_ON_SYNC_REGMASK ((uint8_t)0x40) +#define PIGGYBACKING_REGMASK ((uint8_t)0x20) +#define FAST_CS_TERM_EN_REGMASK ((uint8_t)0x10) +#define SEED_RELOAD_REGMASK ((uint8_t)0x08) +#define CSMA_ON_REGMASK ((uint8_t)0x04) +#define CSMA_PERS_ON_REGMASK ((uint8_t)0x02) +#define AUTO_PCKT_FLT_REGMASK ((uint8_t)0x01) + + +/** + * \brief PROTOCOL0 register + * \code + * Read and Write + * Default value: 0x08 + * 7:4 NMAX_RETX: Max. number of re-TX (from 0 to 15)(0: re-transmission is not performed). + * 3 NACK_TX: 1: field NO_ACK=1 on transmitted packet. + * 2 AUTO_ACK: 1: enable the automatic acknowledgement if packet received request. + * 1 PERS_RX: 1: enable the persistent RX mode. + * 0 RESERVED: - + * \endcode + */ +#define PROTOCOL0_ADDR ((uint8_t)0x3B) + +#define NMAX_RETX_REGMASK ((uint8_t)0xF0) +#define NACK_TX_REGMASK ((uint8_t)0x08) +#define AUTO_ACK_REGMASK ((uint8_t)0x04) +#define PERS_RX_REGMASK ((uint8_t)0x02) + + +/** + * \brief FIFO_CONFIG3 register + * \code + * Read and Write + * Default value: 0x30 + * 7 RESERVED: - + * 6:0 RX_AFTHR: Set the RX FIFO almost full threshold. + * \endcode + */ +#define FIFO_CONFIG3_ADDR ((uint8_t)0x3C) + +#define RX_AFTHR_REGMASK ((uint8_t)0x7F) + + +/** + * \brief FIFO_CONFIG2 register + * \code + * Read and Write + * Default value: 0x30 + * 7 RESERVED: - + * 6:0 RX_AETHR: Set the RX FIFO almost empty threshold. + * \endcode + */ +#define FIFO_CONFIG2_ADDR ((uint8_t)0x3D) + +#define RX_AETHR_REGMASK ((uint8_t)0x7F) + + +/** + * \brief FIFO_CONFIG1 register + * \code + * Read and Write + * Default value: 0x30 + * 7 RESERVED: - + * 6:0 TX_AFTHR: Set the TX FIFO almost full threshold. + * \endcode + */ +#define FIFO_CONFIG1_ADDR ((uint8_t)0x3E) + +#define TX_AFTHR_REGMASK ((uint8_t)0x7F) + + +/** + * \brief FIFO_CONFIG0 register + * \code + * Read and Write + * Default value: 0x30 + * 7 RESERVED: - + * 6:0 TX_AETHR: Set the TX FIFO almost empty threshold. + * \endcode + */ +#define FIFO_CONFIG0_ADDR ((uint8_t)0x3F) + +#define TX_AETHR_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PCKT_FLT_OPTIONS register + * \code + * Read and Write + * Default value: 0x40 + * 7 RESERVED: - + * 6 RX_TIMEOUT_AND_OR_SEL: Logical boolean function applied to CS/SQI/PQI values: 1: OR, 0: AND. + * 5 RESERVED: - + * 4 SOURCE_ADDR_FLT: 1: RX packet accepted if its source field matches with RX_SOURCE_ADDR register + * 3 DEST_VS_BROADCAST_ADDR: 1: RX packet accepted if its source field matches with BROADCAST_ADDR register. + * 2 DEST_VS_MULTICAST_ADDR: 1: RX packet accepted if its destination address matches with MULTICAST_ADDR register. + * 1 DEST_VS_SOURCE_ADDR: 1: RX packet accepted if its destination address matches with RX_SOURCE_ADDR register. + * 0 CRC_FLT: 1: packet discarded if CRC is not valid. + * \endcode + */ +#define PCKT_FLT_OPTIONS_ADDR ((uint8_t)0x40) + +#define RX_TIMEOUT_AND_OR_SEL_REGMASK ((uint8_t)0x40) +#define SOURCE_ADDR_FLT_REGMASK ((uint8_t)0x10) +#define DEST_VS_BROADCAST_ADDR_REGMASK ((uint8_t)0x08) +#define DEST_VS_MULTICAST_ADDR_REGMASK ((uint8_t)0x04) +#define DEST_VS_SOURCE_ADDR_REGMASK ((uint8_t)0x02) +#define CRC_FLT_REGMASK ((uint8_t)0x01) + + +/** + * \brief PCKT_FLT_GOALS4 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 RX_SOURCE_MASK/DUAL_SYNC3: If dual sync mode enabled: dual SYNC word byte 3., Otherwise mask register for source affress filtering. + * \endcode + */ +#define PCKT_FLT_GOALS4_ADDR ((uint8_t)0x41) + +#define RX_SOURCE_MASK_DUAL_SYNC3_REGMASK ((uint8_t)0xFF) + + +/** + * \brief PCKT_FLT_GOALS3 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 RX_SOURCE_ADDR/DUAL_SYNC2: If dual sync mode enabled: dual SYNC word byte 2., Otherwise RX packet source or TX packet destination field. + * \endcode + */ +#define PCKT_FLT_GOALS3_ADDR ((uint8_t)0x42) + +#define RX_SOURCE_ADDR_DUAL_SYNC2_REGMASK ((uint8_t)0xFF) + + +/** + * \brief PCKT_FLT_GOALS2 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 BROADCAST_ADDR/DUAL_SYNC1: If dual sync mode enabled: dual SYNC word byte 1., Broadcast address. + * \endcode + */ +#define PCKT_FLT_GOALS2_ADDR ((uint8_t)0x43) + +#define BROADCAST_ADDR_DUAL_SYNC1_REGMASK ((uint8_t)0xFF) + + +/** + * \brief PCKT_FLT_GOALS1 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 MULTICAST_ADDR/DUAL_SYNC0: If dual sync mode enabled: dual SYNC word byte 0., Multicast address. + * \endcode + */ +#define PCKT_FLT_GOALS1_ADDR ((uint8_t)0x44) + +#define MULTICAST_ADDR_DUAL_SYNC0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief PCKT_FLT_GOALS0 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 TX_SOURCE_ADDR: Tx packet source or RX packet destination field. + * \endcode + */ +#define PCKT_FLT_GOALS0_ADDR ((uint8_t)0x45) + +#define TX_SOURCE_ADDR_REGMASK ((uint8_t)0xFF) + + +/** + * \brief TIMERS5 register + * \code + * Read and Write + * Default value: 0x01 + * 7:0 RX_TIMER_CNTR: Counter for RX timer. + * \endcode + */ +#define TIMERS5_ADDR ((uint8_t)0x46) + +#define RX_TIMER_CNTR_REGMASK ((uint8_t)0xFF) + + +/** + * \brief TIMERS4 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 RX_TIMER_PRESC: Prescaler for RX timer. + * \endcode + */ +#define TIMERS4_ADDR ((uint8_t)0x47) + +#define RX_TIMER_PRESC_REGMASK ((uint8_t)0xFF) + + +/** + * \brief TIMERS3 register + * \code + * Read and Write + * Default value: 0x01 + * 7:0 LDC_TIMER_PRESC: Prescaler for wake up timer. + * \endcode + */ +#define TIMERS3_ADDR ((uint8_t)0x48) + +#define LDC_TIMER_PRESC_REGMASK ((uint8_t)0xFF) + + +/** + * \brief TIMERS2 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 LDC_TIMER_CNTR: Counter for wake up timer. + * \endcode + */ +#define TIMERS2_ADDR ((uint8_t)0x49) + +#define LDC_TIMER_CNTR_REGMASK ((uint8_t)0xFF) + + +/** + * \brief TIMERS1 register + * \code + * Read and Write + * Default value: 0x01 + * 7:0 LDC_RELOAD_PRSC: Prescaler value for reload operation of wake up timer. + * \endcode + */ +#define TIMERS1_ADDR ((uint8_t)0x4A) + +#define LDC_RELOAD_PRSC_REGMASK ((uint8_t)0xFF) + + +/** + * \brief TIMERS0 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 LDC_RELOAD_CNTR: Counter value for reload operation of wake up timer. + * \endcode + */ +#define TIMERS0_ADDR ((uint8_t)0x4B) + +#define LDC_RELOAD_CNTR_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CSMA_CONF3 register + * \code + * Read and Write + * Default value: 0x4C + * 7:0 BU_CNTR_SEED[14:8]: MSB part of the seed for the random generator used to apply the CSMA algorithm. + * \endcode + */ +#define CSMA_CONF3_ADDR ((uint8_t)0x4C) + +#define BU_CNTR_SEED_14_8_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CSMA_CONF2 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 BU_CNTR_SEED[7:0]: LSB part of the seed for the random generator used to apply the CSMA algorithm. + * \endcode + */ +#define CSMA_CONF2_ADDR ((uint8_t)0x4D) + +#define BU_CNTR_SEED_7_0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CSMA_CONF1 register + * \code + * Read and Write + * Default value: 0x04 + * 7:2 BU_PRSC: Prescaler value for the back-off unit BU. + * 1:0 CCA_PERIOD: Multiplier for the Tcca timer. + * \endcode + */ +#define CSMA_CONF1_ADDR ((uint8_t)0x4E) + +#define BU_PRSC_REGMASK ((uint8_t)0xFC) +#define CCA_PERIOD_REGMASK ((uint8_t)0x03) + + +/** + * \brief CSMA_CONF0 register + * \code + * Read and Write + * Default value: 0x00 + * 7:4 CCA_LEN: The number of time in which the listen operation is performed. + * 3 RESERVED: - + * 2:0 NBACKOFF_MAX: Max number of back-off cycles. + * \endcode + */ +#define CSMA_CONF0_ADDR ((uint8_t)0x4F) + +#define CCA_LEN_REGMASK ((uint8_t)0xF0) +#define NBACKOFF_MAX_REGMASK ((uint8_t)0x07) + + +/** + * \brief IRQ_MASK3 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 INT_MASK[31:24]: Enable the routing of the interrupt flag on the configured IRQ GPIO. + * \endcode + */ +#define IRQ_MASK3_ADDR ((uint8_t)0x50) + +#define INT_MASK_31_24_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IRQ_MASK2 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 INT_MASK[23:16]: Enable the routing of the interrupt flag on the configured IRQ GPIO. + * \endcode + */ +#define IRQ_MASK2_ADDR ((uint8_t)0x51) + +#define INT_MASK_23_16_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IRQ_MASK1 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 INT_MASK[15:8]: Enable the routing of the interrupt flag on the configured IRQ GPIO. + * \endcode + */ +#define IRQ_MASK1_ADDR ((uint8_t)0x52) + +#define INT_MASK_15_8_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IRQ_MASK0 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 INT_MASK[7:0]: Enable the routing of the interrupt flag on the configured IRQ GPIO. + * \endcode + */ +#define IRQ_MASK0_ADDR ((uint8_t)0x53) + +#define INT_MASK_7_0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief FAST_RX_TIMER register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 RSSI_SETTLING_LIMIT[7:0]: RSSI settling limit word. This determines the duration of the + * FAST_RX_TERM timer. + * \endcode + */ +#define FAST_RX_TIMER_ADDR ((uint8_t)0x54) + +#define RSSI_SETTLING_LIMIT ((uint8_t)0xFF) + + +/** + * \brief PA_POWER8 register + * \code + * Read and Write + * Default value: 0x01 + * 7 RESERVED: - + * 6:0 PA_LEVEL8: Output power level for 8th slot. + * \endcode + */ +#define PA_POWER8_ADDR ((uint8_t)0x5A) + +#define PA_LEVEL8_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PA_POWER7 register + * \code + * Read and Write + * Default value: 0x0C + * 7 RESERVED: - + * 6:0 PA_LEVEL_7: Output power level for 7th slot. + * \endcode + */ +#define PA_POWER7_ADDR ((uint8_t)0x5B) + +#define PA_LEVEL_7_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PA_POWER6 register + * \code + * Read and Write + * Default value: 0x18 + * 7 RESERVED: - + * 6:0 PA_LEVEL_6: Output power level for 6th slot. + * \endcode + */ +#define PA_POWER6_ADDR ((uint8_t)0x5C) + +#define PA_LEVEL_6_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PA_POWER5 register + * \code + * Read and Write + * Default value: 0x24 + * 7 RESERVED: - + * 6:0 PA_LEVEL_5: Output power level for 5th slot. + * \endcode + */ +#define PA_POWER5_ADDR ((uint8_t)0x5D) + +#define PA_LEVEL_5_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PA_POWER4 register + * \code + * Read and Write + * Default value: 0x30 + * 7 RESERVED: - + * 6:0 PA_LEVEL_4: Output power level for 4th slot. + * \endcode + */ +#define PA_POWER4_ADDR ((uint8_t)0x5E) + +#define PA_LEVEL_4_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PA_POWER3 register + * \code + * Read and Write + * Default value: 0x48 + * 7 RESERVED: - + * 6:0 PA_LEVEL_3: Output power level for 3rd slot. + * \endcode + */ +#define PA_POWER3_ADDR ((uint8_t)0x5F) + +#define PA_LEVEL_3_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PA_POWER2 register + * \code + * Read and Write + * Default value: 0x60 + * 7 RESERVED: - + * 6:0 PA_LEVEL_2: Output power level for 2nd slot. + * \endcode + */ +#define PA_POWER2_ADDR ((uint8_t)0x60) + +#define PA_LEVEL_2_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PA_POWER1 register + * \code + * Read and Write + * Default value: 0x00 + * 7 RESERVED: - + * 6:0 PA_LEVEL_1: Output power level for 1st slot. + * \endcode + */ +#define PA_POWER1_ADDR ((uint8_t)0x61) + +#define PA_LEVEL_1_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PA_POWER0 register + * \code + * Read and Write + * Default value: 0x47 + * 7 DIG_SMOOTH_EN: 1: enable the generation of the internal signal TX_DATA which is the input of the FIR. + * 6 PA_MAXDBM: 1: configure the PA to send maximum output power. + * 5 PA_RAMP_EN: 1: enable the power ramping + * 4:3 PA_RAMP_STEP_LEN: Set the step width (unit: 1/8 of bit period). + * 2:0 PA_LEVEL_MAX_IDX: Final level for power ramping or selected output power index. + * \endcode + */ +#define PA_POWER0_ADDR ((uint8_t)0x62) + +#define DIG_SMOOTH_EN_REGMASK ((uint8_t)0x80) +#define PA_MAXDBM_REGMASK ((uint8_t)0x40) +#define PA_RAMP_EN_REGMASK ((uint8_t)0x20) +#define PA_RAMP_STEP_LEN_REGMASK ((uint8_t)0x18) +#define PA_LEVEL_MAX_IDX_REGMASK ((uint8_t)0x07) + + +/** + * \brief PA_CONFIG1 register + * \code + * Read and Write + * Default value: 0x03 + * 7:5 RESERVED: - + * 4 LIN_NLOG: 1: enable the linear-to-log conversion of the PA code output. + * 3:2 FIR_CFG: FIR configuration: 00b: filtering, 01b : ramping, 10b: switching. + * 1 FIR_EN: 1: enable FIR. + * 0 RESERVED: - + * \endcode + */ +#define PA_CONFIG1_ADDR ((uint8_t)0x63) + +#define LIN_NLOG_REGMASK ((uint8_t)0x10) +#define FIR_CFG_REGMASK ((uint8_t)0xC0) +#define FIR_EN_REGMASK ((uint8_t)0x02) + + +/** + * \brief SYNTH_CONFIG2 register + * \code + * Read and Write + * Default value: 0xD0 + * 7 RESERVED: - + * 6 RESERVED: - + * 5 RESERVED: - + * 4:3 RESERVED: - + * 2 PLL_PFD_SPLIT_EN: Enables increased DN current pulses to improve linearization of CP/PFD. + * 1:0 RESERVED: - + * \endcode + */ +#define SYNTH_CONFIG2_ADDR ((uint8_t)0x65) + +#define PLL_PFD_SPLIT_EN_REGMASK ((uint8_t)0x04) + + +/** + * \brief VCO_CONFIG register + * \code + * Read and Write + * Default value: 0x02 + * 7:6 RESERVED: - + * 5 VCO_CALAMP_EXT_SEL: 1 --> VCO amplitude calibration will be skipped (external amplitude word forced on VCO). + * 4 VCO_CALFREQ_EXT_SEL: 1 --> VCO frequency calibration will be skipped (external amplitude word forced on VCO). + * 3 RESERVED: - + * 2:0 RESERVED: - + * \endcode + */ +#define VCO_CONFIG_ADDR ((uint8_t)0x68) + +#define VCO_CALAMP_EXT_SEL_REGMASK ((uint8_t)0x20) +#define VCO_CALFREQ_EXT_SEL_REGMASK ((uint8_t)0x20) + + +/** + * \brief VCO_CALIBR_IN2 register + * \code + * Read and Write + * Default value: 0x88 + * 7:4 VCO_CALAMP_TX: VCO magnitude calibration word (binary coding to be internally converted in thermometric code) used in TX. + * 3:0 VCO_CALAMP_RX: VCO magnitude calibration word (binary coding to be internally converted in thermometric code) used in RX. + * \endcode + */ +#define VCO_CALIBR_IN2_ADDR ((uint8_t)0x69) + +#define VCO_CALAMP_TX_REGMASK ((uint8_t)0xF0) +#define VCO_CALAMP_RX_REGMASK ((uint8_t)0x0F) + + +/** + * \brief VCO_CALIBR_IN1 register + * \code + * Read and Write + * Default value: 0x40 + * 7 RESERVED: - + * 6:0 VCO_CALFREQ_TX: VCO Cbank frequency calibration word to be used in TX. + * \endcode + */ +#define VCO_CALIBR_IN1_ADDR ((uint8_t)0x6A) + +#define VCO_CALFREQ_TX_REGMASK ((uint8_t)0x7F) + + +/** + * \brief VCO_CALIBR_IN0 register + * \code + * Read and Write + * Default value: 0x40 + * 7 RESERVED: - + * 6:0 VCO_CALFREQ_RX: VCO Cbank frequency calibration word to be used in RX. + * \endcode + */ +#define VCO_CALIBR_IN0_ADDR ((uint8_t)0x6B) + +#define VCO_CALFREQ_RX_REGMASK ((uint8_t)0x7F) + + +/** + * \brief XO_RCO_CONF1 register + * \code + * Read and Write + * Default value: 0x6C + * 7:6 RESERVED: - + * 5 RESERVED: - + * 4 PD_CLKDIV: 1: disable both dividers of digital clock (and reference clockfor the SMPS) and IF-ADC clock. + * 3:2 RESERVED: - + * 1:0 RESERVED: - + * \endcode + */ +#define XO_RCO_CONF1_ADDR ((uint8_t)0x6C) + +#define PD_CLKDIV_REGMASK ((uint8_t)0x10) + + +/** + * \brief XO_RCO_CONF0 register + * \code + * Read and Write + * Default value: 0x30 + * 7 EXT_REF: 0: reference signal from XO circuit, 1: reference signal from XIN pin. + * 5:4 GM_CONF: Set the driver gm of the XO at start up. + * 3 REFDIV: 1: enable the the reference clock divider. + * 2 RESERVED: - + * 1 EXT_RCO_OSC: 1: the 34.7 kHz signal must be supplied from any GPIO. + * 0 RCO_CALIBRATION: 1: enable the automatic RCO calibration. + * \endcode + */ +#define XO_RCO_CONF0_ADDR ((uint8_t)0x6D) + +#define EXT_REF_REGMASK ((uint8_t)0x80) +#define GM_CONF_REGMASK ((uint8_t)0x70) +#define REFDIV_REGMASK ((uint8_t)0x08) +#define EXT_RCO_OSC_REGMASK ((uint8_t)0x02) +#define RCO_CALIBRATION_REGMASK ((uint8_t)0x01) + + +/** + * \brief RCO_CALIBR_CONF3 register + * \code + * Read and Write + * Default value: 0x70 + * 7:4 RWT_IN: RWT word value for the RCO. + * 3:0 RFB_IN_4_1: MSB part of RFB word value for RCO. + * \endcode + */ +#define RCO_CALIBR_CONF3_ADDR ((uint8_t)0x6E) + +#define RWT_IN_REGMASK ((uint8_t)0xF0) +#define RFB_IN_4_1_REGMASK ((uint8_t)0x0F) + + +/** + * \brief RCO_CALIBR_CONF2 register + * \code + * Read and Write + * Default value: 0x4D + * 7 RFB_IN[0]: LSB part of RFB word value for RCO. + * 6:4 RESERVED: - + * 6:4 RESERVED: - + * 3 RESERVED: - + * 2:0 RESERVED: - + * \endcode + */ +#define RCO_CALIBR_CONF2_ADDR ((uint8_t)0x6F) + +#define RFB_IN_0_REGMASK ((uint8_t)0x80) + + +/** + * \brief PM_CONF4 register + * \code + * Read and Write + * Default value: 0x17 + * 7 TEMP_SENSOR_EN: 1: enable the temperature sensor. + * 6 TEMP_SENS_BUFF_EN: 1: enable the output buffer for the temperature sensor. + * 5 EXT_SMPS: 1: disable the internal SMPS. + * 4 RESERVED: - + * 3 RESERVED: - + * 2 RESERVED: - + * 1:0 RESERVED: - + * \endcode + */ +#define PM_CONF4_ADDR ((uint8_t)0x75) + +#define TEMP_SENSOR_EN_REGMASK ((uint8_t)0x80) +#define TEMP_SENS_BUFF_EN_REGMASK ((uint8_t)0x40) +#define EXT_SMPS_REGMASK ((uint8_t)0x20) + + +/** + * \brief PM_CONF3 register + * \code + * Read and Write + * Default value: 0x20 + * 7 KRM_EN: 0: divider by 4 enabled (SMPS' switching frequency is FSW=FCLK/4), 1: rate multiplier enabled (SMPS' switching frequency is FSW=KRM*FOSC/(2^15). + * 6:0 KRM_14_8: Sets the divider ratio (MSB) of the rate multiplier (default: FSW=FCLK/4) + * \endcode + */ +#define PM_CONF3_ADDR ((uint8_t)0x76) + +#define KRM_EN_REGMASK ((uint8_t)0x80) +#define KRM_14_8_REGMASK ((uint8_t)0x7F) + + +/** + * \brief PM_CONF2 register + * \code + * Read and Write + * Default value: 0x00 + * 7:0 KRM[7:0]: Sets the divider ratio (LSB) of the rate multiplier (default: FSW=FCLK/4) + * \endcode + */ +#define PM_CONF2_ADDR ((uint8_t)0x77) + +#define KRM_7_0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief PM_CONF1 register + * \code + * Read and Write + * Default value: 0x39 + * 7 RESERVED: - + * 6 BATTERY_LVL_EN: 1: enable battery level detector circuit. + * 5:4 SET_BLD_TH: Set the BLD threshold: 00b: 2.7V, 01b: 2.5V, 10b: 2.3V, 00b: 2.1V. + * 3 RESERVED: - + * 2 RESERVED: - + * 1 RESERVED: - + * 0 RESERVED: - + * \endcode + */ +#define PM_CONF1_ADDR ((uint8_t)0x78) + +#define BATTERY_LVL_EN_REGMASK ((uint8_t)0x40) +#define SET_BLD_TH_REGMASK ((uint8_t)0x30) + + +/** + * \brief PM_CONF0 register + * \code + * Read and Write + * Default value: 0x42 + * 7 RESERVED: - + * 6:4 SET_SMPS_LVL: 000: SMPS output voltage 1.1 V, 001: SMPS output voltage 1.2 V, 010: SMPS output voltage 1.3 V, 011: SMPS output voltage 1.4 V, 100: SMPS output voltage 1.5 V, 101: SMPS output voltage 1.6 V, 110: SMPS output voltage 1.7 V, 111: SMPS output voltage 1.8 V. + * 3:2 RESERVED: - + * 1 RESERVED: - + * 0 SLEEP_MODE_SEL: 0: SLEEP without FIFO retention; 1: SLEEP with FIFO retention. + * \endcode + */ +#define PM_CONF0_ADDR ((uint8_t)0x79) + +#define SET_SMPS_LVL_REGMASK ((uint8_t)0x70) +#define SLEEP_MODE_SEL_REGMASK ((uint8_t)0x01) + + +/** + * \brief MC_STATE1 register + * \code + * Read only + * Default value: 0x52 + * 7:5 RESERVED: - + * 4 RCO_CAL_OK: RCO calibration succesfully terminated. + * 3 ANT_SEL: Currently selected antenna. + * 2 TX_FIFO_FULL: 1: TX FIFO is full. + * 1 RX_FIFO_EMPTY: 1: RX FIFO is empty. + * 0 ERROR_LOCK: 1: RCO calibrator error. + * \endcode + */ +#define MC_STATE1_ADDR ((uint8_t)0x8D) + +#define RCO_CAL_OK_REGMASK ((uint8_t)0x10) +#define ANT_SEL_REGMASK ((uint8_t)0x08) +#define TX_FIFO_FULL_REGMASK ((uint8_t)0x04) +#define RX_FIFO_EMPTY_REGMASK ((uint8_t)0x02) +#define ERROR_LOCK_REGMASK ((uint8_t)0x01) + + +/** + * \brief MC_STATE0 register + * \code + * Read only + * Default value: 0x07 + * 7:1 STATE: Current state. + * 0 XO_ON: 1: XO is operating. + * \endcode + */ +#define MC_STATE0_ADDR ((uint8_t)0x8E) + +#define STATE_REGMASK ((uint8_t)0xFE) +#define XO_ON_REGMASK ((uint8_t)0x01) + + +/** + * \brief TX_FIFO_STATUS register + * \code + * Read only + * Default value: 0x00 + * 7 RESERVED: - + * 6:0 NELEM_TXFIFO: Number of elements in TX FIFO. + * \endcode + */ +#define TX_FIFO_STATUS_ADDR ((uint8_t)0x8F) + +#define NELEM_TXFIFO_REGMASK ((uint8_t)0x7F) + + +/** + * \brief RX_FIFO_STATUS register + * \code + * Read only + * Default value: 0x00 + * 7 RESERVED: - + * 6:0 NELEM_RXFIFO: Number of elements in RX FIFO. + * \endcode + */ +#define RX_FIFO_STATUS_ADDR ((uint8_t)0x90) + +#define NELEM_RXFIFO_REGMASK ((uint8_t)0x7F) + + +/** + * \brief RCO_CALIBR_OUT4 register + * \code + * Read only + * Default value: 0x70 + * 7:4 RWT_OUT: RWT word from internal RCO calibrator. + * 3:0 RFB_OUT_4_1: RFT word (MSB) from internal RCO calibrator. + * \endcode + */ +#define RCO_CALIBR_OUT4_ADDR ((uint8_t)0x94) + +#define RWT_OUT_REGMASK ((uint8_t)0xF0) +#define RFB_OUT_4_1_REGMASK ((uint8_t)0x0F) + + +/** + * \brief RCO_CALIBR_OUT3 register + * \code + * Read only + * Default value: 0x00 + * 7 RFB_OUT[0]: RFT word (LSB) from internal RCO calibrator. + * 6:0 RESERVED: - + * \endcode + */ +#define RCO_CALIBR_OUT3_ADDR ((uint8_t)0x95) + +#define RFB_OUT_0_REGMASK ((uint8_t)0x80) + + +/** + * \brief VCO_CALIBR_OUT1 register + * \code + * Read only + * Default value: 0x00 + * 7:4 RESERVED: - + * 3:0 VCO_CAL_AMP_OUT: VCO magnitude calibration output word (binary coding internally converted from thermometric coding). + * \endcode + */ +#define VCO_CALIBR_OUT1_ADDR ((uint8_t)0x99) + +#define VCO_CAL_AMP_OUT_REGMASK ((uint8_t)0x0F) + + +/** + * \brief VCO_CALIBR_OUT0 register + * \code + * Read only + * Default value: 0x00 + * 7 RESERVED: - + * 6:0 VCO_CAL_FREQ_OUT: VCO Cbank frequency calibration output word (binary coding internally converted from thermometric coding). + * \endcode + */ +#define VCO_CALIBR_OUT0_ADDR ((uint8_t)0x9A) + +#define VCO_CAL_FREQ_OUT_REGMASK ((uint8_t)0x7F) + + +/** + * \brief TX_PCKT_INFO register + * \code + * Read only + * Default value: 0x00 + * 7:6 RESERVED: - + * 5:4 TX_SEQ_NUM: Current TX packet sequence number. + * 3:0 N_RETX: Number of re-transmissions done for the last TX packet. + * \endcode + */ +#define TX_PCKT_INFO_ADDR ((uint8_t)0x9C) + +#define TX_SEQ_NUM_REGMASK ((uint8_t)0x30) +#define N_RETX_REGMASK ((uint8_t)0x0F) + + +/** + * \brief RX_PCKT_INFO register + * \code + * Read only + * Default value: 0x00 + * 7:3 RESERVED: - + * 2 NACK_RX: NACK field of the received packet. + * 1:0 RX_SEQ_NUM: Sequence number of the received packet. + * \endcode + */ +#define RX_PCKT_INFO_ADDR ((uint8_t)0x9D) + +#define NACK_RX_REGMASK ((uint8_t)0x04) +#define RX_SEQ_NUM_REGMASK ((uint8_t)0x03) + + +/** + * \brief AFC_CORR register + * \code + * Read only + * Default value: 0x00 + * 7:0 AFC_CORR: AFC corrected value. + * \endcode + */ +#define AFC_CORR_ADDR ((uint8_t)0x9E) + +#define AFC_CORR_REGMASK ((uint8_t)0xFF) + + +/** + * \brief LINK_QUALIF2 register + * \code + * Read only + * Default value: 0x00 + * 7:0 PQI: PQI value of the received packet. + * \endcode + */ +#define LINK_QUALIF2_ADDR ((uint8_t)0x9F) + +#define PQI_REGMASK ((uint8_t)0xFF) + + +/** + * \brief LINK_QUALIF1 register + * \code + * Read only + * Default value: 0x00 + * 7 CS: Carrier Sense indication. + * 6:0 SQI: SQI value of the recived packet. + * \endcode + */ +#define LINK_QUALIF1_ADDR ((uint8_t)0xA0) + +#define CS_REGMASK ((uint8_t)0x80) +#define SQI_REGMASK ((uint8_t)0x7F) + + +/** + * \brief RSSI_LEVEL register + * \code + * Read only + * Default value: 0x00 + * 7:0 RSSI_LEVEL: RSSI level captured at the end of the SYNC word detection of the received packet. + * \endcode + */ +#define RSSI_LEVEL_ADDR ((uint8_t)0xA2) + +#define RSSI_LEVEL_REGMASK ((uint8_t)0xFF) + + +/** + * \brief RX_PCKT_LEN1 register + * \code + * Read only + * Default value: 0x00 + * 7:0 RX_PCKT_LEN[14:8]: MSB valueof the length of the packet received. + * \endcode + */ +#define RX_PCKT_LEN1_ADDR ((uint8_t)0xA4) + +#define RX_PCKT_LEN_14_8_REGMASK ((uint8_t)0xFF) + + +/** + * \brief RX_PCKT_LEN0 register + * \code + * Read only + * Default value: 0x00 + * 7:0 RX_PCKT_LEN[7:0]: LSB valueof the length of the packet received. + * \endcode + */ +#define RX_PCKT_LEN0_ADDR ((uint8_t)0xA5) + +#define RX_PCKT_LEN_7_0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CRC_FIELD3 register + * \code + * Read only + * Default value: 0x00 + * 7:0 CRC_FIELD3: CRC field 3 of the received packet. + * \endcode + */ +#define CRC_FIELD3_ADDR ((uint8_t)0xA6) + +#define CRC_FIELD3_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CRC_FIELD2 register + * \code + * Read only + * Default value: 0x00 + * 7:0 CRC_FIELD2: CRC field 2 of the received packet. + * \endcode + */ +#define CRC_FIELD2_ADDR ((uint8_t)0xA7) + +#define CRC_FIELD2_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CRC_FIELD1 register + * \code + * Read only + * Default value: 0x00 + * 7:0 CRC_FIELD1: CRC field 1 of the received packet. + * \endcode + */ +#define CRC_FIELD1_ADDR ((uint8_t)0xA8) + +#define CRC_FIELD1_REGMASK ((uint8_t)0xFF) + + +/** + * \brief CRC_FIELD0 register + * \code + * Read only + * Default value: 0x00 + * 7:0 CRC_FIELD0: CRC field 0 of the received packet. + * \endcode + */ +#define CRC_FIELD0_ADDR ((uint8_t)0xA9) + +#define CRC_FIELD0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief RX_ADDRE_FIELD1 register + * \code + * Read only + * Default value: 0x00 + * 7:0 RX_ADDRE_FIELD1: Source address field of the received packet. + * \endcode + */ +#define RX_ADDRE_FIELD1_ADDR ((uint8_t)0xAA) + +#define RX_ADDRE_FIELD1_REGMASK ((uint8_t)0xFF) + + +/** + * \brief RX_ADDRE_FIELD0 register + * \code + * Read only + * Default value: 0x00 + * 7:0 RX_ADDRE_FIELD0: Destination address field of the received packet. + * \endcode + */ +#define RX_ADDRE_FIELD0_ADDR ((uint8_t)0xAB) + +#define RX_ADDRE_FIELD0_REGMASK ((uint8_t)0xFF) + + +/** + * \brief RSSI_LEVEL_RUN register + * \code + * Read only + * Default value: 0x00 + * 7:0 RSSI_LEVEL_RUN: RSSI level of the received packet, which supports continuos fast SPI reading. + * \endcode + */ +#define RSSI_LEVEL_RUN_ADDR ((uint8_t)0xEF) + +#define RSSI_LEVEL_RUN_REGMASK ((uint8_t)0xFF) + + +/** + * \brief DEVICE_INFO1 register + * \code + * Read only + * Default value: 0x00 + * 7:0 PARTNUM: S2-LP part number + * \endcode + */ +#define DEVICE_INFO1_ADDR ((uint8_t)0xF0) + +#define PARTNUM_REGMASK ((uint8_t)0xFF) + + +/** + * \brief DEVICE_INFO0 register + * \code + * Read only + * Default value: 0x41 + * 7:0 RSSI_LEVEL: S2-LP version number + * \endcode + */ +#define DEVICE_INFO0_ADDR ((uint8_t)0xF1) + +#define RSSI_LEVEL_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IRQ_STATUS3 register + * \code + * Read only + * Default value: 0x00 + * 7:0 INT_LEVEL[31:24]: Interrupt status register 3 + * \endcode + */ +#define IRQ_STATUS3_ADDR ((uint8_t)0xFA) + +#define INT_LEVEL_31_24_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IRQ_STATUS2 register + * \code + * Read only + * Default value: 0x09 + * 7:0 INT_LEVEL[23:16]: Interrupt status register 2 + * \endcode + */ +#define IRQ_STATUS2_ADDR ((uint8_t)0xFB) + +#define INT_LEVEL_23_16_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IRQ_STATUS1 register + * \code + * Read only + * Default value: 0x05 + * 7:0 INT_LEVEL[15:8]: Interrupt status register 1 + * \endcode + */ +#define IRQ_STATUS1_ADDR ((uint8_t)0xFC) + +#define INT_LEVEL_15_8_REGMASK ((uint8_t)0xFF) + + +/** + * \brief IRQ_STATUS0 register + * \code + * Read only + * Default value: 0x00 + * 7:0 INT_LEVEL[7:0]: Interrupt status register 0 + * \endcode + */ +#define IRQ_STATUS0_ADDR ((uint8_t)0xFD) + +#define INT_LEVEL_7_0_REGMASK ((uint8_t)0xFF) + + +/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Timer.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Timer.h new file mode 100644 index 00000000..7b7995e3 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Timer.h @@ -0,0 +1,201 @@ +/** + * @file S2LP_Timer.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP Timers. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This module provides API to configure the S2-LP timing mechanisms. + * They allow the user to set the timer registers using raw values or + * compute them since the desired timer value is expressed in ms. + * Moreover the management of the S2-LP LDCR mode can be done using + * these API. + * + * Example: + * @code + * ... + * + * S2LPTimerSetRxTimeoutMs(50.0); + * S2LPTimerSetWakeUpTimerUs(150000); + * + * // IRQ configuration for RX_TIMEOUT and WAKEUP_TIMEOUT + * ... + * + * S2LPTimerLdcrMode(S_ENABLE); + * + * ... + * + * @endcode + * + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP1_TIMER_H +#define __S2LP1_TIMER_H + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Regs.h" +#include "S2LP_Types.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_Timer Timer + * @brief Configuration and management of S2LP Timers. + * @details See the file @ref S2LP_Timer.h for more details. + * @{ + */ + + +/** + * @defgroup Timer_Exported_Types Timer Exported Types + * @{ + */ + +/** + * @brief All the possible RX timeout stop conditions enumeration. + */ +typedef enum { + NO_TIMEOUT_STOP = 0x00, /*!< Timeout never stopped */ + PQI_ABOVE_THRESHOLD = 0x01, /*!< Timeout stopped on PQI above threshold */ + SQI_ABOVE_THRESHOLD = 0x02, /*!< Timeout stopped on SQI above threshold */ + SQI_AND_PQI_ABOVE_THRESHOLD = 0x03, /*!< Timeout stopped on both SQI and PQI above threshold */ + RSSI_ABOVE_THRESHOLD = 0x04, /*!< Timeout stopped on RSSI above threshold */ + RSSI_AND_PQI_ABOVE_THRESHOLD = 0x05, /*!< Timeout stopped on both RSSI and PQI above threshold */ + RSSI_AND_SQI_ABOVE_THRESHOLD = 0x06, /*!< Timeout stopped on both RSSI and SQI above threshold */ + ALL_ABOVE_THRESHOLD = 0x07, /*!< Timeout stopped only if RSSI, SQI and PQI are above threshold */ + TIMEOUT_ALWAYS_STOPPED = 0x08, /*!< Timeout always stopped (default) */ + SQI_OR_PQI_ABOVE_THRESHOLD = 0x0B, /*!< Timeout stopped if one between SQI or PQI are above threshold */ + RSSI_OR_PQI_ABOVE_THRESHOLD = 0x0D, /*!< Timeout stopped if one between RSSI or PQI are above threshold */ + RSSI_OR_SQI_ABOVE_THRESHOLD = 0x0E, /*!< Timeout stopped if one between RSSI or SQI are above threshold */ + ANY_ABOVE_THRESHOLD = 0x0F /*!< Timeout stopped if one among RSSI, SQI or SQI are above threshold */ +} RxTimeoutStopCondition; + + +/** + * @} + */ + + +/** + * @defgroup Timer_Exported_Constants Timer Exported Constants + * @{ + */ + + +/** + * @} + */ + + +/** + * @defgroup Timer_Exported_Macros Timer Exported Macros + * @{ + */ + +#define SET_INFINITE_RX_TIMEOUT() S2LPTimerSetRxTimerCounter(0) + +/** + * @} + */ + + +/** + * @defgroup Timer_Exported_Functions Timer Exported Functions + * @{ + */ + +void S2LPTimerSetRxTimerStopCondition(RxTimeoutStopCondition xStopCondition); + +void S2LPTimerLdcrMode(SFunctionalState xNewState); +void S2LPTimerLdcrAutoReload(SFunctionalState xNewState); +SFunctionalState S2LPTimerLdcrGetAutoReload(void); +void S2LpTimerFastRxTermTimer(SFunctionalState xNewState); +void S2LpSetTimerFastRxTermTimer(uint8_t fast_rx_word); +void S2LpSetTimerFastRxTermTimerUs(uint32_t fast_rx_us); + +void S2LPTimerLdcrMode(SFunctionalState xNewState); +void S2LPTimerLdcrAutoReload(SFunctionalState xNewState); +SFunctionalState S2LPTimerLdcrGetAutoReload(void); + +void S2LPTimerSetRxTimer(uint8_t cCounter , uint8_t cPrescaler); +void S2LPTimerSetRxTimerUs(uint32_t lDesiredUsec); +void S2LPTimerSetRxTimerCounter(uint8_t cCounter); +void S2LPTimerSetRxTimerPrescaler(uint8_t cPrescaler); +void S2LPTimerGetRxTimerUs(uint32_t* plTimeoutUsec, uint8_t* pcCounter , uint8_t* pcPrescaler); + +void S2LPTimerSetWakeUpTimer(uint8_t cCounter , uint8_t cPrescaler); +void S2LPTimerSetWakeUpTimerUs(uint32_t lDesiredUsec); +void S2LPTimerSetWakeUpTimerCounter(uint8_t cCounter); +void S2LPTimerSetWakeUpTimerPrescaler(uint8_t cPrescaler); +void S2LPTimerSetWakeUpTimerReloadUs(uint32_t lDesiredUsec); +void S2LPTimerGetWakeUpTimerUs(uint32_t* plWakeUpUsec, uint8_t* pcCounter, uint8_t* pcPrescaler, uint8_t* pcMulti); +void S2LPTimerSetWakeUpTimerReload(uint8_t cCounter , uint8_t cPrescaler, uint8_t cMulti); +void S2LPTimerSetWakeUpTimerReloadCounter(uint8_t cCounter); +void S2LPTimerSetWakeUpTimerReloadPrescaler(uint8_t cPrescaler); +void S2LPTimerGetWakeUpTimerReloadUs(uint32_t* plWakeUpReloadUsec, uint8_t* pcCounter, uint8_t* pcPrescaler, uint8_t* pcMulti); + +uint16_t S2LPTimerGetRcoFrequency(void); +void S2LPTimerCalibrationRco(SFunctionalState xCalibration); +void S2LPTimerSleepB(SFunctionalState en); +void S2LPTimerLdcIrqWa(SFunctionalState en); + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Timer_ex.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Timer_ex.h new file mode 100644 index 00000000..b6ca8fb5 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Timer_ex.h @@ -0,0 +1,118 @@ +/** + * @file S2LP_Timer_ex.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP Timers using floating point. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This module provides API to configure the S2-LP timing mechanisms using floating points. + * + * Example: + * @code + * ... + * + * S2LPTimerSetRxTimeoutMs(50.0); + * + * ... + * + * @endcode + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_TIMER_EX_H +#define __S2LP_TIMER_EX_H + + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Timer_ex.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_Timer_ex Timer Wrapper + * @brief Configuration and management of S2LP Timers using floating point. + * @details See the file @ref S2LP_Timer.h for more details. + * @{ + */ + + +/** + * @defgroup Timer_ex_Exported_Types Timer Wrapper Exported Types + * @{ + */ + + + + +/** + * @defgroup Timer_ex_Exported_Functions Timer Wrapper Exported Functions + * @{ + */ +void S2LPTimerSetRxTimerMs(float fDesiredMsec); +void S2LPTimerGetRxTimer(float* pfTimeoutMsec, uint8_t* pcCounter , uint8_t* pcPrescaler); +void S2LPTimerSetWakeUpTimerMs(float fDesiredMsec); +void S2LPTimerSetWakeUpTimerReloadMs(float fDesiredMsec); +void S2LPTimerGetWakeUpTimer(float* pfWakeUpMsec, uint8_t* pcCounter , uint8_t* pcPrescaler, uint8_t* pcMulti); +void S2LPTimerGetWakeUpTimerReload(float* pfWakeUpReloadMsec, uint8_t* pcCounter, uint8_t* pcPrescaler, uint8_t* pcMulti); +void S2LPTimerComputeWakeUpValues(float fDesiredMsec , uint8_t* pcCounter , uint8_t* pcPrescaler); + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2017 STMicroelectronics *****END OF FILE****/ + diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Types.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Types.h new file mode 100644 index 00000000..5d1c2230 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Types.h @@ -0,0 +1,236 @@ +/** + * @file S2LP_Types.h + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date April 12, 2017 + * @brief Header file for S2-LP types. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This module provide some types definitions which will be used in + * all the modules of this library. Here is defined also the global + * variable @ref g_xStatus which contains the status of S2-LP and + * is updated every time an SPI transaction occurs. + * + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __S2LP_GENERICTYPES_H +#define __S2LP_GENERICTYPES_H + + +/* Includes ------------------------------------------------------------------*/ + +/* Include all integer types definitions */ +#include +#include + + + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @defgroup S2LP_Types Types + * @brief Module for S2LP types definition. + * * @details See the file @ref S2LP_Types.h for more details. + * @{ + */ + +/** + * @defgroup Types_Exported_Types Types Exported Types + * @{ + */ + +/** + * @brief S2LP Functional state. Used to enable or disable a specific option. + */ +typedef enum { + S_DISABLE = 0, + S_ENABLE = !S_DISABLE +} SFunctionalState; + + +/** + * @brief S2LP Flag status. Used to control the state of a flag. + */ +typedef enum { + S_RESET = 0, + S_SET = !S_RESET +} SFlagStatus; + + +/** + * @brief boolean type enumeration. + */ +typedef enum { + S_FALSE = 0, + S_TRUE = !S_FALSE +} SBool; + + +/** + * @brief S2LP States enumeration. + */ +typedef enum { + MC_STATE_READY =0x00, /*!< READY */ + MC_STATE_SLEEP_NOFIFO =0x01, /*!< SLEEP NO FIFO RETENTION */ + MC_STATE_STANDBY =0x02, /*!< STANDBY */ + MC_STATE_SLEEP =0x03, /*!< SLEEP */ + MC_STATE_LOCKON =0x0C, /*!< LOCKON */ + MC_STATE_RX =0x30, /*!< RX */ + MC_STATE_LOCK_ST =0x14, /*!< LOCK_ST */ + MC_STATE_TX =0x5C, /*!< TX */ + MC_STATE_SYNTH_SETUP =0x50 /*!< SYNTH_SETUP */ +} S2LPState; + + +/** + * @brief S2LP Status. This definition represents the single field of the S2LP + * status returned on each SPI transaction, equal also to the MC_STATE registers. + * This field-oriented structure allows user to address in simple way the single + * field of the S2LP status. + * The user shall define a variable of S2LPStatus type to access on S2LP status fields. + * @note The fields order in the structure depends on used endianness (little or big + * endian). The actual definition is valid ONLY for LITTLE ENDIAN mode. Be sure to + * change opportunely the fields order when use a different endianness. + */ +typedef struct { + uint8_t XO_ON:1; /*!< XO is operating state */ + S2LPState MC_STATE: 7; /*!< The state of the Main Controller of S2LP @ref S2LPState */ + uint8_t ERROR_LOCK: 1; /*!< RCO calibration error */ + uint8_t RX_FIFO_EMPTY: 1; /*!< RX FIFO is empty */ + uint8_t TX_FIFO_FULL: 1; /*!< TX FIFO is full */ + uint8_t ANT_SELECT: 1; /*!< Currently selected antenna */ + uint8_t RCCAL_OK: 1; /*!< RCO successfully terminated */ + uint8_t : 3; /*!< This 3 bits field are reserved and equal to 2 */ +}S2LPStatus; + + +/** + * @} + */ + + +/** + * @defgroup Types_Exported_Constants Types Exported Constants + * @{ + */ + + +/** + * @} + */ + +/** + * @defgroup Types_Exported_Variables Types Exported Variables + * @{ + */ + +extern volatile S2LPStatus g_xStatus; + +/** + * @} + */ + +/** + * @defgroup Types_Exported_Macros Types Exported Macros + * @{ + */ + +#define IS_SFUNCTIONAL_STATE(STATE) (STATE == S_DISABLE || STATE == S_ENABLE) +#define IS_SFLAG_STATUS(STATUS) (STATUS == S_RESET || STATUS == S_SET) +#define IS_SBOOL(STATUS) (STATUS == S_FALSE || STATUS == S_TRUE) + +#define S_ABS(a) ((a)>0?(a):-(a)) + +/** + * @} + */ + + +/** + * @defgroup Types_Exported_Functions Types Exported Functions + * @{ + */ + +#ifdef S2LP_USE_FULL_ASSERT + /** + * @brief The s_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 s_assert_param(expr) ((expr) ? (void)0 : s_assert_failed((uint8_t *)__FILE__, __LINE__)) + void s_assert_failed(uint8_t* file, uint32_t line); +#elif S2LP_USE_VCOM_ASSERT + /** + * @brief The s_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 s_assert_param(expr) ((expr) ? (void)0 : s_assert_failed((uint8_t *)__FILE__, __LINE__,#expr)) + void s_assert_failed(uint8_t* file, uint32_t line, char* expression); +#else + #define s_assert_param(expr) {} +#endif + +/** + *@} + */ + +/** + * @} + */ + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Commands.c b/strf/s2lp/S2LP_Library/Src/S2LP_Commands.c new file mode 100644 index 00000000..3985ff95 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Commands.c @@ -0,0 +1,159 @@ +/** + * @file S2LP_Commands.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Management of S2-LP Commands. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Commands.h" +#include "MCU_Interface.h" + + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_Commands + * @{ + */ + + +/** + * @defgroup Commands_Private_TypesDefinitions Commands Private TypesDefinitions + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Commands_Private_Defines Commands Private Defines + * @{ + */ + +/** + *@} + */ + +/** + * @defgroup Commands_Private_Macros Commands Private Macros + * @{ + */ + +#define IS_S2LP_CMD(CMD) (CMD == CMD_TX || \ + CMD == CMD_RX || \ + CMD == CMD_READY || \ + CMD == CMD_STANDBY || \ + CMD == CMD_SLEEP || \ + CMD == CMD_LOCKRX || \ + CMD == CMD_LOCKTX || \ + CMD == CMD_SABORT || \ + CMD == CMD_LDC_RELOAD || \ + CMD == CMD_SEQUENCE_UPDATE || \ + CMD == CMD_SRES || \ + CMD == CMD_FLUSHRXFIFO || \ + CMD == CMD_FLUSHTXFIFO \ + ) + +/** + *@} + */ + + +/** + * @defgroup Commands_Private_Variables Commands Private Variables + * @{ + */ + +/** + *@} + */ + + + +/** + * @defgroup Commands_Private_FunctionPrototypes Commands Private Function Prototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Commands_Private_Functions Commands Private Functions + * @{ + */ + +/** + * @brief Send a specific command to S2LP. + * @param xCommandCode code of the command to send. + This parameter can be any value of @ref S2LPCmd. + * @retval None. + */ +void S2LPCmdStrobeCommand(S2LPCmd xCommandCode) +{ + /* Check the parameters */ + s_assert_param(IS_S2LP_CMD(xCommandCode)); + + g_xStatus = S2LPSpiCommandStrobes((uint8_t) xCommandCode); +} + + +/** + *@} + */ + + +/** + *@} + */ + + +/** + *@} + */ + + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Csma.c b/strf/s2lp/S2LP_Library/Src/S2LP_Csma.c new file mode 100644 index 00000000..61580366 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Csma.c @@ -0,0 +1,546 @@ +/** + * @file S2LP_Csma.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP CSMA. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Csma.h" +#include "MCU_Interface.h" + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_Csma + * @{ + */ + + +/** + * @defgroup Csma_Private_TypesDefinitions CSMA Private TypesDefinitions + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup Csma_Private_Defines CSMA Private Defines + * @{ + */ + +/** + *@} + */ + +/** + * @defgroup Csma_Private_Macros CSMA Private Macros + * @{ + */ +#define IS_CCA_PERIOD(PERIOD) (PERIOD == CSMA_PERIOD_64TBIT || \ + PERIOD == CSMA_PERIOD_128TBIT || \ + PERIOD == CSMA_PERIOD_256TBIT || \ + PERIOD == CSMA_PERIOD_512TBIT) + +#define IS_CSMA_LENGTH(LENGTH) (LENGTH < 16) + +#define IS_BU_COUNTER_SEED(SEED) (SEED!=0) +#define IS_BU_PRESCALER(PRESCALER) (PRESCALER<64) +#define IS_CMAX_NB(NB) (NB<8) + +/** + *@} + */ + + +/** + * @defgroup Csma_Private_Variables CSMA Private Variables + * @{ + */ + +/** + *@} + */ + + + +/** + * @defgroup Csma_Private_FunctionPrototypes CSMA Private FunctionPrototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Csma_Private_Functions CSMA Private Functions + * @{ + */ + + +/** + * @brief Initialize the S2LP CSMA according to the specified parameters in the SCsmaInit. + * @param pxCsmaInit Csma init structure. + * This parameter is a pointer to @ref SCsmaInit. + * @retval None. + */ +void S2LPCsmaInit(SCsmaInit* pxCsmaInit) +{ + uint8_t tmpBuffer[4]; + + /* Check the parameters */ + s_assert_param(IS_SFUNCTIONAL_STATE(pxCsmaInit->xCsmaPersistentMode)); + s_assert_param(IS_CCA_PERIOD(pxCsmaInit->xMultiplierTbit)); + s_assert_param(IS_CSMA_LENGTH(pxCsmaInit->xCcaLength)); + s_assert_param(IS_BU_COUNTER_SEED(pxCsmaInit->nBuCounterSeed)); + s_assert_param(IS_BU_PRESCALER(pxCsmaInit->cBuPrescaler)); + s_assert_param(IS_CMAX_NB(pxCsmaInit->cMaxNb)); + + /* CSMA BU counter seed (MSB) config */ + tmpBuffer[0] = (uint8_t)(pxCsmaInit->nBuCounterSeed >> 8); + + /* CSMA BU counter seed (LSB) config */ + tmpBuffer[1] = (uint8_t) pxCsmaInit->nBuCounterSeed; + + /* CSMA BU prescaler config and CCA period config */ + tmpBuffer[2] = (pxCsmaInit->cBuPrescaler << 2) | pxCsmaInit->xMultiplierTbit; + + /* CSMA CCA length config and max number of back-off */ + tmpBuffer[3] = (pxCsmaInit->xCcaLength<<4) | pxCsmaInit->cMaxNb; + + /* Reads the PROTOCOL1_BASE register value, to write the SEED_RELOAD and CSMA_PERS_ON fields */ + S2LPSpiWriteRegisters(CSMA_CONF3_ADDR, 4, tmpBuffer); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]); + + /* Writes the new value for persistent mode */ + if(pxCsmaInit->xCsmaPersistentMode==S_ENABLE) { + tmpBuffer[0] |= CSMA_PERS_ON_REGMASK; + } + else { + tmpBuffer[0] &= ~CSMA_PERS_ON_REGMASK; + } + + /* Writes PROTOCOL1_BASE register */ + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]); + + +} + + + /** + * @brief Return the fitted structure SCsmaInit starting from the registers values. + * @param pxCsmaInit Csma structure to be fitted. + * This parameter is a pointer to @ref SCsmaInit. + * @retval None. + */ +void S2LPCsmaGetInfo(SCsmaInit* pxSCsmaInit) +{ + uint8_t tmpBuffer[4]; + + /* Reads PROTOCOL1_BASE register */ + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]); + + /* Reads the persistent mode enable bit */ + pxSCsmaInit->xCsmaPersistentMode = (SFunctionalState)((tmpBuffer[0]&CSMA_PERS_ON_REGMASK) >> 1); + + /* Reads CSMA_CONFIGx_BASE registers */ + g_xStatus = S2LPSpiReadRegisters(CSMA_CONF3_ADDR, 4, tmpBuffer); + + /* Reads the bu counter seed */ + pxSCsmaInit->nBuCounterSeed = (((uint16_t)tmpBuffer[0]) << 8) | (uint16_t)tmpBuffer[1]; + + /* Reads the bu prescaler */ + pxSCsmaInit->cBuPrescaler = tmpBuffer[2]>>2; + + /* Reads the Cca period */ + pxSCsmaInit->xMultiplierTbit = (SCsmaPeriod)(tmpBuffer[2] & CCA_PERIOD_REGMASK); + + /* Reads the Cca length */ + pxSCsmaInit->xCcaLength = (tmpBuffer[3]&CCA_LEN_REGMASK)>>4; + + /* Reads the max number of back off */ + pxSCsmaInit->cMaxNb = tmpBuffer[3] & NBACKOFF_MAX_REGMASK; + +} + + +/** + * @brief Enable or Disables the CSMA. + * @param xNewState the state of the CSMA mode. + * This parameter can be: S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPCsma(SFunctionalState xNewState) +{ + uint8_t tmp, tmp2; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + + /* Set or reSet the CSMA enable bit */ + if(xNewState==S_ENABLE) + { + tmp |= CSMA_ON_REGMASK; + + S2LPSpiReadRegisters(PM_CONF0_ADDR, 1, &tmp2); + tmp2 |= SLEEP_MODE_SEL_REGMASK; + S2LPSpiWriteRegisters(PM_CONF0_ADDR, 1, &tmp2); + } + else + { + tmp &= ~CSMA_ON_REGMASK; + } + + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp); + +} + +/** + * @brief Gets the CSMA mode. Says if it is enabled or disabled. + * @param None. + * @retval SFunctionalState: CSMA mode. + */ +SFunctionalState S2LPCsmaGetCsma(void) +{ + uint8_t tmp; + + /* Reads the PROTOCOL1 register value */ + g_xStatus = S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + + /* Return if set or reset */ + if(tmp & CSMA_ON_REGMASK) { + return S_ENABLE; + } + else { + return S_DISABLE; + } + +} + +/** + * @brief Enables or Disables the persistent CSMA mode. + * @param xNewState the state of the persistent CSMA mode. + * This parameter can be: S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPCsmaPersistentMode(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + + /* Enables/disables the CSMA persistent mode */ + if(xNewState==S_ENABLE) { + tmp |= CSMA_PERS_ON_REGMASK; + } + else { + tmp &= ~CSMA_PERS_ON_REGMASK; + } + + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp); + +} + + +/** + * @brief Gets the persistent CSMA mode. + * @param None. + * @retval SFunctionalState: CSMA persistent mode. + */ +SFunctionalState S2LPCsmaGetPersistentMode(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + + if(tmp & CSMA_PERS_ON_REGMASK) { + return S_ENABLE; + } + else { + return S_DISABLE; + } + +} + + +/** + * @brief Enables or Disables the seed reload mode (if enabled it reloads the back-off generator seed using the value written in the BU_COUNTER_SEED register). + * @param xNewState the state of the seed reload mode. + * This parameter can be: S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPCsmaSeedReloadMode(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + + /* Enables/disables the seed reload mode */ + if(xNewState==S_ENABLE) { + tmp |= SEED_RELOAD_REGMASK; + } + else { + tmp &= ~SEED_RELOAD_REGMASK; + } + + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp); + +} + + +/** + * @brief Gets the seed reload mode. + * @param None. + * @retval SFunctionalState: CSMA seed reload mode. + */ +SFunctionalState S2LPCsmaGetSeedReloadMode(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + + /* Return if set or reset */ + if(tmp & SEED_RELOAD_REGMASK) { + return S_ENABLE; + } + else { + return S_DISABLE; + } +} + + +/** + * @brief Set the BU counter seed (BU_COUNTER_SEED register). The CSMA back off time is given by the formula: BO = rand(2^NB)*BU. + * @param nBuCounterSeed seed of the random number generator used to apply the BBE algorithm. + * This parameter is an uint16_t. + * @retval None. + */ +void S2LPCsmaSetBuCounterSeed(uint16_t nBuCounterSeed) +{ + uint8_t tmpBuffer[2]; + s_assert_param(IS_BU_COUNTER_SEED(nBuCounterSeed)); + + tmpBuffer[0] = (uint8_t)(nBuCounterSeed>>8); + tmpBuffer[1] = (uint8_t)nBuCounterSeed; + + g_xStatus = S2LPSpiWriteRegisters(CSMA_CONF3_ADDR, 2, tmpBuffer); + +} + +/** + * @brief Return the BU counter seed (BU_COUNTER_SEED register). + * @param None. + * @retval uint16_t Seed of the random number generator used to apply the BBE algorithm. + */ +uint16_t S2LPCsmaGetBuCounterSeed(void) +{ + uint8_t tmpBuffer[2]; + + g_xStatus = S2LPSpiReadRegisters(CSMA_CONF3_ADDR, 2, tmpBuffer); + + return ((((uint16_t)tmpBuffer[0])<<8) + (uint16_t)tmpBuffer[1]); +} + + +/** + * @brief Set the BU prescaler. The CSMA back off time is given by the formula: BO = rand(2^NB)*BU. + * @param cBuPrescaler used to program the back-off unit BU. + * This parameter is an uint8_t. + * @retval None. + */ +void S2LPCsmaSetBuPrescaler(uint8_t cBuPrescaler) +{ + uint8_t tmp; + s_assert_param(IS_BU_PRESCALER(cBuPrescaler)); + + S2LPSpiReadRegisters(CSMA_CONF1_ADDR, 1, &tmp); + + tmp &= ~BU_PRSC_REGMASK; + tmp |= (cBuPrescaler<<2); + + g_xStatus = S2LPSpiWriteRegisters(CSMA_CONF1_ADDR, 1, &tmp); +} + + +/** + * @brief Return the BU prescaler. + * @param None. + * @retval uint8_t Value back-off unit (BU). + */ +uint8_t S2LPCsmaGetBuPrescaler(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(CSMA_CONF1_ADDR, 1, &tmp); + + return (tmp >> 2); +} + + +/** + * @brief Set the CCA period. + * @param xMultiplierTbit value of CCA period to store. + * This parameter can be a value of @ref CcaPeriod. + * @retval None. + */ +void S2LPCsmaSetCcaPeriod(SCsmaPeriod xMultiplierTbit) +{ + uint8_t tmp; + s_assert_param(IS_CCA_PERIOD(xMultiplierTbit)); + + S2LPSpiReadRegisters(CSMA_CONF1_ADDR, 1, &tmp); + + tmp &= ~CCA_PERIOD_REGMASK; + tmp |= xMultiplierTbit; + + g_xStatus = S2LPSpiWriteRegisters(CSMA_CONF1_ADDR, 1, &tmp); + +} + + +/** + * @brief Return the CCA period. + * @param None. + * @retval CcaPeriod CCA period. + */ +uint8_t S2LPCsmaGetCcaPeriod(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(CSMA_CONF1_ADDR, 1, &tmp); + + return (SCsmaPeriod)(tmp & CCA_PERIOD_REGMASK); +} + + +/** + * @brief Set the CCA length. + * @param xCcaLength the CCA length (a value between 1 and 15 that multiplies the CCA period). + * This parameter can be any value of @ref CsmaLength. + * @retval None. + */ +void S2LPCsmaSetCcaLength(uint8_t xCcaLength) +{ + uint8_t tmp; + s_assert_param(IS_CSMA_LENGTH(xCcaLength)); + + S2LPSpiReadRegisters(CSMA_CONF0_ADDR, 1, &tmp); + + tmp &= ~CCA_LEN_REGMASK; + tmp |= xCcaLength; + + g_xStatus = S2LPSpiWriteRegisters(CSMA_CONF0_ADDR, 1, &tmp); + +} + + +/** + * @brief Return the CCA length. + * @param None. + * @retval uint8_t CCA length. + */ +uint8_t S2LPCsmaGetCcaLength(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(CSMA_CONF0_ADDR, 1, &tmp); + + return (tmp >> 4); +} + + +/** + * @brief Set the max number of back-off. If reached S2LP stops the transmission. + * @param cMaxNb the max number of back-off. + * This parameter is an uint8_t. + * @retval None. + */ +void S2LPCsmaSetMaxNumberBackoff(uint8_t cMaxNb) +{ + uint8_t tmp; + s_assert_param(IS_CMAX_NB(cMaxNb)); + + S2LPSpiReadRegisters(CSMA_CONF0_ADDR, 1, &tmp); + + tmp &= ~NBACKOFF_MAX_REGMASK; + tmp |= cMaxNb; + + g_xStatus = S2LPSpiWriteRegisters(CSMA_CONF0_ADDR, 1, &tmp); +} + +/** + * @brief Return the max number of back-off. + * @param None. + * @retval uint8_t Max number of back-off. + */ +uint8_t S2LPCsmaGetMaxNumberBackoff(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(CSMA_CONF0_ADDR, 1, &tmp); + + return (tmp & NBACKOFF_MAX_REGMASK); + +} + + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Fifo.c b/strf/s2lp/S2LP_Library/Src/S2LP_Fifo.c new file mode 100644 index 00000000..888a3020 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Fifo.c @@ -0,0 +1,338 @@ +/** + * @file S2LP_Fifo.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP Fifo. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Fifo.h" +#include "MCU_Interface.h" + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_Fifo + * @{ + */ + + +/** + * @defgroup Fifo_Private_TypesDefinitions FIFO Private Types Definitions + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Fifo_Private_Defines FIFO Private Defines + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Fifo_Private_Macros FIFO Private Macros + * @{ + */ +#define IS_FIFO_THR(VAL) (VAL<=128) + +/** + *@} + */ + + +/** + * @defgroup Fifo_Private_Variables FIFO Private Variables + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Fifo_Private_FunctionPrototypes FIFO Private Function Prototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Fifo_Private_Functions FIFO Private Functions + * @{ + */ + +/** + * @brief Return the number of elements in the Rx FIFO. + * @param None. + * @retval uint8_t Number of elements in the Rx FIFO. + */ +uint8_t S2LPFifoReadNumberBytesRxFifo(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(RX_FIFO_STATUS_ADDR, 1, &tmp); + return tmp; + +} + + +/** + * @brief Return the number of elements in the Tx FIFO. + * @param None. + * @retval uint8_t Number of elements in the Tx FIFO. + */ +uint8_t S2LPFifoReadNumberBytesTxFifo(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(TX_FIFO_STATUS_ADDR, 1, &tmp); + return tmp; + +} + + +/** + * @brief Set the almost full threshold for the Rx FIFO. When the number of elements in RX FIFO reaches this value an interrupt can be generated to the MCU. + * @note The almost full threshold is encountered from the top of the FIFO. For example, if it is set to 7 the almost + * full FIFO irq will be raised when the number of elements is equals to 128-7 = 121. + * @param cThrRxFifo almost full threshold. + * This parameter is an uint8_t. + * @retval None. + */ +void S2LPFifoSetAlmostFullThresholdRx(uint8_t cThrRxFifo) +{ + uint8_t tmp; + + s_assert_param(IS_FIFO_THR(cThrRxFifo)); + + S2LPSpiReadRegisters(FIFO_CONFIG3_ADDR, 1, &tmp); + + tmp &= ~RX_AFTHR_REGMASK; + tmp |= cThrRxFifo; + + g_xStatus = S2LPSpiWriteRegisters(FIFO_CONFIG3_ADDR, 1, &tmp); + +} + + +/** + * @brief Return the almost full threshold for RX FIFO. + * @note The almost full threshold is encountered from the top of the FIFO. For example, if it is 7 the almost + * full FIFO irq will be raised when the number of elements is equals to 128-7 = 121. + * @param None. + * @retval uint8_t Almost full threshold for Rx FIFO. + */ +uint8_t S2LPFifoGetAlmostFullThresholdRx(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(FIFO_CONFIG3_ADDR, 1, &tmp); + + return (tmp & RX_AFTHR_REGMASK); + +} + + +/** + * @brief Set the almost empty threshold for the Rx FIFO. When the number of elements in RX FIFO reaches this value an interrupt can be generated to the MCU. + * @param cThrRxFifo almost empty threshold. + * This parameter is an uint8_t. + * @retval None. + */ +void S2LPFifoSetAlmostEmptyThresholdRx(uint8_t cThrRxFifo) +{ + uint8_t tmp; + + s_assert_param(IS_FIFO_THR(cThrRxFifo)); + + S2LPSpiReadRegisters(FIFO_CONFIG2_ADDR, 1, &tmp); + + tmp &= ~RX_AETHR_REGMASK; + tmp |= cThrRxFifo; + + g_xStatus = S2LPSpiWriteRegisters(FIFO_CONFIG2_ADDR, 1, &tmp); + +} + + +/** + * @brief Return the almost empty threshold for Rx FIFO. + * @param None. + * @retval uint8_t Almost empty threshold for Rx FIFO. + */ +uint8_t S2LPFifoGetAlmostEmptyThresholdRx(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(FIFO_CONFIG2_ADDR, 1, &tmp); + + return (tmp & RX_AETHR_REGMASK); + +} + + +/** + * @brief Set the almost full threshold for the Tx FIFO. When the number of elements in TX FIFO reaches this value an interrupt can be generated to the MCU. + * @note The almost full threshold is encountered from the top of the FIFO. For example, if it is set to 7 the almost + * full FIFO irq will be raised when the number of elements is equals to 128-7 = 121. + * @param cThrTxFifo almost full threshold. + * This parameter is an uint8_t. + * @retval None. + */ +void S2LPFifoSetAlmostFullThresholdTx(uint8_t cThrTxFifo) +{ + uint8_t tmp; + + s_assert_param(IS_FIFO_THR(cThrTxFifo)); + + S2LPSpiReadRegisters(FIFO_CONFIG1_ADDR, 1, &tmp); + + tmp &= ~TX_AFTHR_REGMASK; + tmp |= cThrTxFifo; + + g_xStatus = S2LPSpiWriteRegisters(FIFO_CONFIG1_ADDR, 1, &tmp); + +} + + +/** + * @brief Return the almost full threshold for Tx FIFO. + * @note The almost full threshold is encountered from the top of the FIFO. For example, if it is set to 7 the almost + * full FIFO irq will be raised when the number of elements is equals to 128-7 = 121. + * @param None. + * @retval uint8_t Almost full threshold for Tx FIFO. + */ +uint8_t S2LPFifoGetAlmostFullThresholdTx(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(FIFO_CONFIG1_ADDR, 1, &tmp); + + return (tmp & TX_AFTHR_REGMASK); + +} + + +/** + * @brief Set the almost empty threshold for the Tx FIFO. When the number of elements in Tx FIFO reaches this value an interrupt can can be generated to the MCU. + * @param cThrTxFifo: almost empty threshold. + * This parameter is an uint8_t. + * @retval None. + */ +void S2LPFifoSetAlmostEmptyThresholdTx(uint8_t cThrTxFifo) +{ + uint8_t tmp; + + s_assert_param(IS_FIFO_THR(cThrTxFifo)); + + S2LPSpiReadRegisters(FIFO_CONFIG0_ADDR, 1, &tmp); + + /* Build the register value */ + tmp &= ~TX_AETHR_REGMASK; + tmp |= cThrTxFifo; + + /* Writes the Almost Empty threshold for Tx in the corresponding register */ + g_xStatus = S2LPSpiWriteRegisters(FIFO_CONFIG0_ADDR, 1, &tmp); + +} + + +/** + * @brief Return the almost empty threshold for Tx FIFO. + * @param None. + * @retval uint8_t Almost empty threshold for Tx FIFO. + */ +uint8_t S2LPFifoGetAlmostEmptyThresholdTx(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(FIFO_CONFIG0_ADDR, 1, &tmp); + + return (tmp & TX_AETHR_REGMASK); + +} + + +/** + * @brief Enable the Mux for the Rx FIFO IRQ. To be enabled when RX FIFO THRESHOLD is used. + * @param xNewState. + * @retval None. + */ +void S2LPFifoMuxRxFifoIrqEnable(SFunctionalState xNewState) +{ + /* default TX selection*/ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp); + + if(xNewState == S_ENABLE) { + tmp |= FIFO_GPIO_OUT_MUX_SEL_REGMASK; + } else { + tmp &= ~FIFO_GPIO_OUT_MUX_SEL_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL2_ADDR, 1, &tmp); +} + + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_General.c b/strf/s2lp/S2LP_Library/Src/S2LP_General.c new file mode 100644 index 00000000..9eb7c522 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_General.c @@ -0,0 +1,210 @@ +/** + * @file S2LP_General.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP General functionalities. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_General.h" +#include "MCU_Interface.h" + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_General + * @{ + */ + + +/** + * @defgroup General_Private_TypesDefinitions General Private Types Definitions + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup General_Private_Defines General Private Defines + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup General_Private_Macros General Private Macros + * @{ + */ + +#define IS_MODE_EXT(MODE) (MODE == MODE_EXT_XO || \ + MODE == MODE_EXT_XIN) +/** + *@} + */ + + +/** + * @defgroup General_Private_Variables General Private Variables + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup General_Private_FunctionPrototypes General Private Function Prototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup General_Private_Functions General Private Functions + * @{ + */ + + +/** + * @brief Set External Reference. + * @param xExtMode new state for the external reference. + * This parameter can be: MODE_EXT_XO or MODE_EXT_XIN. + * @retval None. + */ +void S2LPGeneralSetExtRef(ModeExtRef xExtMode) +{ + uint8_t tmp; + s_assert_param(IS_MODE_EXT(xExtMode)); + + S2LPSpiReadRegisters(XO_RCO_CONF0_ADDR, 1, &tmp); + if(xExtMode == MODE_EXT_XO) { + tmp &= ~EXT_REF_REGMASK; + } + else { + tmp |= EXT_REF_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(XO_RCO_CONF0_ADDR, 1, &tmp); + +} + + +/** + * @brief Return External Reference. + * @param None. + * @retval ModeExtRef Settled external reference. + * This parameter can be: MODE_EXT_XO or MODE_EXT_XIN. + */ +ModeExtRef S2LPGeneralGetExtRef(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(XO_RCO_CONF0_ADDR, 1, &tmp); + return (ModeExtRef)(tmp & EXT_REF_REGMASK); +} + + +/** + * @brief Return device part number. + * @param None. + * @retval Device part number. + */ +uint8_t S2LPGeneralGetDevicePN(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(DEVICE_INFO1_ADDR, 1, &tmp); + return tmp; +} + +/** + * @brief Return S2LP version. + * @param None. + * @retval S2LP version. + */ +uint8_t S2LPGeneralGetVersion(void) +{ + uint8_t tmp; + S2LPSpiReadRegisters(DEVICE_INFO0_ADDR, 1, &tmp); + return tmp; +} + + +/** +* @brief Disable or enable the internal SMPS. +* @param xNewState if this value is S_DISABLE the external SMPS is enabled and a vlotage must be provided from outside. +* In this case the internal SMPS will be disabled. +* @retval None. +*/ +void S2LPRadioSetExternalSmpsMode(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PM_CONF4_ADDR, 1, &tmp); + + if(xNewState == S_ENABLE) { + tmp |= EXT_SMPS_REGMASK; + } else { + tmp &= ~EXT_SMPS_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PM_CONF4_ADDR, 1, &tmp); +} + +/** + *@} + */ + + +/** + *@} + */ + + +/** + *@} + */ + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c b/strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c new file mode 100644 index 00000000..7fd74593 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c @@ -0,0 +1,472 @@ +/** + * @file S2LP_Gpio.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief This file provides all the low level API to manage S2-LP GPIO. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ * + */ + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Gpio.h" +#include "MCU_Interface.h" + + +/** @addtogroup S2LP_Libraries + * @{ + */ + + +/** @addtogroup S2LP_Gpio + * @{ + */ + + + + +/** @defgroup Gpio_Private_Macros GPIO Private Macros + * @{ + */ + + +#define IS_S2LP_GPIO(PIN) ((PIN == S2LP_GPIO_0) || \ + (PIN == S2LP_GPIO_1) || \ + (PIN == S2LP_GPIO_2) || \ + (PIN == S2LP_GPIO_3)) + + +#define IS_S2LP_GPIO_MODE(MODE) ((MODE == S2LP_GPIO_MODE_DIGITAL_INPUT) || \ + (MODE == S2LP_GPIO_MODE_DIGITAL_OUTPUT_LP) || \ + (MODE == S2LP_GPIO_MODE_DIGITAL_OUTPUT_HP)) + +#define IS_S2LP_GPIO_IO(IO_SEL) ((IO_SEL == S2LP_GPIO_DIG_OUT_IRQ) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_POR_INV) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_WUT_EXP) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_LBD) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_TX_DATA) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_TX_STATE) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_TXRX_FIFO_ALMOST_EMPTY) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_TXRX_FIFO_ALMOST_FULL) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_RX_DATA) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_RX_CLOCK) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_RX_STATE) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_NOT_STANDBY_SLEEP) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_STANDBY) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_ANTENNA_SWITCH) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_VALID_PREAMBLE) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_SYNC_DETECTED) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_RSSI_THRESHOLD) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_MCU_CLOCK) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_TX_RX_MODE) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_VDD) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_GND) || \ + (IO_SEL == S2LP_GPIO_DIG_OUT_SMPS_EXT) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_SLEEP) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_READY) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_LOCK) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_WAIT_FOR_LOCK_SIG) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_TX_DATA_OOK_SIGNAL) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_WAIT_FOR_READY2_SIG) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_PM_SET) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_WAIT_VCO_CALIBRATION) ||\ + (IO_SEL == S2LP_GPIO_DIG_OUT_ENABLE_SYNTH_FULL_CIRCUIT) ||\ + (IO_SEL == S2LP_GPIO_DIG_IN_TX_COMMAND) ||\ + (IO_SEL == S2LP_GPIO_DIG_IN_RX_COMMAND) ||\ + (IO_SEL == S2LP_GPIO_DIG_IN_TX_DATA_INPUT_FOR_DIRECTRF) ||\ + (IO_SEL == S2LP_GPIO_DIG_IN_DATA_WAKEUP) ||\ + (IO_SEL == S2LP_GPIO_DIG_IN_EXT_CLOCK_AT_34_7KHZ)) + + +#define IS_S2LP_GPIO_LEVEL(LEVEL) ((LEVEL == LOW) || \ + (LEVEL == HIGH)) + +#define IS_S2LP_CLOCK_OUTPUT_XO(RATIO) ((RATIO == XO_RATIO_1) || \ + (RATIO == XO_RATIO_1_2) || \ + (RATIO == XO_RATIO_1_4) || \ + (RATIO == XO_RATIO_1_8) || \ + (RATIO == XO_RATIO_1_16) || \ + (RATIO == XO_RATIO_1_32) || \ + (RATIO == XO_RATIO_1_64) || \ + (RATIO == XO_RATIO_1_128) || \ + (RATIO == XO_RATIO_1_256)) + +#define IS_S2LP_CLOCK_OUTPUT_RCO(RATIO) ((RATIO == RCO_RATIO_1) || \ + (RATIO == RCO_RATIO_1_128)) + + +#define IS_S2LP_CLOCK_OUTPUT_EXTRA_CYCLES(CYCLES) ((CYCLES == EXTRA_CLOCK_CYCLES_0) || \ + (CYCLES == EXTRA_CLOCK_CYCLES_128) || \ + (CYCLES == EXTRA_CLOCK_CYCLES_256) || \ + (CYCLES == EXTRA_CLOCK_CYCLES_512)) + + +#define IS_S2LP_IRQ_LIST(VALUE) ((VALUE == RX_DATA_READY) || \ + (VALUE == RX_DATA_DISC) || \ + (VALUE == TX_DATA_SENT) || \ + (VALUE == MAX_RE_TX_REACH) || \ + (VALUE == CRC_ERROR) || \ + (VALUE == TX_FIFO_ERROR) || \ + (VALUE == RX_FIFO_ERROR) || \ + (VALUE == TX_FIFO_ALMOST_FULL) || \ + (VALUE == TX_FIFO_ALMOST_EMPTY) || \ + (VALUE == RX_FIFO_ALMOST_FULL) || \ + (VALUE == RX_FIFO_ALMOST_EMPTY) || \ + (VALUE == MAX_BO_CCA_REACH) || \ + (VALUE == VALID_PREAMBLE) || \ + (VALUE == VALID_SYNC) || \ + (VALUE == RSSI_ABOVE_TH) || \ + (VALUE == WKUP_TOUT_LDC) || \ + (VALUE == READY) || \ + (VALUE == STANDBY_DELAYED) || \ + (VALUE == LOW_BATT_LVL) || \ + (VALUE == POR) || \ + (VALUE == BOR) || \ + (VALUE == LOCK) || \ + (VALUE == VCO_CALIBRATION_END) || \ + (VALUE == PA_CALIBRATION_END) || \ + (VALUE == PM_COUNT_EXPIRED) || \ + (VALUE == XO_COUNT_EXPIRED) || \ + (VALUE == TX_START_TIME) || \ + (VALUE == RX_START_TIME) || \ + (VALUE == RX_TIMEOUT) || \ + (VALUE == RX_SNIFF_TIMEOUT) || \ + (VALUE == ALL_IRQ )) + + + +/** + * @} + */ + + + +/** @defgroup Gpio_Private_Functions GPIO Private Functions + * @{ + */ + +/** + * @brief Initialize the S2LP GPIOx according to the specified + * parameters in the pxGpioInitStruct. + * @param pxGpioInitStruct pointer to a SGpioInit structure that + * contains the configuration information for the specified S2LP GPIO. + * @retval None. + */ +void S2LPGpioInit(SGpioInit* pxGpioInitStruct) +{ + uint8_t tmp; + + s_assert_param(IS_S2LP_GPIO(pxGpioInitStruct->xS2LPGpioPin)); + s_assert_param(IS_S2LP_GPIO_MODE(pxGpioInitStruct->xS2LPGpioMode)); + s_assert_param(IS_S2LP_GPIO_IO(pxGpioInitStruct->xS2LPGpioIO)); + + tmp = ((uint8_t)(pxGpioInitStruct->xS2LPGpioMode) | (uint8_t)(pxGpioInitStruct->xS2LPGpioIO)); + g_xStatus = S2LPSpiWriteRegisters(pxGpioInitStruct->xS2LPGpioPin, 1, &tmp); + +} + + + +/** + * @brief Force S2LP GPIO_x configured as digital output, to VDD or GND. + * @param xGpioX Specifies the GPIO to be configured. + * This parameter can be one of following parameters: + * @arg S2LP_GPIO_0: S2LP GPIO_0 + * @arg S2LP_GPIO_1: S2LP GPIO_1 + * @arg S2LP_GPIO_2: S2LP GPIO_2 + * @arg S2LP_GPIO_3: S2LP GPIO_3 + * @param xLevel Specifies the level. + * This parameter can be: HIGH or LOW. + * @retval None. + */ +void S2LPGpioSetLevel(S2LPGpioPin xGpioX, OutputLevel xLevel) +{ + uint8_t tmp; + + s_assert_param(IS_S2LP_GPIO(xGpioX)); + s_assert_param(IS_S2LP_GPIO_LEVEL(xLevel)); + + /* Sets the value of the S2LP GPIO register according to the specified level */ + if(xLevel == HIGH) { + tmp = (uint8_t)S2LP_GPIO_DIG_OUT_VDD | (uint8_t)S2LP_GPIO_MODE_DIGITAL_OUTPUT_HP; + } + else { + tmp = (uint8_t)S2LP_GPIO_DIG_OUT_GND | (uint8_t)S2LP_GPIO_MODE_DIGITAL_OUTPUT_HP; + } + + g_xStatus = S2LPSpiWriteRegisters(xGpioX, 1, &tmp); + +} + + +/** + * @brief Return output value (VDD or GND) of S2LP GPIO_x, when it is configured as digital output. + * @param xGpioX Specifies the GPIO to be read. + * This parameter can be one of following parameters: + * @arg S2LP_GPIO_0: S2LP GPIO_0 + * @arg S2LP_GPIO_1: S2LP GPIO_1 + * @arg S2LP_GPIO_2: S2LP GPIO_2 + * @arg S2LP_GPIO_3: S2LP GPIO_3 + * @retval OutputLevel Logical level of selected GPIO configured as digital output. + * This parameter can be: HIGH or LOW. + */ +OutputLevel S2LPGpioGetLevel(S2LPGpioPin xGpioX) +{ + uint8_t tmp = 0x00; + + s_assert_param(IS_S2LP_GPIO(xGpioX)); + + g_xStatus = S2LPSpiReadRegisters(xGpioX, 1, &tmp); + + /* Mask the GPIO_SELECT field and returns the value according */ + tmp &= GPIO_SELECT_REGMASK; + if(tmp == S2LP_GPIO_DIG_OUT_VDD) { + return HIGH; + } + else { + return LOW; + } + +} + + +/** + * @brief Deinit the S2LPIrqs structure setting all the bitfield to 0. + * Moreover, it sets the IRQ mask registers to 0x00000000, disabling all IRQs. + * @param pxIrqInit pointer to a variable of type @ref S2LPIrqs, in which all the + * bitfields will be settled to zero. + * @retval None. + */ +void S2LPGpioIrqDeInit(S2LPIrqs* pxIrqInit) +{ + uint8_t tmp[4] = {0x00,0x00,0x00,0x00}; + + if(pxIrqInit!=NULL) { + uint32_t tempValue = 0x00000000; + + *pxIrqInit = (*(S2LPIrqs*)&tempValue); + } + + g_xStatus = S2LPSpiWriteRegisters(IRQ_MASK3_ADDR, 4, tmp); +} + + +/** + * @brief Enable the IRQs according to the user defined pxIrqInit structure. + * @param pxIrqInit pointer to a variable of type @ref S2LPIrqs, through which the + * user enable specific IRQs. This parameter is a pointer to a S2LPIrqs. + * For example suppose to enable only the two IRQ Low Battery Level and Tx Data Sent: + * @code + * S2LPIrqs myIrqInit = {0}; + * myIrqInit.IRQ_LOW_BATT_LVL = 1; + * myIrqInit.IRQ_TX_DATA_SENT = 1; + * S2LPGpioIrqInit(&myIrqInit); + * @endcode + * @retval None. + */ +void S2LPGpioIrqInit(S2LPIrqs* pxIrqInit) +{ + uint8_t tmp[4]; + uint8_t* tmpPoint; + + tmpPoint = (uint8_t*)(pxIrqInit); + for(int i=0; i<4; i++) { + tmp[3-i]= tmpPoint[i]; + } + + g_xStatus = S2LPSpiWriteRegisters(IRQ_MASK3_ADDR, 4, tmp); + +} + + +/** + * @brief Enable or disables a specific IRQ. + * @param xIrq IRQ to enable or disable. + * This parameter can be any value of @ref IrqList. + * @param xNewState new state for the IRQ. + * This parameter can be: S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPGpioIrqConfig(IrqList xIrq, SFunctionalState xNewState) +{ + uint8_t tmpBuffer[4]; + uint32_t tempValue = 0; + + s_assert_param(IS_S2LP_IRQ_LIST(xIrq)); + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(IRQ_MASK3_ADDR, 4, tmpBuffer); + + /* Build the IRQ mask word */ + for(int i=0; i<4; i++) { + tempValue += ((uint32_t)tmpBuffer[i])<<(8*(3-i)); + } + + /* Rebuild the new mask according to user request */ + if(xNewState == S_DISABLE) { + tempValue &= (~xIrq); + } + else { + tempValue |= (xIrq); + } + + /* Build the array of bytes to write in the IRQ_MASK registers */ + for(int j=0; j<4; j++) { + tmpBuffer[j] = (uint8_t)(tempValue>>(8*(3-j))); + } + + g_xStatus = S2LPSpiWriteRegisters(IRQ_MASK3_ADDR, 4, tmpBuffer); + +} + + +/** + * @brief Fill a pointer to a structure of S2LPIrqs type reading the IRQ_MASK registers. + * @param pxIrqMask pointer to a variable of type @ref S2LPIrqs, through which the + * user can read which IRQs are enabled. All the bitfields equals to zero correspond + * to enabled IRQs, while all the bitfields equals to one correspond to disabled IRQs. + * This parameter is a pointer to a S2LPIrqs. + * For example suppose that the Power On Reset and RX Data ready are the only enabled IRQs. + * @code + * S2LPIrqs myIrqMask; + * S2LPIrqGetStatus(&myIrqMask); + * @endcode + * Then + * myIrqMask.IRQ_POR and myIrqMask.IRQ_RX_DATA_READY are equal to 0 + * while all the other bitfields are equal to one. + * @retval None. + */ +void S2LPGpioIrqGetMask(S2LPIrqs* pxIrqMask) +{ + uint8_t tmp[4]; + uint8_t* pIrqPointer = (uint8_t*)pxIrqMask; + + g_xStatus = S2LPSpiReadRegisters(IRQ_MASK3_ADDR, 4, tmp); + + for(char i=0; i<4; i++) { + *pIrqPointer = tmp[3-i]; + pIrqPointer++; + } + +} + + +/** + * @brief Fill a pointer to a structure of S2LPIrqs type reading the IRQ_STATUS registers. + * @param pxIrqStatus pointer to a variable of type @ref S2LPIrqs, through which the + * user can read the status of all the IRQs. All the bitfields equals to one correspond + * to the raised interrupts. This parameter is a pointer to a S2LPIrqs. + * For example suppose that the XO settling timeout is raised as well as the Sync word + * detection. + * @code + * S2LPIrqs myIrqStatus; + * S2LPGpioIrqGetStatus(&myIrqStatus); + * @endcode + * Then + * myIrqStatus.IRQ_XO_COUNT_EXPIRED and myIrqStatus.IRQ_VALID_SYNC are equals to 1 + * while all the other bitfields are equals to zero. + * @retval None. + */ +void S2LPGpioIrqGetStatus(S2LPIrqs* pxIrqStatus) +{ + uint8_t tmp[4]; + uint8_t* pIrqPointer = (uint8_t*)pxIrqStatus; + + g_xStatus = S2LPSpiReadRegisters(IRQ_STATUS3_ADDR, 4, tmp); + + /* Build the IRQ Status word */ + for(uint8_t i=0; i<4; i++) { + *pIrqPointer = tmp[3-i]; + pIrqPointer++; + } +} + + +/** + * @brief Clear the IRQ status registers. + * @param None. + * @retval None. + */ +void S2LPGpioIrqClearStatus(void) +{ + uint8_t tmp[4]; + g_xStatus = S2LPSpiReadRegisters(IRQ_STATUS3_ADDR, 4, tmp); + +} + + +/** + * @brief Verifie if a specific IRQ has been generated. + * The call resets all the IRQ status, so it can't be used in case of multiple raising interrupts. + * @param xFlag IRQ flag to be checked. + * This parameter can be any value of @ref IrqList. + * @retval SBool S_TRUE or S_FALSE. + */ +SBool S2LPGpioIrqCheckFlag(IrqList xFlag) +{ + uint8_t tmp[4]; + uint32_t tempValue = 0; + SBool flag; + + s_assert_param(IS_S2LP_IRQ_LIST(xFlag)); + + g_xStatus = S2LPSpiReadRegisters(IRQ_STATUS3_ADDR, 4, tmp); + for(uint8_t i=0; i<4; i++) { + tempValue += ((uint32_t)tmp[i])<<(8*(3-i)); + } + + if(tempValue & xFlag) { + flag = S_TRUE; + } + else { + flag = S_FALSE; + } + + return flag; + +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c b/strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c new file mode 100644 index 00000000..0e783716 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c @@ -0,0 +1,891 @@ +/** + * @file S2LP_PacketHandler.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of the common features of S2-LP packets. + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_PacketHandler.h" +#include "MCU_Interface.h" +#include "S2LP_PktWMbus.h" + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_PktCommon + * @{ + */ + + +/** + * @defgroup PktCommon_Private_TypesDefinitions Pkt Common Private Types Definitions + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup PktCommon_Private_Defines Pkt Common Private Defines + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup PktCommon_Private_Macros Pkt Common Private Macros + * @{ + */ + + +#define IS_DIRECT_TX(MODE) (((MODE) == NORMAL_TX_MODE) || \ + ((MODE) == DIRECT_TX_FIFO_MODE) || \ + ((MODE) == DIRECT_TX_GPIO_MODE) || \ + ((MODE) == PN9_TX_MODE)) + +#define IS_DIRECT_RX(MODE) (((MODE) == NORMAL_RX_MODE) || \ + ((MODE) == DIRECT_RX_FIFO_MODE) || \ + ((MODE) == DIRECT_RX_GPIO_MODE)) + + +#define IS_PKT_SEQ_NUMBER_RELOAD(SEQN) (SEQN<=3) + +/** + *@} + */ + + +/** + * @defgroup PktCommon_Private_Variables Pkt Common Private Variables + * @{ + */ + +/** + *@} + */ + + + +/** + * @defgroup PktCommon_Private_FunctionPrototypes Pkt Common Private Function Prototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup PktCommon_Private_Functions Pkt Common Private Functions + * @{ + */ + + +/** + * @brief Get the packet format. + * @param None. + * @retval Packet format code. + */ +uint8_t S2LPGetPacketFormat(void) +{ + uint8_t tmp; + + /* Reads the PCKTCTRL2 register value */ + g_xStatus = S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp); + + tmp &= PCKT_FRMT_REGMASK; + tmp >>= 6; + + /* wmbus or basic */ + if(tmp==0x00) { + if(S2LPPktWMbusGetSubmode() != WMBUS_SUBMODE_NOT_CONFIGURED) { + tmp = 4; // wmbus + } + } + return tmp; +} + + +/** + * @brief Set the PREAMBLE field Length mode for S2LP packets. + * @param xPreambleLength length of PREAMBLE field in bits. + * @retval None. + */ +void S2LPSetPreambleLength(uint16_t cPreambleLength) +{ + uint8_t tmpBuffer[2]; + + s_assert_param(IS_PREAMBLE_LEN(cPreambleLength)); + + S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 1, &tmpBuffer[0]); + + /* Set the preamble length */ + tmpBuffer[0] &= ~PREAMBLE_LEN_9_8_REGMASK; + tmpBuffer[0] |= (cPreambleLength>>8) & PREAMBLE_LEN_9_8_REGMASK; + tmpBuffer[1] = cPreambleLength & PREAMBLE_LEN_7_0_REGMASK; + + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL6_ADDR, 2, tmpBuffer); + +} + + +/** + * @brief Return the PREAMBLE field Length mode for S2LP packets. + * @param None. + * @retval uint8_t Preamble field length in bits. + */ +uint16_t S2LPGetPreambleLength(void) +{ + uint8_t tmpBuffer[2]; + + /* Reads the PCKTCTRL2 register value */ + g_xStatus = S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 2, tmpBuffer); + + /* Rebuild and return value */ + return ( ((((uint16_t)tmpBuffer[0])&PREAMBLE_LEN_9_8_REGMASK)<<8) | ((uint16_t)tmpBuffer[1]) + 1); + +} + + +/** + * @brief Set the SYNC field Length for S2LP packets. + * @param xSyncLength length of SYNC field in bits. + * @retval None. + */ +void S2LPSetSyncLength(uint8_t cSyncLength) +{ + uint8_t tmp; + + s_assert_param(IS_SYNC_LEN(cSyncLength)); + + S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 1, &tmp); + + tmp &= ~SYNC_LEN_REGMASK; + tmp |= (cSyncLength<<2); + + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL6_ADDR, 1, &tmp); + +} + + +/** + * @brief Return the SYNC field Length for S2LP packets. + * @param None. + * @retval uint8_t Sync field length in bits. + */ +uint8_t S2LPGetSyncLength(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 1, &tmp); + return (((tmp & SYNC_LEN_REGMASK)>>2) ); + +} + + +/** + * @brief Enable or Disable WHITENING for S2LP packets. + * @param xNewState new state for WHITENING mode. + * This parameter can be S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPPacketHandlerWhitening(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= WHIT_EN_REGMASK; + } + else { + tmp &= ~WHIT_EN_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL1_ADDR, 1, &tmp); + +} + + +/** +* @brief Enable or Disable the FEC encoding. +* @param xNewState enable (S_ENABLED) or disable (S_DISABLE). +* @retval None. +*/ +void S2LPPacketHandlerFec(SFunctionalState xNewState) +{ + uint8_t tmp; + + S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= FEC_EN_REGMASK; + } + else { + tmp &= ~FEC_EN_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL1_ADDR, 1, &tmp); + +} + + +/** +* @brief Enable or Disable the MANCHESTER encoding. +* @param xNewState enable (S_ENABLED) or disable (S_DISABLE). +* @retval None. +*/ +void S2LPPacketHandlerManchester(SFunctionalState xNewState) +{ + uint8_t tmp; + + S2LPSpiReadRegisters(PCKTCTRL2_ADDR, 1, &tmp); + + tmp &= ~MANCHESTER_EN_REGMASK; + tmp |= (((uint8_t)xNewState)<<1); + + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL2_ADDR, 1, &tmp); + +} + + +/** +* @brief Enable or Disable the 3o6 encoding. +* @param xNewState enable (S_ENABLED) or disable (S_DISABLE). +* @retval None. +*/ +void S2LPPacketHandler3OutOf6(SFunctionalState xNewState) +{ + uint8_t tmp; + + S2LPSpiReadRegisters(PCKTCTRL2_ADDR, 1, &tmp); + + tmp &= ~MBUS_3OF6_EN_REGMASK; + tmp |= (((uint8_t)xNewState)<<2); + + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL2_ADDR, 1, &tmp); + +} + + +/** +* @brief Set the SYNC_WORD. +* @param lSyncWords SYNC_WORD given a 32 bits aligned word. +* @param SyncLength length of the sync word in bits. +* @retval None. +*/ +void S2LPSetSyncWords(uint32_t lSyncWords, uint8_t cSyncLength) +{ + uint8_t tmpBuffer[4], tmp; + + /* Split the 32-bit value in 4 8-bit values */ + for(uint8_t i=0 ; i<4 ; i++) { + tmpBuffer[i]=(uint8_t)(lSyncWords>>(8*i)); + } + + S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 1, &tmp); + + tmp &= ~SYNC_LEN_REGMASK; + tmp |= (cSyncLength<<2); + + S2LPSpiWriteRegisters(PCKTCTRL6_ADDR, 1, &tmp); + + /* Writes the new value on the PCKTCTRL2 register */ + g_xStatus = S2LPSpiWriteRegisters(SYNC3_ADDR, 4, tmpBuffer); + +} + + +/** +* @brief Get the SYNC_WORD. +* @param lSyncWords pointer to the SYNC_WORD 32bit variable where the SYNC word that is set should be stored. +* @param cSyncLength pointer to the uint8_t variable where sync length should be stored. +* @retval None. +*/ +void S2LPGetSyncWords(uint32_t* lSyncWords, uint8_t* cSyncLength) +{ + uint8_t tmpBuffer[4], tmp; + + /* Reads the PCKTCTRL2 register value */ + S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 1, &tmp); + + tmp &= SYNC_LEN_REGMASK; + tmp >>= 2; + *cSyncLength = tmp; + + g_xStatus = S2LPSpiReadRegisters(SYNC3_ADDR, 4, tmpBuffer); + *lSyncWords = ((uint32_t)tmpBuffer[0]<<24) | ((uint32_t)tmpBuffer[1]<<16) | ((uint32_t)tmpBuffer[2]<<8) | ((uint32_t)tmpBuffer[3]); + +} + + +/** + * @brief Enable or Disable the filtering on CRC. + * @param xNewState new state for CRC_CHECK. + * This parameter can be S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPPktCommonFilterOnCrc(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= CRC_FLT_REGMASK; + } + else { + tmp &= ~CRC_FLT_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmp); + +} + + + +/** +* @brief Get the received destination address. +* @param None. +* @retval uint8_t the last received destination address. +*/ +uint8_t S2LPGetReceivedDestinationAddress(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(RX_ADDRE_FIELD0_ADDR, 1, &tmp); + return tmp; +} + + +/** +* @brief Get the received source address. +* @param None. +* @retval uint8_t the last received source address. +*/ +uint8_t S2LPGetReceivedSourceAddress(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(RX_ADDRE_FIELD1_ADDR, 1, &tmp); + return tmp; +} + + +/** +* @brief Get the MY_ADDRESS set on the chip. +* @param None. +* @retval uint8_t MY_ADDRESS set. +*/ +uint8_t S2LPGetMyAddress(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_GOALS0_ADDR, 1, &tmp); + return tmp; +} + + +/** +* @brief Get the BROADCAST_ADDRESS set on the chip. +* @param None. +* @retval uint8_t BROADCAST_ADDRESS set. +*/ +uint8_t S2LPGetBroadcastAddress(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_GOALS2_ADDR, 1, &tmp); + return tmp; +} + + +/** +* @brief Get the MULTICAST_ADDRESS set on the chip. +* @param None. +* @retval uint8_t MULTICAST_ADDRESS set. +*/ +uint8_t S2LPGetMulticastAddress(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_GOALS1_ADDR, 1, &tmp); + return tmp; +} + + +/** +* @brief Get the SOURCE_MASK set on the chip. +* @param None. +* @retval uint8_t SOURCE_MASK set. +*/ +uint8_t S2LPGetRxSourceMask(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_GOALS4_ADDR, 1, &tmp); + return tmp; +} + + +/** +* @brief Get the SOURCE_REFERENCE set on the chip. +* @param None. +* @retval uint8_t SOURCE_REFERENCE set. +*/ +uint8_t S2LPGetRxSourceReferenceAddress(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_GOALS3_ADDR, 1, &tmp); + return tmp; +} + + + +/** +* @brief Set the SOURCE_MASK . +* @param mask Source mask to be set . +* @retval None. +*/ +void S2LPSetRxSourceMask(uint8_t mask) +{ + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS4_ADDR, 1, &mask); +} + + +/** +* @brief Set the SOURCE_REFERENCEK. +* @param address Source address to be used as a reference . +* @retval None. +*/ +void S2LPSetRxSourceReferenceAddress(uint8_t address) +{ + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS3_ADDR, 1, &address); +} + + +/** +* @brief Set the BROADCAST_ADDRESS set on the chip. +* @param address BROADCAST_ADDRESS to be set. +* @retval None. +*/ +void S2LPSetBroadcastAddress(uint8_t address) +{ + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS2_ADDR, 1, &address); +} + + +/** +* @brief Set the MULTICAST_ADDRESS set on the chip. +* @param address MULTICAST_ADDRESS to be set. +* @retval None. +*/ +void S2LPSetMulticastAddress(uint8_t address) +{ + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS1_ADDR, 1, &address); +} + + + +/** +* @brief Set the MY_ADDRESS (source address that will be transmitted). +* @param address MY_ADDRESS to be set. +* @retval None. +*/ +void S2LPSetMyAddress(uint8_t address) +{ + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS0_ADDR, 1, &address); +} + + + + +/** + * @brief Set the DirectRF RX mode of S2LP. + * @param xDirectRx code of the desired mode. + * This parameter can be any value of @ref DirectRx. + * @retval None. + */ +void S2LPPacketHandlerSetRxMode(DirectRx xDirectRx) +{ + uint8_t tmp; + s_assert_param(IS_DIRECT_RX(xDirectRx)); + + S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp); + tmp &= ~RX_MODE_REGMASK; + tmp |= (uint8_t)xDirectRx; + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL3_ADDR, 1, &tmp); + +} + + +/** + * @brief Return the DirectRF RX mode of S2LP. + * @param None. + * @retval DirectRx Direct Rx mode. + */ +DirectRx S2LPPacketHandlerGetRxMode(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp); + return (DirectRx)(tmp & RX_MODE_REGMASK); + +} + + +/** + * @brief Set the TX mode of S2LP. + * @param xDirectTx code of the desired source. + * This parameter can be any value of @ref DirectTx. + * @retval None. + */ +void S2LPPacketHandlerSetTxMode(DirectTx xDirectTx) +{ + uint8_t tmp; + s_assert_param(IS_DIRECT_TX(xDirectTx)); + + S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + tmp &= ~TXSOURCE_REGMASK; + tmp |= (uint8_t)xDirectTx; + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL1_ADDR, 1, &tmp); +} + + +/** + * @brief Return the DirectRF TX mode of S2LP. + * @param None. + * @retval DirectTx Direct Tx mode. + */ +DirectTx S2LPPacketHandlerGetTxMode(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + return (DirectTx)(tmp & TXSOURCE_REGMASK); +} + +/** + * @brief Returns the sequence number of the transmitted packet. + * @param None. + * @retval uint8_t Sequence number of the transmitted packet. + */ +uint8_t S2LPPacketHandlerGetTransmittedSeqNumber(void) +{ + uint8_t tempRegValue; + + /* Reads the TX_PCKT_INFO register value */ + g_xStatus = S2LPSpiReadRegisters(TX_PCKT_INFO_ADDR, 1, &tempRegValue); + + /* Obtains and returns the TX sequence number */ + return (tempRegValue >> 4) & 0x07; + +} + +/** + * @brief Set the extended length field in case of variable length. + * @param xExtendedLenField enable (S_ENABLE) or disable (S_DISABLE). + * @retval None. + */ +void S2LPPacketHandlerSetExtendedLenField(SFunctionalState xExtendedLenField) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xExtendedLenField)); + + S2LPSpiReadRegisters(PCKTCTRL4_ADDR, 1, &tmp); + if(xExtendedLenField == S_ENABLE) { + tmp |= LEN_WID_REGMASK; + } + else { + tmp &= ~LEN_WID_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL4_ADDR, 1, &tmp); +} + + +/** + * @brief Swap the 4FSK symbol mapping. + * @param xSwapSymbol enable (S_ENABLE) or disable (S_DISABLE). + * @retval None. + */ +void S2LPPacketHandlerSwap4FSKSymbol(SFunctionalState xSwapSymbol) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xSwapSymbol)); + + S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp); + if(xSwapSymbol == S_ENABLE) { + tmp |= FSK4_SYM_SWAP_REGMASK; + } + else { + tmp &= ~FSK4_SYM_SWAP_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL3_ADDR, 1, &tmp); +} + +/** + * @brief Change the FIFO endianness . + * @param xEnableSwap if it is S_DISABLE the FIFO will be accessed in big endian mode. + * if it is S_ENABLE the FIFO will be accessed in little endian mode. + * @retval None. + */ +void S2LPPacketHandlerSwapFifoEndianess(SFunctionalState xEnableSwap) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xEnableSwap)); + + S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp); + if(xEnableSwap == S_ENABLE) { + tmp |= BYTE_SWAP_REGMASK; + } + else { + tmp &= ~BYTE_SWAP_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL3_ADDR, 1, &tmp); +} + +/** + * @brief Swap preamble pattern. + * @param xEnableSwap if it is S_DISABLE the preamble pattern will be 10101010. + * if it is S_ENABLE the preamble pattern will be 01010101. + * @retval None. + */ +void S2LPPacketHandlerSwapPreamblePattern(SFunctionalState xEnableSwap) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xEnableSwap)); + + S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp); + tmp&=0xFC; + + if(xEnableSwap == S_DISABLE) { + tmp |= 0x01; + } + + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL3_ADDR, 1, &tmp); +} + + + +/** +* @brief Set the variable length mode. +* @param xVarLen if enabled (S_ENABLE) the length field will be set into the packet. +* @retval None. +*/ +void S2LPPacketHandlerSetVariableLength(SFunctionalState xVarLen) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xVarLen)); + + S2LPSpiReadRegisters(PCKTCTRL2_ADDR, 1, &tmp); + if(xVarLen == S_ENABLE) { + tmp |= FIX_VAR_LEN_REGMASK; + } + else { + tmp &= ~FIX_VAR_LEN_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL2_ADDR, 1, &tmp); +} + + +/** +* @brief Set the CRC mode. +* @param xPktCrcMode This parameter can be one among the @ref PktCrcMode . +* @retval None. +*/ +void S2LPPacketHandlerSetCrcMode(PktCrcMode xPktCrcMode) +{ + uint8_t tmp; + s_assert_param(IS_PKT_CRC_MODE(xPktCrcMode)); + + S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + tmp &= ~CRC_MODE_REGMASK; + tmp |= (uint8_t)xPktCrcMode; + S2LPSpiWriteRegisters(PCKTCTRL1_ADDR, 1, &tmp); + +} + + +/** +* @brief Get the CRC mode. +* @param None. +* @retval PktCrcMode CRC mode in the @ref PktCrcMode enum. +*/ +PktCrcMode S2LPPacketHandlerGetCrcMode(void) +{ + uint8_t tmp; + S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + tmp &= ~CRC_MODE_REGMASK; + return (PktCrcMode)tmp; +} + + + +/** +* @brief Select the secondary sync mode. +* In TX if enabled: it will send the secondary sync word (from the PCKT_FLT_GOALSx), +* otherwise it will send the primary sync (from the SYNCx registers). +* In RX if enabled: it will enable the double sync mode seeking for the 2 sync words in SYNCx or PCKT_FLT_GOALSx in parallel. +* @param xSecondarySync can be S_ENABLE or S_DISABLE. +* @retval None. +*/ +void S2LPPacketHandlerSelectSecondarySync(SFunctionalState xSecondarySync) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xSecondarySync)); + + S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + if(xSecondarySync == S_ENABLE) { + tmp |= SECOND_SYNC_SEL_REGMASK; + } + else { + tmp &= ~SECOND_SYNC_SEL_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL1_ADDR, 1, &tmp); + +} + + +/** +* @brief Enable or Disable the auto packet filter mechanisms. +* @note This must be enabled for any filtering. +* @param xNewState enable(S_ENABLE) or disable (S_DISABLE). +* @retval None. +*/ +void S2LPPacketHandlerSetAutoPcktFilter(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= AUTO_PCKT_FLT_REGMASK; + } + else { + tmp &= ~AUTO_PCKT_FLT_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp); +} + + + +/** +* @brief Set the RX persistent mode. The device will be ever in RX unles an abort command comes. +* @param xNewState enable(S_ENABLE) or disable (S_DISABLE). +* @retval None. +*/ +void S2LPPacketHandlerSetRxPersistentMode(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL0_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= PERS_RX_REGMASK; + } + else { + tmp &= ~PERS_RX_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL0_ADDR, 1, &tmp); +} + + +/** +* @brief Set the source address filtering. +* @param xNewState enable(S_ENABLE) or disable (S_DISABLE). +* @retval None. +*/ +void S2LPPacketHandlerSetSrcAddrFlt(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= SOURCE_ADDR_FLT_REGMASK; + } + else { + tmp &= ~SOURCE_ADDR_FLT_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmp); +} + + + +/** +* @brief Set the secondary sync word. +* @param lSyncWords secondary sync word. +* @retval None. +*/ +void S2LPSetDualSyncWords(uint32_t lSyncWords) +{ + uint8_t tmpBuffer[4]; + + /* Split the 32-bit value in 4 8-bit values */ + for(uint8_t i=0 ; i<4 ; i++) { + tmpBuffer[i]=(uint8_t)(lSyncWords>>(8*i)); + } + + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS3_ADDR, 4, tmpBuffer); +} + + +/** +* @brief Get the secondary sync word. +* @param lSyncWords pointer to the secondary sync word variable. +* @retval None. +*/ +void S2LPGetDualSyncWords(uint32_t* lSyncWords) +{ + uint8_t tmpBuffer[4]; + + g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_GOALS3_ADDR, 4, tmpBuffer); + *lSyncWords = ((uint32_t)tmpBuffer[0]<<24) | ((uint32_t)tmpBuffer[1]<<16) | ((uint32_t)tmpBuffer[2]<<8) | ((uint32_t)tmpBuffer[3]); +} + + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_PktBasic.c b/strf/s2lp/S2LP_Library/Src/S2LP_PktBasic.c new file mode 100644 index 00000000..12c02c2e --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_PktBasic.c @@ -0,0 +1,457 @@ +/** + * @file S2LP_PktBasic.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP Basic packets. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_PktBasic.h" +#include "MCU_Interface.h" +#include "S2LP_PktWMbus.h" + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_PktBasic + * @{ + */ + + + +/** + * @defgroup PktBasic_Private_Defines Pkt Basic Private Defines + * @{ + */ + +#define PKT_FORMAT_BASIC_CODE 0x00 + +/** + *@} + */ + + +/** + * @defgroup PktBasic_Private_Macros Pkt Basic Private Macros + * @{ + */ + +#define IS_BASIC_PREAMBLE_LENGTH IS_PREAMBLE_LEN +#define IS_BASIC_SYNC_LENGTH IS_SYNC_LEN +#define IS_BASIC_PKT_LEN_FIELD_WID IS_PKT_LEN_FIELD_WID +#define IS_BASIC_CRC_MODE IS_PKT_CRC_MODE + +/** + *@} + */ + + + +/** + * @defgroup PktBasic_Private_Functions Pkt Basic Private Functions + * @{ + */ + +/** + * @brief Initialize the S2LP Basic packet according to the specified parameters in the PktBasicInit struct. + * Notice that this function sets the autofiltering option on CRC if it is set to any value different from BASIC_NO_CRC. + * @param pxPktBasicInit Basic packet init structure. + * This parameter is a pointer to @ref PktBasicInit. + * @retval None. + */ +void S2LPPktBasicInit(PktBasicInit* pxPktBasicInit) +{ + uint8_t tmpBuffer[6]; + + /* Check the parameters */ + s_assert_param(IS_BASIC_PREAMBLE_LENGTH(pxPktBasicInit->xPreambleLength)); + s_assert_param(IS_BASIC_SYNC_LENGTH(pxPktBasicInit->xSyncLength)); + s_assert_param(IS_BASIC_CRC_MODE(pxPktBasicInit->xCrcMode)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktBasicInit->cExtendedPktLenField)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktBasicInit->xFixVarLength)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktBasicInit->xAddressField)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktBasicInit->xFec)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktBasicInit->xDataWhitening)); + + S2LPPktWMbusSetSubmode(WMBUS_SUBMODE_NOT_CONFIGURED); + + /* Always set the automatic packet filtering */ + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]); + tmpBuffer[0] |= AUTO_PCKT_FLT_REGMASK; + S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]); + + tmpBuffer[0] = ((pxPktBasicInit->xSyncLength)<<2) | (uint8_t)((pxPktBasicInit->xPreambleLength)>>8); + tmpBuffer[1] = (uint8_t)(pxPktBasicInit->xPreambleLength); + tmpBuffer[2] = (((uint8_t)pxPktBasicInit->xAddressField)<<3); + + if((pxPktBasicInit->cExtendedPktLenField)==S_ENABLE) + { + tmpBuffer[2]|=0x80; + } + + S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmpBuffer[3]); + tmpBuffer[3] &= ~(PCKT_FRMT_REGMASK | RX_MODE_REGMASK); + tmpBuffer[3] |= PKT_FORMAT_BASIC_CODE; + + S2LPSpiReadRegisters(PCKTCTRL2_ADDR, 2, &tmpBuffer[4]); + + if(pxPktBasicInit->xFixVarLength == S_ENABLE) { + tmpBuffer[4] |= FIX_VAR_LEN_REGMASK; + } + else { + tmpBuffer[4] &= ~FIX_VAR_LEN_REGMASK; + } + tmpBuffer[4] &= ~(MANCHESTER_EN_REGMASK | MBUS_3OF6_EN_REGMASK); + + tmpBuffer[5] &= ~(CRC_MODE_REGMASK | TXSOURCE_REGMASK); + tmpBuffer[5] |= (uint8_t)pxPktBasicInit->xCrcMode; + + if(pxPktBasicInit->xDataWhitening == S_ENABLE) { + tmpBuffer[5] |= WHIT_EN_REGMASK; + } + else { + tmpBuffer[5] &= ~WHIT_EN_REGMASK; + } + + if(pxPktBasicInit->xFec == S_ENABLE) + { + tmpBuffer[5] |= FEC_EN_REGMASK; + } + else { + tmpBuffer[5] &= ~FEC_EN_REGMASK; + } + + S2LPSpiWriteRegisters(PCKTCTRL6_ADDR, 6, tmpBuffer); + + /* SYNC word */ + for(uint8_t i=0 ; i<4 ; i++) { + tmpBuffer[i] = (uint8_t)(pxPktBasicInit->lSyncWords>>(8*i)); + } + g_xStatus = S2LPSpiWriteRegisters(SYNC3_ADDR, 4, tmpBuffer); + + /* Sets CRC check bit */ + if(pxPktBasicInit->xCrcMode == PKT_NO_CRC) { + S2LPPktBasicFilterOnCrc(S_DISABLE); + } + else { + S2LPPktBasicFilterOnCrc(S_ENABLE); + } + + /* Constellation map setting */ + S2LPSpiReadRegisters(MOD1_ADDR, 1, tmpBuffer); + tmpBuffer[0] &= ~G4FSK_CONST_MAP_REGMASK; + S2LPSpiWriteRegisters(MOD1_ADDR, 1, tmpBuffer); +} + + +/** + * @brief Return the S2LP Basic packet structure according to the specified parameters in the registers. + * @param pxPktBasicInit Basic packet init structure. + * This parameter is a pointer to @ref PktBasicInit. + * @retval None. + */ +void S2LPPktBasicGetInfo(PktBasicInit* pxPktBasicInit) +{ + uint8_t tmpBuffer[6]; + + S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 6, tmpBuffer); + + /* Sync length */ + pxPktBasicInit->xSyncLength = ((tmpBuffer[0] & SYNC_LEN_REGMASK)>>2); + + /* Preamble length */ + pxPktBasicInit->xPreambleLength = (((uint16_t)(tmpBuffer[0] & PREAMBLE_LEN_9_8_REGMASK))<<8) | ((uint16_t)tmpBuffer[1]); + + /* Length width */ + pxPktBasicInit->cExtendedPktLenField = (SFunctionalState)((tmpBuffer[2] & LEN_WID_REGMASK)>>7); + + /* Address field */ + pxPktBasicInit->xAddressField = (SFunctionalState)((tmpBuffer[2] & ADDRESS_LEN_REGMASK)>>3); + + /* FIX or VAR bit */ + pxPktBasicInit->xFixVarLength = (SFunctionalState)(tmpBuffer[4] & FIX_VAR_LEN_REGMASK); + + /* CRC mode */ + pxPktBasicInit->xCrcMode = (BasicCrcMode)(tmpBuffer[5] & CRC_MODE_REGMASK); + + /* Whitening */ + pxPktBasicInit->xDataWhitening = (SFunctionalState)((tmpBuffer[5] & WHIT_EN_REGMASK)>> 4); + + /* FEC */ + pxPktBasicInit->xFec = (SFunctionalState)(tmpBuffer[5] & FEC_EN_REGMASK); + + g_xStatus = S2LPSpiReadRegisters(SYNC3_ADDR, 4, tmpBuffer); + + /* SYNC word */ + pxPktBasicInit->lSyncWords = 0; + for(uint8_t i=0 ; i<4 ; i++) { + pxPktBasicInit->lSyncWords |= ((uint32_t)tmpBuffer[i])<<(8*i); + } +} + + +/** + * @brief Initialize the S2LP Basic packet addresses according to the specified + * parameters in the PktBasicAddressesInit struct. + * @param pxPktBasicAddresses Basic packet addresses init structure. + * This parameter is a pointer to @ref PktBasicAddresses. + * @retval None. + */ +void S2LPPktBasicAddressesInit(PktBasicAddressesInit* pxPktBasicAddresses) +{ + uint8_t tmpBuffer[3]; + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktBasicAddresses->xFilterOnMyAddress)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktBasicAddresses->xFilterOnMulticastAddress)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktBasicAddresses->xFilterOnBroadcastAddress)); + + /* Reads the PCKT_FLT_OPTIONS ragister */ + S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]); + + /* Enables or disables filtering on my address */ + if(pxPktBasicAddresses->xFilterOnMyAddress == S_ENABLE) { + tmpBuffer[0] |= DEST_VS_SOURCE_ADDR_REGMASK; + } + else { + tmpBuffer[0] &= ~DEST_VS_SOURCE_ADDR_REGMASK; + } + + /* Enables or disables filtering on multicast address */ + if(pxPktBasicAddresses->xFilterOnMulticastAddress == S_ENABLE) { + tmpBuffer[0] |= DEST_VS_MULTICAST_ADDR_REGMASK; + } + else { + tmpBuffer[0] &= ~DEST_VS_MULTICAST_ADDR_REGMASK; + } + + /* Enables or disables filtering on broadcast address */ + if(pxPktBasicAddresses->xFilterOnBroadcastAddress == S_ENABLE) { + tmpBuffer[0] |= DEST_VS_BROADCAST_ADDR_REGMASK; + } + else { + tmpBuffer[0] &= ~DEST_VS_BROADCAST_ADDR_REGMASK; + } + + S2LPSpiWriteRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]); + + /* Fills the array with the addresses passed in the structure */ +#if 0 //indar2 + tmpBuffer[0] = pxPktBasicAddresses->cBroadcastAddress; + tmpBuffer[1] = pxPktBasicAddresses->cMulticastAddress; + tmpBuffer[2] = pxPktBasicAddresses->cMyAddress; +#else + tmpBuffer[0] = pxPktBasicAddresses->cMyAddress; + tmpBuffer[1] = pxPktBasicAddresses->cMulticastAddress; + tmpBuffer[2] = pxPktBasicAddresses->cBroadcastAddress; +#endif + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS2_ADDR, 3, tmpBuffer); +} + + +/** + * @brief Return the S2LP Basic packet addresses structure according to the specified + * parameters in the registers. + * @param pxPktBasicAddresses Basic packet addresses init structure. + * This parameter is a pointer to @ref PktBasicAddresses. + * @retval None. + */ +void S2LPPktBasicGetAddressesInfo(PktBasicAddressesInit* pxPktBasicAddresses) +{ + uint8_t tmpBuffer[3]; + + S2LPSpiReadRegisters(PCKT_FLT_GOALS3_ADDR, 3, tmpBuffer); + pxPktBasicAddresses->cMyAddress = tmpBuffer[0]; + pxPktBasicAddresses->cBroadcastAddress = tmpBuffer[1]; + pxPktBasicAddresses->cMulticastAddress = tmpBuffer[2]; + + g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]); + pxPktBasicAddresses->xFilterOnBroadcastAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_BROADCAST_ADDR_REGMASK) >> 3); + pxPktBasicAddresses->xFilterOnMulticastAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_MULTICAST_ADDR_REGMASK) >> 2); + pxPktBasicAddresses->xFilterOnMyAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_SOURCE_ADDR_REGMASK) >> 1); +} + + +/** + * @brief Configure the Basic packet format as packet used by S2LP. + * @param None. + * @retval None. + */ +void S2LPPktBasicSetFormat(void) +{ + uint8_t tmp; + + S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp); + + /* Build the new value. Also set to 0 the direct RX mode bits */ + tmp &= ~(PCKT_FRMT_REGMASK | RX_MODE_REGMASK); + tmp |= PKT_FORMAT_BASIC_CODE; + S2LPSpiWriteRegisters(PCKTCTRL3_ADDR, 1, &tmp); + + S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + + /* Set to 0 the direct TX mode bits */ + tmp &= ~TXSOURCE_REGMASK; + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL1_ADDR, 1, &tmp); + + S2LPPktWMbusSetSubmode(WMBUS_SUBMODE_NOT_CONFIGURED); +} + + +/** + * @brief Set the address length for S2LP Basic packets. + * @param xAddressField length of ADDRESS in bytes. + * This parameter can be: S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPPktBasicAddressField(SFunctionalState xAddressField) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xAddressField)); + + S2LPSpiReadRegisters(PCKTCTRL4_ADDR, 1, &tmp); + if(xAddressField==S_ENABLE) { + tmp |= ADDRESS_LEN_REGMASK; + } + else { + tmp &= ADDRESS_LEN_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL4_ADDR, 1, &tmp); + +} + + +/** + * @brief Specify if the Address field for S2LP Basic packets is enabled or disabled. + * @param None. + * @retval SFunctionalState Notifies if the address field is enabled or disabled. + */ +SFunctionalState S2LPPktBasicGetAddressField(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(PCKTCTRL4_ADDR, 1, &tmp); + if(tmp & ADDRESS_LEN_REGMASK) { + return S_ENABLE; + } + else { + return S_DISABLE; + } + +} + + +/** + * @brief Set the payload length for S2LP Basic packets. Since the packet length + * depends from the address and the control field size, this + * function reads the correspondent registers in order to determine + * the correct packet length to be written. + * @param nPayloadLength payload length in bytes. + * This parameter is an uint16_t. + * @retval None. + */ +void S2LPPktBasicSetPayloadLength(uint16_t nPayloadLength) +{ + uint8_t tmpBuffer[2]; + + if(S2LPPktBasicGetAddressField()) { + nPayloadLength++; + } + tmpBuffer[0] = (uint8_t)(nPayloadLength>>8); + tmpBuffer[1] = (uint8_t)nPayloadLength; + g_xStatus = S2LPSpiWriteRegisters(PCKTLEN1_ADDR, 2, tmpBuffer); +} + + +/** + * @brief Return the payload length for S2LP Basic packets. Since the + * packet length depends from the address and the control + * field size, this function reads the correspondent + * registers in order to determine the correct payload length + * to be returned. + * @param None. + * @retval uint16_t Payload length in bytes. + */ +uint16_t S2LPPktBasicGetPayloadLength(void) +{ + uint8_t tmpBuffer[2]; + uint16_t nPayloadLength; + + g_xStatus = S2LPSpiReadRegisters(PCKTLEN1_ADDR, 2, tmpBuffer); + nPayloadLength = (((uint16_t)tmpBuffer[0])<<8) | ((uint16_t)tmpBuffer[1]); + + if(S2LPPktBasicGetAddressField()) { + nPayloadLength--; + } + return nPayloadLength; +} + +/** + * @brief Return the packet length field of the received packet. + * @param None. + * @retval uint16_t Packet length. + */ +uint16_t S2LPPktBasicGetReceivedPktLength(void) +{ + uint8_t tmpBuffer[2]; + uint16_t nPayloadLength; + + g_xStatus = S2LPSpiReadRegisters(RX_PCKT_LEN1_ADDR, 2, tmpBuffer); + nPayloadLength = (((uint16_t)tmpBuffer[0])<<8) | ((uint16_t)tmpBuffer[1]); + + if(S2LPPktBasicGetAddressField()) { + nPayloadLength--; + } + return nPayloadLength; +} + + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_PktStack.c b/strf/s2lp/S2LP_Library/Src/S2LP_PktStack.c new file mode 100644 index 00000000..fd4b531d --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_PktStack.c @@ -0,0 +1,530 @@ +/** + * @file S2LP_PktStack.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP STack packets. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_PktStack.h" +#include "MCU_Interface.h" +#include "S2LP_PktWMbus.h" + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_PktStack + * @{ + */ + +/** + * @defgroup PktStack_Private_Defines Pkt STack Private Defines + * @{ + */ +#define PKT_FORMAT_STACK_CODE (uint8_t)3 + +/** + *@} + */ + + +/** + * @defgroup PktStack_Private_Macros Pkt STack Private Macros + * @{ + */ + + +#define IS_STACK_PREAMBLE_LENGTH IS_PREAMBLE_LEN +#define IS_STACK_SYNC_LENGTH IS_SYNC_LEN +#define IS_STACK_PKT_LEN_FIELD_WID IS_PKT_LEN_FIELD_WID +#define IS_STACK_CRC_MODE IS_PKT_CRC_MODE +#define IS_STACK_NMAX_RETX(NRETX) (NRETX<=15) +#define IS_STACK_SEQNUM_RELOAD_VAL(VAL) (VAL<=3) + +/** + *@} + */ + + +/** + * @defgroup PktStack_Private_Functions Pkt STack Private Functions + * @{ + */ + + +/** + * @brief Initialize the S2LP STack packet according to the specified + * parameters in the PktStackInit. + * @param pxPktStackInit STack packet init structure. + * This parameter is a pointer to @ref PktStackInit. + * @retval None. + */ +void S2LPPktStackInit(PktStackInit* pxPktStackInit) +{ + uint8_t tmpBuffer[6]; + + /* Check the parameters */ + s_assert_param(IS_STACK_PREAMBLE_LENGTH(pxPktStackInit->xPreambleLength)); + s_assert_param(IS_STACK_SYNC_LENGTH(pxPktStackInit->xSyncLength)); + s_assert_param(IS_STACK_CRC_MODE(pxPktStackInit->xCrcMode)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackInit->cExtendedPktLenField)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackInit->xFixVarLength)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackInit->xFec)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackInit->xDataWhitening)); + + S2LPPktWMbusSetSubmode(WMBUS_SUBMODE_NOT_CONFIGURED); + + /* Always set the automatic packet filtering */ + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]); + tmpBuffer[0] |= AUTO_PCKT_FLT_REGMASK; + S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]); + + tmpBuffer[0] = ((pxPktStackInit->xSyncLength)<<2) | (uint8_t)((pxPktStackInit->xPreambleLength)>>8); + tmpBuffer[1] = (uint8_t)(pxPktStackInit->xPreambleLength); + tmpBuffer[2] = ((uint8_t)pxPktStackInit->cExtendedPktLenField)<<7 | ADDRESS_LEN_REGMASK; + + S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmpBuffer[3]); + tmpBuffer[3] &= ~(PCKT_FRMT_REGMASK | RX_MODE_REGMASK); + tmpBuffer[3] |= PKT_FORMAT_STACK_CODE<<6; + + S2LPSpiReadRegisters(PCKTCTRL2_ADDR, 2, &tmpBuffer[4]); + + if(pxPktStackInit->xFixVarLength == S_ENABLE) { + tmpBuffer[4] |= FIX_VAR_LEN_REGMASK; + } + else { + tmpBuffer[4] &= ~FIX_VAR_LEN_REGMASK; + } + tmpBuffer[4] &= ~(MANCHESTER_EN_REGMASK | MBUS_3OF6_EN_REGMASK); + + tmpBuffer[5] &= ~(CRC_MODE_REGMASK | TXSOURCE_REGMASK); + tmpBuffer[5] |= (uint8_t)pxPktStackInit->xCrcMode; + + if(pxPktStackInit->xDataWhitening == S_ENABLE) { + tmpBuffer[5] |= WHIT_EN_REGMASK; + } + else { + tmpBuffer[5] &= ~WHIT_EN_REGMASK; + } + + if(pxPktStackInit->xFec == S_ENABLE) { + tmpBuffer[5] |= FEC_EN_REGMASK; + } + else { + tmpBuffer[5] &= ~FEC_EN_REGMASK; + } + + S2LPSpiWriteRegisters(PCKTCTRL6_ADDR, 6, tmpBuffer); + + /* SYNC word */ + for(uint8_t i=0 ; i<4 ; i++) { + tmpBuffer[i] = (uint8_t)(pxPktStackInit->lSyncWords>>(8*i)); + } + g_xStatus = S2LPSpiWriteRegisters(SYNC3_ADDR, 4, tmpBuffer); + + /* Sets CRC check bit */ + if(pxPktStackInit->xCrcMode == PKT_NO_CRC) { + S2LPPktStackFilterOnCrc(S_DISABLE); + } + else { + S2LPPktStackFilterOnCrc(S_ENABLE); + } + /* Constellation map setting */ + S2LPSpiReadRegisters(MOD1_ADDR, 1, tmpBuffer); + tmpBuffer[0] &= ~G4FSK_CONST_MAP_REGMASK; + S2LPSpiWriteRegisters(MOD1_ADDR, 1, tmpBuffer); +} + + +/** + * @brief Return the S2LP STack packet structure according to the specified parameters in the registers. + * @param pxPktStackInit STack packet init structure. + * This parameter is a pointer to @ref PktStackInit. + * @retval None. + */ +void S2LPPktStackGetInfo(PktStackInit* pxPktStackInit) +{ + uint8_t tmpBuffer[6]; + + S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 6, tmpBuffer); + + /* Sync length */ + pxPktStackInit->xSyncLength = ((tmpBuffer[0] & SYNC_LEN_REGMASK)>>2); + + /* Preamble length */ + pxPktStackInit->xPreambleLength = (((uint16_t)(tmpBuffer[0] & PREAMBLE_LEN_9_8_REGMASK))<<8) | ((uint16_t)tmpBuffer[1]); + + /* Length width */ + pxPktStackInit->cExtendedPktLenField = (SFunctionalState)((tmpBuffer[2] & LEN_WID_REGMASK)>>7); + + /* FIX or VAR bit */ + pxPktStackInit->xFixVarLength = (SFunctionalState)(tmpBuffer[4] & FIX_VAR_LEN_REGMASK); + + /* CRC mode */ + pxPktStackInit->xCrcMode = (StackCrcMode)(tmpBuffer[5] & CRC_MODE_REGMASK); + + /* Whitening */ + pxPktStackInit->xDataWhitening = (SFunctionalState)((tmpBuffer[5] & WHIT_EN_REGMASK)>> 4); + + /* FEC */ + pxPktStackInit->xFec = (SFunctionalState)(tmpBuffer[5] & FEC_EN_REGMASK); + + g_xStatus = S2LPSpiReadRegisters(SYNC3_ADDR, 4, tmpBuffer); + + /* SYNC word */ + pxPktStackInit->lSyncWords = 0; + for(uint8_t i=0 ; i<4 ; i++) { + pxPktStackInit->lSyncWords |= ((uint32_t)tmpBuffer[3-i])<<(8*i); + } + +} + + +/** + * @brief Initialize the S2LP STack packet addresses according to the specified + * parameters in the PktStackAddresses struct. + * @param pxPktStackAddresses STack packet addresses init structure. + * This parameter is a pointer to @ref PktStackAddressesInit . + * @retval None. + */ +void S2LPPktStackAddressesInit(PktStackAddressesInit* pxPktStackAddresses) +{ + uint8_t tmpBuffer[3]; + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnMyAddress)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnMulticastAddress)); + s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnBroadcastAddress)); + + /* Reads the PCKT_FLT_OPTIONS ragister */ + S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]); + + /* Enables or disables filtering on my address */ + if(pxPktStackAddresses->xFilterOnMyAddress == S_ENABLE) { + tmpBuffer[0] |= DEST_VS_SOURCE_ADDR_REGMASK; + } + else { + tmpBuffer[0] &= ~DEST_VS_SOURCE_ADDR_REGMASK; + } + + /* Enables or disables filtering on multicast address */ + if(pxPktStackAddresses->xFilterOnMulticastAddress == S_ENABLE) { + tmpBuffer[0] |= DEST_VS_MULTICAST_ADDR_REGMASK; + } + else { + tmpBuffer[0] &= ~DEST_VS_MULTICAST_ADDR_REGMASK; + } + + /* Enables or disables filtering on broadcast address */ + if(pxPktStackAddresses->xFilterOnBroadcastAddress == S_ENABLE) { + tmpBuffer[0] |= DEST_VS_BROADCAST_ADDR_REGMASK; + } + else { + tmpBuffer[0] &= ~DEST_VS_BROADCAST_ADDR_REGMASK; + } + + S2LPSpiWriteRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]); + + /* Fills the array with the addresses passed in the structure */ + tmpBuffer[2] = pxPktStackAddresses->cMyAddress; + tmpBuffer[0] = pxPktStackAddresses->cBroadcastAddress; + tmpBuffer[1] = pxPktStackAddresses->cMulticastAddress; + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS2_ADDR, 3, tmpBuffer); +} + + +/** +* @brief Return the S2LP STack packet addresses structure according to the specified +* parameters in the registers. +* @param pxPktStackAddresses STack packet addresses init structure. +* This parameter is a pointer to @ref PktStackAddresses. +* @retval None. +*/ +void S2LPPktStackGetAddressesInfo(PktStackAddressesInit* pxPktStackAddresses) +{ + uint8_t tmpBuffer[3]; + + S2LPSpiReadRegisters(PCKT_FLT_GOALS3_ADDR, 3, tmpBuffer); + pxPktStackAddresses->cMyAddress = tmpBuffer[0]; + pxPktStackAddresses->cBroadcastAddress = tmpBuffer[1]; + pxPktStackAddresses->cMulticastAddress = tmpBuffer[2]; + + g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]); + pxPktStackAddresses->xFilterOnBroadcastAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_BROADCAST_ADDR_REGMASK) >> 3); + pxPktStackAddresses->xFilterOnMulticastAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_MULTICAST_ADDR_REGMASK) >> 2); + pxPktStackAddresses->xFilterOnMyAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_SOURCE_ADDR_REGMASK) >> 1); +} + + +/** + * @brief Configure the STack packet format for S2LP. + * @param None. + * @retval None. + */ +void S2LPPktStackSetFormat(void) +{ + uint8_t tmp; + + S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp); + + /* Build the new value. Also set to 0 the direct RX mode bits */ + tmp &= ~(PCKT_FRMT_REGMASK | RX_MODE_REGMASK); + tmp |= PKT_FORMAT_STACK_CODE; + S2LPSpiWriteRegisters(PCKTCTRL3_ADDR, 1, &tmp); + + S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp); + + /* Set to 0 the direct TX mode bits */ + tmp &= ~TXSOURCE_REGMASK; + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL1_ADDR, 1, &tmp); + + S2LPPktWMbusSetSubmode(WMBUS_SUBMODE_NOT_CONFIGURED); +} + + + +/** + * @brief Set the payload length for S2LP STack packets. Since the packet length + * depends from the address (always 2 for this packet format) + * and the control field size, this function reads the control length register + * content in order to determine the correct packet length to be written. + * @param nPayloadLength payload length in bytes. + * This parameter can be any value of uint16_t. + * @retval None. + */ +void S2LPPktStackSetPayloadLength(uint16_t nPayloadLength) +{ + uint8_t tmpBuffer[2]; + + nPayloadLength+=2; + tmpBuffer[0] = (uint8_t)(nPayloadLength>>8); + tmpBuffer[1] = (uint8_t)nPayloadLength; + g_xStatus = S2LPSpiWriteRegisters(PCKTLEN1_ADDR, 2, tmpBuffer); +} + + +/** + * @brief Return the payload length for S2LP STack packets. Since the + * packet length depends from the address and the control + * field size, this function reads the correspondent + * registers in order to determine the correct payload length + * to be returned. + * @param None. + * @retval uint16_t Payload length. + */ +uint16_t S2LPPktStackGetPayloadLength(void) +{ + uint8_t tmpBuffer[2]; + uint16_t nPayloadLength; + + g_xStatus = S2LPSpiReadRegisters(PCKTLEN1_ADDR, 2, tmpBuffer); + nPayloadLength = (((uint16_t)tmpBuffer[0])<<8) | ((uint16_t)tmpBuffer[1]); + nPayloadLength-=2; + + return nPayloadLength; +} + + +/** + * @brief Return the packet length field of the received packet. + * @param None. + * @retval uint16_t Packet length. + */ +uint16_t S2LPPktStackGetReceivedPktLength(void) +{ + uint8_t tmpBuffer[2]; + uint16_t nPayloadLength; + + g_xStatus = S2LPSpiReadRegisters(RX_PCKT_LEN1_ADDR, 2, tmpBuffer); + nPayloadLength = (((uint16_t)tmpBuffer[0])<<8) | ((uint16_t)tmpBuffer[1]); + nPayloadLength--; + + return nPayloadLength; +} + + +/** +* @brief Se the AUTO_ACK bit on the receiver . +* @param xNewState if S_ENABLE, the receiver will check the NO_ACK bit to see if the ack should be sent (NO_ACK=0) or not (NO_ACK=1). +* @retval None. +*/ +void S2LPPktStackAutoAck(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL0_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= AUTO_ACK_REGMASK; + } + else { + tmp &= ~AUTO_ACK_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL0_ADDR, 1, &tmp); + +} + + +/** +* @brief Set the number of retransmissions to be done in case of ACK loss. +* @param nRetx number of retransmissions. +* @retval None. +*/ +void S2LPPktStackNRetx(uint8_t nRetx) +{ + uint8_t tmp; + s_assert_param(IS_STACK_NMAX_RETX(nRetx)); + + S2LPSpiReadRegisters(PROTOCOL0_ADDR, 1, &tmp); + tmp &= ~NMAX_RETX_REGMASK; + tmp |= (nRetx<<4); + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL0_ADDR, 1, &tmp); + +} + + +/** +* @brief Get the NO_ACK bit. +* @param None. +* @retval SFlagStatus if it is S_SET, the ack will be not requested, otherwise it will be. +*/ +SFlagStatus S2LPPktStackGetTXAckRequest(void) +{ + uint8_t tmp; + + S2LPSpiReadRegisters(RX_PCKT_INFO_ADDR, 1, &tmp); + tmp &= NACK_RX_REGMASK; + tmp >>= 2; + return (SFlagStatus)tmp; +} + +/** +* @brief This function will set the NO_ACK bit or reset it. +* @param xNewState if it is S_DISABLE, the ack will be not request and thus the NO_ACK bit will be set to 1. +* if this parameter is S_ENABLE, the ack will be request and thus the NO_ACK bit will be set to 0. +* @retval None. +*/ +void S2LPPktStackAckRequest(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL0_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp &= ~NACK_TX_REGMASK; + } + else { + tmp |= NACK_TX_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL0_ADDR, 1, &tmp); + +} + + +/** +* @brief Enable or Disable the piggybacking. +* @param xNewState enable or disable. +* @retval None. +*/ +void S2LPPktStackPiggybacking(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= PIGGYBACKING_REGMASK; + } + else { + tmp &= ~PIGGYBACKING_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp); + +} + + +/** +* @brief Set the reload value of the sequence number. +* @note A SEQ_NUM_RELOAD command must be strobed to make this value available for the next packet. +* @param cReloadValue reload value. +* @retval None. +*/ +void S2LPPktStackSeqNumForReload(uint8_t cReloadValue) +{ + uint8_t tmp; + s_assert_param(IS_STACK_SEQNUM_RELOAD_VAL(cReloadValue)); + + S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp); + tmp &= ~TX_SEQ_NUM_RELOAD_REGMASK; + tmp |= (cReloadValue<<3); + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL2_ADDR, 1, &tmp); +} + +/** + * @brief Returns the number of retransmission done on the transmitted packet. + * @param None. + * @retval uint8_t Number of retransmissions done until now. + */ +uint8_t S2LPPktStackGetNReTx(void) +{ + uint8_t tempRetValue; + + /* Reads the TX_PCKT_INFO register value */ + g_xStatus = S2LPSpiReadRegisters(TX_PCKT_INFO_ADDR, 1, &tempRetValue); + + /* Obtains and returns the number of retransmission done */ + return (tempRetValue & 0x0F); + +} + + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_PktWMbus.c b/strf/s2lp/S2LP_Library/Src/S2LP_PktWMbus.c new file mode 100644 index 00000000..095a8a54 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_PktWMbus.c @@ -0,0 +1,367 @@ +/** + * @file S2LP_PktWMbus.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP WMBUS packets. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_PktWMbus.h" +#include "MCU_Interface.h" + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_PktWMbus + * @{ + */ + + + +/** + * @defgroup PktWMbus_Private_Defines Pkt WMBUS Private Defines + * @{ + */ +#define PKT_FORMAT_WMBUS_CODE 0x00 + +#define WMBUS_PREAMBLE_LEN_S1S2LONGHEADER (uint16_t)279 +#define WMBUS_PREAMBLE_LEN_S1MS2T2OTHERTOMETER (uint16_t)15 +#define WMBUS_PREAMBLE_LEN_T1T2METERTOOTHER (uint16_t)19 +#define WMBUS_PREAMBLE_LEN_R2 (uint16_t)39 +#define WMBUS_PREAMBLE_LEN_N1N2 (uint16_t)8 + +#define WMBUS_SYNC_LEN_S1S2LONGHEADER (uint8_t)18 +#define WMBUS_SYNC_LEN_S1MS2T2OTHERTOMETER (uint8_t)18 +#define WMBUS_SYNC_LEN_T1T2METERTOOTHER (uint8_t)10 +#define WMBUS_SYNC_LEN_R2 (uint8_t)18 +#define WMBUS_SYNC_LEN_N1N2 (uint16_t)16 + +#define WMBUS_SYNCWORD_S1S2LONGHEADER (uint32_t)0xE25A4000 +#define WMBUS_SYNCWORD_S1MS2T2OTHERTOMETER (uint32_t)0xE25A4000 +#define WMBUS_SYNCWORD_T1T2METERTOOTHER (uint32_t)0x0F400000 +#define WMBUS_SYNCWORD_R2 (uint32_t)0xE25A4000 +#define WMBUS_SYNCWORD_N1N2 (uint32_t)0xf68d0000 +/** + *@} + */ + + +/** + * @defgroup PktWMbus_Private_Macros Pkt WMBUS Private Macros + * @{ + */ + +#define IS_WMBUS_SUBMODE(MODE) (((MODE) == WMBUS_SUBMODE_S1_S2_LONG_HEADER) || \ + ((MODE) == WMBUS_SUBMODE_NOT_CONFIGURED) || \ + ((MODE) == WMBUS_SUBMODE_S1_M_S2_T2_OTHER_TO_METER) || \ + ((MODE) == WMBUS_SUBMODE_T1_T2_METER_TO_OTHER) || \ + ((MODE) == WMBUS_SUBMODE_R2_SHORT_HEADER)) + +/** + *@} + */ + + +/** + * @defgroup PktWMbus_Private_Variables Pkt WMBUS Private Variables + * @{ + */ +static WMbusSubmode s_cWMbusSubmode = WMBUS_SUBMODE_NOT_CONFIGURED; + +/** + *@} + */ + + +/** + * @defgroup PktWMbus_Private_Functions Pkt WMBUS Private Functions + * @{ + */ + + +/** + * @brief Initialize the S2LP WMBUS packet according to the specified parameters in the PktWMbusInit struct. + * @param pxPktWMbusInit pointer to a PktWMbusInit structure that contains the configuration information for the specified S2LP WMBUS PACKET FORMAT. + * This parameter is a pointer to @ref PktWMbusInit. + * @retval None. + */ +void S2LPPktWMbusInit(PktWMbusInit* pxPktWMbusInit) +{ + uint8_t tmp; + s_assert_param(IS_WMBUS_SUBMODE(pxPktWMbusInit->xWMbusSubmode)); + + /* Packet format config */ + S2LPPktWMbusSetFormat(); + S2LPPktCommonFilterOnCrc(S_DISABLE); + + s_cWMbusSubmode = pxPktWMbusInit->xWMbusSubmode; + + if(s_cWMbusSubmode==WMBUS_SUBMODE_S1_S2_LONG_HEADER) { + S2LPSetPreambleLength(((uint16_t)pxPktWMbusInit->cPreambleLength) + WMBUS_PREAMBLE_LEN_S1S2LONGHEADER); + S2LPSetSyncLength(WMBUS_SYNC_LEN_S1S2LONGHEADER); + S2LPSetSyncWords(WMBUS_SYNCWORD_S1S2LONGHEADER, WMBUS_SYNC_LEN_S1S2LONGHEADER); + S2LPPacketHandlerManchester(S_ENABLE); + + /* Constellation map setting */ + S2LPSpiReadRegisters(MOD1_ADDR, 1, &tmp); + tmp &= ~G4FSK_CONST_MAP_REGMASK; + tmp |= (((uint8_t)2)<<4); + S2LPSpiWriteRegisters(MOD1_ADDR, 1, &tmp); + + S2LPSpiReadRegisters(0xF1, 1, &tmp); + if((tmp&0xC0)==0xC0) + S2LPPktWMbusSetPostamblePattern(0x01); + } + else if(s_cWMbusSubmode==WMBUS_SUBMODE_S1_M_S2_T2_OTHER_TO_METER) { + S2LPSetPreambleLength(((uint16_t)pxPktWMbusInit->cPreambleLength) + WMBUS_PREAMBLE_LEN_S1MS2T2OTHERTOMETER); + S2LPSetSyncLength(WMBUS_SYNC_LEN_S1MS2T2OTHERTOMETER); + S2LPSetSyncWords(WMBUS_SYNCWORD_S1MS2T2OTHERTOMETER, WMBUS_SYNC_LEN_S1MS2T2OTHERTOMETER); + S2LPPacketHandlerManchester(S_ENABLE); + /* Constellation map setting */ + S2LPSpiReadRegisters(MOD1_ADDR, 1, &tmp); + tmp &= ~G4FSK_CONST_MAP_REGMASK; + tmp |= (((uint8_t)2)<<4); + S2LPSpiWriteRegisters(MOD1_ADDR, 1, &tmp); + + S2LPSpiReadRegisters(0xF1, 1, &tmp); + if((tmp&0xC0)==0xC0) + S2LPPktWMbusSetPostamblePattern(0x01); + } + else if(s_cWMbusSubmode==WMBUS_SUBMODE_T1_T2_METER_TO_OTHER) { + S2LPSetPreambleLength(((uint16_t)pxPktWMbusInit->cPreambleLength) + WMBUS_PREAMBLE_LEN_T1T2METERTOOTHER); + S2LPSetSyncLength(WMBUS_SYNC_LEN_T1T2METERTOOTHER); + S2LPSetSyncWords(WMBUS_SYNCWORD_T1T2METERTOOTHER, WMBUS_SYNC_LEN_T1T2METERTOOTHER); + S2LPPacketHandler3OutOf6(S_ENABLE); + } + else if(s_cWMbusSubmode==WMBUS_SUBMODE_R2_SHORT_HEADER) { + S2LPSetPreambleLength(((uint16_t)pxPktWMbusInit->cPreambleLength) + WMBUS_PREAMBLE_LEN_R2); + S2LPSetSyncLength(WMBUS_SYNC_LEN_R2); + S2LPSetSyncWords(WMBUS_SYNCWORD_R2, WMBUS_SYNC_LEN_R2); + S2LPPacketHandlerManchester(S_ENABLE); + /* Constellation map setting */ + S2LPSpiReadRegisters(MOD1_ADDR, 1, &tmp); + tmp &= ~G4FSK_CONST_MAP_REGMASK; + tmp |= (((uint8_t)2)<<4); + S2LPSpiWriteRegisters(MOD1_ADDR, 1, &tmp); + } + + + S2LPPktWMbusSetPostamble(pxPktWMbusInit->cPostambleLength); +} + +/** + * @brief Return the S2LP WMBUS packet structure according to the specified parameters in the registers. + * @param pxPktWMbusInit WMBUS packet init structure. + * This parameter is a pointer to @ref PktWMbusInit. + * @retval None. + */ +void S2LPPktWMbusGetInfo(PktWMbusInit* pxPktWMbusInit) +{ + uint16_t tmp; + + tmp = S2LPGetPreambleLength(); + + if(s_cWMbusSubmode==WMBUS_SUBMODE_S1_S2_LONG_HEADER) { + if(tmp>=WMBUS_PREAMBLE_LEN_S1S2LONGHEADER) + tmp -= WMBUS_PREAMBLE_LEN_S1S2LONGHEADER; + } + else if(s_cWMbusSubmode==WMBUS_SUBMODE_S1_M_S2_T2_OTHER_TO_METER) { + if(tmp>=WMBUS_PREAMBLE_LEN_S1MS2T2OTHERTOMETER) + tmp -= WMBUS_PREAMBLE_LEN_S1MS2T2OTHERTOMETER; + } + else if(s_cWMbusSubmode==WMBUS_SUBMODE_T1_T2_METER_TO_OTHER) { + if(tmp>=WMBUS_PREAMBLE_LEN_T1T2METERTOOTHER) + tmp -= WMBUS_PREAMBLE_LEN_T1T2METERTOOTHER; + } + else if(s_cWMbusSubmode==WMBUS_SUBMODE_R2_SHORT_HEADER) { + if(tmp>=WMBUS_PREAMBLE_LEN_R2) + tmp -= WMBUS_PREAMBLE_LEN_R2; + } + + pxPktWMbusInit->cPreambleLength = (uint8_t)tmp; + pxPktWMbusInit->cPostambleLength = S2LPPktWMbusGetPostamble(); + pxPktWMbusInit->xWMbusSubmode = s_cWMbusSubmode; + +} + + +/** + * @brief Configure the WMBUS packet format as the one used by S2LP. + * @param None. + * @retval None. + */ +void S2LPPktWMbusSetFormat(void) +{ + uint8_t tmpBuffer[4] = {0,0,0,0}; + + /* Configure the WMBUS mode packet format and reset all the other setting */ + tmpBuffer[1] |= PKT_FORMAT_WMBUS_CODE; + g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL4_ADDR, 4, tmpBuffer); + +} + + + +/** + * @brief Set how many chips will be used in postamble + * @param cPostamble the number of chip sequence. + * This parameter is an uint8_t. + * @retval None. + */ +void S2LPPktWMbusSetPostamble(uint8_t cPostamble) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_PSTMBL_ADDR, 1, &tmp); + tmp = (tmp & 0xC0) | cPostamble; + g_xStatus = S2LPSpiWriteRegisters(PCKT_PSTMBL_ADDR, 1, &tmp); +} + + +/** + * @brief Set the pattern of the postamble. + * @param cPostamble id the preamble pattern: + * This parameter can be '00','01','10' or '11'. + * This parameter is an uint8_t. + * @retval None. + */ +void S2LPPktWMbusSetPostamblePattern(uint8_t cPostamble) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_PSTMBL_ADDR, 1, &tmp); + tmp = (tmp & 0x3F) | (cPostamble<<6); + g_xStatus = S2LPSpiWriteRegisters(PCKT_PSTMBL_ADDR, 1, &tmp); +} + + +/** + * @brief Returns how many chips are used in the postamble + * @param None. + * @retval uint8_t Postamble in number chip sequences. + */ +uint8_t S2LPPktWMbusGetPostamble(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_PSTMBL_ADDR, 1, &tmp); + return (tmp & 0x3F); +} + + +/** + * @brief Returns the pattern of the postamble. + * @param None. + * @retval uint8_t Postamble in chips. + */ +uint8_t S2LPPktWMbusGetPostamblePattern(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PCKT_PSTMBL_ADDR, 1, &tmp); + return ((tmp & 0xC0)>>6); +} + + +/** +* @brief Set the W-MBus submode. +* @param xWMbusSubmode This parameter of @ref WMbusSubmode . +* @retval None. +*/ +void S2LPPktWMbusSetSubmode(WMbusSubmode xWMbusSubmode) +{ + s_cWMbusSubmode = xWMbusSubmode; +} + + +/** + * @brief Return the WMBUS submode used. + * @param None. + * @retval WMbusSubmode WMBUS submode. + */ +WMbusSubmode S2LPPktWMbusGetSubmode(void) +{ + return s_cWMbusSubmode; +} + + +/** + * @brief Sets the payload length for S2LP WMBUS packets. + * @param nPayloadLength payload length in bytes. + * This parameter is an uint16_t. + * @retval None. + */ +void S2LPPktWMbusSetPayloadLength(uint16_t nPayloadLength) +{ + uint8_t tmpBuffer[2]; + + tmpBuffer[0] = (uint8_t)(nPayloadLength>>8); + tmpBuffer[1] = (uint8_t)nPayloadLength; + g_xStatus = S2LPSpiWriteRegisters(PCKTLEN1_ADDR, 2, tmpBuffer); +} + + +/** + * @brief Return the payload length for WMBUS packets. + * @param None. + * @retval uint16_t Payload length in bytes. + */ +uint16_t S2LPPktWMbusGetPayloadLength(void) +{ + uint8_t tmpBuffer[2]; + uint16_t nPayloadLength; + + g_xStatus = S2LPSpiReadRegisters(PCKTLEN1_ADDR, 2, tmpBuffer); + nPayloadLength = (((uint16_t)tmpBuffer[0])<<8) | ((uint16_t)tmpBuffer[1]); + + return nPayloadLength; +} + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Qi.c b/strf/s2lp/S2LP_Library/Src/S2LP_Qi.c new file mode 100644 index 00000000..e3f276b0 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Qi.c @@ -0,0 +1,305 @@ +/** + * @file S2LP_Qi.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP QI. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ */ + + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Qi.h" +#include "MCU_Interface.h" + + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_Qi + * @{ + */ + + +/** + * @defgroup Qi_Private_TypesDefinitions QI Private Types Definitions + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Qi_Private_Defines QI Private Defines + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Qi_Private_Macros QI Private Macros + * @{ + */ + +#define IS_RSSI_MODE(MODE) (MODE<=3) +#define IS_RSSI_DBM(VAL) ((VAL>=-146) && (VAL<=-2)) +#define IS_RSSI_FLT(VAL) (VAL<=15) +#define IS_PQI_LVL_CHECK(VAL) (VAL<=15) +#define S2LPRadioRegToRssidBm(VAL) (VAL - 146) +#define S2LPRadioRssidBmToReg(VAL) (uint8_t)(VAL+146) + +/** + *@} + */ + + +/** + * @defgroup Qi_Private_Variables QI Private Variables + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Qi_Private_FunctionPrototypes QI Private Function Prototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Qi_Private_Functions QI Private Functions + * @{ + */ + +/** + * @brief Returns the RSSI value. + * @param None. + * @retval int32_t RSSI value. + */ +int32_t S2LPRadioGetRssidBm(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(RSSI_LEVEL_ADDR, 1, &tmp); + return S2LPRadioRegToRssidBm((int32_t)tmp); +} + +/** + * @brief Returns the RSSI value from a current RX mode. + * @param None. + * @retval uint8_t RSSI value. + */ +int32_t S2LPRadioGetRssidBmRun(void) +{ + uint8_t tmpBuffer[2]; + + /*The first value is the previous one, so the first read operation clear this value, + than it is read the actual during RX. */ + g_xStatus = S2LPSpiReadRegisters(RSSI_LEVEL_RUN_ADDR, 2, tmpBuffer); + + return S2LPRadioRegToRssidBm((int32_t)tmpBuffer[1]); +} + + + +/** + * @brief Set the RSSI threshold in dBm. + * @param rssiThrehsold in dBm. + * @retval None. + */ +void S2LPRadioSetRssiThreshdBm(int32_t wRssiThrehsold) +{ + uint8_t tmp; + s_assert_param(IS_RSSI_DBM(wRssiThrehsold)); + + tmp = S2LPRadioRssidBmToReg(wRssiThrehsold); + g_xStatus = S2LPSpiWriteRegisters(RSSI_TH_ADDR, 1, &tmp); +} + + + +/** +* @brief Initialize the RSSI measurement. +* @param Pointer to the SRssiInit struct to use fot the initialization. +* @retval None. +*/ +void S2LPRadioRssiInit(SRssiInit* xSRssiInit) +{ + uint8_t tmpBuffer[2]; + + s_assert_param(IS_RSSI_MODE(xSRssiInit->xRssiMode)); + s_assert_param(IS_RSSI_DBM(xSRssiInit->cRssiThreshdBm)); + s_assert_param(IS_RSSI_FLT(xSRssiInit->cRssiFlt)); + + /* Reads the PCKT_FLT_OPTIONS rrgister */ + S2LPSpiReadRegisters(RSSI_FLT_ADDR, 1, &tmpBuffer[0]); + + /* Enables or disables filtering on my address */ + tmpBuffer[0] &= ~(RSSI_FLT_REGMASK | CS_MODE_REGMASK); + tmpBuffer[0] |= (xSRssiInit->cRssiFlt<<4); + tmpBuffer[0] |= (xSRssiInit->xRssiMode<<2); + + tmpBuffer[1] = S2LPRadioRssidBmToReg(xSRssiInit->cRssiThreshdBm); + + g_xStatus = S2LPSpiWriteRegisters(RSSI_FLT_ADDR, 2, tmpBuffer); +} + + +/** +* @brief Return the RSSI measurements information to be filled with the information. +* @param Pointer to the SRssiInit struct. +* It will be filled with RSSI Mode, RSSI filter gain value and RSSI Threshold. +* @retval None. +*/ +void S2LPRadioGetRssiInfo(SRssiInit* xSRssiInit) +{ + uint8_t tmpBuffer[2]; + + S2LPSpiReadRegisters(RSSI_FLT_ADDR, 2, tmpBuffer); + + xSRssiInit->xRssiMode = (SRssiMode)((tmpBuffer[0]&CS_MODE_REGMASK)>>2); + xSRssiInit->cRssiFlt = (tmpBuffer[0]&RSSI_FLT_REGMASK)>>4; + xSRssiInit->cRssiThreshdBm = S2LPRadioRegToRssidBm(tmpBuffer[1]); + +} + + +/** +* @brief Enable or disables the CS blanking. +* @param xCsBlank enable or disable. +* @retval None. +*/ +void S2LPRadioCsBlanking(SFunctionalState xCsBlank) +{ + uint8_t tmp; + + s_assert_param(IS_SFUNCTIONAL_STATE(xCsBlank)); + + S2LPSpiReadRegisters(ANT_SELECT_CONF_ADDR, 1, &tmp); + + if(xCsBlank == S_ENABLE) { + tmp |= CS_BLANKING_REGMASK; + } else { + tmp &= ~CS_BLANKING_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(ANT_SELECT_CONF_ADDR, 1, &tmp); + +} + + +/** +* @brief Enable or Disable the antenna switching. +* @param xAntennaSwitch enable or disable. +* @retval None. +*/ +void S2LPRadioAntennaSwitching(SFunctionalState xAntennaSwitch) +{ + uint8_t tmp; + + s_assert_param(IS_SFUNCTIONAL_STATE(xAntennaSwitch)); + + S2LPSpiReadRegisters(ANT_SELECT_CONF_ADDR, 1, &tmp); + + if(xAntennaSwitch == S_ENABLE) { + tmp |= AS_ENABLE_REGMASK; + } else { + tmp &= ~AS_ENABLE_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(ANT_SELECT_CONF_ADDR, 1, &tmp); + +} + + +/** +* @brief Set the PQI check. +* @param PQI_LEVEL. +* @retval None. +*/ +void S2LPRadioSetPqiCheck(uint8_t cPqiLevel) +{ + uint8_t tmp; + s_assert_param(IS_PQI_LVL_CHECK(cPqiLevel)); + + S2LPSpiReadRegisters(QI_ADDR, 1, &tmp); + tmp &= ~PQI_TH_REGMASK; + tmp |= (((uint8_t)cPqiLevel)<<1); + S2LPSpiWriteRegisters(QI_ADDR, 1, &tmp); + +} + + +/** +* @brief Return the CS (carrier sense) indication. +* @param None. +* @retval CS indication. +*/ +SFlagStatus S2LPQiGetCs(void) +{ + uint8_t tmp; + + S2LPSpiReadRegisters(LINK_QUALIF1_ADDR, 1, &tmp); + tmp = (tmp&CS_REGMASK)>>7; + return (SFlagStatus)tmp; +} + + + +/** + *@} + */ + +/** + *@} + */ + + +/** + *@} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Radio.c b/strf/s2lp/S2LP_Library/Src/S2LP_Radio.c new file mode 100644 index 00000000..d941af06 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Radio.c @@ -0,0 +1,1596 @@ +/** + * @file S2LP_Radio.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief This file provides all the low level API to manage Analog and Digital + * radio part of S2-LP. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2019 STMicroelectronics

+ * + */ + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Radio.h" +#include "S2LP_Config.h" +#include "MCU_Interface.h" + + +/** @addtogroup S2LP_Libraries +* @{ +*/ + + +/** @addtogroup S2LP_Radio +* @{ +*/ + + +/** @defgroup Radio_Private_Defines Radio Private Defines +* @{ +*/ + +#define MAX_PA_VALUE 14 +#define MIN_PA_VALUE -31 + +#define VCO_CENTER_FREQ 3600000000 /*!< VCO center frequency in Hz */ + +#define HIGH_BAND_FACTOR 4 /*!< Band select factor for high band. Factor B in the equation 2 */ +#define MIDDLE_BAND_FACTOR 8 /*!< Band select factor for middle band. Factor B in the equation 2 */ + +#define HIGH_BAND_LOWER_LIMIT 860000000 /*!< Lower limit of the high band: 860 MHz */ +#define HIGH_BAND_UPPER_LIMIT 940000000 /*!< Upper limit of the high band: 940 MHz */ +#define MIDDLE_BAND_LOWER_LIMIT 430000000 /*!< Lower limit of the middle band: 430 MHz */ +#define MIDDLE_BAND_UPPER_LIMIT 470000000 /*!< Upper limit of the middle band: 470 MHz */ + +#define MINIMUM_DATARATE 100 /*!< Minimum datarate supported by S2LP 100 bps */ +#define MAXIMUM_DATARATE 250000 /*!< Maximum datarate supported by S2LP 250 ksps */ + + +/** +* @} +*/ + + +/** @defgroup Radio_Private_Macros Radio Private Macros +* @{ +*/ + +#define IS_PA_MAX_INDEX(INDEX) ((INDEX)<=7) +#define IS_PAPOWER_DBM(PATABLE) ((PATABLE)>= (MIN_PA_VALUE) && (PATABLE)<=(MAX_PA_VALUE)) +#define IS_PAPOWER(PATABLE) ((PATABLE)<=90) +#define IS_PA_STEP_WIDTH(WIDTH) ((WIDTH)>=1 && (WIDTH)<=4) + +#define IS_MODULATION(MOD) (((MOD) == MOD_NO_MOD) || \ + ((MOD) == MOD_2FSK) || \ + ((MOD) == MOD_4FSK) || \ + ((MOD) == MOD_2GFSK_BT05) || \ + ((MOD) == MOD_2GFSK_BT1) || \ + ((MOD) == MOD_4GFSK_BT05) || \ + ((MOD) == MOD_4GFSK_BT1) || \ + ((MOD) == MOD_ASK_OOK) || \ + ((MOD) == MOD_POLAR)) + +#define IS_AFC_MODE(MODE) (MODE<=1) +#define IS_AFC_GAIN(GAIN) (GAIN<=15) +#define IS_ISI_EQU(MODE) (MODE<=2) +#define IS_CLKREC_MODE(MODE) (MODE<=1) +#define IS_CLKREC_P_GAIN(GAIN) (GAIN<=7) +#define IS_CLKREC_I_GAIN(GAIN) (GAIN<=15) + + +#define IS_FREQUENCY_BAND_HIGH(FREQUENCY) ((FREQUENCY)>=HIGH_BAND_LOWER_LIMIT && \ + (FREQUENCY)<=HIGH_BAND_UPPER_LIMIT) + +#define IS_FREQUENCY_BAND_MIDDLE(FREQUENCY) ((FREQUENCY)>=MIDDLE_BAND_LOWER_LIMIT && \ + (FREQUENCY)<=MIDDLE_BAND_UPPER_LIMIT) + +#define IS_FREQUENCY_BAND(FREQUENCY) (IS_FREQUENCY_BAND_HIGH(FREQUENCY) || \ + IS_FREQUENCY_BAND_MIDDLE(FREQUENCY)) + +#define IS_CHANNEL_SPACE(CHANNELSPACE, F_Xo) (CHANNELSPACE<=(F_Xo/32768*255)) + + +#define IS_DATARATE(DATARATE, F_CLK) (DATARATE>=MINIMUM_DATARATE && DATARATE<=((uint64_t)MAXIMUM_DATARATE*F_CLK/1000000)/26) + + +#define F_DEV_LOWER_LIMIT(F_Xo) (F_Xo>>22) +#define F_DEV_UPPER_LIMIT(F_Xo) (((uint64_t)787109*F_Xo/1000000)/26) +#define IS_F_DEV(FDEV,F_Xo) (FDEV>=F_DEV_LOWER_LIMIT(F_Xo) && FDEV<=F_DEV_UPPER_LIMIT(F_Xo)) + +#define CH_BW_LOWER_LIMIT(F_CLK) (((uint64_t)1100*F_CLK/1000000)/26) /*!< Minimum value of the channel filter bandwidth */ +#define CH_BW_UPPER_LIMIT(F_CLK) (((uint64_t)800100*F_CLK/1000000)/26) /*!< Maximum value of the channel filter bandwidth */ + +#define IS_CH_BW(BW,F_Xo) ((BW)>=CH_BW_LOWER_LIMIT(F_Xo) && (BW)<=CH_BW_UPPER_LIMIT(F_Xo)) + +/** +* @} +*/ + + +/** @defgroup Radio_Private_Variables Radio Private Variables +* @{ +*/ + +/** +* @brief The Xtal frequency. To be set by the user (see SetXtalFreq() function) +*/ +static uint32_t s_lXtalFrequency=50000000; + + +/** +* @brief It represents the available channel bandwidth times 10 for 26 Mhz xtal. +* @note The channel bandwidth for others xtal frequencies can be computed since this table +* multiplying the current table by a factor xtal_frequency/26e6. +*/ +static const uint16_t s_vectnBandwidth26M[90]= +{ + 8001, 7951, 7684, 7368, 7051, 6709, 6423, 5867, 5414, \ + 4509, 4259, 4032, 3808, 3621, 3417, 3254, 2945, 2703, \ + 2247, 2124, 2015, 1900, 1807, 1706, 1624, 1471, 1350, \ + 1123, 1062, 1005, 950, 903, 853, 812, 735, 675, \ + 561, 530, 502, 474, 451, 426, 406, 367, 337, \ + 280, 265, 251, 237, 226, 213, 203, 184, 169, \ + 140, 133, 126, 119, 113, 106, 101, 92, 84, \ + 70, 66, 63, 59, 56, 53, 51, 46, 42, \ + 35, 33, 31, 30, 28, 27, 25, 23, 21, \ + 18, 17, 16, 15, 14, 13, 13, 12, 11 +}; + + +/** +* @} +*/ + + +/** @defgroup Radio_Private_FunctionPrototypes Radio Private Function Prototypes +* @{ +*/ +uint32_t S2LPRadioComputeDatarate(uint16_t cM, uint8_t cE); +void S2LPRadioSearchDatarateME(uint32_t lDatarate, uint16_t* pcM, uint8_t* pcE); +void S2LPRadioSearchFreqDevME(uint32_t lFDev, uint8_t* pcM, uint8_t* pcE); +void S2LPRadioSearchChannelBwME(uint32_t lBandwidth, uint8_t* pcM, uint8_t* pcE); +uint32_t S2LPRadioComputeDatarate(uint16_t cM, uint8_t cE); +uint32_t S2LPRadioComputeFreqDeviation(uint8_t cM, uint8_t cE, uint8_t bs, uint8_t refdiv); +uint32_t S2LPRadioComputeChannelFilterBw(uint8_t cM, uint8_t cE); +uint32_t S2LPRadioComputeFrequencyBase(uint32_t lSynthWord, uint8_t bs, uint8_t refdiv); +uint32_t S2LPRadioComputeSynthWord(uint32_t frequency, uint8_t refdiv); +uint8_t S2LPRadioComputeChannelSpacingRegValue(uint32_t lChannelSpace); +uint32_t S2LPRadioComputeChannelSpacing(uint8_t cChSpaceRegVal); +void S2LPRadioSearchWCP(uint8_t* cp_isel, uint8_t* pfd_split, uint32_t lFc, uint8_t refdiv); +void S2LPRadioComputeIF(uint32_t nIF, uint8_t* pcAnaIf, uint8_t* pcPcDigIf); + +/** +* @} +*/ + + +/** @defgroup Radio_Private_Functions Radio Private Functions +* @{ +*/ + +/** +* @brief Returns the mantissa and exponent, whose value used in the datarate formula +* will give the datarate value closer to the given datarate. +* @param fDatarate datarate expressed in bps. This parameter ranging between 100 and 500000. +* @param pcM pointer to the returned mantissa value. +* @param pcE pointer to the returned exponent value. +* @retval None. +*/ +void S2LPRadioSearchDatarateME(uint32_t lDatarate, uint16_t* pcM, uint8_t* pcE) +{ + uint32_t lDatarateTmp, f_dig=s_lXtalFrequency; + uint8_t uDrE; + uint64_t tgt1,tgt2,tgt; + + if(f_dig>DIG_DOMAIN_XTAL_THRESH) { + f_dig >>= 1; + } + + /* Search the exponent value */ + for(uDrE = 0; uDrE != 12; uDrE++) { + lDatarateTmp = S2LPRadioComputeDatarate(0xFFFF, uDrE); + if(lDatarate<=lDatarateTmp) + break; + } + (*pcE) = (uint8_t)uDrE; + + if(uDrE==0) { + tgt=((uint64_t)lDatarate)<<32; + (*pcM) = (uint16_t)(tgt/f_dig); + tgt1=(uint64_t)f_dig*(*pcM); + tgt2=(uint64_t)f_dig*((*pcM)+1); + } + else { + tgt=((uint64_t)lDatarate)<<(33-uDrE); + (*pcM) = (uint16_t)((tgt/f_dig)-65536); + tgt1=(uint64_t)f_dig*((*pcM)+65536); + tgt2=(uint64_t)f_dig*((*pcM)+1+65536); + } + + + (*pcM)=((tgt2-tgt)<(tgt-tgt1))?((*pcM)+1):(*pcM); + +} + +/** +* @brief Returns the mantissa and exponent, whose value used in the frequency deviation formula +* will give a frequency deviation value most closer to the given frequency deviation. +* @param fFDev frequency deviation expressed in Hz. This parameter can be a value in the range [F_Xo*8/2^18, F_Xo*7680/2^18]. +* @param pcM pointer to the returned mantissa value. +* @param pcE pointer to the returned exponent value. +* @retval None. +*/ +void S2LPRadioSearchFreqDevME(uint32_t lFDev, uint8_t* pcM, uint8_t* pcE) +{ + uint8_t uFDevE, tmp, bs = MIDDLE_BAND_FACTOR, refdiv = 1; + uint32_t lFDevTmp; + uint64_t tgt1,tgt2,tgt; + + s_assert_param(IS_F_DEV(lFDev, s_lXtalFrequency)); + + S2LPSpiReadRegisters(SYNT3_ADDR, 1, &tmp); + if((tmp&BS_REGMASK) == 0) { + bs = HIGH_BAND_FACTOR; + } + + if(S2LPRadioGetRefDiv()) { + refdiv = 2; + } + + /* Search the exponent of the frequency deviation value */ + for(uFDevE = 0; uFDevE != 12; uFDevE++) { + lFDevTmp = S2LPRadioComputeFreqDeviation(255, uFDevE, bs, refdiv); + if(lFDevDIG_DOMAIN_XTAL_THRESH) { + f_dig >>= 1; + } + + s_assert_param(IS_CH_BW(lBandwidth,f_dig)); + + /* Search the channel filter bandwidth table index */ + for(i=0;i<90 && (lBandwidth<(uint32_t)(((uint64_t)s_vectnBandwidth26M[i]*f_dig)/260000));i++); + + if(i!=0) { + /* Finds the index value with best approximation in i-1, i and i+1 elements */ + i_tmp = i; + + for(uint8_t j=0;j<3;j++) { + if(((i_tmp+j-1)>=0) && ((i_tmp+j-1)<=89)) { + chfltCalculation[j] = (int32_t)lBandwidth - (int32_t)(((uint64_t)s_vectnBandwidth26M[i_tmp+j-1]*f_dig)/260000); + } + else { + chfltCalculation[j] = 0x7FFFFFFF; + } + } + uint32_t chfltDelta = 0xFFFFFFFF; + + for(uint8_t j=0;j<3;j++) { + if(S_ABS(chfltCalculation[j])DIG_DOMAIN_XTAL_THRESH) { + f_dig >>= 1; + } + + if(cE==0) { + dr=((uint64_t)f_dig*cM); + return (uint32_t)(dr>>32); + } + + dr=((uint64_t)f_dig)*((uint64_t)cM+65536); + + return (uint32_t)(dr>>(33-cE)); +} + +/** +* @brief Returns the mantissa and exponent, whose value used in the datarate formula +* will give the datarate value closer to the given datarate. +* @param fDatarate datarate expressed in bps. This parameter ranging between 100 and 500000. +* @param pcM pointer to the returned mantissa value. +* @param pcE pointer to the returned exponent value. +* @retval None. +*/ +uint32_t S2LPRadioComputeFreqDeviation(uint8_t cM, uint8_t cE, uint8_t bs, uint8_t refdiv) +{ + uint32_t f_xo=s_lXtalFrequency; + + if(cE==0) { + return (uint32_t)(((uint64_t)f_xo*cM)>>22); + } + + return (uint32_t)(((uint64_t)f_xo*(256+cM))>>(23-cE)); +} + + +/** +* @brief Computes the channel filter value starting from mantissa and exponent. +* @param cM mantissa value. +* @param cE exponent value. +* @retval uint32_t the channel filter value in Hz. +*/ +uint32_t S2LPRadioComputeChannelFilterBw(uint8_t cM, uint8_t cE) +{ + uint32_t f_dig=s_lXtalFrequency; + + if(f_dig>DIG_DOMAIN_XTAL_THRESH) { + f_dig >>= 1; + } + + return (uint32_t)((uint64_t)100*s_vectnBandwidth26M[cM+(cE*9)]*f_dig/26000000); + +} + + +/** +* @brief Computes a frequency from a given SYNTH word. +* @param lSynthWord the given SYNTH word. +* @param bs value of the PLL divider. +* @param refdiv reference divider value value (it can be only 1 or 2). +* @retval uint32_t the frequency base filter value in Hz. +*/ +uint32_t S2LPRadioComputeFrequencyBase(uint32_t lSynthWord, uint8_t bs, uint8_t refdiv) +{ + return (uint32_t)((((uint64_t)s_lXtalFrequency*lSynthWord)>>19)/bs/refdiv); +} + + +/** +* @brief Computes the synth word from a given frequency. +* @param frequency Target frequency value expressed in Hz. +* @param refdiv reference divider value value (it can be only 1 or 2). +* @retval uint32_t SYNTH_WORD. +*/ +uint32_t S2LPRadioComputeSynthWord(uint32_t frequency, uint8_t refdiv) +{ + uint8_t band; + + if(IS_FREQUENCY_BAND_HIGH(frequency)) { + band = HIGH_BAND_FACTOR; + } + else { + band = MIDDLE_BAND_FACTOR; + } + + uint64_t tgt1,tgt2,tgt; + uint32_t synth; + + tgt = (((uint64_t)frequency)<<19)*(band*refdiv); + synth=(uint32_t)(tgt/s_lXtalFrequency); + tgt1 = (uint64_t)s_lXtalFrequency*(synth); + tgt2 = (uint64_t)s_lXtalFrequency*(synth+1); + + synth=((tgt2-tgt)<(tgt-tgt1))?(synth+1):(synth); + + return synth; +} + + +/** +* @brief Computes the channel space register staring from the channel space value in Hz. +* The channel spacing step is F_Xo/32768. +* @param lChannelSpace the channel spacing expressed in Hz. +* @retval uint8_t The channel specing register value . +*/ +uint8_t S2LPRadioComputeChannelSpacingRegValue(uint32_t lChannelSpace) +{ + return (uint32_t)(((uint64_t)lChannelSpace)<<15)/s_lXtalFrequency; +} + + +/** +* @brief Compute the channel spacing register from the channel spacing given in Hz. +* The channel spacing step is F_Xo/32768. +* @param cChSpaceRegVal the channel spacing register +* @retval uint32_t The channel specing value in Hz. +*/ +uint32_t S2LPRadioComputeChannelSpacing(uint8_t cChSpaceRegVal) +{ + return (uint32_t)(((uint64_t)s_lXtalFrequency*cChSpaceRegVal)>>15); +} + + +/** +* @brief Computes the ANALOG_IF and DIGITAL_IF register values staring from a image frequency +* value in Hz. +* @param nIF datarate expressed in bps. This parameter ranging between 100 and 500000. +* @param pcAnaIf pointer to the register of analog IF. +* @param pcDigIf pointer to the returned of digital IF. +* @retval None. +*/ +void S2LPRadioComputeIF(uint32_t nIF, uint8_t* pcAnaIf, uint8_t* pcDigIf) +{ + uint32_t f_dig=s_lXtalFrequency; + + if(f_dig>DIG_DOMAIN_XTAL_THRESH) { + f_dig >>= 1; + } + + (*pcAnaIf)=(uint8_t)((((uint64_t)nIF)<<13)*3/s_lXtalFrequency-100); + (*pcDigIf)=(uint8_t)((((uint64_t)nIF)<<13)*3/f_dig-100); +} + + +/** +* @brief Returns the charge pump word for a given VCO frequency. +* @param cp_isel pointer to the charge pump register value. +* @param pfd_split pointer to the pfd register value. +* @param lFc channel center frequency expressed in Hz. +* This parameter can be a value in one of the following ranges:
    +*
  • High_Band: from 779 MHz to 915 MHz
  • +*
  • Middle Band: from 387 MHz to 470 MHz
  • +* @param refdiv reference divider value value (it can be only 1 or 2). +* @retval uint8_t Charge pump word. +*/ +void S2LPRadioSearchWCP(uint8_t* cp_isel, uint8_t* pfd_split, uint32_t lFc, uint8_t refdiv) +{ + uint32_t vcofreq, lFRef; + uint8_t BFactor = MIDDLE_BAND_FACTOR; + + s_assert_param(IS_FREQUENCY_BAND(lFc)); + + /* Search the operating band */ + if(IS_FREQUENCY_BAND_HIGH(lFc)) { + BFactor = HIGH_BAND_FACTOR; + } + + /* Calculates the VCO frequency VCOFreq = lFc*B */ + vcofreq = lFc*BFactor; + + /* Calculated the reference frequency clock */ + lFRef = s_lXtalFrequency/refdiv; + + /* Set the correct charge pump word */ + if(vcofreq>=VCO_CENTER_FREQ) { + if(lFRef>DIG_DOMAIN_XTAL_THRESH) { + *cp_isel = 0x02; + *pfd_split = 0; + } + else { + *cp_isel = 0x01; + *pfd_split = 1; + } + } + else { + if(lFRef>DIG_DOMAIN_XTAL_THRESH) { + *cp_isel = 0x03; + *pfd_split = 0; + } + else { + *cp_isel = 0x02; + *pfd_split = 1; + } + } + +} + + +/** +* @} +*/ + + +/** @defgroup Radio_Public_Functions Radio Public Functions +* @{ +*/ + + +/** +* @brief Initializes the S2LP analog and digital radio part according to the specified +* parameters in the pxSRadioInitStruct. +* @param pxSRadioInitStruct pointer to a SRadioInit structure that +* contains the configuration information for the analog radio part of S2LP. +* @retval Error code: 0=no error, 1=error during calibration of VCO. +*/ +uint8_t S2LPRadioInit(SRadioInit* pxSRadioInitStruct) +{ + uint8_t tmpBuffer[6], tmp8, dr_e, fdev_m, fdev_e, bw_m, bw_e; + uint16_t dr_m; + SFunctionalState xState; + + s_assert_param(IS_FREQUENCY_BAND(pxSRadioInitStruct->lFrequencyBase)); + s_assert_param(IS_MODULATION(pxSRadioInitStruct->xModulationSelect)); + s_assert_param(IS_DATARATE(pxSRadioInitStruct->lDatarate,s_lXtalFrequency)); + s_assert_param(IS_F_DEV(pxSRadioInitStruct->lFreqDev,s_lXtalFrequency)); + + /* Configure the digital, ADC, SMPS reference clock divider */ + xState = S2LPRadioGetDigDiv(); + if(((s_lXtalFrequencyDIG_DOMAIN_XTAL_THRESH) && (xState==S_DISABLE))) { + S2LPSpiCommandStrobes(CMD_STANDBY); + do{ + for(volatile uint8_t i=0; i!=0xFF; i++); + S2LPRefreshStatus(); // add a timer expiration callback + }while(g_xStatus.MC_STATE!=MC_STATE_STANDBY); + + xState = (SFunctionalState)!xState; + S2LPRadioSetDigDiv(xState); + + S2LPSpiCommandStrobes(CMD_READY); + do{ + for(volatile uint8_t i=0; i!=0xFF; i++); + S2LPRefreshStatus(); // add a timer expiration callback + }while(g_xStatus.MC_STATE!=MC_STATE_READY); + } + + if(xState==S_ENABLE) { + s_assert_param(IS_CH_BW(pxSRadioInitStruct->lBandwidth,(s_lXtalFrequency>>1))); + } + else { + s_assert_param(IS_CH_BW(pxSRadioInitStruct->lBandwidth,s_lXtalFrequency)); + } + + /* Intermediate Frequency setting */ + S2LPRadioComputeIF(300000, &tmpBuffer[0], &tmpBuffer[1]); + S2LPSpiWriteRegisters(IF_OFFSET_ANA_ADDR, 2, tmpBuffer); + + /* Calculates the datarate register values */ + S2LPRadioSearchDatarateME(pxSRadioInitStruct->lDatarate, &dr_m, &dr_e); + tmpBuffer[0] = (uint8_t)(dr_m>>8); + tmpBuffer[1] = (uint8_t)dr_m; + tmpBuffer[2] = (uint8_t)(pxSRadioInitStruct->xModulationSelect | dr_e); + + + + /* Calculates the frequency deviation register values */ + S2LPRadioSearchFreqDevME(pxSRadioInitStruct->lFreqDev, &fdev_m, &fdev_e); + S2LPSpiReadRegisters(MOD1_ADDR, 1, &tmpBuffer[3]); + tmpBuffer[3] &= ~FDEV_E_REGMASK; + tmpBuffer[3] |= fdev_e; + tmpBuffer[4] = fdev_m; + + /* Calculates the channel filter register values */ + S2LPRadioSearchChannelBwME(pxSRadioInitStruct->lBandwidth, &bw_m, &bw_e); + tmpBuffer[5] = (bw_m<<4) | bw_e; + + /* Configures the radio registers */ + S2LPSpiWriteRegisters(MOD4_ADDR, 6, tmpBuffer); + + S2LPSpiReadRegisters(PA_POWER0_ADDR, 3, &tmpBuffer[0]); + + /* if OOK is selected enable the PA_FC else enable it */ + if((pxSRadioInitStruct->xModulationSelect)!=MOD_ASK_OOK) + { + tmpBuffer[0] &= 0x7F; + tmpBuffer[1] &= 0xFD; + } + else + { + tmpBuffer[0] |= 0x80; + tmpBuffer[1] |= 0x02; + } + + + tmpBuffer[2]&=0xFC; + + /* Bessel filter config */ + if(pxSRadioInitStruct->lDatarate<16000) + { + tmpBuffer[2]|=0x00; + } + else if(pxSRadioInitStruct->lDatarate<32000) + { + tmpBuffer[2]|=0x01; + } + else if(pxSRadioInitStruct->lDatarate<62500) + { + tmpBuffer[2]|=0x02; + } + else + { + tmpBuffer[2]|=0x03; + } + S2LPSpiWriteRegisters(PA_POWER0_ADDR, 3, &tmpBuffer[0]); + + /* Enable the freeze option of the AFC on the SYNC word */ + S2LPSpiReadRegisters(AFC2_ADDR, 1, &tmp8); + tmp8 |= AFC_FREEZE_ON_SYNC_REGMASK; S2LPSpiWriteRegisters(AFC2_ADDR, 1, &tmp8); + + return S2LPRadioSetFrequencyBase(pxSRadioInitStruct->lFrequencyBase); + +} + + +/** +* @brief Returns the S2LP analog and digital radio structure according to the registers value. +* @param pxSRadioInitStruct pointer to a SRadioInit structure that +* contains the configuration information for the analog radio part of S2LP. +* @retval None. +*/ +void S2LPRadioGetInfo(SRadioInit* pxSRadioInitStruct) +{ + uint8_t tmpBuffer[6]; + uint8_t band, cRefDiv, dr_e, fdev_m, fdev_e, bw_e, bw_m; + uint16_t dr_m; + uint32_t tmp32; + + S2LPSpiReadRegisters(SYNT3_ADDR, 4, tmpBuffer); + + /* Reads the operating band masking the Band selected field */ + if(tmpBuffer[0] & BS_REGMASK) { + band = MIDDLE_BAND_FACTOR; + } + else { + band = HIGH_BAND_FACTOR; + } + + /* Computes the synth word */ + tmp32 = (((uint32_t)(tmpBuffer[0] & SYNT_27_24_REGMASK))<<24) | (((uint32_t)tmpBuffer[1])<<16) | (((uint32_t)tmpBuffer[2])<<8) | ((uint32_t)tmpBuffer[3]); + + /* Calculates the frequency base */ + cRefDiv = (uint8_t)S2LPRadioGetRefDiv() + 1; + + pxSRadioInitStruct->lFrequencyBase = S2LPRadioComputeFrequencyBase(tmp32, band, cRefDiv); + + /* Reads the radio registers */ + g_xStatus = S2LPSpiReadRegisters(MOD4_ADDR, 6, tmpBuffer); + + /* Modulation select */ + pxSRadioInitStruct->xModulationSelect = (ModulationSelect)(tmpBuffer[2] & MOD_TYPE_REGMASK); + + /* Reads the frequency deviation for mantissa and exponent */ + fdev_m = tmpBuffer[4]; + fdev_e = tmpBuffer[3] & FDEV_E_REGMASK; + + /* Reads the channel filter register for mantissa and exponent */ + bw_m = (tmpBuffer[5] & CHFLT_M_REGMASK)>>4; + bw_e = tmpBuffer[5] & CHFLT_E_REGMASK; + + /* Reads the data rate register for mantissa and exponent */ + dr_m = ((uint16_t)tmpBuffer[0]<<8) | ((uint16_t)tmpBuffer[1]); + dr_e = tmpBuffer[2] & DATARATE_E_REGMASK; + + /* Calculates the datarate */ + pxSRadioInitStruct->lDatarate = S2LPRadioComputeDatarate(dr_m, dr_e); + + /* Calculates the frequency deviation */ + pxSRadioInitStruct->lFreqDev = S2LPRadioComputeFreqDeviation(fdev_m, fdev_e, band, cRefDiv); + + /* Reads the channel filter bandwidth from the look-up table and return it */ + pxSRadioInitStruct->lBandwidth = S2LPRadioComputeChannelFilterBw(bw_m, bw_e); + +} + + +/** +* @brief Sets the SYNTH registers. +* @param lSynthWord the synth word to write in the SYNTH[3:0] registers. +* @retval None. +*/ +void S2LPRadioSetSynthWord(uint32_t lSynthWord) +{ + uint8_t tmpBuffer[4]; + uint8_t tmp; + + S2LPSpiReadRegisters(SYNT3_ADDR, 1, &tmp); + tmp &= ~SYNT_27_24_REGMASK; + + /* Build the array for SYNTH registers */ + tmpBuffer[0] = (((uint8_t)(lSynthWord>>24)) & SYNT_27_24_REGMASK) | tmp; + tmpBuffer[1] = (uint8_t)(lSynthWord>>16); + tmpBuffer[2] = (uint8_t)(lSynthWord>>8); + tmpBuffer[3] = (uint8_t)lSynthWord; + + g_xStatus = S2LPSpiWriteRegisters(SYNT3_ADDR, 4, tmpBuffer); +} + + +/** +* @brief Returns the synth word. +* @param None. +* @retval uint32_t Synth word. +*/ +uint32_t S2LPRadioGetSynthWord(void) +{ + uint8_t tmpBuffer[4]; + g_xStatus = S2LPSpiReadRegisters(SYNT3_ADDR, 4, tmpBuffer); + return ((((uint32_t)(tmpBuffer[0] & SYNT_27_24_REGMASK))<<24) | (((uint32_t)tmpBuffer[1])<<16) | (((uint32_t)tmpBuffer[2])<<8) | ((uint32_t)tmpBuffer[3])); +} + + +/** +* @brief Sets the channel number. +* @param cChannel the channel number. +* @retval None. +*/ +void S2LPRadioSetChannel(uint8_t cChannel) +{ + g_xStatus = S2LPSpiWriteRegisters(CHNUM_ADDR, 1, &cChannel); +} + + +/** +* @brief Returns the actual channel number. +* @param None. +* @retval uint8_t Actual channel number. +*/ +uint8_t S2LPRadioGetChannel(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(CHNUM_ADDR, 1, &tmp); + return tmp; +} + + +/** +* @brief Set the reference divider value. +* @param xNewState : S_DISABLE to disable the reference divider and S_ENABLE to enable it. +* @retval None. +*/ +void S2LPRadioSetRefDiv(SFunctionalState xNewState) +{ + uint8_t tmp; + + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(XO_RCO_CONF0_ADDR, 1, &tmp); + + if(xNewState == S_ENABLE) { + tmp |= REFDIV_REGMASK; + } else { + tmp &= ~REFDIV_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(XO_RCO_CONF0_ADDR, 1, &tmp); +} + + +/** +* @brief To know if the reference deivider is enabled or disabled. +* @param None. +* @retval SFunctionalState SET (enabled) or RESET (disabled). +*/ +SFunctionalState S2LPRadioGetRefDiv(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(XO_RCO_CONF0_ADDR, 1, &tmp); + + if(tmp & REFDIV_REGMASK) { + return S_ENABLE; + } else { + return S_DISABLE; + } +} + + +/** +* @brief Set the digital divider . +* @param xNewState S_DISABLE to disable the digital divider and S_ENABLE to enable it. +* @retval None. +*/ +void S2LPRadioSetDigDiv(SFunctionalState xNewState) +{ + uint8_t tmp; + + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(XO_RCO_CONF1_ADDR, 1, &tmp); + + if(xNewState == S_ENABLE) { + tmp &= ~PD_CLKDIV_REGMASK; + } else { + tmp |= PD_CLKDIV_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(XO_RCO_CONF1_ADDR, 1, &tmp); +} + + +/** +* @brief Get the digital divider . +* @retval SFunctionalState S_DISABLE to disable the digital divider and S_ENABLE to enable it. +*/ +SFunctionalState S2LPRadioGetDigDiv(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(XO_RCO_CONF1_ADDR, 1, &tmp); + + if(tmp & PD_CLKDIV_REGMASK) { + return S_DISABLE; + } else { + return S_ENABLE; + } +} + + +/** +* @brief Set the channel space factor in channel space register. +* The channel spacing step is computed as F_Xo/32768. +* @param fChannelSpace the channel space expressed in Hz. +* @retval None. +*/ +void S2LPRadioSetChannelSpace(uint32_t lChannelSpace) +{ + uint8_t tmp; + tmp = S2LPRadioComputeChannelSpacingRegValue(lChannelSpace); + g_xStatus = S2LPSpiWriteRegisters(CH_SPACE_ADDR, 1, &tmp); +} + + +/** +* @brief Return the channel space register. +* @param None. +* @retval uint32_t Channel space. The channel space is: CS = channel_space_factor x XtalFrequency/2^15 +* where channel_space_factor is the CHSPACE register value. +*/ +uint32_t S2LPRadioGetChannelSpace(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(CH_SPACE_ADDR, 1, &tmp); + return S2LPRadioComputeChannelSpacing(tmp); +} + + +/** +* @brief Set the Synth word and the Band Select register according to desired base carrier frequency. +* In this API the Xtal configuration is read out from +* the corresponding register. The user shall fix it before call this API. +* @param lFBase the base carrier frequency expressed in Hz as unsigned word. +* @retval Error code: 0=no error, 1=error during calibration of VCO. +*/ +uint8_t S2LPRadioSetFrequencyBase(uint32_t lFBase) +{ + uint32_t tmp32; + uint8_t tmpBuffer[4], cp_isel, bs = 1, pfd_split, tmp, cRefDiv; + + s_assert_param(IS_FREQUENCY_BAND(lFBase)); + + tmp32 = S2LPRadioComputeSynthWord(lFBase, ((uint8_t)S2LPRadioGetRefDiv()+1)); + + if(IS_FREQUENCY_BAND_HIGH(lFBase)) { + bs = 0; + } + + cRefDiv = (uint8_t)S2LPRadioGetRefDiv() + 1; + + /* Search the VCO charge pump word and set the corresponding register */ + S2LPRadioSearchWCP(&cp_isel, &pfd_split, lFBase, cRefDiv); + + S2LPSpiReadRegisters(SYNTH_CONFIG2_ADDR, 1, &tmp); + tmp &= ~PLL_PFD_SPLIT_EN_REGMASK; + tmp |= (pfd_split<<2); + S2LPSpiWriteRegisters(SYNTH_CONFIG2_ADDR, 1, &tmp); + + /* Build the array of registers values for the analog part */ + tmpBuffer[0] = (((uint8_t)(tmp32>>24)) & SYNT_27_24_REGMASK) | cp_isel<<5 | (bs<<4) ; + tmpBuffer[1] = (uint8_t)(tmp32>>16); + tmpBuffer[2] = (uint8_t)(tmp32>>8); + tmpBuffer[3] = (uint8_t)tmp32; + + g_xStatus = S2LPSpiWriteRegisters(SYNT3_ADDR, 4, tmpBuffer); + + return 0; +} + + +/** +* @brief Return the base carrier frequency. +* @param None. +* @retval uint32_t Base carrier frequency expressed in Hz as unsigned word. +*/ +uint32_t S2LPRadioGetFrequencyBase(void) +{ + uint8_t tmpBuffer[4]; + uint32_t tmp32; + uint8_t cRefDiv, band; + + /* Reads the synth registers */ + g_xStatus = S2LPSpiReadRegisters(SYNT3_ADDR, 4, tmpBuffer); + + /* Reads the operating band masking the Band selected field */ + if(tmpBuffer[0] & BS_REGMASK) { + band = MIDDLE_BAND_FACTOR; + } + else { + band = HIGH_BAND_FACTOR; + } + cRefDiv = (uint8_t)S2LPRadioGetRefDiv() + 1; + + /* Computes the synth word */ + tmp32 = (((uint32_t)(tmpBuffer[0] & SYNT_27_24_REGMASK))<<24) | (((uint32_t)tmpBuffer[1])<<16) | (((uint32_t)tmpBuffer[2])<<8) | ((uint32_t)tmpBuffer[3]); + + /* Calculates the frequency base and return it */ + return S2LPRadioComputeFrequencyBase(tmp32, band, cRefDiv); +} + + +/** +* @brief Set the datarate. +* @param fDatarate datarate expressed in bps. This value shall be in the range +* [100 500000]. +* @retval None. +*/ +void S2LPRadioSetDatarate(uint32_t lDatarate) +{ + uint8_t dr_e, tmpBuffer[3]; + uint16_t dr_m; + + if(s_lXtalFrequency>DIG_DOMAIN_XTAL_THRESH) { + s_assert_param(IS_DATARATE(lDatarate,s_lXtalFrequency/2)); + } + else { + s_assert_param(IS_DATARATE(lDatarate,s_lXtalFrequency)); + } + + /* Calculates the datarate mantissa and exponent */ + S2LPRadioSearchDatarateME(lDatarate, &dr_m, &dr_e); + + /* Reads the MOD_O register*/ + S2LPSpiReadRegisters(MOD4_ADDR, 3, tmpBuffer); + + /* Mask the other fields and set the datarate exponent */ + tmpBuffer[0] = (uint8_t)(dr_m>>8); + tmpBuffer[1] = (uint8_t)dr_m; + tmpBuffer[2] &= ~DATARATE_E_REGMASK; + tmpBuffer[2] |= dr_e; + + /* Writes the Datarate registers */ + g_xStatus = S2LPSpiWriteRegisters(MOD4_ADDR, 3, tmpBuffer); + +} + + +/** +* @brief Return the datarate. +* @param None. +* @retval uint32_t Settled datarate expressed in bps. +*/ +uint32_t S2LPRadioGetDatarate(void) +{ + uint8_t tmpBuffer[3], dr_e; + uint16_t dr_m; + + g_xStatus = S2LPSpiReadRegisters(MOD4_ADDR, 3, tmpBuffer); + dr_m = (((uint16_t)tmpBuffer[0])<<8) | ((uint16_t)tmpBuffer[1]); + dr_e = tmpBuffer[2]&DATARATE_E_REGMASK; + + return S2LPRadioComputeDatarate(dr_m, dr_e); +} + + +/** +* @brief Set the frequency deviation. +* @param fFDev frequency deviation expressed in Hz. Be sure that this value +* is in the correct range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz. +* @retval None. +*/ +void S2LPRadioSetFrequencyDev(uint32_t lFDev) +{ + uint8_t uFDevM, uFDevE, tmpBuffer[2]; + + s_assert_param(IS_F_DEV(lFDev, s_lXtalFrequency)); + + /* Calculates the frequency deviation mantissa and exponent */ + S2LPRadioSearchFreqDevME(lFDev, &uFDevM, &uFDevE); + + S2LPSpiReadRegisters(MOD1_ADDR, 2, tmpBuffer); + tmpBuffer[0] &= ~FDEV_E_REGMASK; + tmpBuffer[0] |= uFDevE; + tmpBuffer[1] = uFDevM; + g_xStatus = S2LPSpiWriteRegisters(MOD1_ADDR, 2, tmpBuffer); +} + + +/** +* @brief Return the frequency deviation. +* @param None. +* @retval uint32_t Frequency deviation value expressed in Hz. +* This value will be in the range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz. +*/ +uint32_t S2LPRadioGetFrequencyDev(void) +{ + uint8_t tmpBuffer[2], uFDevE, tmp, refdiv, cBs = HIGH_BAND_FACTOR; + + refdiv = (uint8_t)S2LPRadioGetRefDiv() + 1; + g_xStatus = S2LPSpiReadRegisters(SYNT3_ADDR, 1, &tmp); + if((tmp&BS_REGMASK) == 0) { + cBs = MIDDLE_BAND_FACTOR; + } + + /* Reads the frequency deviation register for mantissa and exponent */ + S2LPSpiReadRegisters(MOD1_ADDR, 2, tmpBuffer); + uFDevE = tmpBuffer[0] & FDEV_E_REGMASK; + + /* Calculates the frequency deviation and return it */ + return S2LPRadioComputeFreqDeviation(tmpBuffer[1], uFDevE, cBs, refdiv); +} + + +/** +* @brief Set the channel filter bandwidth. +* @param lBandwidth channel filter bandwidth expressed in Hz. This parameter shall be in the range [1100 800100] +* Even if it is possible to pass as parameter any value in the above mentioned range, +* the API will search the most closer value according to a fixed table of channel +* bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet. To verify the settled channel bandwidth +* it is possible to use the S2LPRadioGetChannelBW() API. +* @retval None. +*/ +void S2LPRadioSetChannelBW(uint32_t lBandwidth) +{ + uint8_t uBwM, uBwE, tmpBuffer; + + /* Search in the channel filter bandwidth table the exponent value */ + if(s_lXtalFrequency>DIG_DOMAIN_XTAL_THRESH) { + s_assert_param(IS_CH_BW(lBandwidth,(s_lXtalFrequency>>1))); + } + else { + s_assert_param(IS_CH_BW(lBandwidth,(s_lXtalFrequency))); + } + + /* Calculates the channel bandwidth mantissa and exponent */ + S2LPRadioSearchChannelBwME(lBandwidth, &uBwM, &uBwE); + tmpBuffer = (uBwM<<4)|(uBwE); + + /* Writes the Channel filter register */ + g_xStatus = S2LPSpiWriteRegisters(CHFLT_ADDR, 1, &tmpBuffer); + +} + +/** +* @brief Return the channel filter bandwidth. +* @param None. +* @retval uint32_t Channel filter bandwidth expressed in Hz. +*/ +uint32_t S2LPRadioGetChannelBW(void) +{ + uint8_t tmpBuffer, uBwM, uBwE; + + /* Reads the channel filter register for mantissa and exponent */ + g_xStatus = S2LPSpiReadRegisters(CHFLT_ADDR, 1, &tmpBuffer); + uBwM = (tmpBuffer&0xF0)>>4; + uBwE = tmpBuffer&0x0F; + + return S2LPRadioComputeChannelFilterBw(uBwM, uBwE); + +} + + +/** +* @brief Set the modulation type. +* @param xModulation modulation to set. +* This parameter shall be of type @ref ModulationSelect . +* @retval None. +*/ +void S2LPRadioSetModulation(ModulationSelect xModulation) +{ + uint8_t tmpBuffer; + s_assert_param(IS_MODULATION(xModulation)); + + S2LPSpiReadRegisters(MOD2_ADDR, 1, &tmpBuffer); + tmpBuffer &= ~MOD_TYPE_REGMASK; + tmpBuffer |= xModulation; + g_xStatus = S2LPSpiWriteRegisters(MOD2_ADDR, 1, &tmpBuffer); +} + + +/** +* @brief Return the modulation type used. +* @param None. +* @retval ModulationSelect Settled modulation type. +*/ +ModulationSelect S2LPRadioGetModulation(void) +{ + uint8_t tmpBuffer; + + g_xStatus = S2LPSpiReadRegisters(MOD2_ADDR, 1, &tmpBuffer); + return (ModulationSelect)(tmpBuffer&MOD_TYPE_REGMASK); + +} + + +/** +* @brief Set the XTAL frequency. +* @note this function must be called before any Radio setting. +* @param uint32_t XTAL frequency. +* @retval void. +*/ +void S2LPRadioSetXtalFrequency(uint32_t lXtalFrequency) +{ + s_lXtalFrequency = lXtalFrequency; +} + + +/** +* @brief Return the XTAL frequency. +* @param void. +* @retval uint32_t XTAL frequency. +*/ +uint32_t S2LPRadioGetXtalFrequency(void) +{ + return s_lXtalFrequency; +} + + +/** +* @brief Set the MAX_DBM bit. This will allow to transmit at the maximum power. +* @param xNewState enable (S_ENABLE) to enable or disable (S_DISABLE) the max dBm. +* @retval None. +*/ +void S2LPRadioSetMaxPALevel(SFunctionalState xNewState) +{ + uint8_t tmp; + + S2LPSpiReadRegisters(PA_POWER0_ADDR, 1, &tmp); + + if(xNewState == S_ENABLE) { + tmp |= PA_MAXDBM_REGMASK; + } else { + tmp &= ~PA_MAXDBM_REGMASK; + } + + g_xStatus = S2LPSpiWriteRegisters(PA_POWER0_ADDR, 1, &tmp); +} + + +/** +* @brief Sets a specific PA_LEVEL register, with a value given in dBm. +* @param cIndex PA_LEVEL to set. This parameter shall be in the range [0:7]. +* @param lPowerdBm PA value to write expressed in dBm . Be sure that this values is in the +* correct range [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dBm. +* @retval None. +* @note This function makes use of the @ref S2LPRadioGetdBm2Reg fcn to interpolate the +* power value. +*/ +void S2LPRadioSetPALeveldBm(uint8_t cIndex, int32_t lPowerdBm) +{ + uint8_t address, paLevelValue; + s_assert_param(IS_PA_MAX_INDEX(cIndex)); + s_assert_param(IS_PAPOWER_DBM(lPowerdBm)); + + if(lPowerdBm> 14) + { + paLevelValue = 1; + } + else { + paLevelValue = (uint8_t)((int32_t)29-2*lPowerdBm); + } + + address = PA_POWER8_ADDR + 7 - cIndex; + + g_xStatus = S2LPSpiWriteRegisters(address, 1, &paLevelValue); +} + + +/** +* @brief Returns a specific PA_LEVEL register, returning a value in dBm. +* @param cIndex PA_LEVEL to read. This parameter shall be in the range [0:7] +* @retval int32_t Settled power level expressed in dBm. A value +* higher than PA_UPPER_LIMIT dBm implies no output power +* (output stage is in high impedance). +* @note This function makes use of the @ref S2LPRadioGetReg2dBm fcn to interpolate the +* power value. +*/ +int32_t S2LPRadioGetPALeveldBm(uint8_t cIndex) +{ + uint8_t address, paLevelValue; + s_assert_param(IS_PA_MAX_INDEX(cIndex)); + + address = PA_POWER8_ADDR + 7 - cIndex; + + g_xStatus = S2LPSpiReadRegisters(address, 1, &paLevelValue); + + return ((int32_t)29-paLevelValue)/2; +} + + +/** +* @brief Sets a specific PA_LEVEL_MAX_INDEX. +* @param cIndex PA_LEVEL_MAX_INDEX to set. This parameter shall be in the range [0:7]. +* @retval None +*/ +void S2LPRadioSetPALevelMaxIndex(uint8_t cIndex) +{ + uint8_t tmp; + s_assert_param(IS_PA_MAX_INDEX(cIndex)); + + S2LPSpiReadRegisters(PA_POWER0_ADDR, 1, &tmp); + tmp &= (~PA_LEVEL_MAX_IDX_REGMASK); + tmp |= cIndex; + g_xStatus = S2LPSpiWriteRegisters(PA_POWER0_ADDR, 1, &tmp); +} + + +/** +* @brief Returns the actual PA_LEVEL_MAX_INDEX. +* @param None. +* @retval uint8_t Actual PA_LEVEL_MAX_INDEX. This parameter will be in the range [0:7]. +*/ +uint8_t S2LPRadioGetPALevelMaxIndex(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PA_POWER0_ADDR, 1, &tmp); + return (tmp & PA_LEVEL_MAX_IDX_REGMASK); +} + + + +/** +* @brief Set the autoramping mode. +* If enabled: +*
    • Disable the MAXDBM
    • +*
    • Disable the PA_RAMPING
    • +*
    • Enable the FIR_EN
    • +*
    +* @param xNewState Set the autoramping mode. +* @retval None. +*/ +void S2LPRadioSetAutoRampingMode(SFunctionalState xNewState) +{ + uint8_t tmpBuffer[2]; + + S2LPSpiReadRegisters(PA_POWER0_ADDR, 2, tmpBuffer); + + if(xNewState == S_ENABLE) { + tmpBuffer[0] &= ~PA_MAXDBM_REGMASK; + tmpBuffer[0] &= ~PA_RAMP_EN_REGMASK; + tmpBuffer[1] |= FIR_EN_REGMASK; + } else { + tmpBuffer[1] &= ~FIR_EN_REGMASK; + } + + g_xStatus = S2LPSpiWriteRegisters(PA_POWER0_ADDR, 2, tmpBuffer); +} + + + +/** +* @brief Set the manual ramping mode. +*
    • Disable the MAXDBM
    • +*
    • Enable the PA_RAMPING
    • +*
    • Disable the FIR_EN
    • +*
    +* @param xNewState Set the manual ramping mode. +* @retval None. +*/ +void S2LPRadioSetManualRampingMode(SFunctionalState xNewState) +{ + uint8_t tmpBuffer[2]; + + S2LPSpiReadRegisters(PA_POWER0_ADDR, 2, tmpBuffer); + + if(xNewState == S_ENABLE) { + tmpBuffer[0] &= ~PA_MAXDBM_REGMASK; + tmpBuffer[0] |= PA_RAMP_EN_REGMASK; + tmpBuffer[1] &= ~FIR_EN_REGMASK; + } else { + tmpBuffer[0] &= ~PA_RAMP_EN_REGMASK; + } + + g_xStatus = S2LPSpiWriteRegisters(PA_POWER0_ADDR, 2, tmpBuffer); +} + + +/** +* @brief Enable the calibration of the VCO frequency and amplitude. +* @param xAmplitudeCalibration Enables or Disables the calibration of the VCO Amplitude . +* @param xFrequencyCalibration Enables or Disables the calibration of the VCO Frequency . +* @retval None. +*/ +void S2LPRadioCalibrationVco(SFunctionalState xAmplitudeCalibration, SFunctionalState xFrequencyCalibration) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xAmplitudeCalibration)); + s_assert_param(IS_SFUNCTIONAL_STATE(xFrequencyCalibration)); + + S2LPSpiReadRegisters(VCO_CONFIG_ADDR, 1, &tmp); + + if(xAmplitudeCalibration == S_ENABLE) { + tmp |= VCO_CALAMP_EXT_SEL_REGMASK; + } else { + tmp &= ~VCO_CALAMP_EXT_SEL_REGMASK; + } + + if(xFrequencyCalibration == S_ENABLE) { + tmp |= VCO_CALFREQ_EXT_SEL_REGMASK; + } else { + tmp &= ~VCO_CALFREQ_EXT_SEL_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(VCO_CONFIG_ADDR, 1, &tmp); +} + +/** +* @brief Set calibration word of the aplitude in TX. +* @param value Value of the amplitude calibration word. +* @retval None. +*/ +void S2LPRadioSetTxCalibVcoAmpWord(uint8_t value) +{ + value <<= 4; + g_xStatus = S2LPSpiWriteRegisters(VCO_CALIBR_IN2_ADDR, 1, &value); +} + +/** +* @brief Set calibration word of the aplitude in RX. +* @param value Value of the amplitude calibration word. +* @retval None. +*/ +void S2LPRadioSetRxCalibVcoAmpWord(uint8_t value) +{ + value &= VCO_CALAMP_RX_REGMASK; + g_xStatus = S2LPSpiWriteRegisters(VCO_CALIBR_IN2_ADDR, 1, &value); +} + +/** +* @brief Set calibration word of the frequency in TX. +* @param value Value of the frequency calibration word. +* @retval None. +*/ +void S2LPRadioSetTxCalibVcoFreqWord(uint8_t value) +{ + g_xStatus = S2LPSpiWriteRegisters(VCO_CALIBR_IN1_ADDR, 1, &value); +} + +/** +* @brief Set calibration word of the frequency in RX. +* @param value Value of the frequency calibration word. +* @retval None. +*/ +void S2LPRadioSetRxCalibVcoFreqWord(uint8_t value) +{ + g_xStatus = S2LPSpiWriteRegisters(VCO_CALIBR_IN0_ADDR, 1, &value); +} + + +/** +* @brief Initialize the AFC block according to the passed parameters. +* @param xSAfcInit pointer to the AFC struct that contains the parameters value to be set. +* @retval None. +*/ +void S2LPRadioAfcInit(SAfcInit* xSAfcInit) +{ + uint8_t tmpBuffer[3]; + s_assert_param(IS_SFUNCTIONAL_STATE(xSAfcInit->xAfcEnable)); + s_assert_param(IS_SFUNCTIONAL_STATE(xSAfcInit->xAfcFreezeOnSync)); + s_assert_param(IS_AFC_MODE(xSAfcInit->xAfcMode)); + s_assert_param(IS_AFC_GAIN(xSAfcInit->cAfcFastGain)); + s_assert_param(IS_AFC_GAIN(xSAfcInit->cAfcSlowGain)); + + /* Reads the PCKT_FLT_OPTIONS ragister */ + S2LPSpiReadRegisters(AFC2_ADDR, 1, &tmpBuffer[0]); + + /* Enables or disables filtering on my address */ + if(xSAfcInit->xAfcEnable == S_ENABLE) { + tmpBuffer[0] |= AFC_ENABLED_REGMASK; + } + else { + tmpBuffer[0] &= ~AFC_ENABLED_REGMASK; + } + + /* Enables or disables filtering on multicast address */ + if(xSAfcInit->xAfcFreezeOnSync == S_ENABLE) { + tmpBuffer[0] |= AFC_FREEZE_ON_SYNC_REGMASK; + } + else { + tmpBuffer[0] &= ~AFC_FREEZE_ON_SYNC_REGMASK; + } + + /* Enables or disables filtering on broadcast address */ + if(xSAfcInit->xAfcMode == AFC_MODE_LOOP_CLOSED_ON_SLICER) { + tmpBuffer[0] &= ~AFC_MODE_REGMASK; + } + else { + tmpBuffer[0] |= AFC_MODE_REGMASK; + } + + tmpBuffer[1] = xSAfcInit->cAfcFastPeriod; + tmpBuffer[2] = (xSAfcInit->cAfcFastGain<<4) | xSAfcInit->cAfcSlowGain; + + g_xStatus = S2LPSpiWriteRegisters(AFC2_ADDR, 3, tmpBuffer); +} + + +/** +* @brief Return the AFC struct that corresponds to the AFC block parameters set on the chip. +* @param xSAfcInit pointer to the AFC struct that must be filled with the parameters. +* @retval None. +*/ +void S2LPRadioGetAfcInfo(SAfcInit* xSAfcInit) +{ + uint8_t tmpBuffer[3]; + + S2LPSpiReadRegisters(AFC2_ADDR, 3, tmpBuffer); + + xSAfcInit->xAfcFreezeOnSync = (SFunctionalState)((tmpBuffer[0]&AFC_FREEZE_ON_SYNC_REGMASK)>>7); + xSAfcInit->xAfcEnable = (SFunctionalState)((tmpBuffer[0]&AFC_ENABLED_REGMASK)>>6); + xSAfcInit->xAfcMode = (SAfcMode)(tmpBuffer[0]&AFC_MODE_REGMASK); + + xSAfcInit->cAfcFastPeriod = tmpBuffer[1]; + xSAfcInit->cAfcFastGain = (tmpBuffer[2] & AFC_FAST_GAIN_REGMASK)>>4; + xSAfcInit->cAfcSlowGain = (tmpBuffer[2] & AFC_SLOW_GAIN_REGMASK); + +} + + +/** +* @brief Set the ISI equalizer. +* @param xSIsiMode It can be one of the values of @ref SIsiEqu. +* @retval None. +*/ +void S2LPRadioSetIsiEqualizationMode(SIsiEqu xSIsiMode) +{ + uint8_t tmp; + s_assert_param(IS_ISI_EQU(xSIsiMode)); + + S2LPSpiReadRegisters(ANT_SELECT_CONF_ADDR, 1, &tmp); + tmp &= ~EQU_CTRL_REGMASK; + tmp |= (((uint8_t)xSIsiMode)<<5); + g_xStatus = S2LPSpiWriteRegisters(ANT_SELECT_CONF_ADDR, 1, &tmp); +} + + +/** +* @brief Returnthe ISI equalization. +* @param None. +* @retval xSIsiMode It can be one of the values of @ref SIsiEqu. +*/ +SIsiEqu S2LPRadioGetIsiEqualizationMode(void) +{ + uint8_t tmp; + + g_xStatus = S2LPSpiReadRegisters(ANT_SELECT_CONF_ADDR, 1, &tmp); + return (SIsiEqu)((tmp&EQU_CTRL_REGMASK)>>5); + +} + + +/** +* @brief Clock recovery configuration +* @param xSSymClkRecInit pointer to the clock recovery struct to be used to configure the algorithm. +* @retval None. +*/ +void S2LPRadioSymClkRecoverInit(SSymClkRecInit* xSSymClkRecInit) +{ + uint8_t tmpBuffer[2] = {0x00, 0x00}; + s_assert_param(IS_CLKREC_MODE(xSSymClkRecInit->xSClkRecMode)); + s_assert_param(IS_SFUNCTIONAL_STATE(xSSymClkRecInit->cClkRec16SymPostFlt)); + s_assert_param(IS_CLKREC_I_GAIN(xSSymClkRecInit->cClkRecIGainFast)); + s_assert_param(IS_CLKREC_I_GAIN(xSSymClkRecInit->cClkRecIGainSlow)); + s_assert_param(IS_CLKREC_P_GAIN(xSSymClkRecInit->cClkRecPGainFast)); + s_assert_param(IS_CLKREC_P_GAIN(xSSymClkRecInit->cClkRecPGainSlow)); + + /* Enables or disables filtering on my address */ + if(xSSymClkRecInit->xSClkRecMode == CLKREC_PLL_MODE) { + tmpBuffer[0] |= CLK_REC_ALGO_SEL_REGMASK; + } + tmpBuffer[0] |= xSSymClkRecInit->cClkRecIGainSlow; + tmpBuffer[0] |= (xSSymClkRecInit->cClkRecPGainSlow<<5); + + /* Enables or disables filtering on my address */ + if(xSSymClkRecInit->cClkRec16SymPostFlt == S_ENABLE) { + tmpBuffer[1] |= PSTFLT_LEN_REGMASK; + } + tmpBuffer[1] |= xSSymClkRecInit->cClkRecIGainFast; + tmpBuffer[1] |= (xSSymClkRecInit->cClkRecPGainFast<<5); + + g_xStatus = S2LPSpiWriteRegisters(CLOCKREC1_ADDR, 2, tmpBuffer); +} + + +/** +* @brief Return the clock recovery configuration +* @param xSSymClkRecInit pointer to the clock recovery struct to be filled with the clock recovery settings of the chip. +* @retval None. +*/ +void S2LPRadioGetSymClkRecoverInfo(SSymClkRecInit* xSSymClkRecInit) +{ + uint8_t tmpBuffer[2]; + + S2LPSpiReadRegisters(CLOCKREC1_ADDR, 2, tmpBuffer); + + xSSymClkRecInit->xSClkRecMode = (SClkRecMode)((tmpBuffer[0]&CLK_REC_ALGO_SEL_REGMASK)>>4); + xSSymClkRecInit->cClkRecIGainSlow = tmpBuffer[0]&CLK_REC_I_GAIN_SLOW_REGMASK; + xSSymClkRecInit->cClkRecPGainSlow = (tmpBuffer[0]&CLK_REC_P_GAIN_SLOW_REGMASK)>>5; + + xSSymClkRecInit->cClkRec16SymPostFlt = (SFunctionalState)((tmpBuffer[0]&CLK_REC_ALGO_SEL_REGMASK)>>4); + xSSymClkRecInit->cClkRecIGainFast = tmpBuffer[0]&CLK_REC_I_GAIN_FAST_REGMASK; + xSSymClkRecInit->cClkRecPGainFast = (tmpBuffer[0]&CLK_REC_P_GAIN_FAST_REGMASK)>>5; + +} + + + +/** +* @} +*/ + + +/** +* @} +*/ + + +/** +* @} +*/ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ + diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Timer.c b/strf/s2lp/S2LP_Library/Src/S2LP_Timer.c new file mode 100644 index 00000000..a98a3947 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Timer.c @@ -0,0 +1,815 @@ +/** + * @file S2LP_Timer.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief Configuration and management of S2-LP timers. + ****************************************************************************** + * @attention + * + *

    © COPYRIGHT(c) 2019 STMicroelectronics

    + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

    © COPYRIGHT 2019 STMicroelectronics

    + */ + + +/* Includes ------------------------------------------------------------------*/ + +#include "S2LP_Config.h" +#include "MCU_Interface.h" + + +/** + * @addtogroup S2LP_Libraries + * @{ + */ + + +/** + * @addtogroup S2LP_Timer + * @{ + */ + + +/** + * @defgroup Timer_Private_TypesDefinitions Timer Private Types Definitions + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Timer_Private_Defines Timer Private Defines + * @{ + */ + +#define LDC_FREQ_CLK S2LPTimerGetRcoFrequency() + + +/** + *@} + */ + + +/** + * @defgroup Timer_Private_Macros Timer Private Macros + * @{ + */ + +#define IS_RX_TIMEOUT_STOP_CONDITION(COND) ( COND == NO_TIMEOUT_STOP || \ + COND == TIMEOUT_ALWAYS_STOPPED || \ + COND == RSSI_ABOVE_THRESHOLD || \ + COND == SQI_ABOVE_THRESHOLD || \ + COND == PQI_ABOVE_THRESHOLD || \ + COND == RSSI_AND_SQI_ABOVE_THRESHOLD || \ + COND == RSSI_AND_PQI_ABOVE_THRESHOLD || \ + COND == SQI_AND_PQI_ABOVE_THRESHOLD || \ + COND == ALL_ABOVE_THRESHOLD || \ + COND == RSSI_OR_SQI_ABOVE_THRESHOLD || \ + COND == RSSI_OR_PQI_ABOVE_THRESHOLD || \ + COND == SQI_OR_PQI_ABOVE_THRESHOLD || \ + COND == ANY_ABOVE_THRESHOLD ) + +/** + *@} + */ + + +/** + * @defgroup Timer_Private_Variables Timer Private Variables + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Timer_Private_FunctionPrototypes Timer Private Function Prototypes + * @{ + */ + +void S2LPTimerComputeWakeupTimerValues(uint32_t* plWakeUpUsec , uint8_t cCounter , uint8_t cPrescaler, uint8_t cMulti); +void S2LPTimerComputeRxTimerValues(uint32_t* plDesiredUsec, uint8_t pcCounter, uint8_t pcPrescaler); +void S2LPTimerComputeRxTimerRegValues(uint32_t plDesiredUsec , uint8_t* pcCounter , uint8_t* pcPrescaler); +void S2LPTimerComputeWakeupTimerRegValues(uint32_t plDesiredUsec , uint8_t* pcCounter , uint8_t* pcPrescaler, uint8_t* pcMulti); + + +/** + *@} + */ + + +/** + * @defgroup Timer_Private_Functions Timer Private Functions + * @{ + */ + +/** + * @brief Computes the wake up timer. + * @param plWakeUpUsec: pointer to the variable where the wakeup timer (in microseconds) should be stored. + * @param cCounter: Counter + * @param cPrescaler: Prescaler. + * @param cMulti: Multiplier. + * @retval None. + */ +void S2LPTimerComputeWakeupTimerValues(uint32_t* plWakeUpUsec , uint8_t cCounter , uint8_t cPrescaler, uint8_t cMulti) +{ + (*plWakeUpUsec) = (uint32_t)((uint64_t)1000000*(cCounter+1)*(cPrescaler+1)/LDC_FREQ_CLK*cMulti); +} + +/** + * @brief Computes the values of the wakeup timer counter and prescaler from the user time expressed in millisecond. + * The prescaler and the counter values are computed maintaining the prescaler value as + * small as possible in order to obtain the best resolution, and in the meantime minimizing the error. + * @param lDesiredUsec desired wakeup timeout in microseconds. + * Since the counter and prescaler are 8 bit registers the maximum + * reachable value is maxTime = fTclk x 256 x 256. + * @param pcCounter pointer to the variable in which the value for the wakeup timer counter has to be stored. + * This parameter must be a uint8_t*. + * @param pcPrescaler pointer to the variable in which the value for the wakeup timer prescaler has to be stored. + * This parameter must be an uint8_t*. + * @retval None + */ +void S2LPTimerComputeWakeupTimerRegValues(uint32_t lDesiredUsec, uint8_t* pcCounter , uint8_t* pcPrescaler, uint8_t* pcMulti) +{ + uint32_t n; + uint8_t i; + + for(i=0;i<4;i++) + { + if(lDesiredUsec<(((uint32_t)((uint64_t)1000000*65536/LDC_FREQ_CLK))<>i)/1000000); + + /* check if it is possible to reach that target with prescaler and counter of S2LP */ + if(n/0xFF>0xFD) { + /* if not return the maximum possible value */ + (*pcCounter) = 0xFF; + (*pcPrescaler) = 0xFF; + return; + } + + /* prescaler is really 2 as min value */ + (*pcPrescaler) = (n/0xFF)+2; + (*pcCounter) = n / (*pcPrescaler); + +// /* check if the error is minimum */ +// err = S_ABS((float)((*pcCounter)*(*pcPrescaler)/rco_freq)-fDesiredMsec); +// +// if((*pcCounter)<=254) { +// if(S_ABS((float)((*pcCounter)+1)*(*pcPrescaler)/rco_freq-fDesiredMsec)1) + (*pcCounter)--; + else + (*pcCounter)=1; +} + +/** + * @brief Computes the values of the rx_timeout timer counter and prescaler from the user time expressed in millisecond. + * The prescaler and the counter values are computed maintaining the prescaler value as + * small as possible in order to obtain the best resolution, and in the meantime minimizing the error. + * @param lDesiredUsec desired rx_timeout in microsecs. + * This parameter must be a float. Since the counter and prescaler are 8 bit registers the maximum + * reachable value is maxTime = fTclk x 255 x 255. + * @param pcCounter pointer to the variable in which the value for the rx_timeout counter has to be stored. + * This parameter must be a uint8_t*. + * @param pcPrescaler pointer to the variable in which the value for the rx_timeout prescaler has to be stored. + * This parameter must be an uint8_t*. + * @retval None + */ +void S2LPTimerComputeRxTimerRegValues(uint32_t lDesiredUsec , uint8_t* pcCounter , uint8_t* pcPrescaler) +{ + uint32_t f_dig = S2LPRadioGetXtalFrequency(); + uint32_t n; + uint64_t tgt,tgt1,tgt2; + + /* if xtal is doubled divide it by 2 */ + if(f_dig>DIG_DOMAIN_XTAL_THRESH) { + f_dig >>= 1; + } + + /* N cycles in the time base of the timer: + - clock of the timer is f_dig/1210 + - divide times 1000000 more because we have an input in us + */ + tgt=(uint64_t)lDesiredUsec*f_dig; + n=(uint32_t)(tgt/1210000000); + tgt1=(uint64_t)1210000000*n; + tgt2=(uint64_t)1210000000*(n+1); + + n=((tgt2-tgt)<(tgt-tgt1))?(n+1):(n); + + /* check if it is possible to reach that target with prescaler and counter of S2LP */ + if(n/0xFF>0xFD) { + /* if not return the maximum possible value */ + (*pcCounter) = 0xFF; + (*pcPrescaler) = 0xFF; + return; + } + + /* prescaler is really 2 as min value */ + (*pcPrescaler)=(n/0xFF)+2; + (*pcCounter) = n / (*pcPrescaler); + + + /* decrement prescaler and counter according to the logic of this timer in S2LP */ + (*pcPrescaler)--; + + if((*pcCounter)==0) + (*pcCounter)=1; +} + +/** + * @brief Computes the values of the rx_timeout given the timer counter and prescaler. + * @param pulDesiredUsec pointer to rx_timeout in microsecs. + * Since the counter and prescaler are 8 bit registers the maximum + * reachable value is maxTime = fTclk x 255 x 255. + * @param cCounter counter for the rx_timeout. + * This parameter must be a uint8_t. + * @param cPrescaler prescaler for the rx_timeout. + * This parameter must be an uint8_t. + * @retval None + */ +void S2LPTimerComputeRxTimerValues(uint32_t* pulDesiredUsec, uint8_t cCounter, uint8_t cPrescaler) +{ + uint32_t f_dig = S2LPRadioGetXtalFrequency(); + + /* if xtal is doubled divide it by 2 */ + if(f_dig>DIG_DOMAIN_XTAL_THRESH) { + f_dig >>= 1; + } + + (*pulDesiredUsec) = (uint32_t)((uint64_t)1000000*(cPrescaler+1)*cCounter*1210/f_dig); + +} + +/** + *@} + */ + + +/** + * @defgroup Timer_Public_Functions Timer Public Functions + * @{ + */ + + +/** + * @brief Enables or Disables the LDCR mode. + * @param xNewState new state for LDCR mode. + * This parameter can be: S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPTimerLdcrMode(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + if(xNewState==S_ENABLE) { + tmp |= LDC_MODE_REGMASK; + } + else { + tmp &= ~LDC_MODE_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp); +} + + +/** + * @brief Enables or Disables the LDCR timer reloading with the value stored in the LDCR_RELOAD registers. + * @param xNewState new state for LDCR reloading. + * This parameter can be: S_ENABLE or S_DISABLE. + * @retval None. + */ +void S2LPTimerLdcrAutoReload(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + if(xNewState==S_ENABLE) { + tmp |= LDC_RELOAD_ON_SYNC_REGMASK; + } + else { + tmp &= ~LDC_RELOAD_ON_SYNC_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp); +} + + +/** + * @brief Return the LDCR timer reload bit. + * @param None. + * @retval SFunctionalState: value of the reload bit. + */ +SFunctionalState S2LPTimerLdcrGetAutoReload(void) +{ + uint8_t tmp; + g_xStatus = S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + return (SFunctionalState)((tmp & LDC_RELOAD_ON_SYNC_REGMASK)!=0); +} + +/** + * @brief Set the RX timeout timer initialization registers with the values of COUNTER and PRESCALER according to the formula: Trx=PRESCALER*COUNTER*Tck. + * Remember that it is possible to have infinite RX_Timeout writing 0 in the RX_Timeout_Counter and/or RX_Timeout_Prescaler registers. + * @param cCounter value for the timer counter. + * This parameter must be an uint8_t. + * @param cPrescaler value for the timer prescaler. + * This parameter must be an uint8_t. + * @retval None. + */ +void S2LPTimerSetRxTimer(uint8_t cCounter , uint8_t cPrescaler) +{ + uint8_t tmpBuffer[2] = {cCounter, cPrescaler}; + g_xStatus = S2LPSpiWriteRegisters(TIMERS5_ADDR, 2, tmpBuffer); +} + + +/** + * @brief Set the RX timeout timer counter and prescaler from the desired value in ms. it is possible to fix the RX_Timeout to + * a minimum value of 50.417us to a maximum value of about 3.28 s. + * @param lDesiredUsec desired timer value. + * This parameter must be a uint32_t. + * @retval None + */ +void S2LPTimerSetRxTimerUs(uint32_t lDesiredUsec) +{ + uint8_t tmpBuffer[2]; + S2LPTimerComputeRxTimerRegValues(lDesiredUsec , &tmpBuffer[0] , &tmpBuffer[1]); + g_xStatus = S2LPSpiWriteRegisters(TIMERS5_ADDR, 2, tmpBuffer); +} + + +/** + * @brief Set the RX timeout timer counter. If it is equal to 0 the timeout is infinite. + * @param cCounter value for the timer counter. + * This parameter must be an uint8_t. + * @retval None. + */ +void S2LPTimerSetRxTimerCounter(uint8_t cCounter) +{ + g_xStatus = S2LPSpiWriteRegisters(TIMERS5_ADDR, 1, &cCounter); +} + + +/** + * @brief Set the RX timeout timer prescaler. If it is equal to 0 the timeout is infinite. + * @param cPrescaler value for the timer prescaler. + * This parameter must be an uint8_t. + * @retval None + */ +void S2LPTimerSetRxTimerPrescaler(uint8_t cPrescaler) +{ + g_xStatus = S2LPSpiWriteRegisters(TIMERS4_ADDR, 1, &cPrescaler); +} + + +/** + * @brief Return the RX timeout timer. + * @param plTimeoutUsec pointer to the variable in which the timeout expressed in microseconds has to be stored. + * If the returned value is 0, it means that the RX_Timeout is infinite. + * This parameter must be a uint32_t*. + * @param pcCounter pointer to the variable in which the timer counter has to be stored. + * This parameter must be an uint8_t*. + * @param pcPrescaler pointer to the variable in which the timer prescaler has to be stored. + * This parameter must be an uint8_t*. + * @retval None. + */ +void S2LPTimerGetRxTimerUs(uint32_t* plTimeoutUsec, uint8_t* pcCounter , uint8_t* pcPrescaler) +{ + uint8_t tmpBuffer[2]; + + g_xStatus = S2LPSpiReadRegisters(TIMERS5_ADDR, 2, tmpBuffer); + + (*pcCounter) = tmpBuffer[0]; + (*pcPrescaler) = tmpBuffer[1]; + S2LPTimerComputeRxTimerValues(plTimeoutUsec, tmpBuffer[0], tmpBuffer[1]); +} + +/** + * @brief Set the LDCR wake up timer initialization registers with the values of + * COUNTER and PRESCALER according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where + * Tck = 28.818 us. The minimum vale of the wakeup timeout is 28.818us (PRESCALER and + * COUNTER equals to 0) and the maximum value is about 1.89 s (PRESCALER anc COUNTER equals + * to 255). + * @param cCounter value for the timer counter. + * This parameter must be an uint8_t. + * @param cPrescaler value for the timer prescaler. + * This parameter must be an uint8_t. + * @retval None. + */ +void S2LPTimerSetWakeUpTimer(uint8_t cCounter , uint8_t cPrescaler) +{ + uint8_t tmpBuffer[2] = {cPrescaler, cCounter}; + g_xStatus = S2LPSpiWriteRegisters(TIMERS3_ADDR, 2, tmpBuffer); +} + + +/** + * @brief Set the LDCR wake up timer counter and prescaler from the desired value in ms, + * according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us. + * The minimum vale of the wakeup timeout is 28.818us (PRESCALER and COUNTER equals to 0) + * and the maximum value is about 1.89 s (PRESCALER anc COUNTER equals to 255). + * @param fDesiredMsec desired timer value. + * This parameter must be a float. + * @retval None. + */ +void S2LPTimerSetWakeUpTimerUs(uint32_t lDesiredUsec) +{ + uint8_t tmpBuffer[2], multi, tmp; + + /* Computes counter and prescaler */ + S2LPTimerComputeWakeupTimerRegValues(lDesiredUsec , &tmpBuffer[1] , &tmpBuffer[0], &multi); + + S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp); + tmp &= ~LDC_TIMER_MULT_REGMASK; + tmp |= multi; + S2LPSpiWriteRegisters(PROTOCOL2_ADDR, 1, &tmp); + + g_xStatus = S2LPSpiWriteRegisters(TIMERS3_ADDR, 2, tmpBuffer); + +} + + +/** + * @brief Set the LDCR wake up timer counter. Remember that this value is incresead by one in the Twu calculation. + * Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us + * @param cCounter value for the timer counter. + * This parameter must be an uint8_t. + * @retval None. + */ +void S2LPTimerSetWakeUpTimerCounter(uint8_t cCounter) +{ + g_xStatus = S2LPSpiWriteRegisters(TIMERS2_ADDR, 1, &cCounter); +} + + +/** + * @brief Set the LDCR wake up timer prescaler. Remember that this value is incresead by one in the Twu calculation. + * Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us + * @param cPrescaler value for the timer prescaler. + * This parameter must be an uint8_t. + * @retval None. + */ +void S2LPTimerSetWakeUpTimerPrescaler(uint8_t cPrescaler) +{ + g_xStatus = S2LPSpiWriteRegisters(TIMERS3_ADDR, 1, &cPrescaler); +} + + +/** + * @brief Return the LDCR wake up timer, according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us. + * @param plWakeUpUsec pointer to the variable in which the wake-up time expressed in milliseconds has to be stored. + * This parameter must be a uint32_t*. + * @param pcCounter pointer to the variable in which the timer counter has to be stored. + * This parameter must be an uint8_t*. + * @param pcPrescaler pointer to the variable in which the timer prescaler has to be stored. + * This parameter must be an uint8_t*. + * @retval None. + */ +void S2LPTimerGetWakeUpTimerUs(uint32_t* plWakeUpUsec, uint8_t* pcCounter, uint8_t* pcPrescaler, uint8_t* pcMulti) +{ + uint8_t tmpBuffer[2], tmp; + + S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp); + tmp &= LDC_TIMER_MULT_REGMASK; + *pcMulti = tmp; + + g_xStatus = S2LPSpiReadRegisters(TIMERS3_ADDR, 2, tmpBuffer); + *pcCounter = tmpBuffer[1]; + *pcPrescaler = tmpBuffer[0]; + + S2LPTimerComputeWakeupTimerValues(plWakeUpUsec, tmpBuffer[0], tmpBuffer[1], tmp); +} + + +/** + * @brief Set the LDCR wake up timer reloading registers with the values of + * COUNTER and PRESCALER according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where + * Tck = 28.818 us. The minimum vale of the wakeup timeout is 28.818us (PRESCALER and + * COUNTER equals to 0) and the maximum value is about 1.89 s (PRESCALER anc COUNTER equals + * to 255). + * @param cCounter reload value for the timer counter. + * This parameter must be an uint8_t. + * @param cPrescaler reload value for the timer prescaler. + * This parameter must be an uint8_t. + * @retval None. + */ +void S2LPTimerSetWakeUpTimerReload(uint8_t cCounter , uint8_t cPrescaler, uint8_t cMulti) +{ + uint8_t tmpBuffer[2] = {cPrescaler, cCounter}, tmp; + + S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp); + tmp &= (~LDC_TIMER_MULT_REGMASK); + tmp |= cMulti; + S2LPSpiWriteRegisters(PROTOCOL2_ADDR, 1, &tmp); + + g_xStatus = S2LPSpiWriteRegisters(TIMERS1_ADDR, 2, tmpBuffer); +} + + +/** + * @brief Set the LDCR wake up reload timer counter and prescaler from the desired value in ms, + * according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us. + * The minimum vale of the wakeup timeout is 28.818us (PRESCALER and COUNTER equals to 0) + * and the maximum value is about 1.89 s (PRESCALER anc COUNTER equals to 255). + * @param lDesiredUsec desired timer value in us. + * @retval None. + */ +void S2LPTimerSetWakeUpTimerReloadUs(uint32_t lDesiredUsec) +{ + uint8_t tmpBuffer[2], multi, tmp; + + /* Computes counter and prescaler */ + S2LPTimerComputeWakeupTimerRegValues(lDesiredUsec , &tmpBuffer[1] , &tmpBuffer[0], &multi); + + S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp); + tmp &= ~LDC_TIMER_MULT_REGMASK; + tmp |= multi; + S2LPSpiWriteRegisters(PROTOCOL2_ADDR, 1, &tmp); + + g_xStatus = S2LPSpiWriteRegisters(TIMERS1_ADDR, 2, tmpBuffer); +} + + +/** + * @brief Set the LDCR wake up timer reload counter. Remember that this value is incresead by one in the Twu calculation. + * Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us + * @param cCounter value for the timer counter. + * This parameter must be an uint8_t. + * @retval None + */ +void S2LPTimerSetWakeUpTimerReloadCounter(uint8_t cCounter) +{ + g_xStatus = S2LPSpiWriteRegisters(TIMERS0_ADDR, 1, &cCounter); +} + + +/** + * @brief Set the LDCR wake up timer reload prescaler. Remember that this value is incresead by one in the Twu calculation. + * Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us + * @param cPrescaler value for the timer prescaler. + * This parameter must be an uint8_t. + * @retval None + */ +void S2LPTimerSetWakeUpTimerReloadPrescaler(uint8_t cPrescaler) +{ + g_xStatus = S2LPSpiWriteRegisters(TIMERS1_ADDR, 1, &cPrescaler); +} + + +/** + * @brief Return the LDCR wake up reload timer, according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us. + * @param plWakeUpReloadUsec pointer to the variable in which the wake-up reload time expressed in milliseconds has to be stored. + * This parameter must be a uint32_t*. + * @param pcCounter pointer to the variable in which the timer counter has to be stored. + * This parameter must be an uint8_t*. + * @param pcPrescaler pointer to the variable in which the timer prescaler has to be stored. + * This parameter must be an uint8_t*. + * @retval None. + */ +void S2LPTimerGetWakeUpTimerReloadUs(uint32_t* plWakeUpReloadUsec, uint8_t* pcCounter, uint8_t* pcPrescaler, uint8_t* pcMulti) +{ + uint8_t tmpBuffer[2], tmp; + + S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp); + tmp &= LDC_TIMER_MULT_REGMASK; + *pcMulti = tmp; + + g_xStatus = S2LPSpiReadRegisters(TIMERS3_ADDR, 2, tmpBuffer); + *pcCounter = tmpBuffer[1]; + *pcPrescaler = tmpBuffer[0]; + + S2LPTimerComputeWakeupTimerValues(plWakeUpReloadUsec, tmpBuffer[1], tmpBuffer[0], tmp); +} + + +/** + * @brief Set the RX timeout stop conditions. + * @param xStopCondition new stop condition. + * This parameter can be any value of @ref RxTimeoutStopCondition. + * @retval None + */ +void S2LPTimerSetRxTimerStopCondition(RxTimeoutStopCondition xStopCondition) +{ + uint8_t tmp; + s_assert_param(IS_RX_TIMEOUT_STOP_CONDITION(xStopCondition)); + + S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp); + tmp &= ~(CS_TIMEOUT_MASK_REGMASK | SQI_TIMEOUT_MASK_REGMASK | PQI_TIMEOUT_MASK_REGMASK); + tmp |= (((uint8_t)xStopCondition) << 5); + S2LPSpiWriteRegisters(PROTOCOL2_ADDR, 1, &tmp); + + S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmp); + tmp &= ~RX_TIMEOUT_AND_OR_SEL_REGMASK; + tmp |= (((uint8_t)xStopCondition) >> 1); + g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmp); +} + + +/** + * @brief Computes and Return the RCO frequency. + * This frequency depends on the xtal frequency and the XTAL bit in register 0x01. + * @retval RCO frequency in Hz as an uint16_t. + */ +uint16_t S2LPTimerGetRcoFrequency(void) +{ + uint32_t xtal=S2LPRadioGetXtalFrequency(); + + switch(xtal) + { + case 24000000: + case 48000000: + return 32000; + case 25000000: + case 50000000: + return 33300; + } + return 34700; +} + + +/** + * @brief Enables the Fast RX termination timer. + * @param None + * @retval None + */ +void S2LpTimerFastRxTermTimer(SFunctionalState xNewState) +{ + uint8_t tmp; + s_assert_param(IS_SFUNCTIONAL_STATE(xNewState)); + + S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp); + if(xNewState == S_ENABLE) { + tmp |= FAST_CS_TERM_EN_REGMASK; + } + else { + tmp &= ~FAST_CS_TERM_EN_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp); +} + + +/** + * @brief Set the Fast RX termination timer word. When the timer counter will reach this word, + * the timer expires. + * The timer counter is clocked at frequency: fCLK/24/2^CHFLT_E + * @param fast_rx_word : the FAST_RX_TIMER word (register 0x54 value). + * @retval None + */ +void S2LpSetTimerFastRxTermTimer(uint8_t fast_rx_word) +{ + g_xStatus = S2LPSpiWriteRegisters(FAST_RX_TIMER_ADDR, 1, &fast_rx_word); +} + + +/** + * @brief Set the Fast RX termination timer word starting from a us value. + * The timer counter is clocked at frequency: fCLK/24/2^CHFLT_E. + * @param fast_rx_us : fast rx termination target value in us. + * @retval None + * @note: the user should care about the max value that can be set unless asserts are used. + */ +void S2LpSetTimerFastRxTermTimerUs(uint32_t fast_rx_us) +{ + uint8_t tmp,fast_rx_word; + + S2LPSpiReadRegisters(CHFLT_ADDR, 1, &tmp); + + uint32_t f_dig=S2LPRadioGetXtalFrequency(); + if(f_dig > DIG_DOMAIN_XTAL_THRESH) { + f_dig = f_dig/2; + } + + s_assert_param(fast_rx_us<(1000000*0xff)/(f_dig/24/(1<<(tmp&0x0F)))); + + + fast_rx_word=((f_dig/24/(1<<(tmp&0x0F)))*fast_rx_us)/1000000; + g_xStatus = S2LPSpiWriteRegisters(FAST_RX_TIMER_ADDR, 1, &fast_rx_word); +} + + +/** + * @brief Enables the RCO autocalibration when the device make the transition READY -> SLEEP. + * @param en: + * if it is S_ENABLE: RCO calibration is enabled. + * if it is S_DISABLE: RCO calibration is disabled. + * @retval None + */ +void S2LPTimerCalibrationRco(SFunctionalState xCalibration) +{ + uint8_t tmp; + + s_assert_param(IS_SFUNCTIONAL_STATE(xCalibration)); + + S2LPSpiReadRegisters(XO_RCO_CONF0_ADDR, 1, &tmp); + + if(xCalibration == S_ENABLE) { + tmp |= RCO_CALIBRATION_REGMASK; + } else { + tmp &= ~RCO_CALIBRATION_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(XO_RCO_CONF0_ADDR, 1, &tmp); +} + +/** + * @brief Enable the SLEEP_B mode. SLEEP_A and SLEEP_B are mutually exclusive. + * @param en: + * if it is S_ENABLE: SLEEP_B will be set + * if it is S_DISABLE: SLEEP_A will be set + * @retval None + */ +void S2LPTimerSleepB(SFunctionalState en) +{ + uint8_t tmp; + + s_assert_param(IS_SFUNCTIONAL_STATE(en)); + + S2LPSpiReadRegisters(PM_CONF0_ADDR, 1, &tmp); + + if(en == S_ENABLE) { + tmp |= SLEEP_MODE_SEL_REGMASK; + } else { + tmp &= ~SLEEP_MODE_SEL_REGMASK; + } + g_xStatus = S2LPSpiWriteRegisters(PM_CONF0_ADDR, 1, &tmp); +} + +void S2LPTimerLdcIrqWa(SFunctionalState en) +{ + uint8_t tmp[2]={0x00,0x60}; + + if(en) + { + tmp[0]=0x01; tmp[1]=0x64; + + do + { + S2LPRefreshStatus(); + } + while(g_xStatus.MC_STATE!=0x7C); + } + + g_xStatus = S2LPSpiWriteRegisters(0x7B, 1, &tmp[1]); + g_xStatus = S2LPSpiWriteRegisters(0x7A, 1, &tmp[0]); +} + + +/** + *@} + */ + + +/** + *@} + */ + + +/** + *@} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Timer_ex.c b/strf/s2lp/S2LP_Library/Src/S2LP_Timer_ex.c new file mode 100644 index 00000000..0006d9a8 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Timer_ex.c @@ -0,0 +1,121 @@ +/** + * @file S2LP_Timer_ex.c + * @author LowPower RF BU - AMG + * @version 1.2.0 + * @date October 31, 2016 + * @brief This file provides functions to manage S2-LP debug. + ****************************************************************************** + * @attention + * + *

    © COPYRIGHT(c) 2019 STMicroelectronics

    + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

    © COPYRIGHT 2019 STMicroelectronics

    + * + */ + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Timer.h" +#include "S2LP_Timer_ex.h" +#include "S2LP_Regs.h" +#include "MCU_Interface.h" + + +/** @addtogroup S2LP_Libraries + * @{ + */ + + +/** @addtogroup S2LP_Types + * @{ + */ + +/** @defgroup Types_Private_Functions Types Private Functions + * @{ + */ + + +void S2LPTimerSetRxTimerMs(float fDesiredMsec) +{ + S2LPTimerSetRxTimerUs((uint32_t)(fDesiredMsec*1000)); +} + +void S2LPTimerGetRxTimer(float* pfTimeoutMsec, uint8_t* pcCounter , uint8_t* pcPrescaler) +{ + uint32_t timeoutUsec; + + S2LPTimerGetRxTimerUs(&timeoutUsec, pcCounter , pcPrescaler); + + (*pfTimeoutMsec)=((float)timeoutUsec)/1000; +} + +void S2LPTimerSetWakeUpTimerMs(float fDesiredMsec) +{ + S2LPTimerSetWakeUpTimerUs((uint32_t)(fDesiredMsec*1000)); +} + +void S2LPTimerSetWakeUpTimerReloadMs(float fDesiredMsec) +{ + S2LPTimerSetWakeUpTimerReloadUs((uint32_t)(fDesiredMsec*1000)); +} + +void S2LPTimerGetWakeUpTimer(float* pfWakeUpMsec, uint8_t* pcCounter , uint8_t* pcPrescaler, uint8_t* pcMulti) +{ + uint32_t timeoutUsec; + + S2LPTimerGetWakeUpTimerUs(&timeoutUsec, pcCounter , pcPrescaler, pcMulti); + + (*pfWakeUpMsec)=((float)timeoutUsec)/1000; +} + +void S2LPTimerGetWakeUpTimerReload(float* pfWakeUpReloadMsec, uint8_t* pcCounter, uint8_t* pcPrescaler, uint8_t* pcMulti) +{ + uint32_t timeoutUsec; + + S2LPTimerGetWakeUpTimerReloadUs(&timeoutUsec, pcCounter , pcPrescaler, pcMulti); + + (*pfWakeUpReloadMsec)=((float)timeoutUsec)/1000; +} + + + +/** + * @} + */ + + + +/** + * @} + */ + + + +/** + * @} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Types.c b/strf/s2lp/S2LP_Library/Src/S2LP_Types.c new file mode 100644 index 00000000..6b437ed0 --- /dev/null +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Types.c @@ -0,0 +1,196 @@ +/** + * @file S2LP_Types.c + * @author LowPower RF BU - AMG + * @version 1.3.0 + * @date 10-July-2017 + * @brief This file provides functions to manage S2-LP debug. + ****************************************************************************** + * @attention + * + *

    © COPYRIGHT(c) 2019 STMicroelectronics

    + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *

    © COPYRIGHT 2019 STMicroelectronics

    + * + */ + +/* Includes ------------------------------------------------------------------*/ +#include "S2LP_Types.h" +#include "S2LP_Regs.h" +#include "MCU_Interface.h" + + +/** @addtogroup S2LP_Libraries + * @{ + */ + + +/** @addtogroup S2LP_Types + * @{ + */ + + +/** @defgroup Types_Private_TypesDefinitions Types Private Types Definitions + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup Types_Private_Defines Types Private Defines + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup Types_Private_Macros Types Private Macros + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup Types_Private_Variables Types Private Variables + * @{ + */ + +/** + * @brief S2LP Status global variable. + * This global variable of @ref S2LPStatus type is updated on every SPI transaction + * to maintain memory of S2LP Status. + */ +volatile S2LPStatus g_xStatus; + +/** + * @} + */ + + + +/** @defgroup Types_Private_FunctionPrototypes Types Private FunctionPrototypes + * @{ + */ + + + +/** + * @} + */ + + + +/** @defgroup Types_Private_Functions Types Private Functions + * @{ + */ + +#ifdef S2LP_USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file pointer to the source file name + * @param line assert_param error line source number + * @retval : None + */ +void s_assert_failed(uint8_t* file, uint32_t line) +{ + /* User can add his own implementation to report the file name and line number */ + printf("Wrong parameters value: file %s on line %d\r\n", file, line); + + /* Infinite loop */ + while (1) + { + } +} +#endif + + +/** + * @brief Updates the gState (the global variable used to maintain memory of S2LP Status) + * reading the MC_STATE register of S2LP. + * @param None + * @retval None + */ +#if 0 //indar +void S2LPRefreshStatus(void) +{ + uint8_t tempRegValue[2]; + /* Read the status both from register and from SPI header and exit when they match. + This will protect against possible transition state changes */ + do + { + /* Reads the MC_STATUS register to update the g_xStatus */ + g_xStatus = S2LPSpiReadRegisters(MC_STATE0_ADDR, 2, tempRegValue); + } + while(!((((uint8_t*)&g_xStatus)[0])==tempRegValue[1] && + (((uint8_t*)&g_xStatus)[1]&0x07)==tempRegValue[0])); + +} + +#else + +void S2LPRefreshStatus(void) +{ + uint8_t tempRegValue; + // do + { + /* Reads the MC_STATUS register to update the g_xStatus */ + g_xStatus = S2LPSpiReadRegisters(MC_STATE1_ADDR, 1, &tempRegValue); + } +// while(!((((uint8_t*)&g_xStatus)[0])==tempRegValue[1] && +// (((uint8_t*)&g_xStatus)[1]&0x07)==tempRegValue[0])); + +} +#endif +/** + * @} + */ + + + +/** + * @} + */ + + + +/** + * @} + */ + + + +/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/ From c9de2f14007d87083c1877ae0bb76dda1602ae2c Mon Sep 17 00:00:00 2001 From: Nikos Oikonomou Date: Mon, 1 Feb 2021 15:56:32 +0200 Subject: [PATCH 2/3] strf: s2lp: removed S2LP_Util usages - Removed unneeded S2LP_Util.h include from s2lp MCU_Interface.h. - Removed Config_RangeExt calls from s2lp S2LPCmdStrobeRx/S2LPCmdStrobeTx of S2LP_Commands.h. Impacted files: - strf/s2lp/S2LP_Library/Inc/MCU_Interface.h - strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h Signed-off-by: Nikos Oikonomou --- strf/README | 7 +++++++ strf/s2lp/S2LP_Library/Inc/MCU_Interface.h | 2 +- strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h | 2 -- strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/strf/README b/strf/README index 35a2b2f9..45c2f5ed 100644 --- a/strf/README +++ b/strf/README @@ -35,3 +35,10 @@ License Link: https://opensource.org/licenses/BSD-3-Clause Patch List: + + *Removed unneeded S2LP_Util.h include from s2lp MCU_Interface.h file and Config_RangeExt + calls from s2lp S2LPCmdStrobeRx/S2LPCmdStrobeTx of S2LP_Commands.h. + + *Fixed warnings for parentheses around arithmetic operation. + Impacted files: + s2lp/S2LP_Library/Src/S2LP_PacketHandler.c diff --git a/strf/s2lp/S2LP_Library/Inc/MCU_Interface.h b/strf/s2lp/S2LP_Library/Inc/MCU_Interface.h index 61c919c5..b05b0fb2 100644 --- a/strf/s2lp/S2LP_Library/Inc/MCU_Interface.h +++ b/strf/s2lp/S2LP_Library/Inc/MCU_Interface.h @@ -65,7 +65,7 @@ /* Includes ------------------------------------------------------------------*/ #include "S2LP_Config.h" -#include "S2LP_Util.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h b/strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h index 92b7309e..19a354e6 100644 --- a/strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h +++ b/strf/s2lp/S2LP_Library/Inc/S2LP_Commands.h @@ -134,7 +134,6 @@ typedef enum */ #define S2LPCmdStrobeTx() {uint8_t tmp=0x9C;\ - Config_RangeExt(PA_TX,S2LPManagementGetRangeExtender());\ S2LPSpiWriteRegisters(0x76,1,&tmp);\ S2LPCmdStrobeCommand(CMD_TX);} @@ -146,7 +145,6 @@ typedef enum */ #define S2LPCmdStrobeRx() {uint8_t tmp=0x90;\ - Config_RangeExt(PA_RX,S2LPManagementGetRangeExtender());\ S2LPSpiWriteRegisters(0x76,1,&tmp);\ S2LPCmdStrobeCommand(CMD_RX);} diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c b/strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c index 0e783716..ed641bb0 100644 --- a/strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c +++ b/strf/s2lp/S2LP_Library/Src/S2LP_PacketHandler.c @@ -185,7 +185,7 @@ uint16_t S2LPGetPreambleLength(void) g_xStatus = S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 2, tmpBuffer); /* Rebuild and return value */ - return ( ((((uint16_t)tmpBuffer[0])&PREAMBLE_LEN_9_8_REGMASK)<<8) | ((uint16_t)tmpBuffer[1]) + 1); + return ( (((((uint16_t)tmpBuffer[0])&PREAMBLE_LEN_9_8_REGMASK)<<8) | ((uint16_t)tmpBuffer[1])) + 1); } From 44d5d70b09aeae37c225526e46baa06b5fc79885 Mon Sep 17 00:00:00 2001 From: Nikos Oikonomou Date: Tue, 2 Feb 2021 15:58:12 +0200 Subject: [PATCH 3/3] strf: s2lp: fixed dereference pointer warning Added patch, to SUBG1 package, that resolves dereferencing type-punned pointer warning. Impacted files: - strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c Signed-off-by: Nikos Oikonomou --- strf/README | 4 ++++ strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/strf/README b/strf/README index 45c2f5ed..9a7c59fa 100644 --- a/strf/README +++ b/strf/README @@ -42,3 +42,7 @@ Patch List: *Fixed warnings for parentheses around arithmetic operation. Impacted files: s2lp/S2LP_Library/Src/S2LP_PacketHandler.c + + *Fixed warnings for dereferencing type-punned pointer + Impacted files: + s2lp/S2LP_Library/Src/S2LP_Gpio.c diff --git a/strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c b/strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c index 7fd74593..19b6b515 100644 --- a/strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c +++ b/strf/s2lp/S2LP_Library/Src/S2LP_Gpio.c @@ -267,11 +267,10 @@ OutputLevel S2LPGpioGetLevel(S2LPGpioPin xGpioX) void S2LPGpioIrqDeInit(S2LPIrqs* pxIrqInit) { uint8_t tmp[4] = {0x00,0x00,0x00,0x00}; + S2LPIrqs empty = {0}; if(pxIrqInit!=NULL) { - uint32_t tempValue = 0x00000000; - - *pxIrqInit = (*(S2LPIrqs*)&tempValue); + *pxIrqInit = empty; } g_xStatus = S2LPSpiWriteRegisters(IRQ_MASK3_ADDR, 4, tmp);