fbfea3b440
On CPython, and with pylint, the variables MATCH_ROM and SEARCH_ROM are undefined. This code works in MicroPython because these variables are constants and the MicroPython parser/compiler optimises them out. But it is not valid Python because they are technically undefined within the scope they are used. This commit makes the code valid Python code. The const part is removed completely because these constants are part of the public API and so cannot be moved to the global scope (where they could still use the MicroPython const optimisation).
93 lines
2.3 KiB
Python
93 lines
2.3 KiB
Python
# 1-Wire driver for MicroPython
|
|
# MIT license; Copyright (c) 2016 Damien P. George
|
|
|
|
import _onewire as _ow
|
|
|
|
|
|
class OneWireError(Exception):
|
|
pass
|
|
|
|
|
|
class OneWire:
|
|
SEARCH_ROM = 0xF0
|
|
MATCH_ROM = 0x55
|
|
SKIP_ROM = 0xCC
|
|
|
|
def __init__(self, pin):
|
|
self.pin = pin
|
|
self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP)
|
|
|
|
def reset(self, required=False):
|
|
reset = _ow.reset(self.pin)
|
|
if required and not reset:
|
|
raise OneWireError
|
|
return reset
|
|
|
|
def readbit(self):
|
|
return _ow.readbit(self.pin)
|
|
|
|
def readbyte(self):
|
|
return _ow.readbyte(self.pin)
|
|
|
|
def readinto(self, buf):
|
|
for i in range(len(buf)):
|
|
buf[i] = _ow.readbyte(self.pin)
|
|
|
|
def writebit(self, value):
|
|
return _ow.writebit(self.pin, value)
|
|
|
|
def writebyte(self, value):
|
|
return _ow.writebyte(self.pin, value)
|
|
|
|
def write(self, buf):
|
|
for b in buf:
|
|
_ow.writebyte(self.pin, b)
|
|
|
|
def select_rom(self, rom):
|
|
self.reset()
|
|
self.writebyte(self.MATCH_ROM)
|
|
self.write(rom)
|
|
|
|
def scan(self):
|
|
devices = []
|
|
diff = 65
|
|
rom = False
|
|
for i in range(0xFF):
|
|
rom, diff = self._search_rom(rom, diff)
|
|
if rom:
|
|
devices += [rom]
|
|
if diff == 0:
|
|
break
|
|
return devices
|
|
|
|
def _search_rom(self, l_rom, diff):
|
|
if not self.reset():
|
|
return None, 0
|
|
self.writebyte(self.SEARCH_ROM)
|
|
if not l_rom:
|
|
l_rom = bytearray(8)
|
|
rom = bytearray(8)
|
|
next_diff = 0
|
|
i = 64
|
|
for byte in range(8):
|
|
r_b = 0
|
|
for bit in range(8):
|
|
b = self.readbit()
|
|
if self.readbit():
|
|
if b: # there are no devices or there is an error on the bus
|
|
return None, 0
|
|
else:
|
|
if not b: # collision, two devices with different bit meaning
|
|
if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i):
|
|
b = 1
|
|
next_diff = i
|
|
self.writebit(b)
|
|
if b:
|
|
r_b |= 1 << bit
|
|
i -= 1
|
|
rom[byte] = r_b
|
|
return rom, next_diff
|
|
|
|
def crc8(self, data):
|
|
return _ow.crc8(data)
|