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