loragw_stts751.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. / _____) _ | |
  3. ( (____ _____ ____ _| |_ _____ ____| |__
  4. \____ \| ___ | (_ _) ___ |/ ___) _ \
  5. _____) ) ____| | | || |_| ____( (___| | | |
  6. (______/|_____)_|_|_| \__)_____)\____)_| |_|
  7. (C)2019 Semtech
  8. Description:
  9. Basic driver for ST ts751 temperature sensor
  10. License: Revised BSD License, see LICENSE.TXT file include in the project
  11. */
  12. /* -------------------------------------------------------------------------- */
  13. /* --- DEPENDANCIES --------------------------------------------------------- */
  14. #include <stdint.h> /* C99 types */
  15. #include <stdbool.h> /* bool type */
  16. #include <stdio.h> /* printf fprintf */
  17. #include "loragw_i2c.h"
  18. #include "loragw_stts751.h"
  19. /* -------------------------------------------------------------------------- */
  20. /* --- PRIVATE MACROS ------------------------------------------------------- */
  21. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  22. #if DEBUG_I2C == 1
  23. #define DEBUG_MSG(str) fprintf(stdout, str)
  24. #define DEBUG_PRINTF(fmt, args...) fprintf(stdout,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
  25. #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;}
  26. #else
  27. #define DEBUG_MSG(str)
  28. #define DEBUG_PRINTF(fmt, args...)
  29. #define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;}
  30. #endif
  31. /* -------------------------------------------------------------------------- */
  32. /* --- PRIVATE CONSTANTS ---------------------------------------------------- */
  33. #define STTS751_REG_TEMP_H 0x00
  34. #define STTS751_REG_STATUS 0x01
  35. #define STTS751_STATUS_TRIPT BIT(0)
  36. #define STTS751_STATUS_TRIPL BIT(5)
  37. #define STTS751_STATUS_TRIPH BIT(6)
  38. #define STTS751_REG_TEMP_L 0x02
  39. #define STTS751_REG_CONF 0x03
  40. #define STTS751_CONF_RES_MASK 0x0C
  41. #define STTS751_CONF_RES_SHIFT 2
  42. #define STTS751_CONF_EVENT_DIS BIT(7)
  43. #define STTS751_CONF_STOP BIT(6)
  44. #define STTS751_REG_RATE 0x04
  45. #define STTS751_REG_HLIM_H 0x05
  46. #define STTS751_REG_HLIM_L 0x06
  47. #define STTS751_REG_LLIM_H 0x07
  48. #define STTS751_REG_LLIM_L 0x08
  49. #define STTS751_REG_TLIM 0x20
  50. #define STTS751_REG_HYST 0x21
  51. #define STTS751_REG_SMBUS_TO 0x22
  52. #define STTS751_REG_PROD_ID 0xFD
  53. #define STTS751_REG_MAN_ID 0xFE
  54. #define STTS751_REG_REV_ID 0xFF
  55. #define STTS751_0_PROD_ID 0x00
  56. #define STTS751_1_PROD_ID 0x01
  57. #define ST_MAN_ID 0x53
  58. /* -------------------------------------------------------------------------- */
  59. /* --- PRIVATE VARIABLES ---------------------------------------------------- */
  60. /* -------------------------------------------------------------------------- */
  61. /* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
  62. /* -------------------------------------------------------------------------- */
  63. /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
  64. int stts751_configure(int i2c_fd, uint8_t i2c_addr) {
  65. int err;
  66. uint8_t val;
  67. /* Check Input Params */
  68. if (i2c_fd <= 0) {
  69. printf("ERROR: invalid I2C file descriptor\n");
  70. return LGW_I2C_ERROR;
  71. }
  72. DEBUG_PRINTF("INFO: configuring STTS751 temperature sensor on 0x%02X...\n", i2c_addr);
  73. /* Get product ID and test which sensor is mounted */
  74. err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_PROD_ID, &val);
  75. if (err != 0) {
  76. DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
  77. return LGW_I2C_ERROR;
  78. }
  79. switch (val) {
  80. case STTS751_0_PROD_ID:
  81. DEBUG_MSG("INFO: Product ID: STTS751-0\n");
  82. break;
  83. case STTS751_1_PROD_ID:
  84. DEBUG_MSG("INFO: Product ID: STTS751-1\n");
  85. break;
  86. default:
  87. printf("ERROR: Product ID: UNKNOWN\n");
  88. return LGW_I2C_ERROR;
  89. }
  90. /* Get Manufacturer ID */
  91. err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_MAN_ID, &val);
  92. if (err != 0) {
  93. DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
  94. return LGW_I2C_ERROR;
  95. }
  96. if (val != ST_MAN_ID) {
  97. printf("ERROR: Manufacturer ID: UNKNOWN\n");
  98. return LGW_I2C_ERROR;
  99. } else {
  100. DEBUG_PRINTF("INFO: Manufacturer ID: 0x%02X\n", val);
  101. }
  102. /* Get revision number */
  103. err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_REV_ID, &val);
  104. if (err != 0) {
  105. DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
  106. return LGW_I2C_ERROR;
  107. }
  108. DEBUG_PRINTF("INFO: Revision number: 0x%02X\n", val);
  109. /* Set conversion resolution to 12 bits */
  110. err = i2c_linuxdev_write(i2c_fd, i2c_addr, STTS751_REG_CONF, 0x8C); /* TODO: do not hardcode the whole byte */
  111. if (err != 0) {
  112. DEBUG_PRINTF("ERROR: failed to write I2C device 0x%02X (err=%i)\n", i2c_addr, err);
  113. return LGW_I2C_ERROR;
  114. }
  115. /* Set conversion rate to 1 / second */
  116. err = i2c_linuxdev_write(i2c_fd, i2c_addr, STTS751_REG_RATE, 0x04);
  117. if (err != 0) {
  118. DEBUG_PRINTF("ERROR: failed to write I2C device 0x%02X (err=%i)\n", i2c_addr, err);
  119. return LGW_I2C_ERROR;
  120. }
  121. return LGW_I2C_SUCCESS;
  122. }
  123. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  124. int stts751_get_temperature(int i2c_fd, uint8_t i2c_addr, float * temperature) {
  125. int err;
  126. uint8_t high_byte, low_byte;
  127. int8_t h;
  128. /* Check Input Params */
  129. if (i2c_fd <= 0) {
  130. printf("ERROR: invalid I2C file descriptor\n");
  131. return LGW_I2C_ERROR;
  132. }
  133. /* Read Temperature LSB */
  134. err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_TEMP_L, &low_byte);
  135. if (err != 0) {
  136. printf("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
  137. return LGW_I2C_ERROR;
  138. }
  139. /* Read Temperature MSB */
  140. err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_TEMP_H, &high_byte);
  141. if (err != 0) {
  142. printf("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
  143. return LGW_I2C_ERROR;
  144. }
  145. h = (int8_t)high_byte;
  146. *temperature = ((h << 8) | low_byte) / 256.0;
  147. DEBUG_PRINTF("Temperature: %f C (h:0x%02X l:0x%02X)\n", *temperature, high_byte, low_byte);
  148. return LGW_I2C_SUCCESS;
  149. }
  150. /* --- EOF ------------------------------------------------------------------ */