sensor_nct7717u.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2022-9-1 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #include <rtthread.h>
  13. #include <sys/time.h>
  14. #include "sensor_nct7717u.h"
  15. #define DBG_ENABLE
  16. #define DBG_LEVEL DBG_LOG
  17. #define DBG_SECTION_NAME "sensor.nct7717u"
  18. #define DBG_COLOR
  19. #include <rtdbg.h>
  20. #define NCT7717U_I2C_SLAVE_ADDR 0x48
  21. #define REG_NCT7717U_LDT 0x0
  22. #define REG_NCT7717U_ALERT_STATUS 0x2
  23. #define REG_NCT7717U_CONFIGURATION_R 0x3
  24. #define REG_NCT7717U_CONVERSION_RATE_R 0x4
  25. #define REG_NCT7717U_LH_HAT_R 0x5
  26. #define REG_NCT7717U_CONFIGURATION_W 0x9
  27. #define REG_NCT7717U_CONVERSION_RATE_W 0xA
  28. #define REG_NCT7717U_LH_HAT_W 0xB
  29. #define REG_NCT7717U_ONESHOT_CONVERSION 0xF
  30. #define REG_NCT7717U_CUSTOMER_LOG_1 0x2D
  31. #define REG_NCT7717U_CUSTOMER_LOG_2 0x2E
  32. #define REG_NCT7717U_CUSTOMER_LOG_3 0x2F
  33. #define REG_NCT7717U_ALERT_MODE 0xBF
  34. #define REG_NCT7717U_CID 0xFD
  35. #define REG_NCT7717U_VID 0xFE
  36. #define REG_NCT7717U_DID 0xFF
  37. static rt_err_t nct7717u_i2c_read_reg(struct rt_i2c_bus_device *i2c_bus_dev, const char *reg, int reg_length, char *data, int length)
  38. {
  39. struct rt_i2c_msg msgs[2];
  40. msgs[0].addr = NCT7717U_I2C_SLAVE_ADDR; /* Slave address */
  41. msgs[0].flags = RT_I2C_WR; /* Write flag */
  42. msgs[0].buf = (rt_uint8_t *)reg; /* Slave register address */
  43. msgs[0].len = reg_length; /* Number of bytes sent */
  44. msgs[1].addr = NCT7717U_I2C_SLAVE_ADDR; /* Slave address */
  45. msgs[1].flags = RT_I2C_RD; /* Read flag without READ_ACK */
  46. msgs[1].buf = (rt_uint8_t *)data; /* Read data pointer */
  47. msgs[1].len = length; /* Number of bytes read */
  48. if (rt_i2c_transfer(i2c_bus_dev, &msgs[0], 2) != 2)
  49. {
  50. return -RT_ERROR;
  51. }
  52. return RT_EOK;
  53. }
  54. static rt_err_t nct7717u_read_cid(struct rt_i2c_bus_device *i2c_bus_dev, uint8_t *u8Temp)
  55. {
  56. uint8_t u8Reg = REG_NCT7717U_CID;
  57. return nct7717u_i2c_read_reg(i2c_bus_dev, (const char *)&u8Reg, sizeof(u8Reg), (char *)u8Temp, sizeof(uint8_t));
  58. }
  59. static rt_err_t nct7717u_read_vid(struct rt_i2c_bus_device *i2c_bus_dev, uint8_t *u8Temp)
  60. {
  61. uint8_t u8Reg = REG_NCT7717U_VID;
  62. return nct7717u_i2c_read_reg(i2c_bus_dev, (const char *)&u8Reg, sizeof(u8Reg), (char *)u8Temp, sizeof(uint8_t));
  63. }
  64. static rt_err_t nct7717u_read_did(struct rt_i2c_bus_device *i2c_bus_dev, uint8_t *u8Temp)
  65. {
  66. uint8_t u8Reg = REG_NCT7717U_DID;
  67. return nct7717u_i2c_read_reg(i2c_bus_dev, (const char *)&u8Reg, sizeof(u8Reg), (char *)u8Temp, sizeof(uint8_t));
  68. }
  69. static rt_err_t nct7717u_probe(struct rt_i2c_bus_device *i2c_bus_dev)
  70. {
  71. uint8_t u8Cid, u8Vid, u8Did;
  72. if (nct7717u_read_cid(i2c_bus_dev, &u8Cid) != RT_EOK)
  73. goto exit_nct7717u_probe;
  74. if (nct7717u_read_vid(i2c_bus_dev, &u8Vid) != RT_EOK)
  75. goto exit_nct7717u_probe;
  76. if (nct7717u_read_did(i2c_bus_dev, &u8Did) != RT_EOK)
  77. goto exit_nct7717u_probe;
  78. LOG_I("CID=%02x VID=%02x DID=%02x", u8Cid, u8Vid, u8Did);
  79. if ((u8Cid != 0x50) || (u8Vid != 0x50) || ((u8Did & 0x90) != 0x90))
  80. {
  81. LOG_E("Failed to detect NCT7717U");
  82. goto exit_nct7717u_probe;
  83. }
  84. return RT_EOK;
  85. exit_nct7717u_probe:
  86. return -RT_ERROR;
  87. }
  88. static rt_err_t nct7717u_ldt_readout(struct rt_i2c_bus_device *i2c_bus_dev, uint8_t *u8Temp)
  89. {
  90. uint8_t u8Reg = REG_NCT7717U_LDT;
  91. return nct7717u_i2c_read_reg(i2c_bus_dev, (const char *)&u8Reg, sizeof(u8Reg), (char *)u8Temp, sizeof(uint8_t));
  92. }
  93. static rt_ssize_t nct7717u_fetch_data(rt_sensor_t sensor, rt_sensor_data_t data, rt_size_t len)
  94. {
  95. RT_ASSERT(data);
  96. if (sensor->info.type == RT_SENSOR_TYPE_TEMP)
  97. {
  98. rt_int8_t i8Temp;
  99. struct rt_i2c_bus_device *i2c_bus_dev = sensor->config.intf.arg;
  100. if (nct7717u_ldt_readout(i2c_bus_dev, (uint8_t *)&i8Temp) == RT_EOK)
  101. {
  102. rt_int32_t i32TempValue = i8Temp;
  103. data->type = RT_SENSOR_TYPE_TEMP;
  104. data->data.temp = i32TempValue * 10;
  105. data->timestamp = rt_sensor_get_ts();
  106. return 1;
  107. }
  108. }
  109. return 0;
  110. }
  111. static rt_err_t nct7717u_control(struct rt_sensor_device *sensor, int cmd, void *args)
  112. {
  113. switch (cmd)
  114. {
  115. case RT_SENSOR_CTRL_GET_ID:
  116. {
  117. struct rt_i2c_bus_device *i2c_bus_dev = sensor->config.intf.arg;
  118. uint8_t u8Did;
  119. RT_ASSERT(args);
  120. nct7717u_read_did(i2c_bus_dev, &u8Did);
  121. *((uint8_t *)args) = u8Did;
  122. }
  123. break;
  124. default:
  125. return -RT_ERROR;
  126. }
  127. return RT_EOK;
  128. }
  129. static struct rt_sensor_ops sensor_ops =
  130. {
  131. nct7717u_fetch_data,
  132. nct7717u_control
  133. };
  134. int rt_hw_nct7717u_temp_init(const char *name, struct rt_sensor_config *cfg)
  135. {
  136. rt_int8_t result;
  137. rt_sensor_t sensor = RT_NULL;
  138. sensor = rt_calloc(1, sizeof(struct rt_sensor_device));
  139. if (sensor == RT_NULL)
  140. return -(RT_ENOMEM);
  141. sensor->info.type = RT_SENSOR_TYPE_TEMP;
  142. sensor->info.vendor = RT_SENSOR_VENDOR_UNKNOWN;
  143. sensor->info.name = "nct7717u_temp";
  144. sensor->info.unit = RT_SENSOR_UNIT_CELSIUS;
  145. sensor->info.intf_type = RT_SENSOR_INTF_I2C;
  146. sensor->info.scale.range_max = 127;
  147. sensor->info.scale.range_min = -128;
  148. sensor->info.acquire_min = 100; //100ms
  149. rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config));
  150. sensor->ops = &sensor_ops;
  151. result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDWR, RT_NULL);
  152. if (result != RT_EOK)
  153. {
  154. LOG_E("device register: %d", result);
  155. rt_free(sensor);
  156. return -RT_ERROR;
  157. }
  158. return RT_EOK;
  159. }
  160. int rt_hw_nct7717u_init(const char *name, struct rt_sensor_config *cfg)
  161. {
  162. struct rt_sensor_intf *intf;
  163. struct rt_i2c_bus_device *i2c_bus_dev;
  164. RT_ASSERT(name != NULL);
  165. RT_ASSERT(cfg != NULL);
  166. intf = &cfg->intf;
  167. /* Find I2C bus */
  168. i2c_bus_dev = (struct rt_i2c_bus_device *)rt_device_find(intf->dev_name);
  169. if (i2c_bus_dev == RT_NULL)
  170. {
  171. goto exit_rt_hw_nct7717u_init;
  172. }
  173. intf->arg = i2c_bus_dev;
  174. if (nct7717u_probe(i2c_bus_dev) != RT_EOK)
  175. goto exit_rt_hw_nct7717u_init;
  176. return rt_hw_nct7717u_temp_init(name, cfg);
  177. exit_rt_hw_nct7717u_init:
  178. return -(RT_ERROR);
  179. }