From ecf5d5460b4c0c8da99a4561011bc23cd5413e4d Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 16 Mar 2021 13:08:00 -0500 Subject: [PATCH 01/12] Fix LUT --- adafruit_emc2101.py | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/adafruit_emc2101.py b/adafruit_emc2101.py index 3ed3002..1dcbfa1 100644 --- a/adafruit_emc2101.py +++ b/adafruit_emc2101.py @@ -102,27 +102,6 @@ class FanSpeedLUT: _fan_lut_t8 = UnaryStruct(0x5E, " Date: Sun, 14 Mar 2021 12:43:48 -0500 Subject: [PATCH 02/12] Split file for low mem like samd21, and slightly improve LUT code --- .../__init__.py | 190 -------------- adafruit_emc2101/emc2101_lut.py | 238 ++++++++++++++++++ examples/emc2101_lut_example.py | 4 +- examples/set_pwm_freq.py | 4 +- 4 files changed, 242 insertions(+), 194 deletions(-) rename adafruit_emc2101.py => adafruit_emc2101/__init__.py (57%) create mode 100644 adafruit_emc2101/emc2101_lut.py diff --git a/adafruit_emc2101.py b/adafruit_emc2101/__init__.py similarity index 57% rename from adafruit_emc2101.py rename to adafruit_emc2101/__init__.py index 1dcbfa1..24df5ec 100644 --- a/adafruit_emc2101.py +++ b/adafruit_emc2101/__init__.py @@ -39,7 +39,6 @@ _EXTERNAL_TEMP_MSB = const(0x01) _EXTERNAL_TEMP_LSB = const(0x10) -_STATUS = const(0x02) _REG_CONFIG = const(0x03) _TEMP_FORCE = const(0x0C) _TACH_LSB = const(0x46) @@ -49,11 +48,7 @@ _FAN_CONFIG = const(0x4A) _FAN_SPINUP = const(0x4B) _REG_FAN_SETTING = const(0x4C) -_PWM_FREQ = const(0x4D) -_PWM_DIV = const(0x4E) -_LUT_HYSTERESIS = const(0x4F) -_TEMP_FILTER = const(0xBF) _REG_PARTID = const(0xFD) # 0x16 _REG_MFGID = const(0xFE) # 0xFF16 @@ -62,120 +57,6 @@ _I2C_ADDR = const(0x4C) _FAN_RPM_DIVISOR = const(5400000) -_TEMP_LSB = 0.125 - - -def _speed_to_lsb(percentage): - return round((percentage / 100.0) * MAX_LUT_SPEED) - - -def _lsb_to_speed(lsb_speed): - return round((lsb_speed / MAX_LUT_SPEED) * 100.0) - - -class FanSpeedLUT: - """A class used to provide a dict-like interface to the EMC2101's Temperature to Fan speed - Look Up Table""" - - # seems like a pain but ¯\_(ツ)_/¯ - _fan_lut_t1 = UnaryStruct(0x50, "" % id(self) - - def __str__(self): - """return the official string representation of the LUT""" - value_strs = [] - lut_keys = list(self.lut_values.keys()) - lut_keys.sort() - for temp in lut_keys: - fan_drive = self.lut_values[temp] - value_strs.append("%d deg C => %.1f%% duty cycle" % (temp, fan_drive)) - - return "\n".join(value_strs) - - def __len__(self): - return len(self.lut_values) - - # this function does a whole lot of work to organized the user-supplied lut dict into - # their correct spot within the lut table as pairs of set registers, sorted with the lowest - # temperature first - - def _set_lut(self, lut_dict): - lut_keys = list(lut_dict.keys()) - lut_size = len(lut_dict) - # Make sure we're not going to try to set more entries than we have slots - if lut_size > 8: - raise AttributeError("LUT can only contain a maximum of 8 items") - - # we want to assign the lowest temperature to the lowest LUT slot, so we sort the keys/temps - for k in lut_keys: - # Verify that the value is a correct amount - lut_value = lut_dict[k] - if lut_value > 100.0 or lut_value < 0: - raise AttributeError("LUT values must be a fan speed from 0-100%") - - # add the current temp/speed to our internal representation - self.lut_values[k] = lut_value - current_mode = self.emc_fan.lut_enabled - - # Disable the lut to allow it to be updated - self.emc_fan.lut_enabled = False - - # get and sort the new lut keys so that we can assign them in order - lut_keys = list(self.lut_values.keys()) - lut_keys.sort() - for idx, current_temp in enumerate(sorted(self.lut_values.keys())): - current_speed = _speed_to_lsb(self.lut_values[current_temp]) - setattr(self, "_fan_lut_t%d" % (idx + 1), current_temp) - setattr(self, "_fan_lut_s%d" % (idx + 1), current_speed) - - # Set the remaining LUT entries to the default (Temp/Speed = max value) - for idx in range(8)[len(self.lut_values) :]: - setattr(self, "_fan_lut_t%d" % (idx + 1), MAX_LUT_TEMP) - setattr(self, "_fan_lut_s%d" % (idx + 1), MAX_LUT_SPEED) - self.emc_fan.lut_enabled = current_mode class CV: @@ -285,11 +166,6 @@ class EMC2101: # pylint: disable=too-many-instance-attributes """When set to True, the magnitude of the fan output signal is inverted, making 0 the maximum value and 100 the minimum value""" - _fan_pwm_clock_select = RWBit(_FAN_CONFIG, 3) - _fan_pwm_clock_override = RWBit(_FAN_CONFIG, 2) - _pwm_freq = RWBits(5, _PWM_FREQ, 0) - _pwm_freq_div = UnaryStruct(_PWM_DIV, " 0x1F: - raise AttributeError("pwm_frequency must be from 0-31") - self._pwm_freq = value - - @property - def pwm_frequency_divisor(self): - """The Divisor applied to the PWM frequency to set the final frequency""" - return self._pwm_freq_div - - @pwm_frequency_divisor.setter - def pwm_frequency_divisor(self, divisor): - if divisor < 0 or divisor > 255: - raise AttributeError("pwm_frequency_divisor must be from 0-255") - self._pwm_freq_div = divisor - @property def fan_speed(self): """The current speed in Revolutions per Minute (RPM)""" @@ -422,15 +241,6 @@ def lut_enabled(self): to a fan speed. When the LUT is disabled fan speed can be changed with `manual_fan_speed`""" return not self._fan_lut_prog - @lut_enabled.setter - def lut_enabled(self, enable_lut): - self._fan_lut_prog = not enable_lut - - @property - def lut(self): - """The dict-like representation of the LUT""" - return self._lut - @property def tach_limit(self): """The maximum /minimum speed expected for the fan""" diff --git a/adafruit_emc2101/emc2101_lut.py b/adafruit_emc2101/emc2101_lut.py new file mode 100644 index 0000000..4a818d8 --- /dev/null +++ b/adafruit_emc2101/emc2101_lut.py @@ -0,0 +1,238 @@ +# SPDX-FileCopyrightText: Copyright (c) 2020 Bryan Siepert for Adafruit Industries +# +# SPDX-License-Identifier: MIT +""" +`adafruit_emc2101.emc2101_lut` +================================================================================ + +Brushless fan controller: extended functionality + + +* Author(s): Bryan Siepert + +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit EMC2101 Breakout `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://github.com/adafruit/circuitpython/releases + +# * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice +# * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register + +The class defined here may be used instead of adafruit_emc2101.EMC2101, +if your device has enough RAM to support it. This class adds LUT control +and PWM frequency control to the base feature set. +""" + +from micropython import const +from adafruit_register.i2c_struct import UnaryStruct +from adafruit_register.i2c_bit import RWBit +from adafruit_register.i2c_bits import RWBits +from . import EMC2101 + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_EMC2101.git" + +_FAN_CONFIG = const(0x4A) +_PWM_FREQ = const(0x4D) +_PWM_DIV = const(0x4E) +_LUT_HYSTERESIS = const(0x4F) + +MAX_LUT_SPEED = 0x3F # 6-bit value +MAX_LUT_TEMP = 0x7F # 7-bit + + +def _speed_to_lsb(percentage): + return round((percentage / 100.0) * MAX_LUT_SPEED) + + +class FanSpeedLUT: + """A class used to provide a dict-like interface to the EMC2101's Temperature to Fan speed + Look Up Table""" + + # seems like a pain but ¯\_(ツ)_/¯ + _fan_lut_t1 = UnaryStruct(0x50, " 100.0 or value < 0: + raise AttributeError("LUT values must be a fan speed from 0-100%") + self.lut_values[index] = value + self._update_lut() + + def __repr__(self): + """return the official string representation of the LUT""" + return "FanSpeedLUT <%x>" % id(self) + + def __str__(self): + """return the official string representation of the LUT""" + value_strs = [] + lut_keys = list(sorted(self.lut_values.keys())) + for temp in lut_keys: + fan_drive = self.lut_values[temp] + value_strs.append("%d deg C => %.1f%% duty cycle" % (temp, fan_drive)) + + return "\n".join(value_strs) + + def __len__(self): + return len(self.lut_values) + + # this function does a whole lot of work to organized the user-supplied lut dict into + # their correct spot within the lut table as pairs of set registers, sorted with the lowest + # temperature first + + def _update_lut(self): + # Make sure we're not going to try to set more entries than we have slots + if len(self.lut_values) > 8: + raise AttributeError("LUT can only contain a maximum of 8 items") + + # Backup state + current_mode = self.emc_fan.lut_enabled + + # Disable the lut to allow it to be updated + self.emc_fan.lut_enabled = False + + # we want to assign the lowest temperature to the lowest LUT slot, so we sort the keys/temps + # get and sort the new lut keys so that we can assign them in order + for idx, current_temp in enumerate(sorted(self.lut_values.keys())): + current_speed = _speed_to_lsb(self.lut_values[current_temp]) + setattr(self, "_fan_lut_t%d" % (idx + 1), current_temp) + setattr(self, "_fan_lut_s%d" % (idx + 1), current_speed) + + # Set the remaining LUT entries to the default (Temp/Speed = max value) + for idx in range(8)[len(self.lut_values) :]: + setattr(self, "_fan_lut_t%d" % (idx + 1), MAX_LUT_TEMP) + setattr(self, "_fan_lut_s%d" % (idx + 1), MAX_LUT_SPEED) + self.emc_fan.lut_enabled = current_mode + + +class EMC2101_LUT(EMC2101): # pylint: disable=too-many-instance-attributes + """Driver for the EMC2101 Fan Controller. + :param ~busio.I2C i2c_bus: The I2C bus the EMC is connected to. + """ + + _fan_pwm_clock_select = RWBit(_FAN_CONFIG, 3) + _fan_pwm_clock_override = RWBit(_FAN_CONFIG, 2) + _pwm_freq = RWBits(5, _PWM_FREQ, 0) + _pwm_freq_div = UnaryStruct(_PWM_DIV, " 0x1F: + raise AttributeError("pwm_frequency must be from 0-31") + self._pwm_freq_div = value + + @property + def pwm_frequency_divisor(self): + """The Divisor applied to the PWM frequency to set the final frequency""" + return self._pwm_freq_div + + @pwm_frequency_divisor.setter + def pwm_frequency_divisor(self, divisor): + if divisor < 0 or divisor > 255: + raise AttributeError("pwm_frequency_divisor must be from 0-255") + self._pwm_freq_div = divisor + + @property + def lut_enabled(self): + """Enable or disable the internal look up table used to map a given temperature + to a fan speed. When the LUT is disabled fan speed can be changed with `manual_fan_speed`""" + return not self._fan_lut_prog + + @lut_enabled.setter + def lut_enabled(self, enable_lut): + self._fan_lut_prog = not enable_lut + + @property + def lut(self): + """The dict-like representation of the LUT""" + return self._lut diff --git a/examples/emc2101_lut_example.py b/examples/emc2101_lut_example.py index a68f703..3322105 100644 --- a/examples/emc2101_lut_example.py +++ b/examples/emc2101_lut_example.py @@ -4,12 +4,12 @@ import time import board import busio -from adafruit_emc2101 import EMC2101 +from adafruit_emc2101.emc2101_lut import EMC2101_LUT i2c = busio.I2C(board.SCL, board.SDA) FAN_MAX_RPM = 1700 -emc = EMC2101(i2c) +emc = EMC2101_LUT(i2c) emc.manual_fan_speed = 50 time.sleep(1) emc.lut[27] = 25 diff --git a/examples/set_pwm_freq.py b/examples/set_pwm_freq.py index faf8dc8..3dda875 100644 --- a/examples/set_pwm_freq.py +++ b/examples/set_pwm_freq.py @@ -4,11 +4,11 @@ import time import board import busio -from adafruit_emc2101 import EMC2101 +from adafruit_emc2101.emc2101_lut import EMC2101_LUT i2c = busio.I2C(board.SCL, board.SDA) -emc = EMC2101(i2c) +emc = EMC2101_LUT(i2c) emc.set_pwm_clock(use_preset=False) # Datasheet recommends using the maximum value of 31 (0x1F) # to provide the highest effective resolution From 3e694b7371215f64357801cb6098191ca41a77b9 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Sun, 14 Mar 2021 13:04:44 -0500 Subject: [PATCH 03/12] Update docs --- docs/api.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api.rst b/docs/api.rst index daa9bd5..a798197 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -6,3 +6,7 @@ .. automodule:: adafruit_emc2101 :members: + + +.. automodule:: adafruit_emc2101.emc2101_lut + :members: From a8c1adaa9d28776a55aa1c4d0253f26eebb28268 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 16 Mar 2021 09:36:40 -0500 Subject: [PATCH 04/12] Slightly adjust examples --- examples/emc2101_lut_example.py | 4 ++-- examples/set_pwm_freq.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/emc2101_lut_example.py b/examples/emc2101_lut_example.py index 3322105..9c162e0 100644 --- a/examples/emc2101_lut_example.py +++ b/examples/emc2101_lut_example.py @@ -4,12 +4,12 @@ import time import board import busio -from adafruit_emc2101.emc2101_lut import EMC2101_LUT +from adafruit_emc2101.emc2101_lut import EMC2101_LUT as EMC2101 i2c = busio.I2C(board.SCL, board.SDA) FAN_MAX_RPM = 1700 -emc = EMC2101_LUT(i2c) +emc = EMC2101(i2c) emc.manual_fan_speed = 50 time.sleep(1) emc.lut[27] = 25 diff --git a/examples/set_pwm_freq.py b/examples/set_pwm_freq.py index 3dda875..78df320 100644 --- a/examples/set_pwm_freq.py +++ b/examples/set_pwm_freq.py @@ -4,11 +4,11 @@ import time import board import busio -from adafruit_emc2101.emc2101_lut import EMC2101_LUT +from adafruit_emc2101.emc2101_lut import EMC2101_LUT as EMC2101 i2c = busio.I2C(board.SCL, board.SDA) -emc = EMC2101_LUT(i2c) +emc = EMC2101(i2c) emc.set_pwm_clock(use_preset=False) # Datasheet recommends using the maximum value of 31 (0x1F) # to provide the highest effective resolution From 030db8d10d61b2722a4814ed6fb69877228e85cf Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 16 Mar 2021 14:59:23 -0500 Subject: [PATCH 05/12] Simplify LUT using StructArray, and allow deleting entries by assigning None --- adafruit_emc2101/emc2101_lut.py | 51 ++++++++++++--------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/adafruit_emc2101/emc2101_lut.py b/adafruit_emc2101/emc2101_lut.py index 4a818d8..dba477a 100644 --- a/adafruit_emc2101/emc2101_lut.py +++ b/adafruit_emc2101/emc2101_lut.py @@ -8,7 +8,7 @@ Brushless fan controller: extended functionality -* Author(s): Bryan Siepert +* Author(s): Bryan Siepert, Ryan Pavlik Implementation Notes -------------------- @@ -31,6 +31,7 @@ """ from micropython import const +from adafruit_register.i2c_struct_array import StructArray from adafruit_register.i2c_struct import UnaryStruct from adafruit_register.i2c_bit import RWBit from adafruit_register.i2c_bits import RWBits @@ -43,6 +44,7 @@ _PWM_FREQ = const(0x4D) _PWM_DIV = const(0x4E) _LUT_HYSTERESIS = const(0x4F) +_LUT_BASE = const(0x50) MAX_LUT_SPEED = 0x3F # 6-bit value MAX_LUT_TEMP = 0x7F # 7-bit @@ -56,30 +58,8 @@ class FanSpeedLUT: """A class used to provide a dict-like interface to the EMC2101's Temperature to Fan speed Look Up Table""" - # seems like a pain but ¯\_(ツ)_/¯ - _fan_lut_t1 = UnaryStruct(0x50, " 100.0 or value < 0: + if value is None: + # Assign None to remove this entry + del self.lut_values[index] + elif value > 100.0 or value < 0: + # Range check raise AttributeError("LUT values must be a fan speed from 0-100%") - self.lut_values[index] = value + else: + self.lut_values[index] = value self._update_lut() def __repr__(self): @@ -137,15 +122,17 @@ def _update_lut(self): # get and sort the new lut keys so that we can assign them in order for idx, current_temp in enumerate(sorted(self.lut_values.keys())): current_speed = _speed_to_lsb(self.lut_values[current_temp]) - setattr(self, "_fan_lut_t%d" % (idx + 1), current_temp) - setattr(self, "_fan_lut_s%d" % (idx + 1), current_speed) + self._set_lut_entry(idx, current_temp, current_speed) # Set the remaining LUT entries to the default (Temp/Speed = max value) - for idx in range(8)[len(self.lut_values) :]: - setattr(self, "_fan_lut_t%d" % (idx + 1), MAX_LUT_TEMP) - setattr(self, "_fan_lut_s%d" % (idx + 1), MAX_LUT_SPEED) + for idx in range(len(self.lut_values), 8): + self._set_lut_entry(idx, MAX_LUT_TEMP, MAX_LUT_SPEED) self.emc_fan.lut_enabled = current_mode + def _set_lut_entry(self, idx, temp, speed): + self._fan_lut[idx * 2] = bytearray((temp,)) + self._fan_lut[idx * 2 + 1] = bytearray((speed,)) + class EMC2101_LUT(EMC2101): # pylint: disable=too-many-instance-attributes """Driver for the EMC2101 Fan Controller. From cc0669cd82ff7577b453c1a41978ec94d4de288f Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 16 Mar 2021 14:08:16 -0500 Subject: [PATCH 06/12] Minor performance tweak --- adafruit_emc2101/emc2101_lut.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_emc2101/emc2101_lut.py b/adafruit_emc2101/emc2101_lut.py index dba477a..96d4e36 100644 --- a/adafruit_emc2101/emc2101_lut.py +++ b/adafruit_emc2101/emc2101_lut.py @@ -93,7 +93,7 @@ def __repr__(self): def __str__(self): """return the official string representation of the LUT""" value_strs = [] - lut_keys = list(sorted(self.lut_values.keys())) + lut_keys = tuple(sorted(self.lut_values.keys())) for temp in lut_keys: fan_drive = self.lut_values[temp] value_strs.append("%d deg C => %.1f%% duty cycle" % (temp, fan_drive)) From b75099fcc12f6828061bbfac3b0769d0a1e24e13 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 16 Mar 2021 14:59:33 -0500 Subject: [PATCH 07/12] Docs improvements --- adafruit_emc2101/__init__.py | 19 ++++++++++++++----- adafruit_emc2101/emc2101_lut.py | 21 +++++++++++++++------ docs/examples.rst | 4 ++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/adafruit_emc2101/__init__.py b/adafruit_emc2101/__init__.py index 24df5ec..bd93543 100644 --- a/adafruit_emc2101/__init__.py +++ b/adafruit_emc2101/__init__.py @@ -21,9 +21,8 @@ * Adafruit CircuitPython firmware for the supported boards: https://github.com/adafruit/circuitpython/releases - -# * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice -# * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register +* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice +* Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register """ from micropython import const @@ -133,8 +132,13 @@ class SpinupTime(CV): class EMC2101: # pylint: disable=too-many-instance-attributes - """Driver for the EMC2101 Fan Controller. + """Basic driver for the EMC2101 Fan Controller. + :param ~busio.I2C i2c_bus: The I2C bus the EMC is connected to. + + If you need control over PWM frequency and the controller's built in temperature/speed + look-up table (LUT), you will need :class:`emc2101_lut.EMC2101_LUT` which extends this + class to add those features, at the cost of increased memory usage. """ _part_id = ROUnaryStruct(_REG_PARTID, " Date: Tue, 16 Mar 2021 14:30:39 -0500 Subject: [PATCH 08/12] Fix typo in example --- examples/emc2101_lut_example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/emc2101_lut_example.py b/examples/emc2101_lut_example.py index 9c162e0..2e4ce04 100644 --- a/examples/emc2101_lut_example.py +++ b/examples/emc2101_lut_example.py @@ -27,6 +27,6 @@ time.sleep(3) print("50%% duty cycle is %f RPM:" % emc.fan_speed) -emc.forced_ext_temp = 43 # over 30, should be 50% +emc.forced_ext_temp = 43 # over 42, should be 75% time.sleep(3) print("75%% duty cycle is %f RPM:" % emc.fan_speed) From ce7d6ca3819949d47d79ccb4959d7f19c36c3681 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 16 Mar 2021 14:38:46 -0500 Subject: [PATCH 09/12] Improve comments --- adafruit_emc2101/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/adafruit_emc2101/__init__.py b/adafruit_emc2101/__init__.py index bd93543..01fed23 100644 --- a/adafruit_emc2101/__init__.py +++ b/adafruit_emc2101/__init__.py @@ -145,12 +145,15 @@ class to add those features, at the cost of increased memory usage. _mfg_id = ROUnaryStruct(_REG_MFGID, " Date: Tue, 16 Mar 2021 14:39:01 -0500 Subject: [PATCH 10/12] remove extra space --- adafruit_emc2101/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_emc2101/__init__.py b/adafruit_emc2101/__init__.py index 01fed23..4d0602d 100644 --- a/adafruit_emc2101/__init__.py +++ b/adafruit_emc2101/__init__.py @@ -232,7 +232,7 @@ def manual_fan_speed(self): @manual_fan_speed.setter def manual_fan_speed(self, fan_speed): if fan_speed not in range(0, 101): - raise AttributeError("manual_fan_speed must be from 0-100 ") + raise AttributeError("manual_fan_speed must be from 0-100") # convert from a percentage to an lsb value percentage = fan_speed / 100.0 From 7b27d9a58345b7e80cc35156819c06b0c7ebb84f Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 16 Mar 2021 14:39:29 -0500 Subject: [PATCH 11/12] Fix typo --- adafruit_emc2101/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_emc2101/__init__.py b/adafruit_emc2101/__init__.py index 4d0602d..0ccec77 100644 --- a/adafruit_emc2101/__init__.py +++ b/adafruit_emc2101/__init__.py @@ -63,7 +63,7 @@ class CV: @classmethod def add_values(cls, value_tuples): - "creates CV entires" + "creates CV entries" cls.string = {} cls.lsb = {} From 97ecd43415843e24520294a5ea3138922bd05a20 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 16 Mar 2021 14:29:13 -0500 Subject: [PATCH 12/12] Add ability to clear LUT --- adafruit_emc2101/emc2101_lut.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/adafruit_emc2101/emc2101_lut.py b/adafruit_emc2101/emc2101_lut.py index 3679215..be770ca 100644 --- a/adafruit_emc2101/emc2101_lut.py +++ b/adafruit_emc2101/emc2101_lut.py @@ -62,6 +62,7 @@ class FanSpeedLUT: A max of 8 values may be stored. To remove a single stored point in the LUT, assign it as `None`. + To clear all entries, use :meth:`FanSpeedLUT.clear` """ # 8 (Temperature, Speed) pairs in increasing order @@ -139,6 +140,11 @@ def _set_lut_entry(self, idx, temp, speed): self._fan_lut[idx * 2] = bytearray((temp,)) self._fan_lut[idx * 2 + 1] = bytearray((speed,)) + def clear(self): + """Clear all LUT entries.""" + self.lut_values = {} + self._update_lut() + class EMC2101_LUT(EMC2101): # pylint: disable=too-many-instance-attributes """Driver for the EMC2101 Fan Controller, with PWM frequency and LUT control. @@ -232,3 +238,7 @@ def lut_enabled(self, enable_lut): def lut(self): """The dict-like representation of the LUT, actually of type :class:`FanSpeedLUT`""" return self._lut + + def clear_lut(self): + """Clear all LUT entries.""" + self._lut.clear()