1-Wire Bus

Overview

1-Wire is a low speed half-duplex serial bus using only a single wire plus ground for both data transmission and device power supply. Similarly to I2C, 1-Wire uses a bidirectional open-collector data line, and is a single master multidrop bus. This means one master initiates all data exchanges with the slave devices. The 1-Wire bus supports longer bus lines than I2C, while it reaches speeds of up to 15.4 kbps in standard mode and up to 125 kbps in overdrive mode. Reliable communication in standard speed configuration is possible with 10 nodes over a bus length of 100 meters. Using overdrive speed, 3 nodes on a bus of 10 meters length are expected to work solid. Optimized timing parameters and fewer nodes on the bus may allow to reach larger bus extents.

The implementation details are specified in the BOOK OF IBUTTON STANDARDS.

1-Wire bus topology

A typical 1-Wire bus topology

W1 Master API

Zephyr’s 1-Wire Master API is used to interact with 1-Wire slave devices like temperature sensors and serial memories.

In Zephyr this API is split into the following layers.

  • The link layer handles basic communication functions such as bus reset, presence detect and bit transfer operations. It is the only hardware-dependent layer in Zephyr. This layer is supported by a driver using the Zephyr Universal Asynchronous Receiver-Transmitter (UART) interface, which should work on most Zephyr platforms. In the future, a GPIO/Timer based driver and hardware specific drivers might be added.

  • The 1-Wire network layer handles all means for slave identification and bus arbitration. This includes ROM commands like Match ROM, or Search ROM.

    • All slave devices have a unique 64-bit identification number, which includes a 8-bit 1-Wire Family Code and a 8-bit CRC.

    • In order to find slaves on the bus, the standard specifies an search algorithm which successively detects all slaves on the bus. This algorithm is described in detail by Maxim’s Applicationnote 187.

  • Transport layer and Presentation layer functions are not implemented in the generic 1-Wire driver and therefore must be handled in individual slave drivers.

The 1-Wire API is considered experimental.

Configuration Options

Related configuration options:

API Reference

1-Wire network layer

group w1_network

1-Wire network layer

1-Wire ROM Commands

W1_CMD_SKIP_ROM

This command allows the bus master to read the slave devices without providing their ROM code.

W1_CMD_MATCH_ROM

This command allows the bus master to address a specific slave device by providing its ROM code.

W1_CMD_RESUME

This command allows the bus master to resume a previous read out from where it left off.

W1_CMD_READ_ROM

This command allows the bus master to read the ROM code from a single slave device.

This command should be used when there is only a single slave device on the bus.

W1_CMD_SEARCH_ROM

This command allows the bus master to discover the addresses (i.e., ROM codes) of all slave devices on the bus.

W1_CMD_SEARCH_ALARM

This command allows the bus master to identify which devices have experienced an alarm condition.

W1_CMD_OVERDRIVE_SKIP_ROM

This command allows the bus master to address all devices on the bus and then switch them to overdrive speed.

W1_CMD_OVERDRIVE_MATCH_ROM

This command allows the bus master to address a specific device and switch it to overdrive speed.

CRC Defines

W1_CRC8_SEED

Seed value used to calculate the 1-Wire 8-bit crc.

W1_CRC8_POLYNOMIAL

Polynomial used to calculate the 1-Wire 8-bit crc.

W1_CRC16_SEED

Seed value used to calculate the 1-Wire 16-bit crc.

W1_CRC16_POLYNOMIAL

Polynomial used to calculate the 1-Wire 16-bit crc.

Defines

W1_SEARCH_ALL_FAMILIES

This flag can be passed to searches in order to not filter on family ID.

W1_ROM_INIT_ZERO

Initialize all w1_rom struct members to zero.

Typedefs

typedef void (*w1_search_callback_t)(struct w1_rom rom, void *user_data)

Define the application callback handler function signature for searches.

Param rom:

found The ROM of the found slave.

Param user_data:

User data provided to the w1_search_bus() call.

Functions

int w1_read_rom(const struct device *dev, struct w1_rom *rom)

Read Peripheral 64-bit ROM.

This procedure allows the 1-Wire bus master to read the peripherals’ 64-bit ROM without using the Search ROM procedure. This command can be used as long as not more than a single peripheral is connected to the bus. Otherwise data collisions occur and a faulty ROM is read.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

  • rom[out] Pointer to the ROM structure.

Return values:
  • 0 – If successful.

  • -ENODEV – In case no slave responds to reset.

  • -errno – Other negative error code in case of invalid crc and communication errors.

int w1_match_rom(const struct device *dev, const struct w1_slave_config *config)

Select a specific slave by broadcasting a selected ROM.

This routine allows the 1-Wire bus master to select a slave identified by its unique ROM, such that the next command will target only this single selected slave.

This command is only necessary in multidrop environments, otherwise the Skip ROM command can be issued. Once a slave has been selected, to reduce the communication overhead, the resume command can be used instead of this command to communicate with the selected slave.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

  • config[in] Pointer to the slave specific 1-Wire config.

Return values:
  • 0 – If successful.

  • -ENODEV – In case no slave responds to reset.

  • -errno – Other negative error code on error.

int w1_resume_command(const struct device *dev)

Select the slave last addressed with a Match ROM or Search ROM command.

This routine allows the 1-Wire bus master to re-select a slave device that was already addressed using a Match ROM or Search ROM command.

Parameters:
  • dev – Pointer to the device structure for the driver instance.

Return values:
  • 0 – If successful.

  • -ENODEV – In case no slave responds to reset.

  • -errno – Other negative error code on error.

int w1_skip_rom(const struct device *dev, const struct w1_slave_config *config)

Select all slaves regardless of ROM.

This routine sets up the bus slaves to receive a command. It is usually used when there is only one peripheral on the bus to avoid the overhead of the Match ROM command. But it can also be used to concurrently write to all slave devices.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

  • config[in] Pointer to the slave specific 1-Wire config.

Return values:
  • 0 – If successful.

  • -ENODEV – In case no slave responds to reset.

  • -errno – Other negative error code on error.

int w1_reset_select(const struct device *dev, const struct w1_slave_config *config)

In single drop configurations use Skip Select command, otherwise use Match ROM command.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

  • config[in] Pointer to the slave specific 1-Wire config.

Return values:
  • 0 – If successful.

  • -ENODEV – In case no slave responds to reset.

  • -errno – Other negative error code on error.

int w1_write_read(const struct device *dev, const struct w1_slave_config *config, const uint8_t *write_buf, size_t write_len, uint8_t *read_buf, size_t read_len)

Write then read data from the 1-Wire slave with matching ROM.

This routine uses w1_reset_select to select the given ROM. Then writes given data and reads the response back from the slave.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

  • config[in] Pointer to the slave specific 1-Wire config.

  • write_buf[in] Pointer to the data to be written.

  • write_len – Number of bytes to write.

  • read_buf[out] Pointer to storage for read data.

  • read_len – Number of bytes to read.

Return values:
  • 0 – If successful.

  • -ENODEV – In case no slave responds to reset.

  • -errno – Other negative error code on error.

int w1_search_bus(const struct device *dev, uint8_t command, uint8_t family, w1_search_callback_t callback, void *user_data)

Search 1-wire slaves on the bus.

This function searches slaves on the 1-wire bus, with the possibility to search either all slaves or only slaves that have an active alarm state. If a callback is passed, the callback is called for each found slave.

The algorithm mostly follows the suggestions of https://pdfserv.maximintegrated.com/en/an/AN187.pdf

Note: Filtering on families is not supported.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

  • command – Can either be W1_SEARCH_ALARM or W1_SEARCH_ROM.

  • family – W1_SEARCH_ALL_FAMILIES searcheas all families, filtering on a specific family is not yet supported.

  • callback – Application callback handler function to be called for each found slave.

  • user_data[in] User data to pass to the application callback handler function.

Return values:
  • slave_count – Number of slaves found.

  • -errno – Negative error code on error.

static inline int w1_search_rom(const struct device *dev, w1_search_callback_t callback, void *user_data)

Search for 1-Wire slave on bus.

This routine can discover unknown slaves on the bus by scanning for the unique 64-bit registration number.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

  • callback – Application callback handler function to be called for each found slave.

  • user_data[in] User data to pass to the application callback handler function.

Return values:
  • slave_count – Number of slaves found.

  • -errno – Negative error code on error.

static inline int w1_search_alarm(const struct device *dev, w1_search_callback_t callback, void *user_data)

Search for 1-Wire slaves with an active alarm.

This routine searches 1-Wire slaves on the bus, which currently have an active alarm.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

  • callback – Application callback handler function to be called for each found slave.

  • user_data[in] User data to pass to the application callback handler function.

Return values:
  • slave_count – Number of slaves found.

  • -errno – Negative error code on error.

static inline uint64_t w1_rom_to_uint64(const struct w1_rom *rom)

Function to convert a w1_rom struct to an uint64_t.

Parameters:
  • rom[in] Pointer to the ROM struct.

Return values:

rom64 – The ROM converted to an unsigned integer in endianness.

static inline void w1_uint64_to_rom(const uint64_t rom64, struct w1_rom *rom)

Function to write an uint64_t to struct w1_rom pointer.

Parameters:
  • rom64 – Unsigned 64 bit integer representing the ROM in host endianness.

  • rom[out] The ROM struct pointer.

static inline uint8_t w1_crc8(const uint8_t *src, size_t len)

Compute CRC-8 chacksum as defined in the 1-Wire specification.

The 1-Wire of CRC 8 variant is using 0x31 as its polynomial with the initial value set to 0x00. This CRC is used to check the correctness of the unique 56-bit ROM.

Parameters:
  • src[in] Input bytes for the computation.

  • len – Length of the input in bytes.

Return values:

crc – The computed CRC8 value.

static inline uint16_t w1_crc16(const uint16_t seed, const uint8_t *src, const size_t len)

Compute 1-Wire variant of CRC 16.

The 16-bit 1-Wire crc variant is using the reflected polynomial function X^16 + X^15 * + X^2 + 1 with the initial value set to 0x0000. See also APPLICATION NOTE 27: “UNDERSTANDING AND USING CYCLIC REDUNDANCY CHECKS WITH MAXIM 1-WIRE AND IBUTTON PRODUCTS” https://www.maximintegrated.com/en/design/technical-documents/app-notes/2/27.html

Parameters:
  • seed – Init value for the CRC, it is usually set to 0x0000.

  • src[in] Input bytes for the computation.

  • len – Length of the input in bytes.

Return values:

crc – The computed CRC16 value.

struct w1_rom
#include <w1.h>

w1_rom struct.

Public Members

uint8_t family

The 1-Wire family code identifying the slave device type.

An incomplete list of family codes is available at: https://www.maximintegrated.com/en/app-notes/index.mvp/id/155 others are documented in the respective device data sheet.

uint8_t serial[6]

The serial together with the family code composes the unique 56-bit id.

uint8_t crc

8-bit checksum of the 56-bit unique id.

struct w1_slave_config
#include <w1.h>

Node specific 1-wire configuration struct.

This struct is passed to network functions, such that they can configure the bus to address the specific slave using the selected speed.

Public Members

struct w1_rom rom

Unique 1-Wire ROM.

uint32_t overdrive

overdrive speed is used if set to 1.

1-Wire generic functions and helpers

Functions that are not directly related to any of the networking layers.

group w1_interface

1-Wire Interface

Since

3.2

Version

0.1.0

Enums

enum w1_settings_type

Defines the 1-Wire master settings types, which are runtime configurable.

Values:

enumerator W1_SETTING_SPEED

Overdrive speed is enabled in case a value of 1 is passed and disabled passing 0.

enumerator W1_SETTING_STRONG_PULLUP

The strong pullup resistor is activated immediately after the next written data block by passing a value of 1, and deactivated passing 0.

enumerator W1_SETINGS_TYPE_COUNT

Number of different settings types.

Functions

static inline int w1_lock_bus(const struct device *dev)

Lock the 1-wire bus to prevent simultaneous access.

This routine locks the bus to prevent simultaneous access from different threads. The calling thread waits until the bus becomes available. A thread is permitted to lock a mutex it has already locked.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

Return values:
  • 0 – If successful.

  • -errno – Negative error code on error.

static inline int w1_unlock_bus(const struct device *dev)

Unlock the 1-wire bus.

This routine unlocks the bus to permit access to bus line.

Parameters:
  • dev[in] Pointer to the device structure for the driver instance.

Return values:
  • 0 – If successful.

  • -errno – Negative error code on error.