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-HIDS-2525020210002 sensor.
10  */
11 #include <stdio.h>
12 #include <weplatform.h>
13 #include "WSEN_HIDS_2525020210002_hal.h"
14 
15 /**
16  * @brief Default sensor interface configuration.
17  */
18 static const WE_sensorInterface_t hidsDefaultSensorInterface =
19 {
20 	.sensorType = WE_HIDS,
21 	.interfaceType = WE_i2c,
22 	.options = {.i2c = {.address = HIDS_ADDRESS, .burstMode = 1, .protocol = WE_i2cProtocol_Raw, .useRegAddrMsbForMultiBytesRead = 1, .reserved = 0},
23 				.spi = {.chipSelectPort = 0, .chipSelectPin = 0, .burstMode = 0, .reserved = 0},
24 				.readTimeout = 1000,
25 				.writeTimeout = 1000},
26 	.handle = 0
27 };
28 /***** STATUIC variables *****/
29 
30 /**
31  * @brief Read data from sensor.
32  *
33  * @param[in] sensorInterface Pointer to sensor interface
34  * @param[in] numBytesToRead Number of bytes to be read
35  * @param[out] data Target buffer
36  * @return Error Code
37  */
HIDS_ReadData(WE_sensorInterface_t * sensorInterface,uint8_t * data,uint16_t numBytesToRead)38 static inline int8_t HIDS_ReadData(WE_sensorInterface_t* sensorInterface, uint8_t *data, uint16_t numBytesToRead)
39 {
40 	return WE_ReadReg(sensorInterface, 0xFF, numBytesToRead, data);
41 }
42 
43 /**
44  * @brief generate CRC for the data bytes
45  * @param[in] data input
46  * @param[in] count of data bytes
47  * @retval Error code
48  */
HIDS_GenerateCRC(const uint8_t * data,uint16_t count)49 static uint8_t HIDS_GenerateCRC(const uint8_t* data, uint16_t count)
50 {
51 	uint16_t current_byte;
52 	uint8_t crc = CRC8_INIT;
53 	uint8_t crc_bit;
54 
55 	/* calculates 8-Bit checksum with given polynomial */
56 	for (current_byte = 0; current_byte < count; ++current_byte) {
57 		crc ^= (data[current_byte]);
58 		for (crc_bit = 8; crc_bit > 0; --crc_bit)
59 		{
60 			if (crc & 0x80)
61 			{
62 				crc = (crc << 1) ^ CRC8_POLYNOMIAL;
63 			}
64 			else
65 			{
66 				crc = (crc << 1);
67 			}
68 		}
69 	}
70 	return crc;
71 }
72 
73 /**
74  * @brief CRC check
75  * @param[in] data input
76  * @param[in] count of data bytes
77  * @retval Error code
78  */
HIDS_CheckCRC(const uint8_t * data,uint16_t count,uint8_t checksum)79 static int8_t HIDS_CheckCRC(const uint8_t* data, uint16_t count, uint8_t checksum)
80 {
81 	if (HIDS_GenerateCRC(data, count) != checksum)
82 	{
83 		return WE_FAIL;
84 	}
85 	return WE_SUCCESS;
86 }
87 
88 /**
89  * @brief Write data to sensor.
90  *
91  * @param[in] sensorInterface Pointer to sensor interface
92  * @param[in] numBytesToRead Number of bytes to be read
93  * @param[out] data Target buffer
94  * @return Error Code
95  */
HIDS_WriteData(WE_sensorInterface_t * sensorInterface,uint8_t * data,uint16_t numBytesToWrite)96 static inline int8_t HIDS_WriteData(WE_sensorInterface_t* sensorInterface,uint8_t *data, uint16_t numBytesToWrite)
97 {
98 	/* 0xFF can be used here because it will not be used in the WE_WriteReg with WE_i2c_fifo and useRegAddrMsbForMultiBytesRead = 1; */
99 	return WE_WriteReg(sensorInterface, 0xFF, numBytesToWrite, data);
100 }
101 
102 /**
103  * @brief Returns the default sensor interface configuration.
104  * @param[out] sensorInterface Sensor interface configuration (output parameter)
105  * @return Error code
106  */
HIDS_Get_Default_Interface(WE_sensorInterface_t * sensorInterface)107 int8_t HIDS_Get_Default_Interface(WE_sensorInterface_t* sensorInterface)
108 {
109 	*sensorInterface = hidsDefaultSensorInterface;
110 	return WE_SUCCESS;
111 }
112 
113 /**
114  * @brief Set the measurement type of the sensor
115  * @param[in] sensorInterface Pointer to sensor interface
116  * @retval Error code
117  */
HIDS_Set_Measurement_Type(WE_sensorInterface_t * sensorInterface,hids_measureCmd_t meausurementCmd)118 int8_t HIDS_Set_Measurement_Type(WE_sensorInterface_t* sensorInterface, hids_measureCmd_t meausurementCmd)
119 {
120 	int8_t status = WE_FAIL;
121 	uint8_t  temp = meausurementCmd;
122 	status = HIDS_WriteData(sensorInterface, &temp, 1);
123 
124 	/* mandatory wait for measurement to be performed, see user manual of 2525020210002 */
125 	WE_Delay(10);
126 	if (status != WE_SUCCESS)
127 	{
128 		/* error! */
129 		return WE_FAIL;
130 	}
131 
132 	return WE_SUCCESS;
133 }
134 
135 /**
136  * @brief Measure the data in milli values
137  * @param[in] sensorInterface Pointer to sensor interface
138  * @param[out] Temperature value in milli
139  * @param[out] Humidity value in milli
140  * @retval Error code
141  */
HIDS_Sensor_Measure_Raw(WE_sensorInterface_t * sensorInterface,hids_measureCmd_t measureCmd,int32_t * temperatureRaw,int32_t * humidityRaw)142 int8_t HIDS_Sensor_Measure_Raw(WE_sensorInterface_t* sensorInterface, hids_measureCmd_t measureCmd, int32_t* temperatureRaw, int32_t* humidityRaw)
143 {
144 
145 	if(WE_SUCCESS != HIDS_Set_Measurement_Type(sensorInterface, measureCmd))
146 	{
147 		/* error! */
148 		return WE_FAIL;
149 	}
150 
151 	uint8_t dataBytes[6]={0};
152 	int8_t status= WE_FAIL;
153 	uint16_t t_ticks = 0;
154 	uint16_t rh_ticks = 0;
155 
156 	status = HIDS_ReadData(sensorInterface, dataBytes, 6);
157 	if (status != WE_SUCCESS)
158 	{
159 		/* error! */
160 		return WE_FAIL;
161 	}
162 	status = HIDS_CheckCRC(&dataBytes[0], HIDS_WORD_SIZE, dataBytes[2]);
163 	if (status != WE_SUCCESS)
164 	{
165 		/* error! */
166 	    return WE_FAIL;
167 	}
168 	status = HIDS_CheckCRC(&dataBytes[3], HIDS_WORD_SIZE, dataBytes[5]);
169 	if (status != WE_SUCCESS)
170 	{
171 		/* error! */
172 		return WE_FAIL;
173 	}
174 
175 	t_ticks = ((uint16_t)dataBytes[0] << 8 ) | ((uint16_t)dataBytes[1]);
176 	rh_ticks = ((uint16_t)dataBytes[3] << 8 ) | ((uint16_t)dataBytes[4]);
177 
178 	*temperatureRaw = (int32_t)(((21875 * t_ticks) >> 13) - 45000); /* >> 13 == / 8192; temperatureRaw to be divided by 1000 for reaching rh percent */
179 	*humidityRaw = (int32_t)(((15625 * rh_ticks) >> 13) - 6000); /* humidityRaw to be divided by 1000 for reaching rh percent */
180 	return WE_SUCCESS;
181 }
182 
183 /**
184  * @brief read the sensor serial number
185  * @param[in] sensorInterface Pointer to sensor interface
186  * @param[out] Serial number in Pointer to serial number as 32 bit integer
187  * @retval Error code
188  */
HIDS_Sensor_Read_SlNo(WE_sensorInterface_t * sensorInterface,uint32_t * serialNo)189 int8_t HIDS_Sensor_Read_SlNo(WE_sensorInterface_t* sensorInterface, uint32_t* serialNo)
190 {
191 	int8_t status = WE_FAIL;
192 	uint8_t dataBytes[6] = {0};
193 	hids_measureCmd_t  measureCmd = HIDS_MEASURE_SERIAL_NUMBER;
194 	if(WE_FAIL == HIDS_Set_Measurement_Type(sensorInterface, measureCmd))
195 	{
196 		/* error! */
197 		return WE_FAIL;
198 	}
199 	status = HIDS_ReadData(sensorInterface,dataBytes,6);
200 	if (status != WE_SUCCESS)
201 	{
202 		/* error! */
203 		return WE_FAIL;
204 
205 	}
206 	status = HIDS_CheckCRC(&dataBytes[0], HIDS_WORD_SIZE, dataBytes[2]);
207 	if (status != WE_SUCCESS)
208 	{
209 		/* error! */
210 		return WE_FAIL;
211 	}
212 	status = HIDS_CheckCRC(&dataBytes[3], HIDS_WORD_SIZE, dataBytes[5]);
213 	if (status != WE_SUCCESS)
214 	{
215 	    /* error! */
216 		return WE_FAIL;
217 	}
218 	*serialNo = ((uint32_t)dataBytes[0] << 24) | ((uint32_t)dataBytes[1] << 16) | ((uint32_t)dataBytes[3] << 8) | ((uint32_t)dataBytes[4]) ;
219 	return WE_SUCCESS;
220 }
221 
222 /**
223  * @brief initilaize the seonsor
224  * @param[in] sensorInterface Pointer to sensor interface
225  * @retval Error code
226  */
HIDS_Sensor_Init(WE_sensorInterface_t * sensorInterface)227 int8_t HIDS_Sensor_Init(WE_sensorInterface_t* sensorInterface)
228 {
229 	uint32_t serialNo = 0;
230 	if(WE_SUCCESS != HIDS_Reset(sensorInterface))
231 	{
232 		/* error! */
233 		return WE_FAIL;
234 	}
235 	if(WE_SUCCESS != HIDS_Sensor_Read_SlNo(sensorInterface, &serialNo))
236 	{
237 		/* error! */
238 		return WE_FAIL;
239 	}
240 	return (serialNo>0) ?  WE_SUCCESS :  WE_FAIL ;
241 }
242 
243 /**
244  * @brief reset the sensor
245  * @param[in] sensorInterface Pointer to sensor interface
246  */
HIDS_Reset(WE_sensorInterface_t * sensorInterface)247 int8_t HIDS_Reset(WE_sensorInterface_t* sensorInterface)
248 {
249 
250 	int8_t status = WE_FAIL;
251 	uint8_t  temp = HIDS_SOFT_RESET;
252 	status = HIDS_WriteData(sensorInterface, &temp, 1);
253 	if (status != WE_SUCCESS)
254 	{
255 		/* error! */
256 		return WE_FAIL;
257 	}
258 	WE_Delay(10);
259 	return WE_SUCCESS;
260 }
261 
262