onewire - Bit-banging one wire driver¶
- group onewire
Routines to access devices using the Dallas Semiconductor 1-Wire(tm) protocol.
This is a port of a bit-banging one wire driver based on the implementation from NodeMCU.
This, in turn, appears to have been based on the PJRC Teensy driver (https://www.pjrc.com/teensy/td_libs_OneWire.html), by Jim Studt, Paul Stoffregen, and a host of others.
The original code is licensed under the MIT license. The CRC code was taken (at least partially) from Dallas Semiconductor sample code, which was licensed under an MIT license with an additional clause (prohibiting inappropriate use of the Dallas Semiconductor name). See the accompanying LICENSE file for details.
Defines
-
ONEWIRE_NONE¶
ONEWIRE_NONE is an invalid ROM address that will never occur in a device (CRC mismatch), and so can be useful as an indicator for “no-such-device”, etc.
Typedefs
-
typedef uint64_t onewire_addr_t¶
Type used to hold all 1-Wire device ROM addresses (64-bit)
Functions
-
bool onewire_reset(gpio_num_t pin)¶
Perform a 1-Wire reset cycle.
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
- Returns
true
if at least one device responds with a presence pulse,false
if no devices were detected (or the bus is shorted, etc)
-
bool onewire_select(gpio_num_t pin, const onewire_addr_t addr)¶
Issue a 1-Wire “ROM select” command to select a particular device.
It is necessary to call onewire_reset() before calling this function.
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
addr – The ROM address of the device to select
- Returns
true
if the “ROM select” command could be successfully issued,false
if there was an error.
-
bool onewire_skip_rom(gpio_num_t pin)¶
Issue a 1-Wire “skip ROM” command to select all devices on the bus.
It is necessary to call onewire_reset() before calling this function.
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
- Returns
true
if the “skip ROM” command could be successfully issued,false
if there was an error.
-
bool onewire_write(gpio_num_t pin, uint8_t v)¶
Write a byte on the onewire bus.
The writing code uses open-drain mode and expects the pullup resistor to pull the line high when not driven low. If you need strong power after the write (e.g. DS18B20 in parasite power mode) then call onewire_power() after this is complete to actively drive the line high.
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
v – The byte value to write
- Returns
true
if successful,false
on error.
-
bool onewire_write_bytes(gpio_num_t pin, const uint8_t *buf, size_t count)¶
Write multiple bytes on the 1-Wire bus.
See onewire_write() for more info.
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
buf – A pointer to the buffer of bytes to be written
count – Number of bytes to write
- Returns
true
if all bytes written successfully,false
on error.
-
int onewire_read(gpio_num_t pin)¶
Read a byte from a 1-Wire device.
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
- Returns
the read byte on success, negative value on error.
-
bool onewire_read_bytes(gpio_num_t pin, uint8_t *buf, size_t count)¶
Read multiple bytes from a 1-Wire device.
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
buf – [out] A pointer to the buffer to contain the read bytes
count – Number of bytes to read
- Returns
true
on success,false
on error.
-
bool onewire_power(gpio_num_t pin)¶
Actively drive the bus high to provide extra power for certain operations of parasitically-powered devices.
For parasitically-powered devices which need more power than can be provided via the normal pull-up resistor, it may be necessary for some operations to drive the bus actively high. This function can be used to perform that operation.
The bus can be depowered once it is no longer needed by calling onewire_depower(), or it will be depowered automatically the next time onewire_reset() is called to start another command.
Note
Make sure the device(s) you are powering will not pull more current than the ESP32/ESP8266 is able to supply via its GPIO pins (this is especially important when multiple devices are on the same bus and they are all performing a power-intensive operation at the same time (i.e. multiple DS18B20 sensors, which have all been given a “convert T” operation by using onewire_skip_rom())).
Note
This routine will check to make sure that the bus is already high before driving it, to make sure it doesn’t attempt to drive it high while something else is pulling it low (which could cause a reset or damage the ESP32/ESP8266).
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
- Returns
true
on success,false
on error.
-
void onewire_depower(gpio_num_t pin)¶
Stop forcing power onto the bus.
You only need to do this if you previously called onewire_power() to drive the bus high and now want to allow it to float instead. Note that onewire_reset() will also automatically depower the bus first, so you do not need to call this first if you just want to start a new operation.
- Parameters
pin – The GPIO pin connected to the 1-Wire bus.
-
void onewire_search_start(onewire_search_t *search)¶
Clear the search state so that it will start from the beginning on the next call to onewire_search_next().
- Parameters
search – [out] The onewire_search_t structure to reset.
-
void onewire_search_prefix(onewire_search_t *search, uint8_t family_code)¶
Setup the search to search for devices with the specified “family code”.
- Parameters
search – [out] The onewire_search_t structure to update.
family_code – The “family code” to search for.
-
onewire_addr_t onewire_search_next(onewire_search_t *search, gpio_num_t pin)¶
Search for the next device on the bus.
The order of returned device addresses is deterministic. You will always get the same devices in the same order.
Note
It might be a good idea to check the CRC to make sure you didn’t get garbage.
- Returns
the address of the next device on the bus, or ONEWIRE_NONE if there is no next address. ONEWIRE_NONE might also mean that the bus is shorted, there are no devices, or you have already retrieved all of them.
-
uint8_t onewire_crc8(const uint8_t *data, uint8_t len)¶
Compute a Dallas Semiconductor 8 bit CRC.
These are used in the ROM address and scratchpad registers to verify the transmitted data is correct.
-
bool onewire_check_crc16(const uint8_t *input, size_t len, const uint8_t *inverted_crc, uint16_t crc_iv)¶
Compute the 1-Wire CRC16 and compare it against the received CRC.
Example usage (reading a DS2408):
// Put everything in a buffer so we can compute the CRC easily. uint8_t buf[13]; buf[0] = 0xF0; // Read PIO Registers buf[1] = 0x88; // LSB address buf[2] = 0x00; // MSB address onewire_write_bytes(pin, buf, 3); // Write 3 cmd bytes onewire_read_bytes(pin, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 if (!onewire_check_crc16(buf, 11, &buf[11])) { // TODO: Handle error. }
- Parameters
input – Array of bytes to checksum.
len – Number of bytes in
input
inverted_crc – The two CRC16 bytes in the received data. This should just point into the received data, not at a 16-bit integer.
crc_iv – The crc starting value (optional)
- Returns
true
if the CRC matches,false
otherwise.
-
uint16_t onewire_crc16(const uint8_t *input, size_t len, uint16_t crc_iv)¶
Compute a Dallas Semiconductor 16 bit CRC.
This is required to check the integrity of data received from many 1-Wire devices. Note that the CRC computed here is not what you’ll get from the 1-Wire network, for two reasons:
The CRC is transmitted bitwise inverted.
Depending on the endian-ness of your processor, the binary representation of the two-byte return value may have a different byte order than the two bytes you get from 1-Wire.
- Parameters
input – Array of bytes to checksum.
len – How many bytes are in
input
.crc_iv – The crc starting value (optional)
- Returns
the CRC16, as defined by Dallas Semiconductor.
-
struct onewire_search_t¶
- #include <onewire.h>
Structure to contain the current state for onewire_search_next(), etc.
-
ONEWIRE_NONE¶