-
-
Save bitboy85/cdcd0e7e04082db414b5f1d23ab09005 to your computer and use it in GitHub Desktop.
| import usb_hid | |
| # https://stackoverflow.com/questions/36750287/two-byte-report-count-for-hid-report-descriptor | |
| absolute_mouse = usb_hid.Device( | |
| report_descriptor=bytes( | |
| # Absolute mouse | |
| (0x05, 0x01) # Usage Page (Generic Desktop) | |
| + (0x09, 0x02) # Usage (Mouse) | |
| + (0xA1, 0x01) # Collection (Application) | |
| + (0x09, 0x01) # Usage (Pointer) | |
| + (0xA1, 0x00) # Collection (Physical) | |
| + (0x85, 0x0B) # Report ID [11 is SET at RUNTIME] | |
| # Buttons | |
| + (0x05, 0x09) # Usage Page (Button) | |
| + (0x19, 0x01) # Usage Minimum (0x01) | |
| + (0x29, 0x05) # Usage Maximum (0x05) | |
| + (0x15, 0x00) # Logical Minimum (0) | |
| + (0x25, 0x01) # Logical Maximum (1) | |
| + (0x95, 0x05) # Report Count (5) | |
| + (0x75, 0x01) # Report Size (1) | |
| + (0x81, 0x02) # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) | |
| + (0x75, 0x03) # Report Size (3) | |
| + (0x95, 0x01) # Report Count (1) | |
| + (0x81, 0x03) # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) | |
| # Movement | |
| + (0x05, 0x01) # Usage Page (Generic Desktop Ctrls) | |
| + (0x09, 0x30) # Usage (X) | |
| + (0x09, 0x31) # Usage (Y) | |
| + (0x15, 0x00) # LOGICAL_MINIMUM (0) ; Note: 0x15 = 1 Byte; 0x16 = 2 Byte; 0x17 = 4 Byte | |
| + (0x26, 0xFF, 0x7F) # LOGICAL_MAXIMUM (32767) ; Note: 0x25 = 1 Byte, 0x26 = 2 Byte; 0x27 = 4 Byte Report | |
| #+ (0x35, 0x00) # Physical Minimum (0) | |
| #+ (0x46, 0xff, 0x7f) # Physical Maximum (32767) | |
| + (0x75, 0x10) # REPORT_SIZE (16) | |
| + (0x95, 0x02) # REPORT_COUNT (2) | |
| + (0x81, 0x02) # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) | |
| # Wheel | |
| + (0x09, 0x38) # Usage (Wheel) | |
| + (0x15, 0x81) # Logical Minimum (-127) | |
| + (0x25, 0x7F) # Logical Maximum (127) | |
| #+ (0x35, 0x81) # Physical Minimum (same as logical) | |
| #+ (0x45, 0x7f) # Physical Maximum (same as logical) | |
| + (0x75, 0x08) # Report Size (8) | |
| + (0x95, 0x01) # Report Count (1) | |
| + (0x81, 0x06) # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) | |
| + (0xC0,) # End Collection | |
| + (0xC0,) # End Collection | |
| ), | |
| usage_page=1, | |
| usage=2, | |
| in_report_lengths=(6,), # Number of bytes in the send report = 1 byte for buttons, 2 bytes for x, 2 bytes for y, 1 byte for wheel | |
| out_report_lengths=(0,), | |
| report_ids=(11,), | |
| ) | |
| usb_hid.enable((usb_hid.Device.KEYBOARD,), boot_device=1) | |
| usb_hid.enable((absolute_mouse,), boot_device=0) |
| # SPDX-FileCopyrightText: 2017 Dan Halbert for Adafruit Industries | |
| # | |
| # SPDX-License-Identifier: MIT | |
| """ | |
| `adafruit_hid.mouse.Mouse` | |
| ==================================================== | |
| * Author(s): Dan Halbert, Bitboy | |
| """ | |
| import time | |
| from . import find_device | |
| class Mouse: | |
| """Send USB HID mouse reports.""" | |
| LEFT_BUTTON = 1 | |
| """Left mouse button.""" | |
| RIGHT_BUTTON = 2 | |
| """Right mouse button.""" | |
| MIDDLE_BUTTON = 4 | |
| """Middle mouse button.""" | |
| def __init__(self, devices): | |
| """Create a Mouse object that will send USB mouse HID reports. | |
| Devices can be a list 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._mouse_device = find_device(devices, usage_page=0x1, usage=0x02) | |
| #print(dir(devices)) | |
| # Reuse this bytearray to send mouse reports. | |
| # report[0] buttons pressed (LEFT, MIDDLE, RIGHT) | |
| # report[1] x1 movement | |
| # report[2] x2 movement | |
| # report[3] y1 movement | |
| # report[4] y2 movement | |
| # report[5] wheel movement | |
| self.report = bytearray(6) | |
| # Do a no-op to test if HID device is ready. | |
| # If not, wait a bit and try once more. | |
| try: | |
| self._send_no_move() | |
| except OSError: | |
| time.sleep(1) | |
| self._send_no_move() | |
| def press(self, buttons): | |
| """Press the given mouse buttons. | |
| :param buttons: a bitwise-or'd combination of ``LEFT_BUTTON``, | |
| ``MIDDLE_BUTTON``, and ``RIGHT_BUTTON``. | |
| Examples:: | |
| # Press the left button. | |
| m.press(Mouse.LEFT_BUTTON) | |
| # Press the left and right buttons simultaneously. | |
| m.press(Mouse.LEFT_BUTTON | Mouse.RIGHT_BUTTON) | |
| """ | |
| self.report[0] |= buttons | |
| self._send_no_move() | |
| def release(self, buttons): | |
| """Release the given mouse buttons. | |
| :param buttons: a bitwise-or'd combination of ``LEFT_BUTTON``, | |
| ``MIDDLE_BUTTON``, and ``RIGHT_BUTTON``. | |
| """ | |
| self.report[0] &= ~buttons | |
| self._send_no_move() | |
| def release_all(self): | |
| """Release all the mouse buttons.""" | |
| self.report[0] = 0 | |
| self._send_no_move() | |
| def click(self, buttons): | |
| """Press and release the given mouse buttons. | |
| :param buttons: a bitwise-or'd combination of ``LEFT_BUTTON``, | |
| ``MIDDLE_BUTTON``, and ``RIGHT_BUTTON``. | |
| Examples:: | |
| # Click the left button. | |
| m.click(Mouse.LEFT_BUTTON) | |
| # Double-click the left button. | |
| m.click(Mouse.LEFT_BUTTON) | |
| m.click(Mouse.LEFT_BUTTON) | |
| """ | |
| self.press(buttons) | |
| self.release(buttons) | |
| def move(self, x=0, y=0, wheel=0): | |
| """Move the mouse and turn the wheel as directed. | |
| :param x: Set pointer on x axis. 32767 = 100% to the right | |
| :param y: Set pointer on y axis. 32767 = 100% to the bottom | |
| :param wheel: Rotate the wheel this amount. Negative is toward the user, positive | |
| is away from the user. The scrolling effect depends on the host. | |
| Examples:: | |
| # Move 100 to the left. Do not move up and down. Do not roll the scroll wheel. | |
| m.move(1000, 3000, 0) | |
| # Same, with keyword arguments. | |
| m.move(x=1000, y=3000, wheel=0) | |
| # Roll the mouse wheel away from the user. | |
| m.move(wheel=1) | |
| """ | |
| # Wheel | |
| while wheel != 0: | |
| partial_wheel = self._limit(wheel) | |
| print(wheel) | |
| self.report[5] = partial_wheel & 0xFF | |
| self._mouse_device.send_report(self.report) | |
| wheel -= partial_wheel | |
| # Coordinates | |
| x = self._limit_coord(x) | |
| y = self._limit_coord(y) | |
| # HID reports use little endian | |
| x1, x2 = (x & 0xFFFFFFFF).to_bytes(2, 'little') | |
| y1, y2 = (y & 0xFFFFFFFF).to_bytes(2, 'little') | |
| #print(x1) | |
| #print(x2) | |
| #print(y1) | |
| #print(y2) | |
| self.report[1] = x1 | |
| self.report[2] = x2 | |
| self.report[3] = y1 | |
| self.report[4] = y2 | |
| self._mouse_device.send_report(self.report) | |
| def _send_no_move(self): | |
| """Send a button-only report.""" | |
| self.report[1] = 0 | |
| self.report[2] = 0 | |
| self.report[3] = 0 | |
| self.report[4] = 0 | |
| self._mouse_device.send_report(self.report) | |
| @staticmethod | |
| def _limit(dist): | |
| return min(127, max(-127, dist)) | |
| @staticmethod | |
| def _limit_coord(coord): | |
| return min(32767, max(0, coord)) |
| import usb_hid | |
| from adafruit_hid.mouse_abs import Mouse | |
| mouse = Mouse(usb_hid.devices) | |
| # Note: Values are NOT pixels! 32767 = 100% (to right or to bottom) | |
| mouse.move(x=20000, y=2000) |
Don't have a feather. But in boot.py in line 50 it is specified, that the buffer is 6 bytes. So without further knowledge i would say the feather didn't process boot.py correctly.
I think I know what the problem was, why a change of CircuitPython solved it.
I may not have reset or powered off the board, and so there is a mismatch between what is in the file and what is accepted at runtime in code.py. I had the same error but with 4 when moving back to relative mouse descriptor...
Regards.
I would like to confirm that this "Buffer incorrect size." is occuring when you change the boot.py without powercycling the board.
You need the board to re-negotiate with the host at USB level... unplugging and replugging is the best way to garantee that.
Also I have used your code for this demo: https://github.com/dglaude/CircuitPython_udraw_Absolute_Mouse
A fork of my library is now accepted in CircuitPython Community Bundle and can be found here: https://github.com/Neradoc/CircuitPython_Absolute_Mouse
There is a nice very simple example code there.
Nice! Thanks for mentioning my example :)
(edit: No error with
Adafruit CircuitPython 7.3.0-beta.1 on 2022-04-07; Adafruit Macropad RP2040 with rp2040)I try to replicate the above with Feather RP2040 and CircuitPython 7.2.5 but I encounter an issue.
I believe it is a mismatch on the report size of the normal mouse.py and the new mouse_abs.py.
42 define
self.report = bytearray(6)47 is
self._send_no_move()151 is
self._mouse_device.send_report(self.report)I don't really know where that check and message is coming from
ValueError: Buffer incorrect size. Should be 4 bytes.and what may have change recently either in the firmware or inadafruit_hid.