From 9d87c925a9eaa4fc256be3173c14a20d1469472d Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Wed, 9 Sep 2020 11:53:37 +0100 Subject: everything, mostly, working --- boiler-monster/stm32/app/1wire.c | 392 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 boiler-monster/stm32/app/1wire.c (limited to 'boiler-monster/stm32/app/1wire.c') diff --git a/boiler-monster/stm32/app/1wire.c b/boiler-monster/stm32/app/1wire.c new file mode 100644 index 0000000..c374c5c --- /dev/null +++ b/boiler-monster/stm32/app/1wire.c @@ -0,0 +1,392 @@ +#include "project.h" + +#define USART2_TX GPIO_USART2_TX +#define USART2_TX_PORT GPIOA + +#define BIT_ZERO '0' +#define BIT_ONE '1' +#define BIT_UNKNOWN 'U' +#define BIT_CONFLICT 'C' + + +static int poke; +static volatile unsigned exchange_timeout; + +void onewire_tick (void) +{ + static unsigned ticker; + + if (exchange_timeout) + exchange_timeout--; + + + ticker++; + + if (ticker < MS_TO_TICKS (5000)) + return; + + ticker = 0; + poke = 1; + + +} + + +static unsigned usart_send_ready (uint32_t usart) +{ + return (USART_SR (usart) & USART_SR_TXE); +} + + +static unsigned usart_recv_ready (uint32_t usart) +{ + return (USART_SR (usart) & USART_SR_RXNE); +} + + + +static int onewire_exchange (int tx, unsigned timeout) +{ + int rx; + (void) USART_SR (USART2); + (void) usart_recv (USART2); + + + exchange_timeout = MS_TO_TICKS (timeout); + + while (!usart_send_ready (USART2)) + if (!exchange_timeout) + return -1; + + usart_send (USART2, tx); + + exchange_timeout = MS_TO_TICKS (timeout); + + while (!usart_recv_ready (USART2)) + if (!exchange_timeout) + return -1; + + + rx = usart_recv (USART2); + + return rx; + +} + +/* returns 1 if nothing on bus or error */ +int +onewire_reset (void) +{ + int ret; + + usart_set_baudrate (USART2, 9600); + delay_ms (1); + ret = onewire_exchange (0xf0, 60); + usart_set_baudrate (USART2, 115200); + delay_ms (1); + + return (ret == 0xf0); +} + +static void +onewire_one (void) +{ + onewire_exchange (0xff, 3); +} + +static void +onewire_zero (void) +{ + onewire_exchange (0x00, 3); +} + +static int +onewire_read (void) +{ + uint8_t rx; + + rx = onewire_exchange (0xff, 3); + + return (rx == 0xff); +} + + +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 */ + //MEH; + return -1; + } else if (!r && !ir) { /*Both */ + bits[i] = BIT_CONFLICT; + onewire_zero(); + } + + break; + + case BIT_CONFLICT: + if (!r && !ir) /*Both */ + onewire_zero(); + else { + //MEH; + return -1; + } + + break; + + case BIT_ZERO: + if (!r) + onewire_zero(); + else { + //MEH; + return -1; + } + + break; + + case BIT_ONE: + if (!ir) + onewire_one(); + else { + //MEH; + 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; + + 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 ("QO: {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_AF_OD (USART2_TX); + + usart_set_baudrate (USART2, 115200); + usart_set_databits (USART2, 8); + usart_set_stopbits (USART2, USART_STOPBITS_1); + usart_set_parity (USART2, USART_PARITY_NONE); + usart_set_flow_control (USART2, USART_FLOWCONTROL_NONE); + usart_set_mode (USART2, USART_MODE_TX_RX); + + USART_CR3 (USART2) |= USART_CR3_HDSEL; + + usart_enable (USART2); +} -- cgit v1.2.3