blob: dd8c274fcf91b0521247a86d83baf83660b6d5e0 [file] [log] [blame]
Damien Georgea065d782017-06-22 16:28:07 +10001# 1-Wire driver for MicroPython
2# MIT license; Copyright (c) 2016 Damien P. George
Damien George9be0d592015-03-03 01:29:52 +00003
Damien Georgea065d782017-06-22 16:28:07 +10004from micropython import const
5import _onewire as _ow
Damien George9be0d592015-03-03 01:29:52 +00006
Damien George69661f32020-02-27 15:36:53 +11007
Damien Georgea065d782017-06-22 16:28:07 +10008class OneWireError(Exception):
9 pass
Damien George9be0d592015-03-03 01:29:52 +000010
Damien George69661f32020-02-27 15:36:53 +110011
Damien George9be0d592015-03-03 01:29:52 +000012class OneWire:
Damien George69661f32020-02-27 15:36:53 +110013 SEARCH_ROM = const(0xF0)
Damien Georgea065d782017-06-22 16:28:07 +100014 MATCH_ROM = const(0x55)
Damien George69661f32020-02-27 15:36:53 +110015 SKIP_ROM = const(0xCC)
Damien Georgea065d782017-06-22 16:28:07 +100016
Damien George9be0d592015-03-03 01:29:52 +000017 def __init__(self, pin):
Damien Georgea065d782017-06-22 16:28:07 +100018 self.pin = pin
Damien George683df1c2017-06-26 17:48:05 +100019 self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP)
Damien George9be0d592015-03-03 01:29:52 +000020
Damien Georgea065d782017-06-22 16:28:07 +100021 def reset(self, required=False):
22 reset = _ow.reset(self.pin)
23 if required and not reset:
24 raise OneWireError
25 return reset
Damien George9be0d592015-03-03 01:29:52 +000026
Damien Georgea065d782017-06-22 16:28:07 +100027 def readbit(self):
28 return _ow.readbit(self.pin)
Damien George9be0d592015-03-03 01:29:52 +000029
Damien Georgea065d782017-06-22 16:28:07 +100030 def readbyte(self):
31 return _ow.readbyte(self.pin)
Damien George9be0d592015-03-03 01:29:52 +000032
Damien Georgea065d782017-06-22 16:28:07 +100033 def readinto(self, buf):
34 for i in range(len(buf)):
35 buf[i] = _ow.readbyte(self.pin)
Damien George9be0d592015-03-03 01:29:52 +000036
Damien Georgea065d782017-06-22 16:28:07 +100037 def writebit(self, value):
38 return _ow.writebit(self.pin, value)
Damien George9be0d592015-03-03 01:29:52 +000039
Damien Georgea065d782017-06-22 16:28:07 +100040 def writebyte(self, value):
41 return _ow.writebyte(self.pin, value)
Damien George9be0d592015-03-03 01:29:52 +000042
Damien Georgea065d782017-06-22 16:28:07 +100043 def write(self, buf):
44 for b in buf:
45 _ow.writebyte(self.pin, b)
Damien George9be0d592015-03-03 01:29:52 +000046
47 def select_rom(self, rom):
Damien George9be0d592015-03-03 01:29:52 +000048 self.reset()
Damien Georgea065d782017-06-22 16:28:07 +100049 self.writebyte(MATCH_ROM)
50 self.write(rom)
Damien George9be0d592015-03-03 01:29:52 +000051
52 def scan(self):
Damien George9be0d592015-03-03 01:29:52 +000053 devices = []
Damien Georgea065d782017-06-22 16:28:07 +100054 diff = 65
55 rom = False
Damien George69661f32020-02-27 15:36:53 +110056 for i in range(0xFF):
Damien Georgea065d782017-06-22 16:28:07 +100057 rom, diff = self._search_rom(rom, diff)
58 if rom:
59 devices += [rom]
60 if diff == 0:
61 break
62 return devices
Damien George9be0d592015-03-03 01:29:52 +000063
Damien Georgea065d782017-06-22 16:28:07 +100064 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 George69661f32020-02-27 15:36:53 +110078 if b: # there are no devices or there is an error on the bus
Damien Georgea065d782017-06-22 16:28:07 +100079 return None, 0
Damien George9be0d592015-03-03 01:29:52 +000080 else:
Damien George69661f32020-02-27 15:36:53 +110081 if not b: # collision, two devices with different bit meaning
Damien Georgea065d782017-06-22 16:28:07 +100082 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 George9be0d592015-03-03 01:29:52 +000091
Damien Georgea065d782017-06-22 16:28:07 +100092 def crc8(self, data):
93 return _ow.crc8(data)