void search(onewire_t *ow, uint8_t *id, int depth, int reset) { int i, b1, b2; if (depth == 64) { // we have all 64 bit in this search branch printf("found: "); for (i = 0; i < 8; i++) printf("%02x", id[i]); printf("\n"); return; } if (reset) { if (onewire_reset(ow) != 0) { printf("reset failed\n"); return; } onewire_write_byte(ow, 0xF0); // search ROM command // send currently recognized bits for (i = 0; i < depth; i++) { b1 = onewire_read_bit(ow); b2 = onewire_read_bit(ow); onewire_write_bit(ow, id[i / 8] & (1 << (i % 8))); } } // check another bit b1 = onewire_read_bit(ow); b2 = onewire_read_bit(ow); if (b1 && b2) return; // no response to search if (!b1 && !b2) // two devices with different bits on this position { // check devices with this bit = 0 onewire_write_bit(ow, 0); id[depth / 8] &= ~(1 << (depth % 8)); search(ow, id, depth + 1, 0); // check devices with this bit = 1 id[depth / 8] |= 1 << (depth % 8); search(ow, id, depth + 1, 1); // different branch, reset must be issued } else if (b1) { // devices have 1 on this position onewire_write_bit(ow, 1); id[depth / 8] |= 1 << (depth % 8); search(ow, id, depth + 1, 0); } else if (b2) { // devices have 0 on this position onewire_write_bit(ow, 0); id[depth / 8] &= ~(1 << (depth % 8)); search(ow, id, depth + 1, 0); } }
// // Write a byte. The writing code uses the active drivers to raise the // pin high, if you need power after the write (e.g. DS18S20 in // parasite power mode) then set 'power' to 1, otherwise the pin will // go tri-state at the end of the write to avoid heating in a short or // other mishap. // void ICACHE_FLASH_ATTR onewire_write(uint8 v, uint32 power) { uint8 bitMask; for (bitMask = 0x01; bitMask; bitMask <<= 1) { onewire_write_bit((bitMask & v) ? 1 : 0); } if (power) { GPIO_OUTPUT_SET(ONEWIRE_PIN, 1); } }
void onewire_write_byte(onewire_t *ow, uint8_t byte) { int i; for(i = 0; i < 8; i++) { onewire_write_bit(ow, byte & 1); byte >>= 1; } }
/* pass array of 8 bytes in */ uint32 ICACHE_FLASH_ATTR onewire_search(struct onewire_search_state *state) { // If last search returned the last device (no conflicts). if (state->lastDeviceFlag) { init_search_state(state); return FALSE; } // 1-Wire reset if (!onewire_reset()) { // Reset the search and return fault code. init_search_state(state); return ONEWIRE_SEARCH_NO_DEVICES; } // issue the search command onewire_write(ONEWIRE_SEARCH_ROM, 0); uint8 search_direction; int32 last_zero = -1; // Loop through all 8 bytes = 64 bits int32 id_bit_index; for (id_bit_index = 0; id_bit_index < 8 * ROM_BYTES; id_bit_index++) { const uint32 rom_byte_number = id_bit_index / BITS_PER_BYTE; const uint32 rom_byte_mask = 1 << (id_bit_index % BITS_PER_BYTE); // Read a bit and its complement const uint32 id_bit = onewire_read_bit(); const uint32 cmp_id_bit = onewire_read_bit(); // Line high for both reads means there are no slaves on the 1wire bus. if (id_bit == 1 && cmp_id_bit == 1) { // Reset the search and return fault code. init_search_state(state); return ONEWIRE_SEARCH_NO_DEVICES; } // No conflict for current bit: all devices coupled have 0 or 1 if (id_bit != cmp_id_bit) { // Obviously, we continue the search using the same bit as all the devices have. search_direction = id_bit; } else { // if this discrepancy is before the Last Discrepancy // on a previous next then pick the same as last time if (id_bit_index < state->lastDiscrepancy) { search_direction = ((state->address[rom_byte_number] & rom_byte_mask) > 0); } else { // if equal to last pick 1, if not then pick 0 search_direction = (id_bit_index == state->lastDiscrepancy); } // if 0 was picked then record its position in LastZero if (search_direction == 0) { last_zero = id_bit_index; } } // set or clear the bit in the ROM byte rom_byte_number with mask rom_byte_mask if (search_direction == 1) { state->address[rom_byte_number] |= rom_byte_mask; } else { state->address[rom_byte_number] &= ~rom_byte_mask; } // For the current bit position, write the bit we choose to use in the current search. // Any devices that don't match are disabled. onewire_write_bit(search_direction); } state->lastDiscrepancy = last_zero; // check for last device if (state->lastDiscrepancy == -1) { state->lastDeviceFlag = TRUE; } if (crc8(state->address, 7) != state->address[7]) { // Reset the search and return fault code. init_search_state(state); return ONEWIRE_SEARCH_CRC_INVALID; } return ONEWIRE_SEARCH_FOUND; }