Skip to content

File syn_soft_onewire.h

FileList > drivers > syn_soft_onewire.h

Go to the source code of this file

Software bit-bang 1-Wire master driver. More...

  • #include "../common/syn_defs.h"
  • #include "../port/syn_port_gpio.h"
  • #include <stdbool.h>
  • #include <stdint.h>

Classes

Type Name
struct SYN_SoftOneWire
1-Wire bus handle. Caller allocates; zero heap.

Public Functions

Type Name
void syn_soft_onewire_init (SYN_SoftOneWire * ow, SYN_GPIO_Pin pin, uint32_t delay_loops)
Initialize a 1-Wire bus instance.
uint8_t syn_soft_onewire_read_byte (const SYN_SoftOneWire * ow)
Read one byte LSB-first from the 1-Wire bus.
void syn_soft_onewire_read_rom (const SYN_SoftOneWire * ow, uint8_t rom)
Read an 8-byte ROM code from the bus (after READ ROM command).
bool syn_soft_onewire_reset (const SYN_SoftOneWire * ow)
Issue a 1-Wire reset pulse and detect device presence.
void syn_soft_onewire_write_byte (const SYN_SoftOneWire * ow, uint8_t byte)
Write one byte LSB-first onto the 1-Wire bus.
void syn_soft_onewire_write_rom (const SYN_SoftOneWire * ow, const uint8_t rom)
Write an 8-byte ROM code to the bus (for MATCH ROM command).

Macros

Type Name
define SYN_SOFT_ONEWIRE_LOOPS_PER_US (freq_hz) ((uint32\_t)(((uint32\_t)(freq\_hz)) / 4000000UL))
Compute the delay_loops value for a given CPU frequency.

Detailed Description

Implements the Dallas/Maxim 1-Wire protocol on any GPIO pin. Timing is controlled by a caller-provided loop count (delay_loops), analogous to syn_soft_i2c.h — calibrate for your CPU frequency.

Supports standard-speed 1-Wire (15.4 kbps). No parasitic-power or overdrive mode.

Typical use (DS18B20 temperature sensor, protothread-safe):

// In a protothread — conversion wait is a yield point, not a busy-wait.
static uint32_t ow_start_ms;
SYN_SoftOneWire ow;

// --- Phase 1: start conversion ---
syn_soft_onewire_init(&ow, PIN_OW_DATA,
                     SYN_SOFT_ONEWIRE_LOOPS_PER_US(F_CPU));
if (syn_soft_onewire_reset(&ow)) {           // ~960 µs busy
    syn_soft_onewire_write_byte(&ow, 0xCC);  // SKIP ROM   (~560 µs)
    syn_soft_onewire_write_byte(&ow, 0x44);  // CONVERT T  (~560 µs)
    ow_start_ms = syn_port_get_tick_ms();
}

// --- Phase 2: yield until conversion done (~750 ms) ---
PT_WAIT_UNTIL(pt, syn_port_get_tick_ms() - ow_start_ms >= 750u);

// --- Phase 3: read result ---
if (syn_soft_onewire_reset(&ow)) {
    syn_soft_onewire_write_byte(&ow, 0xCC);  // SKIP ROM
    syn_soft_onewire_write_byte(&ow, 0xBE);  // READ SCRATCHPAD
    uint8_t lsb = syn_soft_onewire_read_byte(&ow);
    uint8_t msb = syn_soft_onewire_read_byte(&ow);
}
// DO NOT use syn_port_delay_ms(750) — that blocks the entire scheduler.

Note:

Each byte write/read blocks the CPU for ~560 µs (8 × 70 µs slots). Each reset() blocks for ~960 µs. Hardware PWM and timer ISRs continue to fire normally during these windows. Do not call these functions from a tight control loop that must execute faster than ~2 ms/cycle.

Public Functions Documentation

function syn_soft_onewire_init

Initialize a 1-Wire bus instance.

void syn_soft_onewire_init (
    SYN_SoftOneWire * ow,
    SYN_GPIO_Pin pin,
    uint32_t delay_loops
) 

Parameters:


function syn_soft_onewire_read_byte

Read one byte LSB-first from the 1-Wire bus.

uint8_t syn_soft_onewire_read_byte (
    const SYN_SoftOneWire * ow
) 

Parameters:

  • ow Initialized bus handle.

Returns:

Byte received.


function syn_soft_onewire_read_rom

Read an 8-byte ROM code from the bus (after READ ROM command).

void syn_soft_onewire_read_rom (
    const SYN_SoftOneWire * ow,
    uint8_t rom
) 

Parameters:

  • ow Initialized bus handle.
  • rom Output buffer, must be at least 8 bytes.

function syn_soft_onewire_reset

Issue a 1-Wire reset pulse and detect device presence.

bool syn_soft_onewire_reset (
    const SYN_SoftOneWire * ow
) 

Parameters:

  • ow Initialized bus handle.

Returns:

true if at least one device acknowledged (presence pulse detected), false if the bus is empty.


function syn_soft_onewire_write_byte

Write one byte LSB-first onto the 1-Wire bus.

void syn_soft_onewire_write_byte (
    const SYN_SoftOneWire * ow,
    uint8_t byte
) 

Parameters:

  • ow Initialized bus handle.
  • byte Byte to transmit.

function syn_soft_onewire_write_rom

Write an 8-byte ROM code to the bus (for MATCH ROM command).

void syn_soft_onewire_write_rom (
    const SYN_SoftOneWire * ow,
    const uint8_t rom
) 

Parameters:

  • ow Initialized bus handle.
  • rom 8-byte ROM code, LSB first.

Macro Definition Documentation

define SYN_SOFT_ONEWIRE_LOOPS_PER_US

Compute the delay_loops value for a given CPU frequency.

#define SYN_SOFT_ONEWIRE_LOOPS_PER_US (
    freq_hz
) `((uint32_t)(((uint32_t)(freq_hz)) / 4000000UL))`

The NOP loop body compiles to approximately 4 clock cycles on most architectures (load, decrement, compare, branch-not-taken). Dividing the CPU frequency by 4 gives loops per second; dividing again by 1 000 000 gives loops per microsecond.

Use this macro when initialising the bus:

syn_soft_onewire_init(&ow, PIN_OW_DATA,
                      SYN_SOFT_ONEWIRE_LOOPS_PER_US(F_CPU));

Or with an explicit frequency:

// 16 MHz Arduino Uno
syn_soft_onewire_init(&ow, PIN_OW_DATA,
                      SYN_SOFT_ONEWIRE_LOOPS_PER_US(16000000UL));
// 8 MHz AVR / STM32 at 8 MHz
syn_soft_onewire_init(&ow, PIN_OW_DATA,
                      SYN_SOFT_ONEWIRE_LOOPS_PER_US(8000000UL));

Parameters:

  • freq_hz CPU frequency in Hz (e.g. F_CPU, 16000000UL).

Note:

The divisor (4) is a conservative estimate for an optimised build. If timing measurements show pulses running consistently long or short, tune by replacing 4 with the actual loop-body cycle count from the generated disassembly.



The documentation for this class was generated from the following file src/syntropic/drivers/syn_soft_onewire.h