33# MIT license; Copyright (c) 2023-2024 Angus Gratton
44from micropython import const
55import struct
6+ import machine
67
78from usb .device .hid import HIDInterface
89
@@ -20,6 +21,7 @@ def __init__(self, interface_str="MicroPython Mouse"):
2021 self ._l = False # Left button
2122 self ._m = False # Middle button
2223 self ._r = False # Right button
24+ self ._buf = bytearray (3 )
2325
2426 def send_report (self , dx = 0 , dy = 0 ):
2527 b = 0
@@ -29,16 +31,20 @@ def send_report(self, dx=0, dy=0):
2931 b |= 1 << 1
3032 if self ._m :
3133 b |= 1 << 2
32- # Note: This allocates the bytes object 'report' each time a report is
33- # sent.
34+
35+ # Wait for any pending report to be sent to the host
36+ # before updating contents of _buf.
3437 #
35- # However, at the moment the HIDInterface class doesn't keep track of each
36- # transfer after it's submitted. So reusing a bytearray() creates a risk
37- # of a race condition if a new report transfer is submitted using the
38- # same buffer, before the previous one has completed.
39- report = struct .pack ("Bbb" , b , dx , dy )
38+ # This loop can be removed if you don't care about possibly missing a
39+ # transient report, the final report buffer contents will always be the
40+ # last one sent to the host (it just might lose one of the ones in the
41+ # middle).
42+ while self .busy ():
43+ machine .idle ()
44+
45+ struct .pack_into ("Bbb" , self ._buf , 0 , b , dx , dy )
4046
41- return super ().send_report (report )
47+ return super ().send_report (self . _buf )
4248
4349 def click_left (self , down = True ):
4450 self ._l = down
0 commit comments