EFM32 Gecko Software Documentation  efm32g-doc-5.1.2
si7013.c
Go to the documentation of this file.
1 /***************************************************************************/
16 #include <stddef.h>
17 #include "si7013.h"
18 #include "i2cspm.h"
19 
20 #include "stddef.h"
21 
22 /*******************************************************************************
23  ******************************* DEFINES ***********************************
24  ******************************************************************************/
25 
29 #define SI7013_READ_TEMP 0xE0 /* Read previous T data from RH measurement
30  * command*/
31 
32 #define SI7013_READ_RH 0xE5 /* Perform RH (and T) measurement. */
33 
34 #define SI7013_READ_RH_NH 0xF5 /* Perform RH (and T) measurement in no hold mode. */
35 
36 #define SI7013_READ_VIN 0xEE /* Perform thermistor measurement. */
37 
38 #define SI7013_READ_ID1_1 0xFA
39 #define SI7013_READ_ID1_2 0x0F
40 #define SI7013_READ_ID2_1 0xFc
41 #define SI7013_READ_ID2_2 0xc9
42 
43 #define SI7013_READ_FWREV_1 0x84
44 #define SI7013_READ_FWREV_2 0xB8
45 
48 /*******************************************************************************
49  ************************** GLOBAL FUNCTIONS *******************************
50  ******************************************************************************/
51 
52 
54 /**************************************************************************/
69 static int32_t Si7013_Measure(I2C_TypeDef *i2c, uint8_t addr, uint32_t *data,
70  uint8_t command)
71 {
74  uint8_t i2c_read_data[2];
75  uint8_t i2c_write_data[1];
76 
77  seq.addr = addr;
79  /* Select command to issue */
80  i2c_write_data[0] = command;
81  seq.buf[0].data = i2c_write_data;
82  seq.buf[0].len = 1;
83  /* Select location/length of data to be read */
84  seq.buf[1].data = i2c_read_data;
85  seq.buf[1].len = 2;
86 
87  ret = I2CSPM_Transfer(i2c, &seq);
88 
89  if (ret != i2cTransferDone)
90  {
91  *data = 0;
92  return((int) ret);
93  }
94 
95  *data = ((uint32_t) i2c_read_data[0] << 8) + (i2c_read_data[1] & 0xfc);
96 
97  return((int) 2);
98 }
102 /**************************************************************************/
115 static int32_t Si7013_StartNoHoldMeasure(I2C_TypeDef *i2c, uint8_t addr, uint8_t command)
116 
117 {
120  uint8_t i2c_read_data[2];
121  uint8_t i2c_write_data[1];
122 
123  seq.addr = addr;
124  seq.flags = I2C_FLAG_WRITE;
125  /* Select command to issue */
126  i2c_write_data[0] = command;
127  seq.buf[0].data = i2c_write_data;
128  seq.buf[0].len = 1;
129  /* Select location/length of data to be read */
130  seq.buf[1].data = i2c_read_data;
131  seq.buf[1].len = 0;
132 
133  ret = I2CSPM_Transfer(i2c, &seq);
134 
135  if (ret != i2cTransferDone)
136  {
137  return((int) ret);
138  }
139 
140  return((int) 0);
141 }
145 /**************************************************************************/
157 int32_t Si7013_GetFirmwareRevision(I2C_TypeDef *i2c, uint8_t addr, uint8_t *fwRev)
158 {
161  uint8_t i2c_write_data[2];
162  uint8_t i2c_read_data[1];
163 
164  seq.addr = addr;
166  /* Select command to issue */
167  i2c_write_data[0] = SI7013_READ_FWREV_1;
168  i2c_write_data[1] = SI7013_READ_FWREV_2;
169  seq.buf[0].data = i2c_write_data;
170  seq.buf[0].len = 2;
171  /* Select location/length of data to be read */
172  seq.buf[1].data = i2c_read_data;
173  seq.buf[1].len = 1;
174 
175  ret = I2CSPM_Transfer(i2c, &seq);
176 
177  if (ret != i2cTransferDone)
178  {
179  *fwRev = 0;
180  return (uint32_t) ret;
181  }
182  *fwRev = i2c_read_data[0];
183 
184  return (uint32_t) i2cTransferDone;
185 }
186 
187 /**************************************************************************/
198 {
199  int ret = Si7013_StartNoHoldMeasure(i2c, addr, SI7013_READ_RH_NH);
200 
201  return ret;
202 }
203 
205 /**************************************************************************/
218 static int32_t Si7013_ReadNoHoldData(I2C_TypeDef *i2c, uint8_t addr, uint32_t *data)
219 {
222  uint8_t i2c_read_data[2];
223 
224  seq.addr = addr;
225  seq.flags = I2C_FLAG_READ;
226  /* Select command to issue */
227  seq.buf[0].data = i2c_read_data;
228  seq.buf[0].len = 2;
229  /* Select location/length of data to be read */
230  seq.buf[1].data = i2c_read_data;
231  seq.buf[1].len = 2;
232 
233  ret = I2CSPM_Transfer(i2c, &seq);
234 
235  if (ret != i2cTransferDone)
236  {
237  *data = 0;
238  return((int) ret);
239  }
240 
241  *data = ((uint32_t) i2c_read_data[0] << 8) + (i2c_read_data[1] & 0xfc);
242 
243  return((int) 2);
244 }
247 /**************************************************************************/
261 int32_t Si7013_ReadNoHoldRHAndTemp(I2C_TypeDef *i2c, uint8_t addr, uint32_t *rhData,
262  int32_t *tData)
263 {
264  int ret = Si7013_ReadNoHoldData(i2c, addr, rhData);
265 
266  if (ret == 2)
267  {
268  /* convert to milli-percent */
269  *rhData = (((*rhData) * 15625L) >> 13) - 6000;
270  }
271  else
272  {
273  return -1;
274  }
275 
276  ret = Si7013_Measure(i2c, addr, (uint32_t *) tData, SI7013_READ_TEMP);
277 
278  if (ret == 2)
279  {
280  *tData = (((*tData) * 21965L) >> 13) - 46850; /* convert to milli-degC */
281  }
282  else
283  {
284  return -1;
285  }
286 
287  return 0;
288 }
289 
290 /**************************************************************************/
304 int32_t Si7013_MeasureRHAndTemp(I2C_TypeDef *i2c, uint8_t addr, uint32_t *rhData,
305  int32_t *tData)
306 {
307  int ret = Si7013_Measure(i2c, addr, rhData, SI7013_READ_RH);
308 
309  if (ret == 2)
310  {
311  /* convert to milli-percent */
312  *rhData = (((*rhData) * 15625L) >> 13) - 6000;
313  }
314  else
315  {
316  return -1;
317  }
318 
319  ret = Si7013_Measure(i2c, addr, (uint32_t *) tData, SI7013_READ_TEMP);
320 
321  if (ret == 2)
322  {
323  *tData = (((*tData) * 21965L) >> 13) - 46850; /* convert to milli-degC */
324  }
325  else
326  {
327  return -1;
328  }
329 
330  return 0;
331 }
332 
334 static int32_t Si7013_WriteUserReg2(I2C_TypeDef *i2c, uint8_t addr, int8_t data)
335 {
338  uint8_t i2c_read_data[2];
339  uint8_t i2c_write_data[2];
340 
341  seq.addr = addr;
342  seq.flags = I2C_FLAG_WRITE;
343  /* Select command to issue */
344  i2c_write_data[0] = 0x50;
345  i2c_write_data[1] = data;
346  seq.buf[0].data = i2c_write_data;
347  seq.buf[0].len = 2;
348  /* Select location/length of data to be read */
349  seq.buf[1].data = i2c_read_data;
350  seq.buf[1].len = 0;
351 
352  ret = I2CSPM_Transfer(i2c, &seq);
353 
354  if (ret != i2cTransferDone)
355  {
356  return((int) ret);
357  }
358 
359  return((int) 0);
360 }
364 /**************************************************************************/
376 int32_t Si7013_MeasureV(I2C_TypeDef *i2c, uint8_t addr, int32_t *vData)
377 {
378  int ret;
379  Si7013_WriteUserReg2(i2c, addr, 0x0e);
380  ret = Si7013_Measure(i2c, addr, (uint32_t *) vData, SI7013_READ_VIN);
381  Si7013_WriteUserReg2(i2c, addr, 0x09);
382  if (ret == 2)
383  {
384  /* convert */
385  }
386  else
387  {
388  return -1;
389  }
390  return 0;
391 }
392 
393 
394 /**************************************************************************/
407 bool Si7013_Detect(I2C_TypeDef *i2c, uint8_t addr, uint8_t *deviceId)
408 {
411  uint8_t i2c_read_data[8];
412  uint8_t i2c_write_data[2];
413 
414  seq.addr = addr;
416  /* Select command to issue */
417  i2c_write_data[0] = SI7013_READ_ID2_1;
418  i2c_write_data[1] = SI7013_READ_ID2_2;
419  seq.buf[0].data = i2c_write_data;
420  seq.buf[0].len = 2;
421  /* Select location/length of data to be read */
422  seq.buf[1].data = i2c_read_data;
423  seq.buf[1].len = 8;
424 
425  ret = I2CSPM_Transfer(i2c, &seq);
426  if (ret != i2cTransferDone)
427  {
428  return false;
429  }
430  if (NULL != deviceId)
431  {
432  *deviceId = i2c_read_data[0];
433  }
434  return true;
435 }
Driver for the Si7013 Temperature / Humidity sensor.
I2C_TransferReturn_TypeDef I2CSPM_Transfer(I2C_TypeDef *i2c, I2C_TransferSeq_TypeDef *seq)
Perform I2C transfer.
Definition: i2cspm.c:124
int32_t Si7013_MeasureV(I2C_TypeDef *i2c, uint8_t addr, int32_t *vData)
Reads relative humidity and temperature from a Si7013 sensor.
Definition: si7013.c:376
#define I2C_FLAG_READ
Indicate plain read sequence: S+ADDR(R)+DATA0+P.
Definition: em_i2c.h:135
bool Si7013_Detect(I2C_TypeDef *i2c, uint8_t addr, uint8_t *deviceId)
Checks if a Si7013 is present on the I2C bus or not.
Definition: si7013.c:407
#define I2C_FLAG_WRITE
Indicate plain write sequence: S+ADDR(W)+DATA0+P.
Definition: em_i2c.h:124
I2C_TransferReturn_TypeDef
Definition: em_i2c.h:179
int32_t Si7013_ReadNoHoldRHAndTemp(I2C_TypeDef *i2c, uint8_t addr, uint32_t *rhData, int32_t *tData)
Reads relative humidity and temperature from a Si7013 sensor.
Definition: si7013.c:261
int32_t Si7013_StartNoHoldMeasureRHAndTemp(I2C_TypeDef *i2c, uint8_t addr)
Starts no hold measurement of relative humidity and temperature from a Si7013 sensor.
Definition: si7013.c:197
int32_t Si7013_GetFirmwareRevision(I2C_TypeDef *i2c, uint8_t addr, uint8_t *fwRev)
Reads Firmware Revision from a Si7013 sensor.
Definition: si7013.c:157
I2C simple poll-based master mode driver for the DK/STK.
struct I2C_TransferSeq_TypeDef::@0 buf[2]
Master mode transfer message structure used to define a complete I2C transfer sequence (from start to...
Definition: em_i2c.h:252
#define I2C_FLAG_WRITE_READ
Indicate combined write/read sequence: S+ADDR(W)+DATA0+Sr+ADDR(R)+DATA1+P.
Definition: em_i2c.h:148
int32_t Si7013_MeasureRHAndTemp(I2C_TypeDef *i2c, uint8_t addr, uint32_t *rhData, int32_t *tData)
Reads relative humidity and temperature from a Si7013 sensor.
Definition: si7013.c:304
uint16_t addr
Address to use after (repeated) start.
Definition: em_i2c.h:262