diff --git a/boot.py b/boot.py old mode 100755 new mode 100644 diff --git a/code.py b/code.py index 4cb8613..7c5ee06 100644 --- a/code.py +++ b/code.py @@ -1,6 +1,6 @@ from keyboard import Keyboard -from config import io_extenders_pinout, pinout, keymap, rgb_pins +from config import io_extenders_pinout, pinout, keymap, rgb_pins, layer_colors -keyboard_state_manager = Keyboard(io_extenders_pinout, pinout, keymap, rgb_pins) +keyboard_state_manager = Keyboard(io_extenders_pinout, pinout, keymap, rgb_pins, layer_colors) keyboard_state_manager.start() \ No newline at end of file diff --git a/config.py b/config.py old mode 100755 new mode 100644 index 53cb532..9bb0207 --- a/config.py +++ b/config.py @@ -1,6 +1,7 @@ # pimodori tiny 2040 8MB import board +from keyboard import Hold, Toggle from keycodes import SE io_extenders_pinout = [(0x20, board.GP1, board.GP0)] @@ -13,11 +14,12 @@ pinout: tuple[int,int] = [ ] keymap: list[int] = [ - 121, SE.TWO, SE.THREE, SE.FOUR, + Hold(1), Toggle(2), Toggle(3), Toggle(4), SE.A, SE.B, SE.C, SE.D, SE.E, SE.F, SE.G, SE.H, SE.I, SE.J, SE.K, SE.L ] +layer_colors = [(255,255,255),(0,255,0),(0,0,255), (255,0,255), (255, 255, 0)] rgb_pins: tuple[int,int,int] = (board.LED_R, board.LED_G, board.LED_B) \ No newline at end of file diff --git a/keyboard.py b/keyboard.py old mode 100755 new mode 100644 index 7f828f8..aef9077 --- a/keyboard.py +++ b/keyboard.py @@ -7,6 +7,17 @@ import pwmio import time from micropython import const +class LayerKey: + layer: int + def __init__(self, layer:int): + self.layer = layer +class Toggle(LayerKey): + def __init__(self, layer:int): + super().__init__(layer) +class Hold(LayerKey): + def __init__(self, layer:int): + super().__init__(layer) + __RED = (255,0,0) __BLUE = (0,0,255) __GREEN = (0,255,0) @@ -28,6 +39,8 @@ class RGBLED: def set(self, rgb_values: tuple[int, int, int]): for i in range(3): + input = rgb_values[i] + assert 0 <= input <=255 value = self.__to_inverse_8_bit_value(rgb_values[i]) self.leds[i].duty_cycle = value @@ -65,9 +78,16 @@ class RGBLED: else: time.sleep(color_sleep_cycles[i][0]) -__PRESSED = False -__UNPRESSED = True +__PRESSED = const(0) +__UNPRESSED = const(1) +__TOGGLED_PRESSED = const(2) +__TOGGLED_RELEASED = const(3) +__UNTOGGLED_PRESSED = const(4) class Keyboard: + active_layer: int + previous_layers: list[int] + layer_colors: list[tuple[int,int,int]] + pressed_keys_last_cycle: set[int] pressed_keys: set[int] @@ -79,7 +99,7 @@ class Keyboard: keyboard_device: usb_hid.Device led: RGBLED - def __init__(self, io_extenders_pinout: list[tuple[int, int, int]], pinout: list[tuple[int,int]], keymap: list[int], rgb_pins: tuple[int, int, int]): + def __init__(self, io_extenders_pinout: list[tuple[int, int, int]], pinout: list[tuple[int,int]], keymap: list[int], rgb_pins: tuple[int, int, int], layer_colors: list[tuple[int, int, int]]): """Initialize new keyboard 'io_extenders_pinout': list of tuple containing the i2c address, clock pin and data pin of the device. The order of the extenders are decided by the order in the list. @@ -92,6 +112,7 @@ class Keyboard: self.pins = self.initialize_pins(io_extenders, pinout) self.keymap = keymap + self.layer_colors = layer_colors self.led = RGBLED(rgb_pins) self.led.indicate_boot() @@ -135,6 +156,8 @@ class Keyboard: def start(self): try: + self.active_layer = 0 + self.previous_layers = [] self.pressed_keys = set() self.pressed_keys_last_cycle = set() self.pin_states_last_cycle = [] @@ -145,20 +168,61 @@ class Keyboard: keycode = self.keymap[pin_index] previously = self.pin_states_last_cycle[pin_index] value = pin.value - currentlyPressed = value is __PRESSED - previouslyPressed = previously is __PRESSED - if currentlyPressed: - if not previouslyPressed: - self.pressed_keys.add(keycode) - else: - if previouslyPressed: - try: - self.pressed_keys.remove(keycode) - # Catch silenly if same keycode is pressed twice then released - except KeyError: - pass - self.pin_states_last_cycle[pin_index] = value - + currentlyPressed = value == __PRESSED + previouslyPressed = previously == __PRESSED + previouslyToggled = previously == __TOGGLED_PRESSED + previouslyToggledReleased = previously == __TOGGLED_RELEASED + previouslyUntoggledPressed = previously == __UNTOGGLED_PRESSED + if not isinstance(keycode, LayerKey): + if currentlyPressed: + if not previouslyPressed: + self.pressed_keys.add(keycode) + else: + if previouslyPressed: + try: + self.pressed_keys.remove(keycode) + # Catch silenly if same keycode is pressed twice then released + except KeyError: + pass + self.pin_states_last_cycle[pin_index] = value + continue + # TODO: Always release old key when entering new layer + if type(keycode) is Hold: + if currentlyPressed and not previouslyPressed: + self.previous_layers.append(self.active_layer) + self.active_layer = keycode.layer + print(f"hold: {self.previous_layers}") + self.pin_states_last_cycle[pin_index] = value + continue + if previouslyPressed and not currentlyPressed: + self.active_layer = self.previous_layers.pop() + self.pin_states_last_cycle[pin_index] = value + print(f"release: {self.previous_layers}") + continue + if type(keycode) is Toggle: + if currentlyPressed and not previouslyToggled and not previouslyToggledReleased and not previouslyUntoggledPressed: + self.previous_layers.append(self.active_layer) + self.active_layer = keycode.layer + print(f"Toggled: {self.previous_layers}") + self.pin_states_last_cycle[pin_index] = __TOGGLED_PRESSED + continue + if not currentlyPressed and previouslyToggled: + print(f"Toggled Released: {self.previous_layers}") + self.pin_states_last_cycle[pin_index] = __TOGGLED_RELEASED + continue + if currentlyPressed and previouslyToggledReleased: + print(f"Untoggled: {self.previous_layers}") + self.active_layer = self.previous_layers.pop() + self.pin_states_last_cycle[pin_index] = __UNTOGGLED_PRESSED + continue + if not currentlyPressed and previouslyUntoggledPressed: + print(f"Untoggled unpressed: {self.previous_layers}") + self.pin_states_last_cycle[pin_index] = __UNPRESSED + continue + if len(self.layer_colors) >= (self.active_layer + 1): + self.led.set(self.layer_colors[self.active_layer]) + else: + self.led.off() if self.pressed_keys != self.pressed_keys_last_cycle: self.send_nkro_report() self.pressed_keys_last_cycle = set(self.pressed_keys) diff --git a/keycodes.py b/keycodes.py old mode 100755 new mode 100644 diff --git a/lib/adafruit_mcp230xx/__init__.mpy b/lib/adafruit_mcp230xx/__init__.mpy old mode 100644 new mode 100755 diff --git a/lib/adafruit_mcp230xx/digital_inout.mpy b/lib/adafruit_mcp230xx/digital_inout.mpy old mode 100644 new mode 100755 diff --git a/lib/adafruit_mcp230xx/mcp23008.mpy b/lib/adafruit_mcp230xx/mcp23008.mpy old mode 100644 new mode 100755 diff --git a/lib/adafruit_mcp230xx/mcp23016.mpy b/lib/adafruit_mcp230xx/mcp23016.mpy old mode 100644 new mode 100755 diff --git a/lib/adafruit_mcp230xx/mcp23017.mpy b/lib/adafruit_mcp230xx/mcp23017.mpy old mode 100644 new mode 100755 diff --git a/lib/adafruit_mcp230xx/mcp230xx.mpy b/lib/adafruit_mcp230xx/mcp230xx.mpy old mode 100644 new mode 100755 diff --git a/lib/adafruit_mcp230xx/mcp23s17.mpy b/lib/adafruit_mcp230xx/mcp23s17.mpy old mode 100644 new mode 100755 diff --git a/lib/adafruit_mcp230xx/mcp23sxx.mpy b/lib/adafruit_mcp230xx/mcp23sxx.mpy old mode 100644 new mode 100755 diff --git a/lib/adafruit_mcp230xx/mcp23xxx.mpy b/lib/adafruit_mcp230xx/mcp23xxx.mpy old mode 100644 new mode 100755 diff --git a/lib/simpleio.mpy b/lib/simpleio.mpy old mode 100644 new mode 100755