diff --git a/Doc/drivers/si72xx.md b/Doc/drivers/si72xx.md
new file mode 100644
index 0000000..d5f4954
--- /dev/null
+++ b/Doc/drivers/si72xx.md
@@ -0,0 +1,85 @@
+# SI72XX - Hall Effect Magnetic Position and Temperature Sensor Driver
+
+The Si7210 family of Hall effect magnetic sensors from Silicon Labs combines a
+chopper-stabilized Hall element with a low-noise analog amplifier, 13-bit
+analog-to-digital converter, and an I2C interface. Leveraging Silicon Labs' proven
+CMOS design techniques, the Si7210 family incorporates digital signal processing
+to provide precise compensation for temperature and offset drift.
+
+## Sources
+ - Datasheet: https://www.silabs.com/documents/public/data-sheets/si7210-datasheet.pdf
+ - Application Note AN1018: https://www.silabs.com/documents/public/application-notes/an1018-si72xx-sensors.pdf
+
+## Setup the SI72XX
+As all the drivers you need to enable it and setup it in the _configDrivers.h_
+
+## Using the SI72XX
+
+### SI72XX HW versions
+
+
+Constant declared in `drivers/hall/si72xx/si72xx.h`
+
+```C
+#define SI72XX_ADDR_0 0x30
+#define SI72XX_ADDR_1 0x31
+#define SI72XX_ADDR_2 0x32
+#define SI72XX_ADDR_3 0x33
+```
+
+Based on the sensor version must be used proper I2C address:
+ - SI72XX_ADDR_0 (0x30):
+ - Si7210-B-00-IV(R)
+ - Si7210-B-01-IV(R)
+ - Si7210-B-10-IM2(R)
+ - Si7210-B-11-IM2(R)
+ - SI72XX_ADDR_1 (0x31):
+ - Si7210-B-02-IV(R)
+ - Si7210-B-12-IM2(R)
+ - SI72XX_ADDR_2 (0x32):
+ - Si7210-B-03-IV(R)
+ - Si7210-B-13-IM2(R)
+ - SI72XX_ADDR_3 (0x33):
+ - Si7210-B-04-IV(R)
+ - Si7210-B-05-IV(R)
+ - Si7210-B-14-IM2(R)
+ - Si7210-B-15-IM2(R)
+
+
+### Measurement of magnetic field
+
+Read magnetic field with sensor SI72XX_ADDR_0 and go to sleep.
+
+```C
+...
+
+int16_t data = 0;
+
+if (Si72xx_ReadMagFieldDataAndSleep(SI72XX_ADDR_0, SI7210_20MT, SI72XX_SLEEP_MODE, &data) == __SI72XX_OK)
+{
+ return __SI72XX_ERROR;
+}
+
+return data;
+
+...
+```
+
+### Measurement of temperature
+
+Read temperature with sensor SI72XX_ADDR_0 and go to sleep.
+
+```C
+...
+
+int32_t temp_mC = 0; /* output in milli Celsius */
+
+if (Si72xx_ReadTemperatureAndSleep(SI72XX_ADDR_0, &temp_mC) != __SI72XX_OK)
+{
+ return __SI72XX_ERROR;
+}
+
+return temp_mC;
+
+...
+```
\ No newline at end of file
diff --git a/Inc/drivers/hall/si72xx/si72xx.h b/Inc/drivers/hall/si72xx/si72xx.h
new file mode 100755
index 0000000..9a63ba0
--- /dev/null
+++ b/Inc/drivers/hall/si72xx/si72xx.h
@@ -0,0 +1,154 @@
+/* ==========================================================
+ * si72xx.h - Driver for the Si72xx Hall Effect Sensor
+ * ----------------------------------------------------------
+ *
+ * Created on: 21 dec 2021
+ * Author: Zbynek Kocur
+ * ----------------------------------------------------------
+ * Copyright (C) 2021 CTU in Prague
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU LESSER General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ * ==========================================================
+ * Datasheet - https://www.silabs.com/documents/public/data-sheets/si7210-datasheet.pdf
+ * App Note - AN1018: Using the Si72xx Hall-effect Magnetic Position Sensors - https://www.silabs.com/documents/public/application-notes/an1018-si72xx-sensors.pdf
+ *
+ * ==========================================================
+ * Some peaces of that code directly comes from Silicon Laboratories Inc.
+ * and identified with << Copyright 2018 Silicon Laboratories Inc. www.silabs.com >>
+ *
+ * ==========================================================
+ */
+
+#ifndef DRIVERS_HALL_SI72XX_SI72XX_H
+#define DRIVERS_HALL_SI72XX_SI72XX_H
+
+/*******************************************************************************
+ ******************************* DEFINES ***********************************
+ ******************************************************************************/
+
+/** I2C device address for Si72xx */
+#define SI72XX_ADDR_0 0x30
+#define SI72XX_ADDR_1 0x31
+#define SI72XX_ADDR_2 0x32
+#define SI72XX_ADDR_3 0x33
+
+/** I2C registers for Si72xx */
+#define SI72XX_HREVID 0xC0
+#define SI72XX_DSPSIGM 0xC1
+#define SI72XX_DSPSIGL 0xC2
+#define SI72XX_DSPSIGSEL 0xC3
+#define SI72XX_POWER_CTRL 0xC4
+#define SI72XX_ARAUTOINC 0xC5
+#define SI72XX_CTRL1 0xC6
+#define SI72XX_CTRL2 0xC7
+#define SI72XX_SLTIME 0xC8
+#define SI72XX_CTRL3 0xC9
+#define SI72XX_A0 0xCA
+#define SI72XX_A1 0xCB
+#define SI72XX_A2 0xCC
+#define SI72XX_CTRL4 0xCD
+#define SI72XX_A3 0xCE
+#define SI72XX_A4 0xCF
+#define SI72XX_A5 0xD0
+#define SI72XX_OTP_ADDR 0xE1
+#define SI72XX_OTP_DATA 0xE2
+#define SI72XX_OTP_CTRL 0xE3
+#define SI72XX_TM_FG 0xE4
+
+#define SI72XX_OTP_20MT_ADDR 0x21
+#define SI72XX_OTP_200MT_ADDR 0x27
+
+/*******************************************************************************
+ ******************************** ENUMS ************************************
+ ******************************************************************************/
+/** Si72xx magnetic field full-scales */
+typedef enum {
+ SI7210_20MT,
+ SI7210_200MT
+} Si72xxFieldScale_t;
+
+/** Si72xx sleep modes */
+typedef enum {
+ SI72XX_SLEEP_MODE,
+ SI72XX_SLTIMEENA_MODE,
+ SI72XX_IDLE_MODE
+} Si72xxSleepMode_t;
+
+
+/*!
+ * @brief Si72xx API status result code.
+ */
+typedef enum drivers_si72xx_ret_e
+{
+ __SI72XX_OK = 0,
+ __SI72XX_ERROR = 1,
+ __SI72XX_BUSY = 2,
+ __SI72XX_TIMEOUT = 3, /* until here, I2C errors (cf. _I2C_Status) */
+ __SI72XX_NODATA = 4,
+ __SI72XX_MISCALIB = 5,
+ __SI72XX_UNKNOWN = 6,
+ __SI72XX_INVALID_ARG = 7
+} drivers_si72xx_ret_e;
+
+/*******************************************************************************
+ ***************************** PROTOTYPES **********************************
+ ******************************************************************************/
+
+drivers_si72xx_ret_e Si72xx_WakeUpAndIdle(uint8_t addr);
+drivers_si72xx_ret_e Si72xx_Read_MagField_Data(uint8_t addr,
+ int16_t *magData);
+drivers_si72xx_ret_e Si72xx_FromIdle_GoToSleep(uint8_t addr);
+drivers_si72xx_ret_e Si72xx_FromIdle_GoToSltimeena(uint8_t addr);
+
+drivers_si72xx_ret_e Si72xx_Set_mT_Range(uint8_t addr,
+ Si72xxFieldScale_t mTScale);
+drivers_si72xx_ret_e Si72xx_ReadMagFieldDataAndSleep(uint8_t addr,
+ Si72xxFieldScale_t mTScale,
+ Si72xxSleepMode_t sleepMode,
+ int16_t *magFieldData);
+drivers_si72xx_ret_e Si72xx_EnterSleepMode(uint8_t addr,
+ Si72xxSleepMode_t sleepMode);
+drivers_si72xx_ret_e Si72xx_EnterLatchMode (uint8_t addr);
+drivers_si72xx_ret_e Si72xx_ReadTemperatureAndSleep(uint8_t addr,
+ int32_t *rawTemp);
+drivers_si72xx_ret_e Si72xx_ReadCorrectedTempAndSleep(uint8_t addr,
+ int16_t offsetData,
+ int16_t gainData,
+ int32_t *correctedTemp);
+drivers_si72xx_ret_e Si72xx_ReadTempCorrectionDataAndSleep(uint8_t addr,
+ int16_t *offsetValue,
+ int16_t *gainValue);
+
+drivers_si72xx_ret_e Si72xx_IdentifyAndSleep(uint8_t addr,
+ uint8_t *partId,
+ uint8_t *partRev);
+drivers_si72xx_ret_e Si72xx_ReadVariantAndSleep(uint8_t addr,
+ uint8_t *basePn,
+ uint8_t *pnVariant);
+drivers_si72xx_ret_e Si72xx_SelfTest(uint8_t addr);
+
+
+// =============================================================================================
+
+ int32_t Si72xx_ConvertDataCodesToMagneticField(Si72xxFieldScale_t fieldScale, int16_t dataCode);
+
+drivers_si72xx_ret_e Si72xx_Set_Threshold (uint8_t addr,
+ Si72xxFieldScale_t mTScale,
+ float threshold);
+drivers_si72xx_ret_e Si72xx_Set_Hysteresis (uint8_t addr,
+ Si72xxFieldScale_t mTScale,
+ float hysteresis);
+drivers_si72xx_ret_e Debug_Si72xx_register (uint8_t addr);
+
+#endif /* DRIVERS_HALL_SI72XX_SI72XX_H */
diff --git a/Inc/drivers/lorawan/utilities.h b/Inc/drivers/lorawan/utilities.h
old mode 100644
new mode 100755
index 84c49e6..47e3faa
--- a/Inc/drivers/lorawan/utilities.h
+++ b/Inc/drivers/lorawan/utilities.h
@@ -70,7 +70,9 @@ typedef uint32_t TimerTime_t;
* \param [IN] b 2nd value
* \retval minValue Minimum value
*/
-#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
+#ifndef MIN
+ #define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
+#endif
/*!
* \brief Returns the maximum value between a and b
@@ -79,8 +81,9 @@ typedef uint32_t TimerTime_t;
* \param [IN] b 2nd value
* \retval maxValue Maximum value
*/
-#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
-
+#ifndef MAX
+ #define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
+#endif
/*!
* \brief Returns 2 raised to the power of n
*
diff --git a/Inc/it_sdk/configDrivers.h.template b/Inc/it_sdk/configDrivers.h.template
index 830123b..f7c30c9 100644
--- a/Inc/it_sdk/configDrivers.h.template
+++ b/Inc/it_sdk/configDrivers.h.template
@@ -299,5 +299,18 @@
#define ITSDK_DRIVERS_SL353_INT_BANK __BANK_A // HALL pin configuration
#define ITSDK_DRIVERS_SL353_INT_PIN __LP_GPIO_0 // __LP_GPIO_NONE if not used
+// ------------------------------------------------------------------------
+// Hall : SI72XX
+
+#define ITSDK_DRIVERS_SI72XX __DISABLE // Si72xx Hall Effect Sensor
+#if ITSDK_DRIVERS_SI72XX == __ENABLE
+ #ifndef __I2C_INCLUDED
+ #define __I2C_INCLUDED
+ #include "i2c.h"
+ #endif
+ #include
+#endif
+#define ITSDK_DRIVERS_SI72XX_I2C hi2c1 // I2C port to be used for communications
+
#endif /* INC_IT_SDK_CONFIGDRIVERS_H_ */
\ No newline at end of file
diff --git a/Src/drivers/hall/si72xx/si72xx.c b/Src/drivers/hall/si72xx/si72xx.c
new file mode 100755
index 0000000..42c08bc
--- /dev/null
+++ b/Src/drivers/hall/si72xx/si72xx.c
@@ -0,0 +1,1117 @@
+/* ==========================================================
+ * si72xx.c - Driver for the Si72xx Hall Effect Sensor
+ * ----------------------------------------------------------
+ *
+ * Created on: 21 dec 2021
+ * Author: Zbynek Kocur
+ * ----------------------------------------------------------
+ * Copyright (C) 2021 CTU in Prague
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU LESSER General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ * ==========================================================
+ * Datasheet - https://www.silabs.com/documents/public/data-sheets/si7210-datasheet.pdf
+ * App Note - AN1018: Using the Si72xx Hall-effect Magnetic Position Sensors - https://www.silabs.com/documents/public/application-notes/an1018-si72xx-sensors.pdf
+ *
+ * ==========================================================
+ * Some peaces of that code directly comes from Silicon Laboratories Inc.
+ * and identified with << Copyright 2018 Silicon Laboratories Inc. www.silabs.com >>
+ *
+ * ==========================================================
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+
+#if ITSDK_DRIVERS_SI72XX == __ENABLE
+
+/*******************************************************************************
+ ******************************* DEFINES ***********************************
+ ******************************************************************************/
+
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
+
+#define SI72XX_SWOP_LATCHMODE 0x7F
+#define SI72XX_FIELDPOLSEL_LATCHMODE 2
+#define SI72XX_FIELDPOLSEL_SHIFT 6
+#define SI72XX_SWHYST_LATCHMODE 0x12
+
+#define SI72XX_OTP_BUSY_MASK 1
+#define SI72XX_OTP_READ_EN_MASK 2
+
+#define SI72XX_DSPSIGSEL_MASK 0x07
+#define SI72XX_DSPSIGSEL_TEMP 0x01
+
+#define SI72XX_ZERO_FIELD 16384
+#define SI72XX_FRESH_BIT_MASK 0x80
+#define SI72XX_FRESH_BIT_SHIFT 7
+#define SI72XX_DSPSIGM_MASK 0x7F
+#define SI72XX_DSPSIGM_SHIFT 8
+
+#define SI72XX_SLEEP_MASK 1
+#define SI72XX_STOP_MASK 2
+#define SI72XX_ONEBURST_MASK 4
+#define SI72XX_USESTORE_MASK 8
+#define SI72XX_POWERCTRL_MASK 0x0F
+#define SI72XX_MEASRO_MASK 0x80
+#define SI72XX_MEASRO_SHIFT 7
+
+#define SI72XX_SW_LOW4FIELD_MASK 0x80
+#define SI72XX_SW_OP_MASK 0x7F
+
+#define SI72XX_SWFIELDPOLSEL_MASK 0xC0
+#define SI72XX_SWHYST_MASK 0x3F
+
+#define SI72XX_SLTIMEENA_MASK 1
+#define SI72XX_SL_FAST_MASK 2
+#define SI72XX_SW_TAMPER_MASK 0xFC
+
+/* Burst sizes for mag. measurement */
+#define SI72XX_DF_BW_1 0x0U << 1
+#define SI72XX_DF_BW_2 0x1U << 1
+#define SI72XX_DF_BW_4 0x2U << 1
+#define SI72XX_DF_BW_8 0x3U << 1
+#define SI72XX_DF_BW_16 0x4U << 1
+#define SI72XX_DF_BW_32 0x5U << 1
+#define SI72XX_DF_BW_64 0x6U << 1
+#define SI72XX_DF_BW_128 0x7U << 1 /* default */
+#define SI72XX_DF_BW_256 0x8U << 1
+#define SI72XX_DF_BW_512 0x9U << 1
+#define SI72XX_DF_BW_1024 0xAU << 1
+#define SI72XX_DF_BW_2048 0xBU << 1
+#define SI72XX_DF_BW_4096 0xCU << 1
+#define SI72XX_DF_BURSTSIZE_1 0x0U << 5 /* default */
+#define SI72XX_DF_BURSTSIZE_2 0x1U << 5
+#define SI72XX_DF_BURSTSIZE_4 0x2U << 5
+#define SI72XX_DF_BURSTSIZE_8 0x3U << 5
+#define SI72XX_DF_BURSTSIZE_16 0x4U << 5
+#define SI72XX_DF_BURSTSIZE_32 0x5U << 5
+#define SI72XX_DF_BURSTSIZE_64 0x6U << 5
+#define SI72XX_DF_BURSTSIZE_128 0x7U << 5
+#define SI72XX_DFBW_MASK 0x1E
+#define SI72XX_DFIIR_MASK 1
+
+#define SI72XX_REV_MASK 0x0F
+#define SI72XX_ID_MASK 0xF0
+#define SI72XX_ID_SHIFT 4
+
+#define SI72XX_BASE_PART_NUMBER 0x14
+#define SI72XX_PART_VARIANT 0x15
+
+#define SI72XX_OFFSET_ADDR 0x1D
+#define SI72XX_GAIN_ADDR 0x1E
+/** @endcond */
+
+// macros
+
+// convert type _I2C_Status -> drivers_si72xx_ret_e
+// (which reflects original I2C errors, but it has some extra values)
+#define SI72XX_FROM_I2C_STATUS(i2c_st) \
+ i2c_st == __I2C_ERROR ? __SI72XX_ERROR : \
+ i2c_st == __I2C_BUSY ? __SI72XX_BUSY : \
+ i2c_st == __I2C_TIMEOUT ? __SI72XX_TIMEOUT : \
+ __SI72XX_UNKNOWN
+
+/***********************************************************************//**
+ * @brief
+ * Reads register from the Si72xx sensor.
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] i2c
+ * The I2C peripheral to use (not used).
+ * @param[in] addr
+ * The I2C address of the sensor.
+ * @param[in] reg_addr
+ * The register address to read from in the sensor.
+ * @param[out] read_ptr
+ * The data read from the sensor.
+ * @return
+ * the behavior can be changed easily so that it, e.g., does not check the status and only
+ * OR's the I2C status as follows: i2c_st |= i2c_read8BRegister(...);
+ **************************************************************************/
+#define SI72XX_READ_8B(reg_addr, read_ptr) \
+ i2c_st = i2c_read8BRegister(&ITSDK_DRIVERS_SI72XX_I2C, addr, reg_addr, read_ptr, 1); \
+ if (i2c_st != __I2C_OK) \
+ { \
+ log_info("\r\n(d) ERROR SI72XX_READ_8B\r\n"); \
+ res = SI72XX_FROM_I2C_STATUS(i2c_st); \
+ goto RETURN; \
+ }
+
+/***********************************************************************//**
+ * @brief
+ * Writes register in the Si72xx sensor.
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] i2c
+ * The I2C peripheral to use (not used).
+ * @param[in] addr
+ * The I2C address of the sensor.
+ * @param[in] reg_addr
+ * The register address to write to in the sensor.
+ * @param[in] write_val
+ * The data to write to the sensor.
+ * @return
+ * the behavior can be changed easily so that it, e.g., does not check the status and only
+ * OR's the I2C status as follows: i2c_st |= i2c_write8BRegister(...);
+ **************************************************************************/
+#define SI72XX_WRITE_8B(reg_addr, write_val) \
+ i2c_st = i2c_write8BRegister(&ITSDK_DRIVERS_SI72XX_I2C, addr, reg_addr, write_val, 1); \
+ if (i2c_st != __I2C_OK) \
+ { \
+ log_info("\r\n(d) ERROR SI72XX_WRITE_8B\r\n"); \
+ res = SI72XX_FROM_I2C_STATUS(i2c_st); \
+ goto RETURN; \
+ }
+
+#define SI72XX_INT_CALL(func) \
+ res = func; \
+ if (res != __SI72XX_OK) goto RETURN;
+
+// "private" functions
+
+//static inline int32_t Si72xx_ConvertDataCodesToMagneticField(Si72xxFieldScale_t fieldScale, int16_t dataCode);
+
+
+/***********************************************************************//**
+ * @brief
+ * Read out Si72xx Magnetic Field Conversion Data
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[out] magData
+ * Mag-field conversion reading, signed 16-bit integer
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_Read_MagField_Data(uint8_t addr,
+ int16_t *magData)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t read = 0;
+ uint8_t freshBit = 0;
+
+ SI72XX_READ_8B(SI72XX_DSPSIGM, &read);
+
+ freshBit = ((read & SI72XX_FRESH_BIT_MASK) >> SI72XX_FRESH_BIT_SHIFT);
+ if (freshBit == 0)
+ {
+ res = __SI72XX_NODATA;
+ goto RETURN;
+ }
+
+ *magData = ((((uint16_t)read) & SI72XX_DSPSIGM_MASK) << SI72XX_DSPSIGM_SHIFT);
+
+ SI72XX_READ_8B(SI72XX_DSPSIGL, &read);
+ /* Data code output is 15-bit unsigned value where 0mT=16384 */
+ *magData |= read;
+ /* Converts data code output to a signed integer */
+ *magData = *magData - SI72XX_ZERO_FIELD;
+
+ RETURN:
+ return res;
+}
+
+/***********************************************************************//**
+ * @brief
+ * Puts Si72xx into Sleep mode (lowest power)..
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] addr
+ * The I2C address of the sensor.
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_FromIdle_GoToSleep(uint8_t addr)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t read = 0;
+
+ SI72XX_READ_8B(SI72XX_CTRL3, &read);
+ read = (read & (~SI72XX_SLTIMEENA_MASK));
+ SI72XX_WRITE_8B(SI72XX_CTRL3, read);
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = (read | SI72XX_SLEEP_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ RETURN:
+ return res;
+}
+
+/***********************************************************************//**
+ * @brief
+ * Puts Si72xx into Sleep-Timer-Enable mode.
+ * Si72xx periodically wakes-up, samples the magnetic field, updates the
+ * output, and goes back to sleep-timer-enabled mode.
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] addr
+ * The I2C address of the sensor.
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_FromIdle_GoToSltimeena(uint8_t addr)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ /* To store read register value */
+ uint8_t read = 0;
+
+ /* Setting SLTIMEENA to enable the sleep timer in order to make periodic measurements and update output pin
+ * Resetting ONEBURST, SLEEP and STOP to don't go to classic sleep
+ * Setting USESTORE to not reloaded after each sleep cycle the SI72XX_CTRL1 and SI72XX_CTRL2 registers
+ * */
+ SI72XX_READ_8B(SI72XX_CTRL3, &read);
+ read = ((read & ~SI72XX_SL_FAST_MASK) | SI72XX_SLTIMEENA_MASK);
+ SI72XX_WRITE_8B(SI72XX_CTRL3, read);
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ /* Reset the ONEBURST, SLEEP and STOP bits
+ * Set the USESTORE bit
+ * */
+ read = (read & ~( SI72XX_ONEBURST_MASK |
+ SI72XX_STOP_MASK |
+ SI72XX_SLEEP_MASK)) |
+ SI72XX_USESTORE_MASK;
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ RETURN:
+ return res;
+}
+
+
+
+/***********************************************************************//**
+ * @brief
+ * Wake-up Si72xx and places sensor in idle-mode.
+ * @param[in] addr
+ * The I2C address of the sensor.
+ * @return
+ * Returns zero on success. Otherwise returns error codes
+ * based on the I2CCSPM
+ **************************************************************************/
+
+drivers_si72xx_ret_e Si72xx_WakeUpAndIdle(uint8_t devAdr)
+{
+ uint8_t value;
+
+ if (i2c_write(&ITSDK_DRIVERS_SI72XX_I2C, devAdr, NULL, 0) != __I2C_OK)
+ return __I2C_ERROR;
+
+ return i2c_read(&ITSDK_DRIVERS_SI72XX_I2C, devAdr, &value, 1);
+
+}
+
+
+/***********************************************************************//**
+ * @brief
+ * Read Si72xx OTP Data
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[in] otpAddr
+ * The OTB Byte address of the coefficients
+ * @param[out] data
+ * OTP data read out
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_Read_OTP(uint8_t addr,
+ uint8_t otpAddr,
+ uint8_t *otpData)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t read = 0;
+
+ SI72XX_READ_8B(SI72XX_OTP_CTRL, &read);
+ if (read & SI72XX_OTP_BUSY_MASK)
+ return __SI72XX_BUSY;
+
+ SI72XX_WRITE_8B(SI72XX_OTP_ADDR, otpAddr);
+ SI72XX_WRITE_8B(SI72XX_OTP_CTRL, SI72XX_OTP_READ_EN_MASK);
+ SI72XX_READ_8B(SI72XX_OTP_DATA, &read);
+
+ *otpData = read;
+
+ RETURN:
+ return res;
+}
+
+/***********************************************************************//**
+ * @brief
+ * Set magnetic-field output range, 20mT or 200mT full-scale
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[in] mTScale
+ * 20mT or 200mT
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_Set_mT_Range(uint8_t addr,
+ Si72xxFieldScale_t mTScale)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t srcAddr = 0;
+ uint8_t data = 0;
+
+ if (mTScale == SI7210_20MT)
+ {
+ srcAddr = SI72XX_OTP_20MT_ADDR;
+ }
+ else if (mTScale == SI7210_200MT)
+ {
+ srcAddr = SI72XX_OTP_200MT_ADDR;
+ }
+
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, srcAddr++, &data))
+ SI72XX_WRITE_8B(SI72XX_A0, data);
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, srcAddr++, &data))
+ SI72XX_WRITE_8B(SI72XX_A1, data);
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, srcAddr++, &data))
+ SI72XX_WRITE_8B(SI72XX_A2, data);
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, srcAddr++, &data))
+ SI72XX_WRITE_8B(SI72XX_A3, data);
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, srcAddr++, &data))
+ SI72XX_WRITE_8B(SI72XX_A4, data);
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, srcAddr++, &data))
+ SI72XX_WRITE_8B(SI72XX_A5, data);
+
+ RETURN:
+ return res;
+}
+
+/***********************************************************************//**
+ * @brief
+ * Wake-up SI72xx, performs a magnetic-field conversion with FIR,
+ * and places Si72xx back to sleep-mode or idle.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[in] mTScale
+ * mTScale= Si7210_20MT: 20mT full-scale magnetic-field range
+ * mTScale= Si7210_200MT: 200mT full-scale magnetic-field range
+ * @param[in] sleepMode
+ * SI72XX_SLEEP: Sleep mode. Lowest power & doesn't update output
+ * SI72XX_SLTIMEENA: Sleep-Timer-Enabled mode. Updates output periodically
+ * SI72XX_IDLE: No sleep
+ * @param[out] magFieldData
+ * Magnetic-field conversion reading, signed 16-bit integer
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_ReadMagFieldDataAndSleep(uint8_t addr,
+ Si72xxFieldScale_t mTScale,
+ Si72xxSleepMode_t sleepMode,
+ int16_t *magFieldData)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ /* to get register value */
+ uint8_t read = 0;
+
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+
+ /* set the stop-bit */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = ((read & ~SI72XX_POWERCTRL_MASK) | SI72XX_STOP_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ SI72XX_INT_CALL(Si72xx_Set_mT_Range(addr, mTScale))
+
+ /* Set the burst-size for averaging */
+ SI72XX_WRITE_8B(SI72XX_CTRL4, SI72XX_DF_BURSTSIZE_1 | SI72XX_DF_BW_128); // SI72XX_DF_BURSTSIZE_128 | SI72XX_DF_BW_4096
+
+ /* Perform a magnetic field conversion */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = ((read & ~SI72XX_POWERCTRL_MASK) | SI72XX_ONEBURST_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ /* Wait for measurement to complete */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ while ((read & SI72XX_MEASRO_MASK) >> SI72XX_MEASRO_SHIFT)
+ {
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ }
+
+ SI72XX_INT_CALL(Si72xx_Read_MagField_Data(addr, magFieldData))
+
+ switch (sleepMode)
+ {
+ case SI72XX_SLEEP_MODE :
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSleep(addr))
+ break;
+ case SI72XX_SLTIMEENA_MODE :
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSltimeena(addr))
+ break;
+ case SI72XX_IDLE_MODE :
+ // TODO
+ break;
+ default :
+ ;
+ }
+
+ RETURN:
+ return res;
+}
+
+/***********************************************************************//**
+ * @brief
+ * Wake-up Si72xx, and set sleep-mode option.
+ * If Si72xx is in a sleep-mode, it requires a wake-up command first.
+ * Useful for placing Si72xx in SLTIMEENA mode from SLEEP mode,
+ * or vice-versa.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[in] sleepMode
+ * SI72XX_SLEEP: Puts Si72xx into sleep mode. Lowest power & doesn't update
+ * SI72XX_SLTIMEENA: Si72xx into sltimeena mode. Updates output periodically
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_EnterSleepMode(uint8_t addr,
+ Si72xxSleepMode_t sleepMode)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+
+ switch (sleepMode)
+ {
+ case SI72XX_SLEEP_MODE :
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSleep(addr))
+ break;
+ case SI72XX_SLTIMEENA_MODE :
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSltimeena(addr))
+ break;
+ case SI72XX_IDLE_MODE :
+ // TODO
+ break;
+ default :
+ ;
+ }
+
+ RETURN:
+ return res;
+}
+
+/***********************************************************************//**
+ * @brief
+ * Wake-up Si72xx, and configures output for Latch mode.
+ * Switch point = 0mT w/ 0.2mT hysteresis
+ * @param[in] addr
+ * The I2C address of the sensor
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_EnterLatchMode(uint8_t addr)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t read = 0;
+
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+
+ /* Set Stop-bit */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = (read | SI72XX_USESTORE_MASK | SI72XX_STOP_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ /* Set output high for low magnetic field */
+ /* Set sw_op to zero for latch mode */
+ read = (SI72XX_SWOP_LATCHMODE | SI72XX_SW_LOW4FIELD_MASK);
+ SI72XX_WRITE_8B(SI72XX_CTRL1, read);
+
+ /* Set output to unipolar positive with hysteresis = 0.2mT */
+ read = ((SI72XX_FIELDPOLSEL_LATCHMODE << SI72XX_FIELDPOLSEL_SHIFT)
+ | SI72XX_SWHYST_LATCHMODE);
+ SI72XX_WRITE_8B(SI72XX_CTRL2, read);
+
+ /* Enable the sleep-timer for periodic measurements */
+ SI72XX_READ_8B(SI72XX_CTRL3, &read);
+ read = (read | SI72XX_SLTIMEENA_MASK);
+ SI72XX_WRITE_8B(SI72XX_CTRL3, read);
+
+ /* Clear stop-bit */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = (read & ~SI72XX_STOP_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ RETURN:
+ return res;
+}
+
+/***********************************************************************//**
+ * @brief
+ * Wakes up SI72xx, performs temperature conversion and places Si72xx
+ * into SI72XX_SLEEP sleep-mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[out] temp
+ * Temperature measurement in millidegree Celsius
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_ReadTemperatureAndSleep(uint8_t addr,
+ int32_t *rawTemp)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t read = 0;
+ uint8_t dspSigM, dspSigL;
+ uint8_t freshBit;
+ int16_t dataValue;
+ int32_t milliCelsius;
+
+ uint16_t tempCtrl4Setting = 0x00;
+
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+
+ /* Set stop-bit */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = ((read & ~SI72XX_POWERCTRL_MASK) | SI72XX_STOP_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ /* clear IIR & FIR filtering */
+ SI72XX_WRITE_8B(SI72XX_CTRL4, tempCtrl4Setting);
+
+ /* Select temperature conversion */
+ SI72XX_READ_8B(SI72XX_DSPSIGSEL, &read);
+ read = ((read & ~SI72XX_DSPSIGSEL_MASK) | SI72XX_DSPSIGSEL_TEMP);
+ SI72XX_WRITE_8B(SI72XX_DSPSIGSEL, read);
+
+ /* Perform temperature conversion */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = (((read & (~SI72XX_STOP_MASK)) & ~(SI72XX_SLEEP_MASK))
+ | SI72XX_ONEBURST_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ /* Read conversion res */
+ SI72XX_READ_8B(SI72XX_DSPSIGM, &dspSigM);
+ SI72XX_READ_8B(SI72XX_DSPSIGL, &dspSigL);
+
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSleep(addr))
+
+ freshBit = dspSigM >> SI72XX_FRESH_BIT_SHIFT;
+ if (freshBit == 0)
+ {
+ res = __SI72XX_NODATA;
+ goto RETURN;
+ }
+
+ /* dataValue = (Dspigm[6:0]<<5) + (Dspigl[7:0]>>3) */
+ dataValue = (((uint16_t)dspSigM) & SI72XX_DSPSIGM_MASK) << 8;
+ dataValue = (dataValue | dspSigL) >> 3;
+
+ /* rawTemp(mC) = ((dataValue^2)*(-3.83*10^-6))+(0.16094*dataValue)-279.8 */
+ milliCelsius = ((int32_t)dataValue * (int32_t)dataValue * -383 / 100000)
+ + ((16094 * dataValue) / 100) - 279800;
+
+ *rawTemp = milliCelsius;
+
+ RETURN:
+ return res;
+}
+
+/***********************************************************************//**
+ * @brief
+ * Wakes up SI72xx, performs temperature conversion and places Si72xx
+ * into SI72XX_SLEEP sleep-mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[out] offsetValue
+ * Temperature offset correction
+ * @param[out] gainValue
+ * Temperature gain correction
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_ReadTempCorrectionDataAndSleep(uint8_t addr,
+ int16_t *offsetValue,
+ int16_t *gainValue)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t read = 0;
+
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+
+ /* Set Stop-bit */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = ((read & ~SI72XX_POWERCTRL_MASK) | SI72XX_STOP_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ /* Read offset register value */
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, SI72XX_OFFSET_ADDR, &read))
+ /* Calculate offset: Offset = value(0x1D)/16 */
+ *offsetValue = (int8_t)read * 1000 / 16;
+
+ /* Read gain register value */
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, SI72XX_GAIN_ADDR, &read))
+ /* calculate gain: Gain = (value(0x1E)/2048) + 1 */
+ *gainValue = ((int8_t)read * 1000 / 2048) + 1000;
+
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSleep(addr))
+
+ RETURN:
+ return res;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Wakes up SI72xx, performs a temperature conversion, and places sensor
+ * back to sleep. Temperature calculation is performed using compensation
+ * data.
+ * @param[out] temp
+ * Temperature measurement in millidegree Celsius
+ * @param[in] offsetData
+ * Offset correction data
+ * @param[in] gainData
+ * Gain correction data
+ *****************************************************************************/
+drivers_si72xx_ret_e Si72xx_ReadCorrectedTempAndSleep(uint8_t addr,
+ int16_t offsetData,
+ int16_t gainData,
+ int32_t *correctedTemp)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t read = 0;
+ uint8_t dspSigM, dspSigL;
+ uint8_t freshBit;
+ int16_t dataValue;
+ int32_t rawTemp;
+ int32_t milliCelsius;
+
+ uint16_t tempCtrl4Setting = 0x00;
+
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+
+ /* Set stop-bit */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = ((read & ~SI72XX_POWERCTRL_MASK) | SI72XX_STOP_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ /* Clear IIR and FIR filtering */
+ SI72XX_WRITE_8B(SI72XX_CTRL4, tempCtrl4Setting);
+
+ /* Select Temperature conversion */
+ SI72XX_READ_8B(SI72XX_DSPSIGSEL, &read);
+ read = ((read & ~SI72XX_DSPSIGSEL_MASK) | SI72XX_DSPSIGSEL_TEMP);
+ SI72XX_WRITE_8B(SI72XX_DSPSIGSEL, read);
+
+ /* Perform temperature conversion */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ read = (((read & (~SI72XX_STOP_MASK)) & ~(SI72XX_SLEEP_MASK))
+ | SI72XX_ONEBURST_MASK);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, read);
+
+ /* Read temperature conversion result */
+ SI72XX_READ_8B(SI72XX_DSPSIGM, &dspSigM);
+ SI72XX_READ_8B(SI72XX_DSPSIGL, &dspSigL);
+
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSleep(addr))
+
+ freshBit = dspSigM >> SI72XX_FRESH_BIT_SHIFT;
+ if (freshBit == 0)
+ {
+ res = __SI72XX_NODATA;
+ goto RETURN;
+ }
+
+ /* dataValue = (Dspigm[6:0]<<5) + (Dspigl[7:0]>>3) */
+ dataValue = (((uint16_t)dspSigM) & SI72XX_DSPSIGM_MASK) << 8;
+ dataValue = (dataValue | dspSigL) >> 3;
+
+ /* rawTemp equation is from Si7210 datasheet */
+ /* rawTemp(mC) = ((dataValue^2)*(-3.83*10^-6))+(0.16094*dataValue)-279.8 */
+ rawTemp = ((int32_t)dataValue * (int32_t)dataValue * -383 / 100000)
+ + ((16094 * dataValue) / 100) - 279800;
+
+ milliCelsius = ((rawTemp * (int32_t)gainData) + offsetData) / 1000;
+
+ *correctedTemp = milliCelsius;
+
+ RETURN:
+ return res;
+}
+
+/**************************************************************************
+ * @brief
+ * Wake-up Si72xx, read out part Revision and ID, and place Si72xx
+ * back to SLEEP sleep-mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[out] partId
+ * Si7210 part ID
+ * @param[out] partRev
+ * Si72xx part Revision
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_IdentifyAndSleep(uint8_t addr,
+ uint8_t *partId,
+ uint8_t *partRev)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ uint8_t read = 0;
+
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, (read | SI72XX_STOP_MASK));
+ SI72XX_READ_8B(SI72XX_HREVID, &read);
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSleep(addr))
+
+ *partRev = read & SI72XX_REV_MASK;
+ *partId = read >> SI72XX_ID_SHIFT;
+
+ RETURN:
+ return res;
+}
+
+/**************************************************************************
+ * @brief
+ * Wake-up Si72xx, read out Si72xx base part-number and variant, and
+ * place sensor back to SLEEP sleep-mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[out] basePn
+ * Si7210 part ID
+ * @param[out] partRev
+ * Si72xx part Revision
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_ReadVariantAndSleep(uint8_t addr,
+ uint8_t *basePn,
+ uint8_t *pnVariant)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+
+ uint8_t read = 0;
+
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, SI72XX_BASE_PART_NUMBER, &read))
+ *basePn = read;
+ SI72XX_INT_CALL(Si72xx_Read_OTP(addr, SI72XX_PART_VARIANT, &read))
+ *pnVariant = read;
+ SI72XX_INT_CALL(Si72xx_FromIdle_GoToSleep(addr))
+
+ RETURN:
+ return res;
+}
+
+/**************************************************************************
+ * @brief
+ * Self-test sequence offered by the device. It uses an internal
+ * coil to generate and test the + and - field.
+ * @param[in] addr
+ * The I2C address of the sensor
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_SelfTest(uint8_t addr)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ int16_t field_pos = 0;
+ int16_t field_neg = 0;
+
+ /* Enable test field generator coil in POSITIVE direction. */
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr))
+ SI72XX_WRITE_8B(SI72XX_TM_FG, 1);
+
+ /* Measure field strength */
+ SI72XX_INT_CALL(Si72xx_ReadMagFieldDataAndSleep(addr, SI7210_200MT, SI72XX_IDLE_MODE, &field_pos)); // 200mT
+ field_pos = Si72xx_ConvertDataCodesToMagneticField(SI7210_200MT, field_pos)/1000;
+
+ /* Enable test field generator coil in POSITIVE direction. */
+ SI72XX_WRITE_8B(SI72XX_TM_FG, 2);
+
+ /* Measure field strength */
+ SI72XX_INT_CALL(Si72xx_ReadMagFieldDataAndSleep(addr, SI7210_200MT, SI72XX_IDLE_MODE, &field_neg))
+ field_neg = Si72xx_ConvertDataCodesToMagneticField(SI7210_200MT, field_neg)/1000;
+
+ /* Disable test field generator coil. */
+ SI72XX_WRITE_8B(SI72XX_TM_FG, 0);
+
+ /* Send to sleep mode */
+ SI72XX_INT_CALL(Si72xx_EnterSleepMode(addr, SI72XX_SLEEP_MODE))
+
+ /* Vdd of SI7210. This is used in device's self-test calculations */
+#define SI72xx_VDD (3.3f)
+
+ float b_out = 1.16 * SI72xx_VDD;
+ float b_upper = b_out + (b_out * 0.25); /* +25% */
+ float b_lower = b_out - (b_out * 0.25); /* -25% */
+
+ if( (field_pos <= b_upper) &&
+ (field_pos >= b_lower) &&
+ (field_neg >= (b_upper * -1)) &&
+ (field_neg <= (b_lower * -1)))
+ {
+ log_info("(i) Sensor 0x%X self test PASS\r\n", addr);
+ }
+ else
+ {
+ log_info("(i) Sensor 0x%X self test FAIL!\r\n", addr);
+ res = __SI72XX_MISCALIB;
+ goto RETURN;
+ }
+
+ RETURN:
+ return res;
+}
+
+/****************************************************************************
+ * @brief Convert Si7210 I2C Data Readings to Magnetic Field in microTeslas
+ * @param[in] fieldScale
+ * 20mT or 200mT full-scale magnetic field range
+ * @param[in] dataCodes
+ * signed 15bit value read from hall sensor after magnetic field conversion
+ * @return microTeslas
+ *****************************************************************************/
+//static inline int32_t Si72xx_ConvertDataCodesToMagneticField(Si72xxFieldScale_t fieldScale, int16_t dataCode)
+int32_t Si72xx_ConvertDataCodesToMagneticField(Si72xxFieldScale_t fieldScale, int16_t dataCode)
+{
+ switch (fieldScale)
+ {
+ case SI7210_20MT :
+ /* 20mT: 1(LSB) = 1.25uT */
+ return (dataCode * 125) / 100;
+ case SI7210_200MT :
+ /* 200mT: 1(LSB) = 12.5uT */
+ return (dataCode * 125) / 10;
+ default :
+ return 0;
+ }
+}
+
+
+
+
+// =============================================================================
+
+
+/**************************************************************************
+ * @brief
+ * Function to set threshold value in sw_op register of Si7210 sensor (based on application note AN1018 and https://github.com/FARLY7/si7210-driver)
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[in] mTScale
+ * The magnetic scale sensor
+ * @param[in] threshold
+ * The threshold value in mT. Threshold value available from 0.08 mT to 19.2 mT (for 20 mT scale) or 0.8 mT to 192 mT (for 200 mT scale)
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_Set_Threshold (uint8_t addr, Si72xxFieldScale_t mTScale, float threshold)
+{
+ /* required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call */
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ /* hysteresis value set to 10% of the threshold */
+ float hysteresis = threshold * 0.1;
+
+ /* Idle mode */
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr));
+
+ /* Verifying the threshold value according to the scale */
+ if (mTScale != SI7210_200MT && mTScale != SI7210_20MT)
+ {
+ return __SI72XX_INVALID_ARG;
+ }
+
+ /* To store read register value */
+ uint8_t read = 0;
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ SI72XX_WRITE_8B(SI72XX_POWER_CTRL, (read & ~SI72XX_USESTORE_MASK) | SI72XX_STOP_MASK); /* Set the STOP bit */
+
+ /* Calculation of the threshold value and adapt his scale according to datasheet */
+ if (mTScale == SI7210_200MT)
+ {
+ /* x20 (LSB = 0.05 mT) to adapt the range from 200mT to 4000 */
+ threshold *= 20.0;
+ }
+ else
+ {
+ /* x200 (LSB = 0.005 mT) : to adapt the range from 20mT to 4000 */
+ threshold *= 200.0;
+ }
+
+ /* Available range from 16 to 3840,
+ * from 0.08 mT to 19.2 mT (20 mT scale) or 0.8 mT to 192 mT (200 mT scale) */
+ if(threshold < 16)
+ {
+ threshold = 16;
+ }
+ else if (threshold > 3840)
+ {
+ threshold = 3840;
+ }
+
+ /* sw_op register to fill for threshold
+ * threshold = ( 16 + sw_op[3:0] ) × 2^sw_op[6:4] */
+ uint8_t div2_thr = 0;
+
+ /* 4 bits max value : 15 */
+ while (threshold >= 32)
+ {
+ threshold /= 2;
+ div2_thr++;
+ }
+ threshold -= 16;
+
+
+ /* Build the register value */
+ uint8_t ctrl1 = 0; /* reset sw_low4field to have 0V by default on alert pin */
+ ctrl1 |= ((div2_thr & 0x07) << 4) | ((uint8_t)(roundf(threshold)) & 0x0F);
+
+ /* Write ctrl1 into SI72XX_CTRL1 register */
+ SI72XX_WRITE_8B(SI72XX_CTRL1, ctrl1);
+
+ RETURN:
+ return res;
+}
+
+
+
+/**************************************************************************
+ * @brief
+ * Function to set hysteresis value in sw_hyst register of Si7210 sensor (based on application note AN1018)
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ * @param[in] mTScale
+ * The magnetic scale sensor
+ * @param[in] hysteresis
+ * The hysteresis value in mT. Hysteresis value available from 0.04 mT to 8.96 mT (for 20 mT scale) or 0.4 mT to 89.6 mT (for 200 mT scale)
+ **************************************************************************/
+drivers_si72xx_ret_e Si72xx_Set_Hysteresis (uint8_t addr, Si72xxFieldScale_t mTScale, float hysteresis)
+{
+ /* required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call */
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ /* Idle mode */
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr));
+
+ /****************************************************/
+ /* SET HYSTERESIS */
+ /****************************************************/
+
+ /* Calculation of the hysteresis value and adapt his scale according to datasheet
+ * LSB = 0.005 mT */
+ if (mTScale == SI7210_200MT)
+ {
+ /* x20 to adapt the range from 90 mT to 2000 */
+ hysteresis *= 20.0;
+ }
+ else if (mTScale == SI7210_20MT)
+ {
+ /* x200 : to adapt the range from 9 mT to 2000 */
+ hysteresis *= 200.0;
+ }
+ else
+ {
+ return __SI72XX_INVALID_ARG;
+ }
+
+ /* Available range from 8 to 1792,
+ * from 0.04 mT to 8.96 mT (20 mT scale) or 0.4 mT to 89.6 mT (200 mT scale) */
+ if (hysteresis < 8)
+ {
+ hysteresis = 8;
+ }
+ else if (hysteresis > 1792)
+ {
+ hysteresis = 1792;
+ }
+
+ /* sw_hyst register to fill for hysteresis
+ * hysteresis = (8 + sw_hyst[2:0]) × 2^sw_hyst[5:3] */
+ uint8_t div2_hys = 0;
+
+ /* 3 bits max value : 7 */
+ while (hysteresis >= 16)
+ {
+ hysteresis /= 2;
+ div2_hys++;
+ }
+ hysteresis -= 8;
+
+ /* Build the register value
+ * sw_fieldpolsel = 0b00 => absolute value field to compare with threshold
+ * sw_hyst = 0b00 0000 */
+ uint8_t ctrl2 = 0; /* reset sw_fieldpolsel to compare with absolute value */
+ ctrl2 |= ((div2_hys & 0x07) << 3) | ((uint8_t)(roundf(hysteresis)) & 0x07);
+
+ /* Write ctrl2 into SI72XX_CTRL2 register */
+ SI72XX_WRITE_8B(SI72XX_CTRL2, ctrl2);
+
+ RETURN:
+ return res;
+}
+
+
+
+
+
+/**************************************************************************
+ * @brief
+ * Print some of the hall sensor registers.
+ * Command can only be issued if Si72xx is idle mode.
+ * @param[in] addr
+ * The I2C address of the sensor
+ **************************************************************************/
+drivers_si72xx_ret_e Debug_Si72xx_register (uint8_t addr)
+{
+ // required for SI72XX_READ/WRITE_8B / SI72XX_INT_CALL macro call
+ drivers_si72xx_ret_e res = __SI72XX_OK;
+ _I2C_Status i2c_st = __I2C_OK;
+
+ /* To store read register value */
+ uint8_t read = 0;
+
+ /* Idle mode */
+ SI72XX_INT_CALL(Si72xx_WakeUpAndIdle(addr));
+
+ log_info("\r(i) Debug SI72xx register :\r\n");
+ /* Read every register and deplay their value on uart terminal */
+ SI72XX_READ_8B(SI72XX_POWER_CTRL, &read);
+ log_info("\r\t(i) SI72XX_POWER_CTRL (0x%02x) : %02x\r\n", SI72XX_POWER_CTRL, read);
+
+ SI72XX_READ_8B(SI72XX_CTRL1, &read);
+ log_info("\t(i) SI72XX_CTRL1 (0x%02x) : %02x\r\n", SI72XX_CTRL1, read);
+
+ SI72XX_READ_8B(SI72XX_CTRL2, &read);
+ log_info("\t(i) SI72XX_CTRL2 (0x%02x) : %02x\r\n", SI72XX_CTRL2, read);
+
+ RETURN:
+ return res;
+}
+
+
+
+#endif
+
+
+
+
+
diff --git a/Src/it_sdk/eeprom/sdk_state.c b/Src/it_sdk/eeprom/sdk_state.c
index 3d4545d..024b00c 100644
--- a/Src/it_sdk/eeprom/sdk_state.c
+++ b/Src/it_sdk/eeprom/sdk_state.c
@@ -32,6 +32,7 @@
#include
#endif
#include
+#include
itsdk_state_t itsdk_state;