File syn_soft_onewire.c¶
File List > drivers > syn_soft_onewire.c
Go to the documentation of this file
#if __has_include("syn_config.h")
#include "syn_config.h"
#endif
#if !defined(SYN_USE_ONEWIRE) || SYN_USE_ONEWIRE
#include "../util/syn_assert.h"
#include "syn_soft_onewire.h"
static void ow_delay(const SYN_SoftOneWire *ow, uint32_t us)
{
if (ow == NULL)
return;
volatile uint32_t cnt = us * ow->delay_loops;
while (cnt--) {
/* NOP */
}
}
static void ow_drive_low(const SYN_SoftOneWire *ow)
{
if (ow == NULL)
return;
syn_port_gpio_write(ow->pin, 0u);
}
static void ow_release(const SYN_SoftOneWire *ow)
{
if (ow == NULL)
return;
syn_port_gpio_write(ow->pin, 1u);
}
static void ow_write_bit(const SYN_SoftOneWire *ow, uint8_t bit)
{
if (bit != 0u) {
/* Write-1: 6 µs low, 64 µs high */
ow_drive_low(ow);
ow_delay(ow, 6u);
ow_release(ow);
ow_delay(ow, 64u);
} else {
/* Write-0: 60 µs low, 10 µs recovery */
ow_drive_low(ow);
ow_delay(ow, 60u);
ow_release(ow);
ow_delay(ow, 10u);
}
}
static uint8_t ow_read_bit(const SYN_SoftOneWire *ow)
{
/* Initiate read: 6 µs drive low */
ow_drive_low(ow);
ow_delay(ow, 6u);
ow_release(ow);
/* Sample window: ~9 µs after release */
ow_delay(ow, 9u);
uint8_t bit = (uint8_t)(syn_port_gpio_read(ow->pin) != 0 ? 1u : 0u);
/* Recovery: remainder of 70 µs slot */
ow_delay(ow, 55u);
return bit;
}
void syn_soft_onewire_init(SYN_SoftOneWire *ow, SYN_GPIO_Pin pin, uint32_t delay_loops)
{
SYN_ASSERT(ow != NULL);
ow->pin = pin;
ow->delay_loops = delay_loops;
/* Configure as output, drive high (open-drain idle state) */
syn_port_gpio_init(pin, SYN_GPIO_OUTPUT);
syn_port_gpio_write(pin, 1u);
}
bool syn_soft_onewire_reset(const SYN_SoftOneWire *ow)
{
SYN_ASSERT(ow != NULL);
/* Drive low ≥ 480 µs */
ow_drive_low(ow);
ow_delay(ow, 480u);
/* Release and wait 70 µs, then sample for presence pulse */
ow_release(ow);
ow_delay(ow, 70u);
uint8_t present = (uint8_t)(syn_port_gpio_read(ow->pin) == 0 ? 1u : 0u);
/* Wait out remainder of reset sequence */
ow_delay(ow, 410u);
return (present != 0u);
}
void syn_soft_onewire_write_byte(const SYN_SoftOneWire *ow, uint8_t byte)
{
SYN_ASSERT(ow != NULL);
uint8_t i;
for (i = 0u; i < 8u; i++) {
ow_write_bit(ow, byte & 0x01u);
byte >>= 1u;
}
}
uint8_t syn_soft_onewire_read_byte(const SYN_SoftOneWire *ow)
{
SYN_ASSERT(ow != NULL);
uint8_t byte = 0u;
uint8_t i;
for (i = 0u; i < 8u; i++) {
if (ow_read_bit(ow) != 0u) {
byte |= (uint8_t)(1u << i);
}
}
return byte;
}
void syn_soft_onewire_write_rom(const SYN_SoftOneWire *ow, const uint8_t rom[8])
{
SYN_ASSERT(ow != NULL);
SYN_ASSERT(rom != NULL);
uint8_t i;
for (i = 0u; i < 8u; i++) {
syn_soft_onewire_write_byte(ow, rom[i]);
}
}
void syn_soft_onewire_read_rom(const SYN_SoftOneWire *ow, uint8_t rom[8])
{
SYN_ASSERT(ow != NULL);
SYN_ASSERT(rom != NULL);
uint8_t i;
for (i = 0u; i < 8u; i++) {
rom[i] = syn_soft_onewire_read_byte(ow);
}
}
#endif /* SYN_USE_ONEWIRE */