280 lines
10 KiB
C
280 lines
10 KiB
C
/*
|
|
* Copyright (c) 2022 Thomas Stranger
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_DRIVERS_W1_DS2477_DS2485_COMMON_H_
|
|
#define ZEPHYR_DRIVERS_W1_DS2477_DS2485_COMMON_H_
|
|
|
|
#include <zephyr/drivers/i2c.h>
|
|
#include <zephyr/drivers/w1.h>
|
|
#include <zephyr/kernel.h>
|
|
|
|
/* memory specific commands */
|
|
#define CMD_WR_MEM 0x96
|
|
#define CMD_RD_MEM 0x44
|
|
#define CMD_SET_PAGE_PROTECT 0xc3
|
|
#define CMD_RD_STATUS 0xaa
|
|
/* configuration specific commands */
|
|
#define CMD_SET_I2C_ADDR 0x75
|
|
#define CMD_RD_W1_PORT_CFG 0x52
|
|
#define CMD_WR_W1_PORT_CFG 0x99
|
|
#define CMD_MASTER_RESET 0x62
|
|
/* 1-Wire specific commands */
|
|
#define CMD_W1_SCRIPT 0x88
|
|
#define CMD_W1_BLOCK 0xab
|
|
#define CMD_RD_BLOCK 0x50
|
|
#define CMD_WR_BLOCK 0x68
|
|
#define CMD_SEARCH 0x11
|
|
#define CMD_FULL_CMD_SEQ 0x57
|
|
/* crc16 specific commands */
|
|
#define CMD_COMPUTE_CRC 0xcc
|
|
|
|
/* i2c command overhead len */
|
|
#define CMD_OVERHEAD_LEN 2U
|
|
/* memory specific commands' data length */
|
|
#define CMD_WR_MEM_LEN 33U
|
|
#define CMD_RD_MEM_LEN 1U
|
|
#define CMD_SET_PAGE_PROTECT_LEN 2U
|
|
#define CMD_RD_STATUS_LEN 1U
|
|
/* configuration specific commands */
|
|
#define CMD_SET_I2C_ADDR_LEN 1U
|
|
#define CMD_RD_W1_PORT_CFG_LEN 1U
|
|
#define CMD_WR_W1_PORT_CFG_LEN 3U
|
|
/* 1-Wire specific commands */
|
|
#define CMD_W1_SCRIPT_LEN 1U
|
|
#define CMD_W1_BLOCK_LEN 1U
|
|
#define CMD_RD_BLOCK_LEN 1U
|
|
#define CMD_WR_BLOCK_LEN 1U
|
|
#define CMD_SEARCH_LEN 2U
|
|
#define CMD_FULL_CMD_SEQ_LEN 9U
|
|
/* crc16 specific commands */
|
|
#define CMD_COMPUTE_CRC_LEN 1U
|
|
|
|
/* I2C communication result bytes */
|
|
#define DS2477_88_RES_SUCCESS 0xaa
|
|
#define DS2477_88_RES_INVALID_PARAM 0x77
|
|
#define DS2477_88_RES_COMM_FAILURE 0x22
|
|
#define DS2477_88_RES_RESET_FAILURE 0x22
|
|
#define DS2477_88_RES_NO_PRESENCE 0x33
|
|
#define DS2477_88_RES_WP_FAILURE 0x55
|
|
|
|
/* primitive commands, executable via the script command */
|
|
#define SCRIPT_OW_RESET 0x00
|
|
#define SCRIPT_OW_WRITE_BIT 0x01
|
|
#define SCRIPT_OW_READ_BIT 0x02
|
|
#define SCRIPT_OW_WRITE_BYTE 0x03
|
|
#define SCRIPT_OW_READ_BYTE 0x04
|
|
#define SCRIPT_OW_TRIPLET 0x05
|
|
#define SCRIPT_OW_OV_SKIP 0x06
|
|
#define SCRIPT_OW_SKIP 0x07
|
|
#define SCRIPT_OW_READ_BLOCK 0x08
|
|
#define SCRIPT_OW_WRITE_BLOCK 0x09
|
|
#define SCRIPT_OW_DELAY 0x0a
|
|
#define SCRIPT_OW_PRIME_SPU 0x0b
|
|
#define SCRIPT_OW_SPU_OFF 0x0c
|
|
#define SCRIPT_OW_SPEED 0x0d
|
|
|
|
/* port configuration register offsets */
|
|
#define PORT_REG_MASTER_CONFIGURATION 0x00
|
|
#define PORT_REG_STANDARD_SPEED_T_RSTL 0x01
|
|
#define PORT_REG_STANDARD_SPEED_T_MSI 0x02
|
|
#define PORT_REG_STANDARD_SPEED_T_MSP 0x03
|
|
#define PORT_REG_STANDARD_SPEED_T_RSTH 0x04
|
|
#define PORT_REG_STANDARD_SPEED_T_W0L 0x05
|
|
#define PORT_REG_STANDARD_SPEED_T_W1L 0x06
|
|
#define PORT_REG_STANDARD_SPEED_T_MSR 0x07
|
|
#define PORT_REG_STANDARD_SPEED_T_REC 0x08
|
|
#define PORT_REG_OVERDRIVE_SPEED_T_RSTL 0x09
|
|
#define PORT_REG_OVERDRIVE_SPEED_T_MSI 0x0a
|
|
#define PORT_REG_OVERDRIVE_SPEED_T_MSP 0x0b
|
|
#define PORT_REG_OVERDRIVE_SPEED_T_RSTH 0x0c
|
|
#define PORT_REG_OVERDRIVE_SPEED_T_W0L 0x0d
|
|
#define PORT_REG_OVERDRIVE_SPEED_T_W1L 0x0e
|
|
#define PORT_REG_OVERDRIVE_SPEED_T_MSR 0x0f
|
|
#define PORT_REG_OVERDRIVE_SPEED_T_REC 0x10
|
|
#define PORT_REG_RPUP_BUF 0x11
|
|
#define PORT_REG_PDSLEW 0x12
|
|
#define PORT_REG_COUNT 0x13
|
|
|
|
/* upper limit of 1-wire command length supported(in bytes) */
|
|
#define MAX_BLOCK_LEN 126U
|
|
/* limit of 1-wire command len is 126 bytes, but currently not used: */
|
|
#define SCRIPT_WR_LEN 1U
|
|
|
|
/* variant independent timing */
|
|
#define DS2477_85_T_RM_us 50000U
|
|
#define DS2477_85_T_WM_us 100000U
|
|
#define DS2477_85_T_WS_us 15000U
|
|
|
|
/* default 1-wire timing parameters (cfg. value==6) */
|
|
#define DS2477_85_STD_SPD_T_RSTL_us 560U
|
|
#define DS2477_85_STD_SPD_T_MSI_us 7U
|
|
#define DS2477_85_STD_SPD_T_MSP_us 68U
|
|
#define DS2477_85_STD_SPD_T_RSTH_us 560U
|
|
#define DS2477_85_STD_SPD_T_W0L_us 68U
|
|
#define DS2477_85_STD_SPD_T_W1L_us 8U
|
|
#define DS2477_85_STD_SPD_T_MSR_us 12U
|
|
#define DS2477_85_STD_SPD_T_REC_us 6U
|
|
|
|
#define DS2477_85_OVD_SPD_T_RSTL_us 56U
|
|
#define DS2477_85_OVD_SPD_T_MSI_us 2U
|
|
#define DS2477_85_OVD_SPD_T_MSP_us 8U
|
|
#define DS2477_85_OVD_SPD_T_RSTH_us 56U
|
|
#define DS2477_85_OVD_SPD_T_W0L_us 8U
|
|
#define DS2477_85_OVD_SPD_T_W1L_us 1U
|
|
#define DS2477_85_OVD_SPD_T_MSR_us 2U
|
|
#define DS2477_85_OVD_SPD_T_REC_us 6U
|
|
|
|
#define DS2477_85_STD_SPD_T_SLOT_us \
|
|
(DS2477_85_STD_SPD_T_W0L_us + DS2477_85_STD_SPD_T_REC_us)
|
|
#define DS2477_85_STD_SPD_T_RESET_us \
|
|
(DS2477_85_STD_SPD_T_RSTL_us + DS2477_85_STD_SPD_T_RSTH_us)
|
|
|
|
#define DS2477_85_OVD_SPD_T_SLOT_us \
|
|
(DS2477_85_OVD_SPD_T_W0L_us + DS2477_85_OVD_SPD_T_REC_us)
|
|
#define DS2477_85_OVD_SPD_T_RESET_us \
|
|
(DS2477_85_OVD_SPD_T_RSTL_us + DS2477_85_OVD_SPD_T_RSTH_us)
|
|
|
|
/* defines for DTS switching-th, active-pull-th and weak-pullup enums */
|
|
#define RPUP_BUF_CUSTOM BIT(15)
|
|
|
|
#define RPUP_BUF_SW_TH_Msk GENMASK(5, 4)
|
|
#define RPUP_BUF_SW_TH_PREP(x) FIELD_PREP(RPUP_BUF_SW_TH_Msk, x)
|
|
#define RPUP_BUF_SW_TH_LOW RPUP_BUF_SW_TH_PREP(0)
|
|
#define RPUP_BUF_SW_TH_MEDIUM RPUP_BUF_SW_TH_PREP(1)
|
|
#define RPUP_BUF_SW_TH_HIGH RPUP_BUF_SW_TH_PREP(2)
|
|
#define RPUP_BUF_SW_TH_OFF RPUP_BUF_SW_TH_PREP(3)
|
|
#define RPUP_BUF_APULL_TH_Msk GENMASK(3, 2)
|
|
#define RPUP_BUF_APULL_TH_PREP(x) FIELD_PREP(RPUP_BUF_APULL_TH_Msk, x)
|
|
#define RPUP_BUF_APULL_TH_LOW RPUP_BUF_APULL_TH_PREP(0)
|
|
#define RPUP_BUF_APULL_TH_MEDIUM RPUP_BUF_APULL_TH_PREP(1)
|
|
#define RPUP_BUF_APULL_TH_HIGH RPUP_BUF_APULL_TH_PREP(2)
|
|
#define RPUP_BUF_APULL_TH_OFF RPUP_BUF_APULL_TH_PREP(3)
|
|
#define RPUP_BUF_WPULL_Msk GENMASK(1, 0)
|
|
#define RPUP_BUF_WPULL_PREP(x) FIELD_PREP(RPUP_BUF_WPULL_Msk, x)
|
|
#define RPUP_BUF_WPULL_EXTERN RPUP_BUF_WPULL_PREP(0)
|
|
#define RPUP_BUF_WPULL_500 RPUP_BUF_WPULL_PREP(1)
|
|
#define RPUP_BUF_WPULL_1000 RPUP_BUF_WPULL_PREP(2)
|
|
#define RPUP_BUF_WPULL_333 RPUP_BUF_WPULL_PREP(3)
|
|
|
|
/* defines for standard and overdrive slew enums */
|
|
#define PDSLEW_CUSTOM BIT(15)
|
|
#define PDSLEW_STD_Msk GENMASK(5, 3)
|
|
#define PDSLEW_STD_PREP(x) FIELD_PREP(PDSLEW_STD_Msk, BIT(x))
|
|
#define PDSLEW_STD_50 PDSLEW_STD_PREP(0)
|
|
#define PDSLEW_STD_150 PDSLEW_STD_PREP(1)
|
|
#define PDSLEW_STD_1300 PDSLEW_STD_PREP(2)
|
|
#define PDSLEW_OVD_Msk GENMASK(2, 0)
|
|
#define PDSLEW_OVD_PREP(x) FIELD_PREP(PDSLEW_OVD_Msk, BIT(x))
|
|
#define PDSLEW_OVD_50 PDSLEW_OVD_PREP(0)
|
|
#define PDSLEW_OVD_150 PDSLEW_OVD_PREP(1)
|
|
|
|
/* speed mode dependent timing parameters */
|
|
struct mode_timing {
|
|
uint16_t t_slot;
|
|
uint16_t t_reset;
|
|
};
|
|
|
|
union master_config_reg {
|
|
struct {
|
|
uint16_t res : 12;
|
|
uint16_t apu : 1;
|
|
uint16_t spu : 1;
|
|
uint16_t pdn : 1;
|
|
uint16_t od_active : 1;
|
|
};
|
|
uint16_t value;
|
|
};
|
|
|
|
typedef int (*variant_w1_script_cmd_fn)(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);
|
|
|
|
struct w1_ds2477_85_config {
|
|
/** w1 master config, common to all drivers */
|
|
struct w1_master_config master_config;
|
|
/** I2C device */
|
|
const struct i2c_dt_spec i2c_spec;
|
|
/** config reg of weak pullup, active pullup, and switch threshold */
|
|
uint16_t rpup_buf;
|
|
/** config reg of standard and overdrive slew */
|
|
uint16_t pdslew;
|
|
/** mode dependent timing parameters (@0: standard, @1: overdrive) */
|
|
struct mode_timing mode_timing[2];
|
|
/** variant dependent time of 1 operation in us */
|
|
uint16_t t_op_us;
|
|
/** variant dependent time of 1 sequence in us */
|
|
uint16_t t_seq_us;
|
|
/** variant specific script command */
|
|
variant_w1_script_cmd_fn w1_script_cmd;
|
|
/** indicates enable active pull-up configuration */
|
|
bool apu;
|
|
};
|
|
|
|
struct w1_ds2477_85_data {
|
|
/** w1 master data, common to all drivers */
|
|
struct w1_master_data master_data;
|
|
/** master specific runtime configuration */
|
|
union master_config_reg master_reg;
|
|
};
|
|
|
|
#define W1_DS2477_85_DT_CONFIG_GET(node_id, _t_op, _t_seq, _script_cmd) \
|
|
{ \
|
|
.i2c_spec = I2C_DT_SPEC_GET(node_id), \
|
|
.master_config.slave_count = \
|
|
W1_SLAVE_COUNT(node_id), \
|
|
.rpup_buf = RPUP_BUF_CUSTOM | \
|
|
RPUP_BUF_SW_TH_PREP(DT_ENUM_IDX(node_id, \
|
|
switching_threshold)) | \
|
|
RPUP_BUF_APULL_TH_PREP(DT_ENUM_IDX(node_id, \
|
|
active_pull_threshold)) | \
|
|
RPUP_BUF_WPULL_PREP(DT_ENUM_IDX(node_id, weak_pullup)),\
|
|
.pdslew = PDSLEW_CUSTOM | \
|
|
PDSLEW_STD_PREP(DT_ENUM_IDX(node_id, \
|
|
standard_slew)) | \
|
|
PDSLEW_OVD_PREP(DT_ENUM_IDX(node_id, \
|
|
overdrive_slew)), \
|
|
.apu = DT_PROP(node_id, active_pullup), \
|
|
.mode_timing = { \
|
|
{ \
|
|
.t_slot = DS2477_85_STD_SPD_T_SLOT_us, \
|
|
.t_reset = DS2477_85_STD_SPD_T_RESET_us, \
|
|
}, \
|
|
{ \
|
|
.t_slot = DS2477_85_OVD_SPD_T_SLOT_us, \
|
|
.t_reset = DS2477_85_OVD_SPD_T_RESET_us, \
|
|
}, \
|
|
}, \
|
|
.t_op_us = _t_op, \
|
|
.t_seq_us = _t_seq, \
|
|
.w1_script_cmd = _script_cmd, \
|
|
}
|
|
|
|
#define W1_DS2477_85_DT_CONFIG_INST_GET(inst, _t_op, _t_seq, _script_cmd) \
|
|
W1_DS2477_85_DT_CONFIG_GET(DT_DRV_INST(inst), _t_op, _t_seq, \
|
|
_script_cmd)
|
|
|
|
int w1_ds2477_85_init(const struct device *dev);
|
|
int ds2477_85_write_port_config(const struct device *dev, uint8_t reg,
|
|
uint16_t value);
|
|
int ds2477_85_read_port_config(const struct device *dev, uint8_t reg,
|
|
uint16_t *value);
|
|
int ds2477_85_reset_master(const struct device *dev);
|
|
int ds2477_85_reset_bus(const struct device *dev);
|
|
int ds2477_85_read_bit(const struct device *dev);
|
|
int ds2477_85_write_bit(const struct device *dev, const bool bit);
|
|
int ds2477_85_read_byte(const struct device *dev);
|
|
int ds2477_85_write_byte(const struct device *dev, const uint8_t tx_byte);
|
|
int ds2477_85_write_block(const struct device *dev, const uint8_t *buffer,
|
|
size_t tx_len);
|
|
int ds2477_85_read_block(const struct device *dev, uint8_t *buffer,
|
|
size_t rx_len);
|
|
int ds2477_85_configure(const struct device *dev, enum w1_settings_type type,
|
|
uint32_t value);
|
|
|
|
#endif /* ZEPHYR_DRIVERS_W1_DS2477_DS2485_COMMON_H_ */
|