#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); }