1 /*
2 * Copyright (c) 2022 Thomas Stranger
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @brief Common functions for Maxim DS2477,DS2485 1-Wire Masters
9 */
10
11 #include "w1_ds2477_85_common.h"
12
13 #include <zephyr/drivers/i2c.h>
14 #include <zephyr/drivers/w1.h>
15 #include <zephyr/logging/log.h>
16 #include <zephyr/kernel.h>
17
18 LOG_MODULE_REGISTER(w1_ds2477_85, CONFIG_W1_LOG_LEVEL);
19
ds2477_85_write_port_config(const struct device * dev,uint8_t reg,uint16_t value)20 int ds2477_85_write_port_config(const struct device *dev, uint8_t reg, uint16_t value)
21 {
22 const struct w1_ds2477_85_config *cfg = dev->config;
23 uint8_t buf[5] = {CMD_WR_W1_PORT_CFG, CMD_WR_W1_PORT_CFG_LEN, reg};
24 int ret;
25
26 __ASSERT_NO_MSG(reg <= PORT_REG_COUNT);
27
28 sys_put_le16(value, &buf[3]);
29 ret = i2c_write_dt(&cfg->i2c_spec, buf, (CMD_WR_W1_PORT_CFG_LEN + CMD_OVERHEAD_LEN));
30 if (ret < 0) {
31 return ret;
32 }
33
34 k_usleep(cfg->t_op_us);
35
36 ret = i2c_read_dt(&cfg->i2c_spec, buf, 2);
37 if (ret < 0) {
38 return ret;
39 }
40 if ((buf[0] != 1) || (buf[1] != DS2477_88_RES_SUCCESS)) {
41 return -EIO;
42 }
43
44 return 0;
45 }
46
ds2477_85_read_port_config(const struct device * dev,uint8_t reg,uint16_t * value)47 int ds2477_85_read_port_config(const struct device *dev, uint8_t reg, uint16_t *value)
48 {
49 const struct w1_ds2477_85_config *cfg = dev->config;
50 uint8_t buf[4] = {CMD_RD_W1_PORT_CFG, CMD_RD_W1_PORT_CFG_LEN, reg};
51 int ret;
52
53 __ASSERT_NO_MSG(value != NULL && reg <= PORT_REG_COUNT);
54
55 ret = i2c_write_dt(&cfg->i2c_spec, buf, (CMD_RD_W1_PORT_CFG_LEN + CMD_OVERHEAD_LEN));
56 if (ret < 0) {
57 return ret;
58 }
59
60 k_usleep(cfg->t_op_us);
61
62 ret = i2c_read_dt(&cfg->i2c_spec, buf, 4);
63 if (ret < 0) {
64 return ret;
65 }
66 if ((buf[0] != 3) || (buf[1] != DS2477_88_RES_SUCCESS)) {
67 return -EIO;
68 }
69
70 *value = sys_get_le16(&buf[2]);
71
72 return 0;
73 }
74
ds2477_85_reset_master(const struct device * dev)75 int ds2477_85_reset_master(const struct device *dev)
76 {
77 const struct w1_ds2477_85_config *cfg = dev->config;
78 uint8_t buf[2] = {CMD_MASTER_RESET};
79 int ret;
80
81 ret = i2c_write_dt(&cfg->i2c_spec, buf, 1);
82 if (ret < 0) {
83 LOG_ERR("initiate reset failed");
84 return ret;
85 }
86
87 k_usleep(cfg->t_op_us);
88
89 ret = i2c_read_dt(&cfg->i2c_spec, buf, 2);
90 if (ret < 0) {
91 return ret;
92 }
93 if ((buf[0] != 1) || (buf[1] != DS2477_88_RES_SUCCESS)) {
94 return -EIO;
95 }
96
97 return 0;
98 }
99
ds2477_85_reset_bus(const struct device * dev)100 int ds2477_85_reset_bus(const struct device *dev)
101 {
102 const struct w1_ds2477_85_config *cfg = dev->config;
103 struct w1_ds2477_85_data *data = dev->data;
104 uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_reset;
105 uint8_t tx_data;
106 uint8_t rx_data;
107 int ret;
108
109 tx_data = data->master_reg.od_active ? BIT(3) : BIT(7);
110 ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_RESET, &tx_data, 1, &rx_data, 1);
111
112 switch (ret) {
113 case DS2477_88_RES_COMM_FAILURE:
114 /* presence not detected */
115 return 0;
116 case DS2477_88_RES_SUCCESS:
117 /* at least 1 device present */
118 return 1;
119 default:
120 return -EIO;
121 }
122 }
123
ds2477_85_read_bit(const struct device * dev)124 int ds2477_85_read_bit(const struct device *dev)
125 {
126 const struct w1_ds2477_85_config *cfg = dev->config;
127 struct w1_ds2477_85_data *data = dev->data;
128 uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_slot;
129 uint8_t rx_data;
130 int ret;
131
132 ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_READ_BIT, NULL, 0, &rx_data, 1);
133 if (ret != DS2477_88_RES_SUCCESS) {
134 return -EIO;
135 }
136
137 return (rx_data & BIT(5)) ? 1 : 0;
138 }
139
ds2477_85_write_bit(const struct device * dev,const bool bit)140 int ds2477_85_write_bit(const struct device *dev, const bool bit)
141 {
142 const struct w1_ds2477_85_config *cfg = dev->config;
143 struct w1_ds2477_85_data *data = dev->data;
144 uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_slot;
145 uint8_t tx_data = (uint8_t)bit;
146 uint8_t rx_data;
147 int ret;
148
149 ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_WRITE_BIT, &tx_data, 1, &rx_data, 1);
150 if (ret != DS2477_88_RES_SUCCESS) {
151 return -EIO;
152 }
153
154 return 0;
155 }
156
ds2477_85_read_byte(const struct device * dev)157 int ds2477_85_read_byte(const struct device *dev)
158 {
159 const struct w1_ds2477_85_config *cfg = dev->config;
160 struct w1_ds2477_85_data *data = dev->data;
161 uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_slot * 8;
162 uint8_t rx_data;
163 int ret;
164
165 ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_READ_BYTE, NULL, 0, &rx_data, 1);
166 if (ret != DS2477_88_RES_SUCCESS) {
167 return -EIO;
168 }
169
170 return rx_data;
171 }
172
ds2477_85_write_byte(const struct device * dev,const uint8_t tx_byte)173 int ds2477_85_write_byte(const struct device *dev, const uint8_t tx_byte)
174 {
175 const struct w1_ds2477_85_config *cfg = dev->config;
176 struct w1_ds2477_85_data *data = dev->data;
177 uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_slot * 8;
178 uint8_t rx_data;
179 int ret;
180
181 ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_WRITE_BYTE, &tx_byte, 1, &rx_data, 1);
182 if (ret != DS2477_88_RES_SUCCESS) {
183 return -EIO;
184 }
185
186 return 0;
187 }
188
ds2477_85_write_block(const struct device * dev,const uint8_t * buffer,size_t tx_len)189 int ds2477_85_write_block(const struct device *dev, const uint8_t *buffer, size_t tx_len)
190 {
191 const struct w1_ds2477_85_config *cfg = dev->config;
192 struct w1_ds2477_85_data *data = dev->data;
193 int w1_timing = cfg->mode_timing[data->master_reg.od_active].t_slot * 8 * tx_len;
194 uint8_t buf[3] = {CMD_WR_BLOCK, (tx_len + CMD_WR_BLOCK_LEN), 0};
195 struct i2c_msg tx_msg[2] = {
196 {.buf = buf, .len = (CMD_WR_BLOCK_LEN + CMD_OVERHEAD_LEN), .flags = I2C_MSG_WRITE},
197 {.buf = (uint8_t *)buffer, .len = tx_len, .flags = (I2C_MSG_WRITE | I2C_MSG_STOP)},
198 };
199 int ret;
200
201 __ASSERT_NO_MSG(tx_len <= MAX_BLOCK_LEN);
202
203 if (tx_len == 0) {
204 return 0;
205 }
206
207 ret = i2c_transfer_dt(&cfg->i2c_spec, tx_msg, 2);
208 if (ret < 0) {
209 LOG_ERR("write block fail: %x", ret);
210 return ret;
211 }
212
213 k_usleep(cfg->t_op_us + (cfg->t_seq_us * tx_len) + w1_timing);
214
215 ret = i2c_read_dt(&cfg->i2c_spec, buf, 2);
216 if (ret < 0) {
217 return ret;
218 }
219 if ((buf[0] != 1) || (buf[1] != DS2477_88_RES_SUCCESS)) {
220 return -EIO;
221 }
222
223 return 0;
224 }
225
ds2477_85_read_block(const struct device * dev,uint8_t * buffer,size_t rx_len)226 int ds2477_85_read_block(const struct device *dev, uint8_t *buffer, size_t rx_len)
227 {
228 const struct w1_ds2477_85_config *cfg = dev->config;
229 struct w1_ds2477_85_data *data = dev->data;
230 int w1_timing = cfg->mode_timing[data->master_reg.od_active].t_slot * 8 * rx_len;
231 uint8_t buf[3] = {CMD_RD_BLOCK, CMD_RD_BLOCK_LEN, rx_len};
232 struct i2c_msg rx_msg[2] = {
233 {.buf = buf, .len = 2, .flags = I2C_MSG_READ},
234 {.buf = buffer, .len = rx_len, .flags = (I2C_MSG_READ | I2C_MSG_STOP)}
235 };
236 int ret;
237
238 __ASSERT_NO_MSG(rx_len <= MAX_BLOCK_LEN);
239
240 if (rx_len == 0) {
241 return 0;
242 }
243
244 ret = i2c_write_dt(&cfg->i2c_spec, buf, (CMD_RD_BLOCK_LEN + CMD_OVERHEAD_LEN));
245 if (ret < 0) {
246 LOG_ERR("read block fail: %x", ret);
247 return ret;
248 }
249
250 k_usleep(cfg->t_op_us + (cfg->t_seq_us * rx_len) + w1_timing);
251
252 ret = i2c_transfer_dt(&cfg->i2c_spec, rx_msg, 2);
253 if (ret < 0) {
254 return ret;
255 }
256 if (buf[1] != DS2477_88_RES_SUCCESS) {
257 return -EIO;
258 }
259
260 return 0;
261 }
262
ds2477_85_configure(const struct device * dev,enum w1_settings_type type,uint32_t value)263 int ds2477_85_configure(const struct device *dev, enum w1_settings_type type, uint32_t value)
264 {
265 struct w1_ds2477_85_data *data = dev->data;
266
267 switch (type) {
268 case W1_SETTING_SPEED:
269 __ASSERT_NO_MSG(value <= 1);
270 data->master_reg.od_active = value;
271 break;
272 default:
273 return -EINVAL;
274 }
275
276 return ds2477_85_write_port_config(dev, PORT_REG_MASTER_CONFIGURATION,
277 data->master_reg.value);
278 }
279
w1_ds2477_85_init(const struct device * dev)280 int w1_ds2477_85_init(const struct device *dev)
281 {
282 const struct w1_ds2477_85_config *cfg = dev->config;
283 struct w1_ds2477_85_data *data = dev->data;
284
285 data->master_reg.apu = cfg->apu;
286
287 if (ds2477_85_write_port_config(dev, PORT_REG_MASTER_CONFIGURATION,
288 data->master_reg.value) < 0) {
289 return -EIO;
290 }
291
292 if (ds2477_85_write_port_config(dev, PORT_REG_RPUP_BUF, cfg->rpup_buf) < 0) {
293 return -EIO;
294 }
295
296 if (ds2477_85_write_port_config(dev, PORT_REG_PDSLEW, cfg->pdslew) < 0) {
297 return -EIO;
298 }
299
300 LOG_DBG("cfg: rpup_buf=%02x, pdslew:%02x", cfg->rpup_buf, cfg->pdslew);
301
302 /* RPUP/BUF configuration is applied after a bus reset */
303 (void)ds2477_85_reset_bus(dev);
304
305 LOG_DBG("w1-ds2477/85 init; %d slave devices",
306 cfg->master_config.slave_count);
307
308 return 0;
309 }
310