foxBMS - Unit Tests  1.5.0
The foxBMS Unit Tests API Documentation
htsensor.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file htsensor.c
44  * @author foxBMS Team
45  * @date 2021-08-05 (date of creation)
46  * @updated 2023-02-03 (date of last update)
47  * @version v1.5.0
48  * @ingroup DRIVERS
49  * @prefix HTSEN
50  *
51  * @brief Driver for the Sensirion SHT35-DIS I2C humidity/temperature sensor
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "htsensor.h"
57 
58 #include "database.h"
59 #include "i2c.h"
60 
61 #include <math.h>
62 #include <stdbool.h>
63 #include <stdint.h>
64 
65 /*========== Macros and Definitions =========================================*/
66 
67 /** Sensor I2C interface */
68 #define HTSEN_I2C_INTERFACE (i2cREG1)
69 /** Sensor I2C address */
70 #define HTSEN_I2C_ADDRESS (0x44u)
71 
72 /** Number of read tries before restart, to avoid infinite waiting for results */
73 #define HTSEN_READ_TRIES (5u)
74 
75 /** Conversion coefficients to get measurement from raw temperature value @{ */
76 #define HTSEN_TEMP_SCALING (175.0f)
77 #define HTSEN_TEMP_OFFSET (-45.0f)
78 #define HTSEN_TEMP_DEG_TO_DDEG (10.0f)
79 /**@}*/
80 
81 /** Conversion coefficients to get measurement from raw humidity value @{ */
82 #define HTSEN_HUMIDITY_SCALING (100.0f)
83 #define HTSEN_FULL_SCALE (65535.0f)
84 /**@}*/
85 
86 /** Defines for byte positions for data handling @{ */
87 #define HTSEN_TEMPERATURE_LSB (1u)
88 #define HTSEN_TEMPERATURE_MSB (0u)
89 #define HTSEN_TEMPERATURE_BYTE_CRC (2u)
90 #define HTSEN_HUMIDITY_LSB (4u)
91 #define HTSEN_HUMIDITY_MSB (3u)
92 #define HTSEN_HUMIDITY_BYTE_CRC (5u)
93 #define HTSEN_BYTE_SHIFT (8u)
94 #define HTSEN_MEASUREMENT_LENGTH_IN_BYTES (2u)
95 #define HTSEN_TOTAL_DATA_LENGTH_IN_BYTES (6u)
96 /**@}*/
97 
98 /** Defines for sensor CRC computation @{ */
99 #define HTSEN_CRC_POLYNOMIAL (0x31u)
100 #define HTSEN_CRC_SEED (0xFF)
101 #define HTSEN_CRC_BYTE_SHIFT (0x8u)
102 #define HTSEN_CRC_MSB_MASK (0x80u)
103 #define HTSEN_CRC_8BIT_MASK (0xFFu)
104 /**@}*/
105 
106 /**
107  * Definition of single measurement command
108  * data sheet February 2019 - Version 6, table 9, page 10
109  *
110  * Clock stretching can be used to let sensor tell that the measurement
111  * is not finished by pulling the clock low
112  * Not recommended: if system is stopped during clock stretching,
113  * sensor could be blocked in this mode and render I2C bus unusable.
114  * !!!---WARNING---!!!: if clock stretching is used, the timeout in the
115  * receive loop of the function #I2C_Read() must be adapted,
116  * the current value is too small compared to the time the slave will
117  * make the master wait in the clock stretching mode.
118  *
119  * Depending on the clock stretching setting, the code for the instructions
120  * changes:
121  * -> With stretching
122  * - 1 MSB
123  * - 1 LSB for high repeatability
124  * - 1 LSB for medium repeatability
125  * - 1 LSB for low repeatability
126  * -> Without stretching
127  * - 1 MSB
128  * - 1 LSB for high repeatability
129  * - 1 LSB for medium repeatability
130  * - 1 LSB for low repeatability
131  * This results in 6 possible configurations
132  * Durability changes the measurement duration.
133  * @{
134  */
135 #define HTSEN_CLOCK_STRETCHING (false)
136 #if (HTSEN_CLOCK_STRETCHING == false)
137 #define HTSEN_SINGLE_MEAS_MSB (0x24u)
138 #define HTSEN_HIGH_REPEATABILITY (0x00u)
139 #define HTSEN_MEDIUM_REPEATABILITY (0x0Bu)
140 #define HTSEN_LOW_REPEATABILITY (0x16u)
141 #else
142 #define HTSEN_SINGLE_MEAS_MSB (0x2Cu)
143 #define HTSEN_HIGH_REPEATABILITY (0x06u)
144 #define HTSEN_MEDIUM_REPEATABILITY (0x0Du)
145 #define HTSEN_LOW_REPEATABILITY (0x10u)
146 #endif
147 
148 #define HTSEN_SINGLE_MEAS_LSB (HTSEN_HIGH_REPEATABILITY)
149 /**@}*/
150 
151 /*========== Static Constant and Variable Definitions =======================*/
152 #pragma SET_DATA_SECTION(".sharedRAM")
153 uint8_t i2cReadBuffer[HTSEN_TOTAL_DATA_LENGTH_IN_BYTES] = {0u, 0u, 0u, 0u, 0u, 0u};
155 #pragma SET_DATA_SECTION()
156 
157 /** variable to store the measurement results */
159 /** number of tries to read the sensor data before requested a new measurement */
160 static uint8_t htsen_readTries = 0u;
161 
162 /*========== Extern Constant and Variable Definitions =======================*/
163 
164 /*========== Static Function Prototypes =====================================*/
165 
166 /**
167  * @brief computes CRC8.
168  * @param[in] data: data to use to compute CRC
169  * @param[in] length: length of data
170  * @return 8-bit CRC value
171  */
172 static uint8_t HTSEN_CalculateCrc8(const uint8_t *data, uint32_t length);
173 
174 /**
175  * @brief computes temperature measurement from raw value.
176  * @param[in] data: raw temperature value
177  * @return temperature measurement in deci &deg;C
178  */
179 static int16_t HTSEN_ConvertRawTemperature(uint16_t data);
180 
181 /**
182  * @brief computes humidity measurement from raw value.
183  * @param[in] data: raw humidity value
184  * @return humidity measurement in %
185  */
186 static uint8_t HTSEN_ConvertRawHumidity(uint16_t data);
187 
188 /*========== Static Function Implementations ================================*/
189 
190 static uint8_t HTSEN_CalculateCrc8(const uint8_t *data, uint32_t length) {
191  FAS_ASSERT(data != NULL_PTR);
192  FAS_ASSERT(length <= UINT32_MAX);
193 
194  uint16_t crc = HTSEN_CRC_SEED;
195 
196  for (uint8_t i = 0u; i < length; i++) {
197  crc ^= data[i];
198  for (uint8_t j = 0u; j < HTSEN_CRC_BYTE_SHIFT; j++) {
199  if ((crc & HTSEN_CRC_MSB_MASK) != 0u) {
200  crc = ((crc << 1u) & HTSEN_CRC_8BIT_MASK) ^ HTSEN_CRC_POLYNOMIAL;
201  } else {
202  crc = (crc & HTSEN_CRC_8BIT_MASK) << 1u;
203  }
204  }
205  }
206  return (uint8_t)(crc & HTSEN_CRC_8BIT_MASK);
207 }
208 
209 static int16_t HTSEN_ConvertRawTemperature(uint16_t data) {
210  /* AXIVION Routine Generic-MissingParameterAssert: data: parameter accepts whole range */
211  float_t temperature_ddeg = HTSEN_TEMP_DEG_TO_DDEG *
212  (HTSEN_TEMP_OFFSET + (HTSEN_TEMP_SCALING * (((float_t)data) / HTSEN_FULL_SCALE)));
213  return (int16_t)temperature_ddeg;
214 }
215 
216 static uint8_t HTSEN_ConvertRawHumidity(uint16_t data) {
217  float_t humidity_perc = (HTSEN_HUMIDITY_SCALING * (((float_t)data) / HTSEN_FULL_SCALE));
218  return (uint8_t)humidity_perc;
219 }
220 
221 /*========== Extern Function Implementations ================================*/
222 
223 extern void HTSEN_Trigger(void) {
224  static HTSEN_STATE_e htsenState = HTSEN_START_MEAS;
225  STD_RETURN_TYPE_e htsenReturnValue = STD_OK;
226  uint32_t current_time = OS_GetTickCount();
227 
228  switch (htsenState) {
229  case HTSEN_START_MEAS:
230  /* Trigger a measurement */
232  OS_DelayTaskUntil(&current_time, 2u);
233  if (htsenReturnValue == STD_OK) {
234  htsenState = HTSEN_READ_RESULTS;
235  }
237  break;
238  case HTSEN_READ_RESULTS:
239  /* Try to read values */
240  htsenReturnValue =
242  OS_DelayTaskUntil(&current_time, 2u);
243  if (htsenReturnValue == STD_OK) {
244  /* If sensor acknowledges on I2C bus, results are available */
245  /* Check if CRC valid */
246  /* Only take temperature value if CRC valid */
252  }
253  /* Only take humidity value if CRC valid */
258  (uint16_t)i2cReadBuffer[HTSEN_HUMIDITY_LSB]);
259  }
261  htsenState = HTSEN_START_MEAS;
262  } else {
263  /* If sensor does not acknowledge on I2C bus, results are not available ye */
264  if (htsen_readTries > 0u) {
265  htsen_readTries--;
266  } else {
267  htsenState = HTSEN_START_MEAS;
268  }
269  }
270  break;
271  default:
272  /* invalid state */
274  break;
275  }
276 }
277 
278 /*========== Getter for static Variables (Unit Test) ========================*/
279 
280 /*========== Externalized Static Function Implementations (Unit Test) =======*/
281 #ifdef UNITY_UNIT_TEST
282 extern uint8_t TEST_HTSEN_TestCalculateCrc8(uint8_t *data, uint32_t length) {
283  return HTSEN_CalculateCrc8(data, 2u);
284 }
285 #endif
Database module header.
#define DATA_WRITE_DATA(...)
Definition: database.h:96
@ DATA_BLOCK_ID_HTSEN
Definition: database_cfg.h:109
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:250
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
#define HTSEN_BYTE_SHIFT
Definition: htsensor.c:93
#define HTSEN_TEMPERATURE_BYTE_CRC
Definition: htsensor.c:89
#define HTSEN_CRC_MSB_MASK
Definition: htsensor.c:102
#define HTSEN_SINGLE_MEAS_LSB
Definition: htsensor.c:148
static int16_t HTSEN_ConvertRawTemperature(uint16_t data)
computes temperature measurement from raw value.
Definition: htsensor.c:209
static uint8_t htsen_readTries
Definition: htsensor.c:160
static uint8_t HTSEN_ConvertRawHumidity(uint16_t data)
computes humidity measurement from raw value.
Definition: htsensor.c:216
#define HTSEN_HUMIDITY_SCALING
Definition: htsensor.c:82
#define HTSEN_I2C_ADDRESS
Definition: htsensor.c:70
uint8_t i2cWriteBuffer[2u]
Definition: htsensor.c:154
static uint8_t HTSEN_CalculateCrc8(const uint8_t *data, uint32_t length)
computes CRC8.
Definition: htsensor.c:190
#define HTSEN_CRC_SEED
Definition: htsensor.c:100
#define HTSEN_HUMIDITY_LSB
Definition: htsensor.c:90
#define HTSEN_TEMP_OFFSET
Definition: htsensor.c:77
#define HTSEN_TOTAL_DATA_LENGTH_IN_BYTES
Definition: htsensor.c:95
#define HTSEN_TEMP_SCALING
Definition: htsensor.c:76
#define HTSEN_TEMPERATURE_MSB
Definition: htsensor.c:88
#define HTSEN_SINGLE_MEAS_MSB
Definition: htsensor.c:137
#define HTSEN_TEMPERATURE_LSB
Definition: htsensor.c:87
#define HTSEN_READ_TRIES
Definition: htsensor.c:73
uint8_t i2cReadBuffer[HTSEN_TOTAL_DATA_LENGTH_IN_BYTES]
Definition: htsensor.c:153
#define HTSEN_HUMIDITY_BYTE_CRC
Definition: htsensor.c:92
#define HTSEN_FULL_SCALE
Definition: htsensor.c:83
#define HTSEN_TEMP_DEG_TO_DDEG
Definition: htsensor.c:78
#define HTSEN_HUMIDITY_MSB
Definition: htsensor.c:91
#define HTSEN_MEASUREMENT_LENGTH_IN_BYTES
Definition: htsensor.c:94
#define HTSEN_I2C_INTERFACE
Definition: htsensor.c:68
static DATA_BLOCK_HTSEN_s htsen_data
Definition: htsensor.c:158
uint8_t TEST_HTSEN_TestCalculateCrc8(uint8_t *data, uint32_t length)
Definition: htsensor.c:282
#define HTSEN_CRC_BYTE_SHIFT
Definition: htsensor.c:101
#define HTSEN_CRC_POLYNOMIAL
Definition: htsensor.c:99
#define HTSEN_CRC_8BIT_MASK
Definition: htsensor.c:103
void HTSEN_Trigger(void)
triggers a measurement of the I2C humidity/temperature sensor.
Definition: htsensor.c:223
Header for the driver for the Sensirion SHT35-DIS I2C humidity/temperature sensor.
HTSEN_STATE_e
Definition: htsensor.h:67
@ HTSEN_READ_RESULTS
Definition: htsensor.h:69
@ HTSEN_START_MEAS
Definition: htsensor.h:68
STD_RETURN_TYPE_e I2C_ReadDma(i2cBASE_t *pI2cInterface, uint32_t slaveAddress, uint32_t nrBytes, uint8_t *readData)
reads from an I2C slave, no register address written first, using DMA.
Definition: i2c.c:415
STD_RETURN_TYPE_e I2C_WriteDma(i2cBASE_t *pI2cInterface, uint32_t slaveAddress, uint32_t nrBytes, uint8_t *writeData)
writes to an I2C slave, no register address written first, using DMA.
Definition: i2c.c:510
Header for the driver for the I2C module.
void OS_DelayTaskUntil(uint32_t *pPreviousWakeTime, uint32_t milliseconds)
Delay a task until a specified time.
Definition: os_freertos.c:146
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:142
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:122
int16_t temperature_ddegC
Definition: database_cfg.h:584
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:583