3
3
# MIT license; Copyright (c) 2023-2024 Angus Gratton
4
4
from micropython import const
5
5
import struct
6
+ import machine
6
7
7
8
from usb .device .hid import HIDInterface
8
9
@@ -20,6 +21,7 @@ def __init__(self, interface_str="MicroPython Mouse"):
20
21
self ._l = False # Left button
21
22
self ._m = False # Middle button
22
23
self ._r = False # Right button
24
+ self ._buf = bytearray (3 )
23
25
24
26
def send_report (self , dx = 0 , dy = 0 ):
25
27
b = 0
@@ -29,16 +31,20 @@ def send_report(self, dx=0, dy=0):
29
31
b |= 1 << 1
30
32
if self ._m :
31
33
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.
34
37
#
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 )
40
46
41
- return super ().send_report (report )
47
+ return super ().send_report (self . _buf )
42
48
43
49
def click_left (self , down = True ):
44
50
self ._l = down
0 commit comments