|
| 1 | +# 1-Wire driver for MicroPython |
| 2 | +# MIT license; Copyright (c) 2016 Damien P. George |
| 3 | + |
| 4 | +import _onewire as _ow |
| 5 | + |
| 6 | + |
| 7 | +class OneWireError(Exception): |
| 8 | + pass |
| 9 | + |
| 10 | + |
| 11 | +class OneWire: |
| 12 | + SEARCH_ROM = 0xF0 |
| 13 | + MATCH_ROM = 0x55 |
| 14 | + SKIP_ROM = 0xCC |
| 15 | + |
| 16 | + def __init__(self, pin): |
| 17 | + self.pin = pin |
| 18 | + self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP) |
| 19 | + |
| 20 | + def reset(self, required=False): |
| 21 | + reset = _ow.reset(self.pin) |
| 22 | + if required and not reset: |
| 23 | + raise OneWireError |
| 24 | + return reset |
| 25 | + |
| 26 | + def readbit(self): |
| 27 | + return _ow.readbit(self.pin) |
| 28 | + |
| 29 | + def readbyte(self): |
| 30 | + return _ow.readbyte(self.pin) |
| 31 | + |
| 32 | + def readinto(self, buf): |
| 33 | + for i in range(len(buf)): |
| 34 | + buf[i] = _ow.readbyte(self.pin) |
| 35 | + |
| 36 | + def writebit(self, value): |
| 37 | + return _ow.writebit(self.pin, value) |
| 38 | + |
| 39 | + def writebyte(self, value): |
| 40 | + return _ow.writebyte(self.pin, value) |
| 41 | + |
| 42 | + def write(self, buf): |
| 43 | + for b in buf: |
| 44 | + _ow.writebyte(self.pin, b) |
| 45 | + |
| 46 | + def select_rom(self, rom): |
| 47 | + self.reset() |
| 48 | + self.writebyte(self.MATCH_ROM) |
| 49 | + self.write(rom) |
| 50 | + |
| 51 | + def scan(self): |
| 52 | + devices = [] |
| 53 | + diff = 65 |
| 54 | + rom = False |
| 55 | + for i in range(0xFF): |
| 56 | + rom, diff = self._search_rom(rom, diff) |
| 57 | + if rom: |
| 58 | + devices += [rom] |
| 59 | + if diff == 0: |
| 60 | + break |
| 61 | + return devices |
| 62 | + |
| 63 | + def _search_rom(self, l_rom, diff): |
| 64 | + if not self.reset(): |
| 65 | + return None, 0 |
| 66 | + self.writebyte(self.SEARCH_ROM) |
| 67 | + if not l_rom: |
| 68 | + l_rom = bytearray(8) |
| 69 | + rom = bytearray(8) |
| 70 | + next_diff = 0 |
| 71 | + i = 64 |
| 72 | + for byte in range(8): |
| 73 | + r_b = 0 |
| 74 | + for bit in range(8): |
| 75 | + b = self.readbit() |
| 76 | + if self.readbit(): |
| 77 | + if b: # there are no devices or there is an error on the bus |
| 78 | + return None, 0 |
| 79 | + else: |
| 80 | + if not b: # collision, two devices with different bit meaning |
| 81 | + if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i): |
| 82 | + b = 1 |
| 83 | + next_diff = i |
| 84 | + self.writebit(b) |
| 85 | + if b: |
| 86 | + r_b |= 1 << bit |
| 87 | + i -= 1 |
| 88 | + rom[byte] = r_b |
| 89 | + return rom, next_diff |
| 90 | + |
| 91 | + def crc8(self, data): |
| 92 | + return _ow.crc8(data) |
0 commit comments