-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from Noloxs/Add_pico_executer
Add pico executer
- Loading branch information
Showing
15 changed files
with
836 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import usb_cdc | ||
usb_cdc.enable(console=True, data=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Adafruit CircuitPython 9.0.5 on 2024-05-22; Raspberry Pi Pico with rp2040 | ||
Board ID:raspberry_pi_pico | ||
UID:E66098F29B4F3239 | ||
[2K[0Gboot.py output: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import time | ||
import usb_cdc | ||
import usb_hid | ||
import binascii | ||
from adafruit_hid.keyboard import Keyboard | ||
from adafruit_hid.keycode import Keycode | ||
|
||
# Initialize serial | ||
serial = usb_cdc.data | ||
|
||
# Initialize USB HID keyboard | ||
keyboard = Keyboard(usb_hid.devices) | ||
|
||
def unsigned_to_signed(unsigned_val): | ||
# Ensure the input is within the range of a 2-byte unsigned integer | ||
if not (0 <= unsigned_val <= 0xFFFF): | ||
raise ValueError("Input should be a 2-byte unsigned integer (0 to 65535)") | ||
|
||
# If the value is greater than the maximum for a signed 2-byte integer, convert it | ||
if unsigned_val > 0x7FFF: # 32767 in decimal | ||
return unsigned_val - 0x10000 # 65536 in decimal | ||
else: | ||
return unsigned_val | ||
|
||
while True: | ||
if serial.in_waiting >= 3: # Wait for at least 3 bytes (1 byte key + 2 bytes delay) | ||
key_byte = int.from_bytes(serial.read(1), 'big') # Read 1 byte for the key | ||
keyboard.press(int(key_byte)) | ||
|
||
delay_bytes = serial.read(2) # Read 2 bytes for the delay | ||
delay = unsigned_to_signed(int.from_bytes(delay_bytes, 'big')) # Convert bytes to signed integer (big-endian) | ||
time.sleep(abs(delay)/1000) | ||
|
||
if delay >= 0: | ||
keyboard.release(int(key_byte)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# SPDX-FileCopyrightText: 2017 Scott Shawcroft for Adafruit Industries | ||
# | ||
# SPDX-License-Identifier: MIT | ||
|
||
""" | ||
`adafruit_hid` | ||
==================================================== | ||
This driver simulates USB HID devices. | ||
* Author(s): Scott Shawcroft, Dan Halbert | ||
Implementation Notes | ||
-------------------- | ||
**Software and Dependencies:** | ||
* Adafruit CircuitPython firmware for the supported boards: | ||
https://github.com/adafruit/circuitpython/releases | ||
""" | ||
|
||
# imports | ||
from __future__ import annotations | ||
import time | ||
|
||
try: | ||
import supervisor | ||
except ImportError: | ||
supervisor = None | ||
|
||
try: | ||
from typing import Sequence | ||
except ImportError: | ||
pass | ||
|
||
# usb_hid may not exist on some boards that still provide BLE or other HID devices. | ||
try: | ||
from usb_hid import Device | ||
except ImportError: | ||
Device = None | ||
|
||
__version__ = "0.0.0+auto.0" | ||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_HID.git" | ||
|
||
|
||
def find_device( | ||
devices: Sequence[object], | ||
*, | ||
usage_page: int, | ||
usage: int, | ||
timeout: int = None, | ||
) -> object: | ||
"""Search through the provided sequence of devices to find the one with the matching | ||
usage_page and usage. | ||
:param timeout: Time in seconds to wait for USB to become ready before timing out. | ||
Defaults to None to wait indefinitely. | ||
Ignored if device is not a `usb_hid.Device`; it might be BLE, for instance.""" | ||
|
||
if hasattr(devices, "send_report"): | ||
devices = [devices] # type: ignore | ||
device = None | ||
for dev in devices: | ||
if ( | ||
dev.usage_page == usage_page | ||
and dev.usage == usage | ||
and hasattr(dev, "send_report") | ||
): | ||
device = dev | ||
break | ||
if device is None: | ||
raise ValueError("Could not find matching HID device.") | ||
|
||
# Wait for USB to be connected only if this is a usb_hid.Device. | ||
if Device and isinstance(device, Device): | ||
if supervisor is None: | ||
# Blinka doesn't have supervisor (see issue Adafruit_Blinka#711), so wait | ||
# one second for USB to become ready | ||
time.sleep(1.0) | ||
elif timeout is None: | ||
# default behavior: wait indefinitely for USB to become ready | ||
while not supervisor.runtime.usb_connected: | ||
time.sleep(1.0) | ||
else: | ||
# wait up to timeout seconds for USB to become ready | ||
for _ in range(timeout): | ||
if supervisor.runtime.usb_connected: | ||
return device | ||
time.sleep(1.0) | ||
raise OSError("Failed to initialize HID device. Is USB connected?") | ||
|
||
return device |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
# SPDX-FileCopyrightText: 2017 Dan Halbert for Adafruit Industries | ||
# | ||
# SPDX-License-Identifier: MIT | ||
|
||
""" | ||
`adafruit_hid.keyboard.Keyboard` | ||
==================================================== | ||
* Author(s): Scott Shawcroft, Dan Halbert | ||
""" | ||
|
||
from micropython import const | ||
import usb_hid | ||
|
||
from .keycode import Keycode | ||
|
||
from . import find_device | ||
|
||
try: | ||
from typing import Sequence | ||
except: # pylint: disable=bare-except | ||
pass | ||
|
||
_MAX_KEYPRESSES = const(6) | ||
|
||
|
||
class Keyboard: | ||
"""Send HID keyboard reports.""" | ||
|
||
LED_NUM_LOCK = 0x01 | ||
"""LED Usage ID for Num Lock""" | ||
LED_CAPS_LOCK = 0x02 | ||
"""LED Usage ID for Caps Lock""" | ||
LED_SCROLL_LOCK = 0x04 | ||
"""LED Usage ID for Scroll Lock""" | ||
LED_COMPOSE = 0x08 | ||
"""LED Usage ID for Compose""" | ||
|
||
# No more than _MAX_KEYPRESSES regular keys may be pressed at once. | ||
|
||
def __init__(self, devices: Sequence[usb_hid.Device], timeout: int = None) -> None: | ||
"""Create a Keyboard object that will send keyboard HID reports. | ||
:param timeout: Time in seconds to wait for USB to become ready before timing out. | ||
Defaults to None to wait indefinitely. | ||
Devices can be a sequence of devices that includes a keyboard device or a keyboard device | ||
itself. A device is any object that implements ``send_report()``, ``usage_page`` and | ||
``usage``. | ||
""" | ||
self._keyboard_device = find_device( | ||
devices, usage_page=0x1, usage=0x06, timeout=timeout | ||
) | ||
|
||
# Reuse this bytearray to send keyboard reports. | ||
self.report = bytearray(8) | ||
|
||
# report[0] modifiers | ||
# report[1] unused | ||
# report[2:8] regular key presses | ||
|
||
# View onto byte 0 in report. | ||
self.report_modifier = memoryview(self.report)[0:1] | ||
|
||
# List of regular keys currently pressed. | ||
# View onto bytes 2-7 in report. | ||
self.report_keys = memoryview(self.report)[2:] | ||
|
||
# No keyboard LEDs on. | ||
self._led_status = b"\x00" | ||
|
||
def press(self, *keycodes: int) -> None: | ||
"""Send a report indicating that the given keys have been pressed. | ||
:param keycodes: Press these keycodes all at once. | ||
:raises ValueError: if more than six regular keys are pressed. | ||
Keycodes may be modifiers or regular keys. | ||
No more than six regular keys may be pressed simultaneously. | ||
Examples:: | ||
from adafruit_hid.keycode import Keycode | ||
# Press ctrl-x. | ||
kbd.press(Keycode.LEFT_CONTROL, Keycode.X) | ||
# Or, more conveniently, use the CONTROL alias for LEFT_CONTROL: | ||
kbd.press(Keycode.CONTROL, Keycode.X) | ||
# Press a, b, c keys all at once. | ||
kbd.press(Keycode.A, Keycode.B, Keycode.C) | ||
""" | ||
for keycode in keycodes: | ||
self._add_keycode_to_report(keycode) | ||
self._keyboard_device.send_report(self.report) | ||
|
||
def release(self, *keycodes: int) -> None: | ||
"""Send a USB HID report indicating that the given keys have been released. | ||
:param keycodes: Release these keycodes all at once. | ||
If a keycode to be released was not pressed, it is ignored. | ||
Example:: | ||
# release SHIFT key | ||
kbd.release(Keycode.SHIFT) | ||
""" | ||
for keycode in keycodes: | ||
self._remove_keycode_from_report(keycode) | ||
self._keyboard_device.send_report(self.report) | ||
|
||
def release_all(self) -> None: | ||
"""Release all pressed keys.""" | ||
for i in range(8): | ||
self.report[i] = 0 | ||
self._keyboard_device.send_report(self.report) | ||
|
||
def send(self, *keycodes: int) -> None: | ||
"""Press the given keycodes and then release all pressed keys. | ||
:param keycodes: keycodes to send together | ||
""" | ||
self.press(*keycodes) | ||
self.release_all() | ||
|
||
def _add_keycode_to_report(self, keycode: int) -> None: | ||
"""Add a single keycode to the USB HID report.""" | ||
modifier = Keycode.modifier_bit(keycode) | ||
if modifier: | ||
# Set bit for this modifier. | ||
self.report_modifier[0] |= modifier | ||
else: | ||
report_keys = self.report_keys | ||
# Don't press twice. | ||
for i in range(_MAX_KEYPRESSES): | ||
report_key = report_keys[i] | ||
if report_key == 0: | ||
# Put keycode in first empty slot. Since the report_keys | ||
# are compact and unique, this is not a repeated key | ||
report_keys[i] = keycode | ||
return | ||
if report_key == keycode: | ||
# Already pressed. | ||
return | ||
# All slots are filled. Shuffle down and reuse last slot | ||
for i in range(_MAX_KEYPRESSES - 1): | ||
report_keys[i] = report_keys[i + 1] | ||
report_keys[-1] = keycode | ||
|
||
def _remove_keycode_from_report(self, keycode: int) -> None: | ||
"""Remove a single keycode from the report.""" | ||
modifier = Keycode.modifier_bit(keycode) | ||
if modifier: | ||
# Turn off the bit for this modifier. | ||
self.report_modifier[0] &= ~modifier | ||
else: | ||
report_keys = self.report_keys | ||
# Clear the at most one matching slot and move remaining keys down | ||
j = 0 | ||
for i in range(_MAX_KEYPRESSES): | ||
pressed = report_keys[i] | ||
if not pressed: | ||
break # Handled all used report slots | ||
if pressed == keycode: | ||
continue # Remove this entry | ||
if i != j: | ||
report_keys[j] = report_keys[i] | ||
j += 1 | ||
# Clear any remaining slots | ||
while j < _MAX_KEYPRESSES and report_keys[j]: | ||
report_keys[j] = 0 | ||
j += 1 | ||
|
||
@property | ||
def led_status(self) -> bytes: | ||
"""Returns the last received report""" | ||
# get_last_received_report() returns None when nothing was received | ||
led_report = self._keyboard_device.get_last_received_report() | ||
if led_report is not None: | ||
self._led_status = led_report | ||
return self._led_status | ||
|
||
def led_on(self, led_code: int) -> bool: | ||
"""Returns whether an LED is on based on the led code | ||
Examples:: | ||
import usb_hid | ||
from adafruit_hid.keyboard import Keyboard | ||
from adafruit_hid.keycode import Keycode | ||
import time | ||
# Initialize Keyboard | ||
kbd = Keyboard(usb_hid.devices) | ||
# Press and release CapsLock. | ||
kbd.press(Keycode.CAPS_LOCK) | ||
time.sleep(.09) | ||
kbd.release(Keycode.CAPS_LOCK) | ||
# Check status of the LED_CAPS_LOCK | ||
print(kbd.led_on(Keyboard.LED_CAPS_LOCK)) | ||
""" | ||
return bool(self.led_status[0] & led_code) |
Oops, something went wrong.