From 9d87c925a9eaa4fc256be3173c14a20d1469472d Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Wed, 9 Sep 2020 11:53:37 +0100 Subject: everything, mostly, working --- radiator-plc/stm32/app/1wire.c | 384 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 radiator-plc/stm32/app/1wire.c (limited to 'radiator-plc/stm32/app/1wire.c') diff --git a/radiator-plc/stm32/app/1wire.c b/radiator-plc/stm32/app/1wire.c new file mode 100644 index 0000000..dd66e92 --- /dev/null +++ b/radiator-plc/stm32/app/1wire.c @@ -0,0 +1,384 @@ +#include "project.h" + +#define GPIO_PORT GPIOB +#define GPIO GPIO1 + +#define BIT_ZERO '0' +#define BIT_ONE '1' +#define BIT_UNKNOWN 'U' +#define BIT_CONFLICT 'C' + + +static inline void +low (void) +{ + CLEAR (GPIO); +} + +static inline void +hiz (void) +{ + SET (GPIO); +} + +static inline int +get (void) +{ + return ! !GET (GPIO); +} + +/*Returns 1 if timeout - waits ~100ms */ +static inline int +wait_hiz (void) +{ + unsigned int timeout = 10000; + hiz(); + + while (!get()) { + timeout--; + + if (! (timeout--)) + return 1; + + delay_us (10); + } + + return 0; +} + + +/* returns 1 if nothing on bus or error */ +int +onewire_reset (void) +{ + int ret; + cm_disable_interrupts(); + low(); + delay_us (600); + hiz(); + delay_us (65); + ret = get(); + + if (wait_hiz()) + ret = 1; + + delay_us (100); + cm_enable_interrupts(); + return ret; +} + +void +onewire_one (void) +{ + cm_disable_interrupts(); + low(); + delay_us (10); + hiz(); + delay_us (90); + cm_enable_interrupts(); +} + +void +onewire_zero (void) +{ + cm_disable_interrupts(); + low(); + delay_us (90); + hiz(); + delay_us (10); + cm_enable_interrupts(); +} + +int +onewire_read (void) +{ + int ret; + cm_disable_interrupts(); + low(); + delay_us (10); + hiz(); + delay_us (20); + ret = get(); + delay_us (70); + cm_enable_interrupts(); + return ret; +} + + +void +onewire_write_byte (uint8_t v) +{ + int c; + + for (c = 0; c < 8; ++c) { + if (v & 1) + onewire_one(); + else + onewire_zero(); + + v >>= 1; + } +} + +uint8_t +onewire_read_byte (void) +{ + uint8_t v = 0; + int c; + + for (c = 0; c < 8; ++c) { + v >>= 1; + + if (onewire_read()) + v |= 0x80; + } + + + return v; +} + +void +onewire_read_bytes (uint8_t *buf, int n) +{ + while (n--) + * (buf++) = onewire_read_byte(); +} + + +void +onewire_write_bytes (const uint8_t *buf, int n) +{ + while (n--) + onewire_write_byte (* (buf++)); +} + + +int onewire_select (const Onewire_addr *a) +{ + if (!a) + onewire_write_byte (ONEWIRE_SKIP_ROM); + else { + onewire_write_byte (ONEWIRE_MATCH_ROM); + onewire_write_bytes (a->a, 8); + } + + return 0; +} + + +int onewire_reset_and_select (const Onewire_addr *a) +{ + if (onewire_reset()) + return 1; + + if (onewire_select (a)) + return 1; + + return 0; +} + + + +int onewire_wait_complete (unsigned timeout) +{ + while (! (onewire_read())) { + delay_ms (10); + + if (! (timeout--)) + return 1; + } + + return 0; +} + + + +int +onewire_check_crc (uint8_t *buf, int n, uint8_t v) +{ + uint8_t crc = 0; + int i; + + while (n--) { + uint8_t v = * (buf++); + + for (i = 0; i < 8; ++i) { + uint8_t mix = (crc ^ v) & 0x01; + crc >>= 1; + + if (mix) + crc ^= 0x8C; + + v >>= 1; + } + } + + return ! (crc == v); + +} + +static int onewire_conduct_search (uint8_t *bits) +{ + unsigned i, ir, r; + + if (onewire_reset()) + return -1; + + onewire_write_byte (ONEWIRE_SEARCH_ROM); + + + for (i = 0; i < 64; ++i) { + + r = onewire_read(); + ir = onewire_read(); + +#if 0 + + if ((i == 27) || (i == 24) || (i == 39)) + ir = r = 0; + +#endif + + switch (bits[i]) { + case BIT_UNKNOWN: + + if (!r && ir) { /* Zero */ + bits[i] = BIT_ZERO; + onewire_zero(); + } else if (r && !ir) { /*One */ + bits[i] = BIT_ONE; + onewire_one(); + } else if (r && ir) /*Nothing here */ + return -1; + + else if (!r && !ir) { /*Both */ + bits[i] = BIT_CONFLICT; + onewire_zero(); + } + + break; + + case BIT_CONFLICT: + if (!r && !ir) /*Both */ + onewire_zero(); + else + return -1; + + break; + + case BIT_ZERO: + if (!r) + onewire_zero(); + else + return -1; + + break; + + case BIT_ONE: + if (!ir) + onewire_one(); + else + return -1; + + break; + } + } + + return 0; +} + +static int onewire_next (uint8_t *bits) +{ + unsigned i; + + for (i = 0; i < 64; ++i) { + + if (bits[63 - i] == BIT_CONFLICT) { + bits[63 - i] = BIT_ONE; + return 1; + } + + bits[63 - i] = BIT_UNKNOWN; + } + + return 0; +} + +static void onewire_bits_to_a (uint8_t *bits, Onewire_addr *a) +{ + unsigned i, j, c; + + for (i = 0, j = 0; i < 8; ++i) { + + a->a[i] = 0; + + for (c = 1; c < 0x100; c <<= 1, ++j) { + if (bits[j] == BIT_ONE) + a->a[i] |= c; + } + } +} + +int onewire_search (void) +{ + uint8_t bits[64]; + Onewire_addr a; + int r, c; + + + printf ("One wire search\n"); + //delay_ms (2000); + + memset (bits, BIT_UNKNOWN, sizeof (bits)); + + do { + r = onewire_conduct_search (bits); + + if (!r) { + onewire_bits_to_a (bits, &a); + c = onewire_check_crc (&a.a[0], 7, a.a[7]); + + if (!c) { + printf ("O: {0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}\r\n", + a.a[0], + a.a[1], + a.a[2], + a.a[3], + a.a[4], + a.a[5], + a.a[6], + a.a[7]); + } + + } + + } while (onewire_next (bits)); + + + + + + + return 0; +} + + +void +onewire_init (void) +{ + MAP_OUTPUT_OD_SLOW (GPIO); + + hiz(); + delay_us (20); + printf ("hiz -> %d\n", get()); + + low(); + + delay_us (20); + printf ("low -> %d\n", get()); + + hiz(); + delay_us (20); + + +} -- cgit v1.2.3