1 /*
2 * Copyright (c) 2023 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-2521020222501 sensor.
10 */
11
12 #include "WSEN_TIDS_2521020222501_hal.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, .protocol = WE_i2cProtocol_RegisterBased, .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 Temperature upper limit in milli Celsius
334 * @retval Error code
335 */
TIDS_setTempHighLimit(WE_sensorInterface_t * sensorInterface,int32_t hLimit)336 int8_t TIDS_setTempHighLimit(WE_sensorInterface_t* sensorInterface, int32_t hLimit)
337 {
338 int32_t upperLimit = ((hLimit / (int32_t)(10 * 64)) + (int32_t)63);
339 int16_t upperLimitMod = (hLimit % (int32_t)(10 * 64)); //remainder operator sign matches the numerator
340
341 if(hLimit > 0 && upperLimitMod > 320){
342 upperLimit += 1;
343 }else if(hLimit < 0 && -upperLimitMod > 320){
344 upperLimit -= 1;
345 }
346
347 if(upperLimit > 255){
348 upperLimit = 255;
349 }else if (upperLimit < 0){
350 upperLimit = 0;
351 }
352
353 uint8_t upperLimitBits = (uint8_t)upperLimit;
354
355 return TIDS_WriteReg(sensorInterface, TIDS_LIMIT_T_H_REG, 1, &upperLimitBits);
356 }
357
358 /**
359 * @brief Get upper temperature limit
360 * @param[in] sensorInterface Pointer to sensor interface
361 * @param[out] hLimit The returned temperature high limit in milli Celsius
362 * @retval Error code
363 */
TIDS_getTempHighLimit(WE_sensorInterface_t * sensorInterface,int32_t * hLimit)364 int8_t TIDS_getTempHighLimit(WE_sensorInterface_t* sensorInterface, int32_t *hLimit)
365 {
366
367 uint8_t hlimitBits;
368
369 if(WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_LIMIT_T_H_REG, 1, &hlimitBits)){
370 return WE_FAIL;
371 }
372
373 *hLimit = ((int32_t)hlimitBits - 63) * 64 * 10;
374
375 return WE_SUCCESS;
376 }
377
378 /**
379 * @brief Set lower temperature limit
380 * @param[in] sensorInterface Pointer to sensor interface
381 * @param[in] lLimit Temperature lower limit in milli Celsius
382 * @retval Error code
383 */
TIDS_setTempLowLimit(WE_sensorInterface_t * sensorInterface,int32_t lLimit)384 int8_t TIDS_setTempLowLimit(WE_sensorInterface_t* sensorInterface, int32_t lLimit)
385 {
386 int32_t lowerLimit = ((lLimit / (int32_t)(10 * 64)) + (int32_t)63);
387 int16_t lowerLimitMod = (lLimit % (int32_t)(10 * 64)); //remainder operator sign matches the numerator
388
389 if(lLimit > 0 && lowerLimitMod > 320){
390 lowerLimit += 1;
391 }else if(lLimit < 0 && -lowerLimitMod > 320){
392 lowerLimit -= 1;
393 }
394
395 if(lowerLimit > 255){
396 lowerLimit = 255;
397 }else if (lowerLimit < 0){
398 lowerLimit = 0;
399 }
400
401 uint8_t lowerLimitBits = (uint8_t)lowerLimit;
402
403 return TIDS_WriteReg(sensorInterface, TIDS_LIMIT_T_L_REG, 1, &lowerLimitBits);
404 }
405
406 /**
407 * @brief Get lower temperature limit
408 * @param[in] sensorInterface Pointer to sensor interface
409 * @param[out] lLimit The returned temperature lower limit in milli Celsius
410 * @retval Error code
411 */
TIDS_getTempLowLimit(WE_sensorInterface_t * sensorInterface,int32_t * lLimit)412 int8_t TIDS_getTempLowLimit(WE_sensorInterface_t* sensorInterface, int32_t *lLimit)
413 {
414 uint8_t lLimitBits;
415
416 if(WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_LIMIT_T_L_REG, 1, &lLimitBits)){
417 return WE_FAIL;
418 }
419
420 *lLimit = ((int32_t)lLimitBits - 63) * 64 * 10;
421
422 return WE_SUCCESS;
423 }
424
425 /**
426 * @brief Get overall sensor status
427 * @param[in] sensorInterface Pointer to sensor interface
428 * @param[out] status The returned sensor status data
429 * @retval Error code
430 */
TIDS_getStatusRegister(WE_sensorInterface_t * sensorInterface,TIDS_status_t * status)431 int8_t TIDS_getStatusRegister(WE_sensorInterface_t* sensorInterface, TIDS_status_t *status)
432 {
433 return TIDS_ReadReg(sensorInterface, TIDS_STATUS_REG, 1, (uint8_t *) status);
434 }
435
436 /**
437 * @brief Check if the sensor is busy
438 * @param[in] sensorInterface Pointer to sensor interface
439 * @param[out] busy The returned busy state
440 * @retval Error code
441 */
TIDS_isBusy(WE_sensorInterface_t * sensorInterface,TIDS_state_t * busy)442 int8_t TIDS_isBusy(WE_sensorInterface_t* sensorInterface, TIDS_state_t *busy)
443 {
444 TIDS_status_t statusReg;
445
446 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_STATUS_REG, 1, (uint8_t *) &statusReg))
447 {
448 return WE_FAIL;
449 }
450
451 *busy = (TIDS_state_t) statusReg.busy;
452
453 return WE_SUCCESS;
454 }
455
456 /**
457 * @brief Check if upper limit has been exceeded
458 * @param[in] sensorInterface Pointer to sensor interface
459 * @param[out] state The returned limit exceeded state
460 * @retval Error code
461 */
TIDS_isUpperLimitExceeded(WE_sensorInterface_t * sensorInterface,TIDS_state_t * state)462 int8_t TIDS_isUpperLimitExceeded(WE_sensorInterface_t* sensorInterface, TIDS_state_t *state)
463 {
464 TIDS_status_t statusReg;
465
466 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_STATUS_REG, 1, (uint8_t *) &statusReg))
467 {
468 return WE_FAIL;
469 }
470
471 *state = (TIDS_state_t) statusReg.upperLimitExceeded;
472
473 return WE_SUCCESS;
474 }
475
476 /**
477 * @brief Check if lower limit has been exceeded
478 * @param[in] sensorInterface Pointer to sensor interface
479 * @param[out] state The returned limit exceeded state
480 * @retval Error code
481 */
TIDS_isLowerLimitExceeded(WE_sensorInterface_t * sensorInterface,TIDS_state_t * state)482 int8_t TIDS_isLowerLimitExceeded(WE_sensorInterface_t* sensorInterface, TIDS_state_t *state)
483 {
484 TIDS_status_t statusReg;
485
486 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_STATUS_REG, 1, (uint8_t *) &statusReg))
487 {
488 return WE_FAIL;
489 }
490
491 *state = (TIDS_state_t) statusReg.lowerLimitExceeded;
492
493 return WE_SUCCESS;
494 }
495
496 /**
497 * @brief Read the raw measured temperature value
498 * @param[in] sensorInterface Pointer to sensor interface
499 * @param[out] rawTemp The returned temperature measurement
500 * @retval Error code
501 */
TIDS_getRawTemperature(WE_sensorInterface_t * sensorInterface,int16_t * rawTemp)502 int8_t TIDS_getRawTemperature(WE_sensorInterface_t* sensorInterface, int16_t *rawTemp)
503 {
504 uint8_t tmp[2] = {0};
505
506 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_DATA_T_L_REG, 1, &tmp[0]))
507 {
508 return WE_FAIL;
509 }
510
511 if (WE_FAIL == TIDS_ReadReg(sensorInterface, TIDS_DATA_T_H_REG, 1, &tmp[1]))
512 {
513 return WE_FAIL;
514 }
515
516 *rawTemp = (int16_t)(tmp[1] << 8);
517 *rawTemp |= (int16_t)tmp[0];
518 return WE_SUCCESS;
519 }
520
521 #ifdef WE_USE_FLOAT
522
523 /**
524 * @brief Read the measured temperature value in °C
525 * @param[in] sensorInterface Pointer to sensor interface
526 * @param[out] tempDegC The returned temperature measurement
527 * @retval Error code
528 */
TIDS_getTemperature(WE_sensorInterface_t * sensorInterface,float * tempDegC)529 int8_t TIDS_getTemperature(WE_sensorInterface_t* sensorInterface, float *tempDegC)
530 {
531 int16_t rawTemp = 0;
532 if (WE_FAIL == TIDS_getRawTemperature(sensorInterface, &rawTemp))
533 {
534 return WE_FAIL;
535 }
536
537 *tempDegC = (float) rawTemp;
538 *tempDegC = *tempDegC / 100;
539 return WE_SUCCESS;
540 }
541
542 #endif /* WE_USE_FLOAT */
543