1 /*
2 * Copyright (c) 2024 Würth Elektronik eiSos GmbH & Co. KG
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT we_wsen_pdus_25131308xxxxx
8
9 #include <stdlib.h>
10
11 #include <zephyr/sys/__assert.h>
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/logging/log.h>
14
15 #include "wsen_pdus_25131308XXXXX.h"
16
17 LOG_MODULE_REGISTER(WSEN_PDUS_25131308XXXXX, CONFIG_SENSOR_LOG_LEVEL);
18
pdus_25131308XXXXX_sample_fetch(const struct device * dev,enum sensor_channel chan)19 static int pdus_25131308XXXXX_sample_fetch(const struct device *dev, enum sensor_channel chan)
20 {
21 struct pdus_25131308XXXXX_data *data = dev->data;
22 uint16_t pressure_dummy;
23
24 switch (chan) {
25 case SENSOR_CHAN_ALL: {
26 if (PDUS_getRawPressureAndTemperature(&data->sensor_interface, &data->pressure,
27 &data->temperature) != WE_SUCCESS) {
28 LOG_ERR("Failed to fetch data sample");
29 return -EIO;
30 }
31 break;
32 }
33 case SENSOR_CHAN_AMBIENT_TEMP: {
34 if (PDUS_getRawPressureAndTemperature(&data->sensor_interface, &pressure_dummy,
35 &data->temperature) != WE_SUCCESS) {
36 LOG_ERR("Failed to fetch data sample");
37 return -EIO;
38 }
39 break;
40 }
41 case SENSOR_CHAN_PRESS: {
42 if (PDUS_getRawPressure(&data->sensor_interface, &data->pressure) != WE_SUCCESS) {
43 LOG_ERR("Failed to fetch data sample");
44 return -EIO;
45 }
46 break;
47 }
48 default:
49 LOG_ERR("Fetching is not supported on channel %d.", chan);
50 return -ENOTSUP;
51 }
52
53 return 0;
54 }
55
pdus_25131308XXXXX_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * value)56 static int pdus_25131308XXXXX_channel_get(const struct device *dev, enum sensor_channel chan,
57 struct sensor_value *value)
58 {
59 struct pdus_25131308XXXXX_data *data = dev->data;
60 const struct pdus_25131308XXXXX_config *config = dev->config;
61
62 switch (chan) {
63 case SENSOR_CHAN_AMBIENT_TEMP: {
64 int32_t temperature_mega = ((int32_t)(data->temperature - T_MIN_VAL_PDUS)) * 4272;
65
66 value->val1 = temperature_mega / 1000000;
67 value->val2 = temperature_mega % 1000000;
68 break;
69 }
70 case SENSOR_CHAN_PRESS: {
71 int32_t pressure_temp = ((int32_t)(data->pressure - P_MIN_VAL_PDUS));
72
73 /*
74 * these values are conversion factors based on the sensor type defined in the user
75 * manual of the respective sensor
76 */
77 switch (config->sensor_type) {
78 case PDUS_pdus0:
79 value->val1 = ((pressure_temp * 763) - 10000000) / 100000000;
80 value->val2 = (((pressure_temp * 763) - 10000000) % 100000000) / 100;
81 break;
82 case PDUS_pdus1:
83 value->val1 = ((pressure_temp * 763) - 10000000) / 10000000;
84 value->val2 = (((pressure_temp * 763) - 10000000) % 10000000) / 10;
85 break;
86 case PDUS_pdus2:
87 value->val1 = ((pressure_temp * 763) - 10000000) / 1000000;
88 value->val2 = ((pressure_temp * 763) - 10000000) % 1000000;
89 break;
90 case PDUS_pdus3:
91 value->val1 = (pressure_temp * 3815) / 1000000;
92 value->val2 = (pressure_temp * 3815) % 1000000;
93 break;
94 case PDUS_pdus4:
95 value->val1 = ((pressure_temp * 4196) - 10000000) / 100000;
96 value->val2 =
97 ((pressure_temp * 4196) - 10000000) % 100000 * (1000000 / 100000);
98 break;
99 case PDUS_pdus5:
100 value->val1 = (pressure_temp * 5722) / 100000;
101 value->val2 = (pressure_temp * 5722) % 100000 * (1000000 / 100000);
102 break;
103 default:
104 LOG_ERR("Sensor type doesn't exist");
105 return -ENOTSUP;
106 }
107 break;
108 }
109 default:
110 LOG_ERR("Channel not supported %d", chan);
111 return -ENOTSUP;
112 }
113
114 return 0;
115 }
116
117 static DEVICE_API(sensor, pdus_25131308XXXXX_driver_api) = {
118 .sample_fetch = pdus_25131308XXXXX_sample_fetch,
119 .channel_get = pdus_25131308XXXXX_channel_get
120 };
121
pdus_25131308XXXXX_init(const struct device * dev)122 static int pdus_25131308XXXXX_init(const struct device *dev)
123 {
124 struct pdus_25131308XXXXX_data *data = dev->data;
125 const struct pdus_25131308XXXXX_config *config = dev->config;
126
127 /* Initialize WE sensor interface */
128 PDUS_getDefaultInterface(&data->sensor_interface);
129 data->sensor_interface.interfaceType = WE_i2c;
130
131 if (!i2c_is_ready_dt(&config->bus_cfg.i2c)) {
132 LOG_ERR("I2C bus device not ready");
133 return -ENODEV;
134 }
135
136 data->sensor_interface.handle = (void *)&config->bus_cfg.i2c;
137
138 return 0;
139 }
140
141 /*
142 * Main instantiation macro.
143 */
144 #define PDUS_25131308XXXXX_DEFINE(inst) \
145 static struct pdus_25131308XXXXX_data pdus_25131308XXXXX_data_##inst; \
146 static const struct pdus_25131308XXXXX_config pdus_25131308XXXXX_config_##inst = { \
147 .bus_cfg = \
148 { \
149 .i2c = I2C_DT_SPEC_INST_GET(inst), \
150 }, \
151 .sensor_type = (PDUS_SensorType_t)DT_INST_ENUM_IDX(inst, sensor_type)}; \
152 SENSOR_DEVICE_DT_INST_DEFINE(inst, pdus_25131308XXXXX_init, NULL, \
153 &pdus_25131308XXXXX_data_##inst, \
154 &pdus_25131308XXXXX_config_##inst, POST_KERNEL, \
155 CONFIG_SENSOR_INIT_PRIORITY, &pdus_25131308XXXXX_driver_api);
156
157 DT_INST_FOREACH_STATUS_OKAY(PDUS_25131308XXXXX_DEFINE)
158