sensor_st_sths34pf80.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-01-29 Rick the first version
  9. */
  10. #include "sensor_st_sths34pf80.h"
  11. #define DBG_TAG "sensor.st.sths34pf80"
  12. #define DBG_LVL DBG_LOG
  13. static STHS34PF80_Object_t sths34pf80;
  14. static struct rt_i2c_bus_device *i2c_bus_dev;
  15. static int32_t i2c_init(void)
  16. {
  17. return 0;
  18. }
  19. static int32_t sths34pf80_get_tick(void)
  20. {
  21. return rt_tick_get();
  22. }
  23. static int rt_i2c_write_reg(uint16_t addr, uint16_t reg, uint8_t *data, uint16_t len)
  24. {
  25. rt_uint8_t tmp = reg;
  26. struct rt_i2c_msg msgs[2];
  27. msgs[0].addr = addr; /* Slave address */
  28. msgs[0].flags = RT_I2C_WR; /* Write flag */
  29. msgs[0].buf = &tmp; /* Slave register address */
  30. msgs[0].len = 1; /* Number of bytes sent */
  31. msgs[1].addr = addr; /* Slave address */
  32. msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START; /* Read flag */
  33. msgs[1].buf = data; /* Read data pointer */
  34. msgs[1].len = len; /* Number of bytes read */
  35. if (rt_i2c_transfer(i2c_bus_dev, msgs, 2) != 2)
  36. {
  37. return -RT_ERROR;
  38. }
  39. return RT_EOK;
  40. }
  41. static int rt_i2c_read_reg(uint16_t addr, uint16_t reg, uint8_t *data, uint16_t len)
  42. {
  43. rt_uint8_t tmp = reg;
  44. struct rt_i2c_msg msgs[2];
  45. msgs[0].addr = addr; /* Slave address */
  46. msgs[0].flags = RT_I2C_WR; /* Write flag */
  47. msgs[0].buf = &tmp; /* Slave register address */
  48. msgs[0].len = 1; /* Number of bytes sent */
  49. msgs[1].addr = addr; /* Slave address */
  50. msgs[1].flags = RT_I2C_RD; /* Read flag */
  51. msgs[1].buf = data; /* Read data pointer */
  52. msgs[1].len = len; /* Number of bytes read */
  53. if (rt_i2c_transfer(i2c_bus_dev, msgs, 2) != 2)
  54. {
  55. return -RT_ERROR;
  56. }
  57. return RT_EOK;
  58. }
  59. static rt_err_t _sths34pf80_init(struct rt_sensor_intf *intf)
  60. {
  61. STHS34PF80_IO_t io_ctx;
  62. rt_uint8_t id;
  63. i2c_bus_dev = (struct rt_i2c_bus_device *)rt_device_find(intf->dev_name);
  64. if (i2c_bus_dev == RT_NULL)
  65. {
  66. return -RT_ERROR;
  67. }
  68. /* Configure the baroelero driver */
  69. io_ctx.BusType = STHS34PF80_I2C_BUS; /* I2C */
  70. io_ctx.Address = (rt_uint32_t)(intf->user_data) & 0xff;
  71. io_ctx.Init = i2c_init;
  72. io_ctx.DeInit = i2c_init;
  73. io_ctx.ReadReg = rt_i2c_read_reg;
  74. io_ctx.WriteReg = rt_i2c_write_reg;
  75. io_ctx.GetTick = sths34pf80_get_tick;
  76. sths34pf80.Config.LPF_Motion = 0x04;
  77. sths34pf80.Config.LPF_Presence = 0x04;
  78. sths34pf80.Config.LPF_Temperature = 0x02;
  79. sths34pf80.Config.AVG_TMOS = 0x02;
  80. sths34pf80.Config.ODR = 0x07;
  81. sths34pf80.Config.THS_Presence = 5000;
  82. sths34pf80.Config.THS_Motion = 2300;
  83. sths34pf80.Config.THS_Temp_Shock = 2000;
  84. if (STHS34PF80_RegisterBusIO(&sths34pf80, &io_ctx) != STHS34PF80_OK)
  85. {
  86. return -RT_ERROR;
  87. }
  88. else if (STHS34PF80_ReadID(&sths34pf80, &id) != STHS34PF80_OK)
  89. {
  90. rt_kprintf("read id failed\n");
  91. return -RT_ERROR;
  92. }
  93. if (STHS34PF80_Init(&sths34pf80) != STHS34PF80_OK)
  94. {
  95. rt_kprintf("sths34pf80 init failed\n");
  96. return -RT_ERROR;
  97. }
  98. return RT_EOK;
  99. }
  100. static rt_err_t _sths34pf80_set_odr(rt_sensor_t sensor, rt_uint16_t odr)
  101. {
  102. sths34pf80_ctrl1_odr_set(&sths34pf80.Ctx, odr);
  103. return RT_EOK;
  104. }
  105. static RT_SIZE_TYPE _sths34pf80_polling_get_data(rt_sensor_t sensor, struct rt_sensor_data *data)
  106. {
  107. uint16_t val;
  108. switch(sensor->info.type)
  109. {
  110. case RT_SENSOR_CLASS_PROXIMITY:
  111. STHS34PF80_ReadPresence(&sths34pf80, &val);
  112. data->type = RT_SENSOR_CLASS_PROXIMITY;
  113. data->data.proximity = val;
  114. data->timestamp = rt_sensor_get_ts();
  115. break;
  116. case RT_SENSOR_CLASS_TEMP:
  117. STHS34PF80_ReadTemperature(&sths34pf80, &val);
  118. data->type = RT_SENSOR_CLASS_TEMP;
  119. data->data.temp = (int)(val*0.1);
  120. data->timestamp = rt_sensor_get_ts();
  121. break;
  122. case RT_SENSOR_CLASS_FORCE:
  123. STHS34PF80_ReadMotion(&sths34pf80, &val);
  124. data->type = RT_SENSOR_CLASS_FORCE;
  125. data->data.proximity = val;
  126. data->timestamp = rt_sensor_get_ts();
  127. break;
  128. default:
  129. break;
  130. }
  131. return 1;
  132. }
  133. static rt_err_t _sths34pf80_set_mode(rt_sensor_t sensor, rt_uint8_t mode)
  134. {
  135. switch(sensor->info.type)
  136. {
  137. case RT_SENSOR_CLASS_PROXIMITY:
  138. if(mode == RT_SENSOR_MODE_INT)
  139. {
  140. STHS34PF80_ControlINT(&sths34pf80,2,1);
  141. }
  142. break;
  143. case RT_SENSOR_CLASS_TEMP:
  144. if(mode == RT_SENSOR_MODE_INT)
  145. {
  146. STHS34PF80_ControlINT(&sths34pf80,0,1);
  147. }
  148. break;
  149. case RT_SENSOR_CLASS_FORCE:
  150. if(mode == RT_SENSOR_MODE_INT)
  151. {
  152. STHS34PF80_ControlINT(&sths34pf80,1,1);
  153. }
  154. break;
  155. default:
  156. break;
  157. }
  158. return RT_EOK;
  159. }
  160. static RT_SIZE_TYPE sths34pf80_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len)
  161. {
  162. if (sensor->config.mode == RT_SENSOR_MODE_POLLING)
  163. {
  164. return _sths34pf80_polling_get_data(sensor, buf);
  165. }
  166. else if (sensor->config.mode == RT_SENSOR_MODE_INT)
  167. {
  168. return _sths34pf80_polling_get_data(sensor, buf);
  169. }
  170. else
  171. {
  172. return 0;
  173. }
  174. }
  175. static rt_err_t sths34pf80_control(struct rt_sensor_device *sensor, int cmd, void *args)
  176. {
  177. rt_err_t result = RT_EOK;
  178. switch (cmd)
  179. {
  180. case RT_SENSOR_CTRL_GET_ID:
  181. STHS34PF80_ReadID(&sths34pf80, args);
  182. break;
  183. case RT_SENSOR_CTRL_SET_RANGE:
  184. result = -RT_ERROR;
  185. break;
  186. case RT_SENSOR_CTRL_SET_ODR:
  187. result = _sths34pf80_set_odr(sensor, (rt_uint32_t)args & 0xffff);
  188. break;
  189. case RT_SENSOR_CTRL_SET_MODE:
  190. result = _sths34pf80_set_mode(sensor, (rt_uint32_t)args & 0xff);
  191. break;
  192. case RT_SENSOR_CTRL_SET_POWER:
  193. result = -RT_ERROR;
  194. break;
  195. case RT_SENSOR_CTRL_SELF_TEST:
  196. result = -RT_ERROR;
  197. break;
  198. default:
  199. return -RT_ERROR;
  200. }
  201. return result;
  202. }
  203. static struct rt_sensor_ops sensor_ops =
  204. {
  205. sths34pf80_fetch_data,
  206. sths34pf80_control
  207. };
  208. int rt_hw_sths34pf80_init(const char *name, struct rt_sensor_config *cfg)
  209. {
  210. rt_int8_t result;
  211. rt_sensor_t sensor_presence = RT_NULL, sensor_temp = RT_NULL,sensor_motion = RT_NULL;
  212. struct rt_sensor_module *module = RT_NULL;
  213. module = rt_calloc(1, sizeof(struct rt_sensor_module));
  214. if (module == RT_NULL)
  215. {
  216. return -1;
  217. }
  218. {
  219. sensor_presence = rt_calloc(1, sizeof(struct rt_sensor_device));
  220. if (sensor_presence == RT_NULL)
  221. goto __exit;
  222. sensor_presence->info.type = RT_SENSOR_CLASS_PROXIMITY;
  223. sensor_presence->info.vendor = RT_SENSOR_VENDOR_STM;
  224. sensor_presence->info.model = "sths34pf80_presence";
  225. sensor_presence->info.unit = RT_SENSOR_UNIT_CM;
  226. sensor_presence->info.intf_type = RT_SENSOR_INTF_I2C;
  227. rt_memcpy(&sensor_presence->config, cfg, sizeof(struct rt_sensor_config));
  228. sensor_presence->ops = &sensor_ops;
  229. sensor_presence->module = module;
  230. result = rt_hw_sensor_register(sensor_presence, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, RT_NULL);
  231. if (result != RT_EOK)
  232. {
  233. LOG_E("device register err code: %d", result);
  234. goto __exit;
  235. }
  236. }
  237. {
  238. sensor_temp = rt_calloc(1, sizeof(struct rt_sensor_device));
  239. if (sensor_temp == RT_NULL)
  240. return -1;
  241. sensor_temp->info.type = RT_SENSOR_CLASS_TEMP;
  242. sensor_temp->info.vendor = RT_SENSOR_VENDOR_STM;
  243. sensor_temp->info.model = "sths34pf80_temp";
  244. sensor_temp->info.unit = RT_SENSOR_UNIT_DCELSIUS;
  245. sensor_temp->info.intf_type = RT_SENSOR_INTF_I2C;
  246. rt_memcpy(&sensor_temp->config, cfg, sizeof(struct rt_sensor_config));
  247. sensor_temp->ops = &sensor_ops;
  248. sensor_temp->module = module;
  249. result = rt_hw_sensor_register(sensor_temp, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, RT_NULL);
  250. if (result != RT_EOK)
  251. {
  252. LOG_E("device register err code: %d", result);
  253. goto __exit;
  254. }
  255. }
  256. {
  257. sensor_motion = rt_calloc(1, sizeof(struct rt_sensor_device));
  258. if (sensor_motion == RT_NULL)
  259. return -1;
  260. sensor_motion->info.type = RT_SENSOR_CLASS_FORCE;
  261. sensor_motion->info.vendor = RT_SENSOR_VENDOR_STM;
  262. sensor_motion->info.model = "sths34pf80_motion";
  263. sensor_motion->info.unit = RT_SENSOR_UNIT_MN;
  264. sensor_motion->info.intf_type = RT_SENSOR_INTF_I2C;
  265. rt_memcpy(&sensor_motion->config, cfg, sizeof(struct rt_sensor_config));
  266. sensor_motion->ops = &sensor_ops;
  267. sensor_motion->module = module;
  268. result = rt_hw_sensor_register(sensor_motion, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,RT_NULL);
  269. if (result != RT_EOK)
  270. {
  271. LOG_E("device register err code: %d", result);
  272. goto __exit;
  273. }
  274. }
  275. module->sen[0] = sensor_presence;
  276. module->sen[1] = sensor_temp;
  277. module->sen[2] = sensor_motion;
  278. module->sen_num = 3;
  279. if(_sths34pf80_init(&cfg->intf) != RT_EOK)
  280. {
  281. LOG_E("sensor init failed");
  282. goto __exit;
  283. }
  284. LOG_I("sensor init success");
  285. return RT_EOK;
  286. __exit:
  287. if(sensor_presence)
  288. {
  289. rt_device_unregister(&sensor_presence->parent);
  290. rt_free(sensor_presence);
  291. }
  292. if(sensor_temp)
  293. {
  294. rt_device_unregister(&sensor_temp->parent);
  295. rt_free(sensor_temp);
  296. }
  297. if(sensor_motion)
  298. {
  299. rt_device_unregister(&sensor_motion->parent);
  300. rt_free(sensor_motion);
  301. }
  302. if (module)
  303. rt_free(module);
  304. return -RT_ERROR;
  305. }
  306. int sths34pf80_port(void)
  307. {
  308. uint8_t STHS34PF80_ADDR_DEFAULT = 0x5A;
  309. struct rt_sensor_config cfg;
  310. cfg.intf.dev_name = "i2c1";
  311. cfg.intf.user_data = (void *)STHS34PF80_ADDR_DEFAULT;
  312. cfg.irq_pin.pin = RT_PIN_NONE;
  313. cfg.irq_pin.mode = PIN_MODE_INPUT;
  314. rt_hw_sths34pf80_init("sths34pf80", &cfg);
  315. return 0;
  316. }
  317. INIT_APP_EXPORT(sths34pf80_port);