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