/* * Copyright (c) 2022 Thomas Stranger * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT maxim_ds2485 /** * @brief Driver for the Maxim ds2485 1-Wire Master */ #include "w1_ds2477_85_common.h" #include #include #include #include LOG_MODULE_REGISTER(w1_ds2485, CONFIG_W1_LOG_LEVEL); /* upper limits; guaranteed over operating temperature range */ #define DS2485_T_OSCWUP_us 1000U #define DS2485_T_OP_us 400U #define DS2485_T_SEQ_us 10U int ds2485_w1_script_cmd(const struct device *dev, int w1_delay_us, uint8_t w1_cmd, const uint8_t *tx_buf, const uint8_t tx_len, uint8_t *rx_buf, uint8_t rx_len) { const struct w1_ds2477_85_config *cfg = dev->config; uint8_t i2c_len = 3 + tx_len; uint8_t tx_bytes[3 + SCRIPT_WR_LEN] = { CMD_W1_SCRIPT, tx_len + CMD_W1_SCRIPT_LEN, w1_cmd }; uint8_t rx_bytes[3]; struct i2c_msg rx_msg[2] = { { .buf = rx_bytes, .len = (CMD_W1_SCRIPT_LEN + CMD_OVERHEAD_LEN), .flags = I2C_MSG_READ, }, { .buf = rx_buf, .len = rx_len, .flags = (I2C_MSG_READ | I2C_MSG_STOP), }, }; int ret; __ASSERT_NO_MSG(tx_len <= SCRIPT_WR_LEN); memcpy(&tx_bytes[3], tx_buf, tx_len); ret = i2c_write_dt(&cfg->i2c_spec, tx_bytes, i2c_len); if (ret < 0) { return ret; } k_usleep(DS2485_T_OP_us + DS2485_T_SEQ_us + w1_delay_us); ret = i2c_transfer_dt(&cfg->i2c_spec, rx_msg, 2); if (ret < 0) { LOG_ERR("scripts_cmd fail: ret: %x", ret); return ret; } if ((rx_bytes[0] != (rx_len + 2)) || (rx_bytes[2] != w1_cmd)) { LOG_ERR("scripts_cmd fail: response: %x,%x:", rx_bytes[0], rx_bytes[2]); return -EIO; } return rx_bytes[1]; } static int w1_ds2485_init(const struct device *dev) { const struct w1_ds2477_85_config *cfg = dev->config; if (!device_is_ready(cfg->i2c_spec.bus)) { LOG_ERR("%s is not ready", cfg->i2c_spec.bus->name); return -ENODEV; } if (ds2477_85_reset_master(dev)) { return -EIO; } k_usleep(DS2485_T_OSCWUP_us); return w1_ds2477_85_init(dev); } static const struct w1_driver_api w1_ds2485_driver_api = { .reset_bus = ds2477_85_reset_bus, .read_bit = ds2477_85_read_bit, .write_bit = ds2477_85_write_bit, .read_byte = ds2477_85_read_byte, .write_byte = ds2477_85_write_byte, .read_block = ds2477_85_read_block, .write_block = ds2477_85_write_block, .configure = ds2477_85_configure, }; #define W1_DS2485_INIT(inst) \ static const struct w1_ds2477_85_config w1_ds2477_85_cfg_##inst = \ W1_DS2477_85_DT_CONFIG_INST_GET(inst, DS2485_T_OP_us, \ DS2485_T_SEQ_us, \ ds2485_w1_script_cmd); \ \ static struct w1_ds2477_85_data w1_ds2477_85_data_##inst = {}; \ DEVICE_DT_INST_DEFINE(inst, &w1_ds2485_init, NULL, \ &w1_ds2477_85_data_##inst, \ &w1_ds2477_85_cfg_##inst, POST_KERNEL, \ CONFIG_W1_INIT_PRIORITY, &w1_ds2485_driver_api); DT_INST_FOREACH_STATUS_OKAY(W1_DS2485_INIT)