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