// // Created by MightyPork on 2018/02/01. // #include #include #include #include #include "ow_search.h" void ow_search_init(struct ow_search_state *state, uint8_t command) { state->prev_last_fork = 64; memset(&state->prev_code[0], 0, 8); state->status = OW_SEARCH_MORE; state->command = command; state->first = true; } uint16_t ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capacity) { if (state->status != OW_SEARCH_MORE) return 0; uint16_t found_devices = 0; while (found_devices < capacity) { uint8_t index = 0; ow_romcode_t code = {}; int8_t last_fork = -1; // Start a new transaction. Devices respond to reset if (!ow_reset()) { state->status = OW_SEARCH_FAILED; goto done; } // Send the search command (SEARCH_ROM, SEARCH_ALARM) ow_write_u8(state->command); bool p, n; while (index != 64) { // Read a bit and its complement p = ow_read_bit(); n = ow_read_bit(); if (!p && !n) { // A fork: there are devices on the bus with different bit value // (the bus is open-drain, in both cases one device pulls it low) if ((found_devices > 0 || !state->first) && index < state->prev_last_fork) { // earlier than the last fork, take the same turn as before p = ow_code_getbit(state->prev_code, index); if (!p) last_fork = index; // remember for future runs, 1 not explored yet } else if (index == state->prev_last_fork) { p = 1; // both forks are now exhausted } else { // a new fork last_fork = index; } } else if (p && n) { // No devices left connected - this doesn't normally happen state->status = OW_SEARCH_FAILED; goto done; } // All devices have a matching bit here, or it was resolved in a fork if (p) ow_code_setbit(code, index); ow_write_bit(p); index++; } // Record a found address for (int i = 0; i < 8; i++) { state->prev_code[i] = codes[found_devices][i] = code[i]; } found_devices++; // Stop condition if (last_fork == -1) { state->status = OW_SEARCH_DONE; goto done; } state->prev_last_fork = last_fork; } done: state->first = false; return found_devices; }