1 /*
2 * Copyright (c) 2022 Wuerth Elektronik eiSos GmbH & Co. KG
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Driver file for the WSEN-TIDS sensor.
10 */
11
12 #include "WSEN_TIDS_2521020222501.h"
13
14 #include <stdio.h>
15
16 #include <weplatform.h>
17
18 /**
19 * @brief Default sensor interface configuration.
20 */
21 static WE_sensorInterface_t tidsDefaultSensorInterface = {
22 .sensorType = WE_TIDS,
23 .interfaceType = WE_i2c,
24 .options = {.i2c = {.address = TIDS_ADDRESS_I2C_1, .burstMode = 0, .slaveTransmitterMode = 0, .useRegAddrMsbForMultiBytesRead = 0, .reserved = 0},
25 .spi = {.chipSelectPort = 0, .chipSelectPin = 0, .burstMode = 0, .reserved = 0},
26 .readTimeout = 1000,
27 .writeTimeout = 1000},
28 .handle = 0};
29
30 /**
31 * @brief Read data from sensor.
32 *
33 * @param[in] sensorInterface Pointer to sensor interface
34 * @param[in] regAdr Address of register to read from
35 * @param[in] numBytesToRead Number of bytes to be read
36 * @param[out] data Target buffer
37 * @return Error Code
38 */
TIDS_ReadReg(WE_sensorInterface_t * sensorInterface,uint8_t regAdr,uint16_t numBytesToRead,uint8_t * data)39 static inline int8_t TIDS_ReadReg(WE_sensorInterface_t* sensorInterface,
40 uint8_t regAdr,
41 uint16_t numBytesToRead,
42 uint8_t *data)
43 {
44 return WE_ReadReg(sensorInterface, regAdr, numBytesToRead, data);
45 }
46
47 /**
48 * @brief Write data to sensor.
49 *
50 * @param[in] sensorInterface Pointer to sensor interface
51 * @param[in] regAdr Address of register to write to
52 * @param[in] numBytesToWrite Number of bytes to be written
53 * @param[in] data Source buffer
54 * @return Error Code
55 */
TIDS_WriteReg(WE_sensorInterface_t * sensorInterface,uint8_t regAdr,uint16_t numBytesToWrite,uint8_t * data)56 static inline int8_t TIDS_WriteReg(WE_sensorInterface_t* sensorInterface,
57 uint8_t regAdr,
58 uint16_t numBytesToWrite,
59 uint8_t *data)
60 {
61 return WE_WriteReg(sensorInterface, regAdr, numBytesToWrite, data);
62 }
63
64 /**
65 * @brief Returns the default sensor interface configuration.
66 * @param[out] sensorInterface Sensor interface configuration (output parameter)
67 * @return Error code
68 */
TIDS_getDefaultInterface(WE_sensorInterface_t * sensorInterface)69 int8_t TIDS_getDefaultInterface(WE_sensorInterface_t* sensorInterface)
70 {
71 *sensorInterface = tidsDefaultSensorInterface;
72 return WE_SUCCESS;
73 }
74
75 /**
76 * @brief Read the device ID
77 *
78 * Expected value is TIDS_DEVICE_ID_VALUE.
79 *
80 * @param[in] sensorInterface Pointer to sensor interface
81 * @param[out] deviceID The returned device ID.
82 * @retval Error code
83 */
TIDS_getDeviceID(WE_sensorInterface_t * sensorInterface,uint8_t * deviceID)84 int8_t TIDS_getDeviceID(WE_sensorInterface_t* sensorInterface, uint8_t *deviceID)
85 {
86 return TIDS_ReadReg(sensorInterface, TIDS_DEVICE_ID_REG, 1, deviceID);
87 }
88
89 /**
90 * @brief Set software reset [enabled, disabled]
91 * @param[in] sensorInterface Pointer to sensor interface
92 * @param[in] swReset Software reset state
93 * @retval Error code
94 */
TIDS_softReset(WE_sensorInterface_t * sensorInterface,TIDS_state_t swReset)95 int8_t TIDS_softReset(WE_sensorInterface_t* sensorInterface, TIDS_state_t swReset)
96 {
97 TIDS_softReset_t swRstReg;
98
99 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_SOFT_RESET_REG, 1, (uint8_t *) &swRstReg))
100 {
101 return WE_FAIL;
102 }
103
104 swRstReg.reset = swReset;
105
106 return TIDS_WriteReg(sensorInterface, TIDS_SOFT_RESET_REG, 1, (uint8_t *) &swRstReg);
107 }
108
109 /**
110 * @brief Read the software reset state [enabled, disabled]
111 * @param[in] sensorInterface Pointer to sensor interface
112 * @param[out] swReset The returned software reset state.
113 * @retval Error code
114 */
TIDS_getSoftResetState(WE_sensorInterface_t * sensorInterface,TIDS_state_t * swReset)115 int8_t TIDS_getSoftResetState(WE_sensorInterface_t* sensorInterface, TIDS_state_t *swReset)
116 {
117 TIDS_softReset_t swRstReg;
118
119 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_SOFT_RESET_REG, 1, (uint8_t *) &swRstReg))
120 {
121 return WE_FAIL;
122 }
123
124 *swReset = (TIDS_state_t) swRstReg.reset;
125
126 return WE_SUCCESS;
127 }
128
129 /**
130 * @brief Enable/disable continuous (free run) mode
131 * @param[in] sensorInterface Pointer to sensor interface
132 * @param[in] mode Continuous mode state
133 * @retval Error code
134 */
TIDS_enableContinuousMode(WE_sensorInterface_t * sensorInterface,TIDS_state_t mode)135 int8_t TIDS_enableContinuousMode(WE_sensorInterface_t* sensorInterface, TIDS_state_t mode)
136 {
137 TIDS_ctrl_t ctrlReg;
138
139 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
140 {
141 return WE_FAIL;
142 }
143
144 ctrlReg.freeRunBit = mode;
145
146 return TIDS_WriteReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg);
147 }
148
149 /**
150 * @brief Check if continuous (free run) mode is enabled
151 * @param[in] sensorInterface Pointer to sensor interface
152 * @param[out] mode The returned continuous mode enable state
153 * @retval Error code
154 */
TIDS_isContinuousModeEnabled(WE_sensorInterface_t * sensorInterface,TIDS_state_t * mode)155 int8_t TIDS_isContinuousModeEnabled(WE_sensorInterface_t* sensorInterface, TIDS_state_t *mode)
156 {
157 TIDS_ctrl_t ctrlReg;
158
159 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
160 {
161 return WE_FAIL;
162 }
163
164 *mode = (TIDS_state_t) ctrlReg.freeRunBit;
165
166 return WE_SUCCESS;
167 }
168
169 /**
170 * @brief Enable/disable block data update mode
171 * @param[in] sensorInterface Pointer to sensor interface
172 * @param[in] bdu Block data update state
173 * @retval Error code
174 */
TIDS_enableBlockDataUpdate(WE_sensorInterface_t * sensorInterface,TIDS_state_t bdu)175 int8_t TIDS_enableBlockDataUpdate(WE_sensorInterface_t* sensorInterface, TIDS_state_t bdu)
176 {
177 TIDS_ctrl_t ctrlReg;
178
179 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
180 {
181 return WE_FAIL;
182 }
183
184 ctrlReg.blockDataUpdate = bdu;
185
186 return TIDS_WriteReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg);
187 }
188
189 /**
190 * @brief Read the block data update state
191 * @param[in] sensorInterface Pointer to sensor interface
192 * @param[out] bdu The returned block data update state
193 * @retval Error code
194 */
TIDS_isBlockDataUpdateEnabled(WE_sensorInterface_t * sensorInterface,TIDS_state_t * bdu)195 int8_t TIDS_isBlockDataUpdateEnabled(WE_sensorInterface_t* sensorInterface, TIDS_state_t *bdu)
196 {
197 TIDS_ctrl_t ctrlReg;
198
199 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
200 {
201 return WE_FAIL;
202 }
203
204 *bdu = (TIDS_state_t) ctrlReg.blockDataUpdate;
205
206 return WE_SUCCESS;
207 }
208
209 /**
210 * @brief Set the output data rate of the sensor
211 * @param[in] sensorInterface Pointer to sensor interface
212 * @param[in] odr Output data rate
213 * @return Error code
214 */
TIDS_setOutputDataRate(WE_sensorInterface_t * sensorInterface,TIDS_outputDataRate_t odr)215 int8_t TIDS_setOutputDataRate(WE_sensorInterface_t* sensorInterface, TIDS_outputDataRate_t odr)
216 {
217 TIDS_ctrl_t ctrlReg;
218
219 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
220 {
221 return WE_FAIL;
222 }
223
224 ctrlReg.outputDataRate = odr;
225
226 return TIDS_WriteReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg);
227 }
228
229 /**
230 * @brief Read the output data rate of the sensor
231 * @param[in] sensorInterface Pointer to sensor interface
232 * @param[out] odr The returned output data rate
233 * @return Error code
234 */
TIDS_getOutputDataRate(WE_sensorInterface_t * sensorInterface,TIDS_outputDataRate_t * odr)235 int8_t TIDS_getOutputDataRate(WE_sensorInterface_t* sensorInterface, TIDS_outputDataRate_t* odr)
236 {
237 TIDS_ctrl_t ctrlReg;
238
239 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
240 {
241 return WE_FAIL;
242 }
243
244 *odr = (TIDS_outputDataRate_t) ctrlReg.outputDataRate;
245
246 return WE_SUCCESS;
247 }
248
249 /**
250 * @brief Trigger capturing of a new value in one-shot mode.
251 * Note: One shot mode can be used for measurement frequencies up to 1 Hz.
252 * @param[in] sensorInterface Pointer to sensor interface
253 * @param[in] oneShot One shot bit state
254 * @return Error code
255 */
TIDS_enableOneShot(WE_sensorInterface_t * sensorInterface,TIDS_state_t oneShot)256 int8_t TIDS_enableOneShot(WE_sensorInterface_t* sensorInterface, TIDS_state_t oneShot)
257 {
258 TIDS_ctrl_t ctrlReg;
259
260 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
261 {
262 return WE_FAIL;
263 }
264
265 ctrlReg.oneShotBit = oneShot;
266
267 return TIDS_WriteReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg);
268 }
269
270 /**
271 * @brief Read the one shot bit state
272 * @param[in] sensorInterface Pointer to sensor interface
273 * @param[out] oneShot The returned one shot bit state
274 * @retval Error code
275 */
TIDS_isOneShotEnabled(WE_sensorInterface_t * sensorInterface,TIDS_state_t * oneShot)276 int8_t TIDS_isOneShotEnabled(WE_sensorInterface_t* sensorInterface, TIDS_state_t *oneShot)
277 {
278 TIDS_ctrl_t ctrlReg;
279
280 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
281 {
282 return WE_FAIL;
283 }
284
285 *oneShot = (TIDS_state_t) ctrlReg.oneShotBit;
286
287 return WE_SUCCESS;
288 }
289
290 /**
291 * @brief Enable/disable auto increment mode
292 * @param[in] sensorInterface Pointer to sensor interface
293 * @param[in] autoIncr Auto increment mode state
294 * @retval Error code
295 */
TIDS_enableAutoIncrement(WE_sensorInterface_t * sensorInterface,TIDS_state_t autoIncr)296 int8_t TIDS_enableAutoIncrement(WE_sensorInterface_t* sensorInterface, TIDS_state_t autoIncr)
297 {
298 TIDS_ctrl_t ctrlReg;
299
300 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
301 {
302 return WE_FAIL;
303 }
304
305 ctrlReg.autoAddIncr = autoIncr;
306
307 return TIDS_WriteReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg);
308 }
309
310 /**
311 * @brief Read the auto increment mode state
312 * @param[in] sensorInterface Pointer to sensor interface
313 * @param[out] autoIncr The returned auto increment mode state
314 * @retval Error code
315 */
TIDS_isAutoIncrementEnabled(WE_sensorInterface_t * sensorInterface,TIDS_state_t * autoIncr)316 int8_t TIDS_isAutoIncrementEnabled(WE_sensorInterface_t* sensorInterface, TIDS_state_t *autoIncr)
317 {
318 TIDS_ctrl_t ctrlReg;
319
320 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_CTRL_REG, 1, (uint8_t *) &ctrlReg))
321 {
322 return WE_FAIL;
323 }
324
325 *autoIncr = (TIDS_state_t) ctrlReg.autoAddIncr;
326
327 return WE_SUCCESS;
328 }
329
330 /**
331 * @brief Set upper temperature limit
332 * @param[in] sensorInterface Pointer to sensor interface
333 * @param[in] hLimit Upper limit
334 * @retval Error code
335 */
TIDS_setTempHighLimit(WE_sensorInterface_t * sensorInterface,uint8_t hLimit)336 int8_t TIDS_setTempHighLimit(WE_sensorInterface_t* sensorInterface, uint8_t hLimit)
337 {
338 return TIDS_WriteReg(sensorInterface, TIDS_LIMIT_T_H_REG, 1, &hLimit);
339 }
340
341 /**
342 * @brief Get upper temperature limit
343 * @param[in] sensorInterface Pointer to sensor interface
344 * @param[out] hLimit The returned temperature high limit
345 * @retval Error code
346 */
TIDS_getTempHighLimit(WE_sensorInterface_t * sensorInterface,uint8_t * hLimit)347 int8_t TIDS_getTempHighLimit(WE_sensorInterface_t* sensorInterface, uint8_t *hLimit)
348 {
349 return TIDS_ReadReg(sensorInterface, TIDS_LIMIT_T_H_REG, 1, hLimit);
350 }
351
352 /**
353 * @brief Set lower temperature limit
354 * @param[in] sensorInterface Pointer to sensor interface
355 * @param[in] lLimit Low limit
356 * @retval Error code
357 */
TIDS_setTempLowLimit(WE_sensorInterface_t * sensorInterface,uint8_t lLimit)358 int8_t TIDS_setTempLowLimit(WE_sensorInterface_t* sensorInterface, uint8_t lLimit)
359 {
360 return TIDS_WriteReg(sensorInterface, TIDS_LIMIT_T_L_REG, 1, &lLimit);
361 }
362
363 /**
364 * @brief Get lower temperature limit
365 * @param[in] sensorInterface Pointer to sensor interface
366 * @param[out] lLimit The returned temperature low limit
367 * @retval Error code
368 */
TIDS_getTempLowLimit(WE_sensorInterface_t * sensorInterface,uint8_t * lLimit)369 int8_t TIDS_getTempLowLimit(WE_sensorInterface_t* sensorInterface, uint8_t *lLimit)
370 {
371 return TIDS_ReadReg(sensorInterface, TIDS_LIMIT_T_L_REG, 1, lLimit);
372 }
373
374 /**
375 * @brief Get overall sensor status
376 * @param[in] sensorInterface Pointer to sensor interface
377 * @param[out] status The returned sensor status data
378 * @retval Error code
379 */
TIDS_getStatusRegister(WE_sensorInterface_t * sensorInterface,TIDS_status_t * status)380 int8_t TIDS_getStatusRegister(WE_sensorInterface_t* sensorInterface, TIDS_status_t *status)
381 {
382 return TIDS_ReadReg(sensorInterface, TIDS_STATUS_REG, 1, (uint8_t *) status);
383 }
384
385 /**
386 * @brief Check if the sensor is busy
387 * @param[in] sensorInterface Pointer to sensor interface
388 * @param[out] busy The returned busy state
389 * @retval Error code
390 */
TIDS_isBusy(WE_sensorInterface_t * sensorInterface,TIDS_state_t * busy)391 int8_t TIDS_isBusy(WE_sensorInterface_t* sensorInterface, TIDS_state_t *busy)
392 {
393 TIDS_status_t statusReg;
394
395 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_STATUS_REG, 1, (uint8_t *) &statusReg))
396 {
397 return WE_FAIL;
398 }
399
400 *busy = (TIDS_state_t) statusReg.busy;
401
402 return WE_SUCCESS;
403 }
404
405 /**
406 * @brief Check if upper limit has been exceeded
407 * @param[in] sensorInterface Pointer to sensor interface
408 * @param[out] state The returned limit exceeded state
409 * @retval Error code
410 */
TIDS_isUpperLimitExceeded(WE_sensorInterface_t * sensorInterface,TIDS_state_t * state)411 int8_t TIDS_isUpperLimitExceeded(WE_sensorInterface_t* sensorInterface, TIDS_state_t *state)
412 {
413 TIDS_status_t statusReg;
414
415 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_STATUS_REG, 1, (uint8_t *) &statusReg))
416 {
417 return WE_FAIL;
418 }
419
420 *state = (TIDS_state_t) statusReg.upperLimitExceeded;
421
422 return WE_SUCCESS;
423 }
424
425 /**
426 * @brief Check if lower limit has been exceeded
427 * @param[in] sensorInterface Pointer to sensor interface
428 * @param[out] state The returned limit exceeded state
429 * @retval Error code
430 */
TIDS_isLowerLimitExceeded(WE_sensorInterface_t * sensorInterface,TIDS_state_t * state)431 int8_t TIDS_isLowerLimitExceeded(WE_sensorInterface_t* sensorInterface, TIDS_state_t *state)
432 {
433 TIDS_status_t statusReg;
434
435 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_STATUS_REG, 1, (uint8_t *) &statusReg))
436 {
437 return WE_FAIL;
438 }
439
440 *state = (TIDS_state_t) statusReg.lowerLimitExceeded;
441
442 return WE_SUCCESS;
443 }
444
445 /**
446 * @brief Read the raw measured temperature value
447 * @param[in] sensorInterface Pointer to sensor interface
448 * @param[out] rawTemp The returned temperature measurement
449 * @retval Error code
450 */
TIDS_getRawTemperature(WE_sensorInterface_t * sensorInterface,int16_t * rawTemp)451 int8_t TIDS_getRawTemperature(WE_sensorInterface_t* sensorInterface, int16_t *rawTemp)
452 {
453 uint8_t tmp[2] = {0};
454
455 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_DATA_T_L_REG, 1, &tmp[0]))
456 {
457 return WE_FAIL;
458 }
459
460 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_DATA_T_H_REG, 1, &tmp[1]))
461 {
462 return WE_FAIL;
463 }
464
465 *rawTemp = (int16_t)(tmp[1] << 8);
466 *rawTemp |= (int16_t)tmp[0];
467 return WE_SUCCESS;
468 }
469
470 /**
471 * @brief Read the measured temperature value in °C
472 * @param[in] sensorInterface Pointer to sensor interface
473 * @param[out] tempDegC The returned temperature measurement
474 * @retval Error code
475 */
TIDS_getTemperature(WE_sensorInterface_t * sensorInterface,float * tempDegC)476 int8_t TIDS_getTemperature(WE_sensorInterface_t* sensorInterface, float *tempDegC)
477 {
478 int16_t rawTemp = 0;
479 if (WE_FAIL == TIDS_getRawTemperature(sensorInterface, &rawTemp))
480 {
481 return WE_FAIL;
482 }
483
484 *tempDegC = (float) rawTemp;
485 *tempDegC = *tempDegC / 100;
486 return WE_SUCCESS;
487 }
488