@@ -83,6 +83,9 @@ static supervisor_allocation *hid_report_descriptor_allocation;
8383static usb_hid_device_obj_t hid_devices [MAX_HID_DEVICES ];
8484static mp_int_t hid_devices_num ;
8585
86+ // This tuple is store in usb_hid.devices.
87+ static mp_obj_tuple_t * hid_devices_tuple ;
88+
8689static mp_obj_tuple_t default_hid_devices_tuple = {
8790 .base = {
8891 .type = & mp_type_tuple ,
@@ -132,6 +135,19 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
132135 return sizeof (usb_hid_descriptor_template );
133136}
134137
138+ // Make up a fresh tuple containing the device objects saved in the static
139+ // devices table. Save the tuple in usb_hid.devices.
140+ static void usb_hid_set_devices_from_hid_devices (void ) {
141+ mp_obj_t tuple_items [hid_devices_num ];
142+ for (mp_int_t i = 0 ; i < hid_devices_num ; i ++ ) {
143+ tuple_items [i ] = & hid_devices [i ];
144+ }
145+
146+ // Remember tuple for gc purposes.
147+ hid_devices_tuple = mp_obj_new_tuple (hid_devices_num , tuple_items );
148+ usb_hid_set_devices (hid_devices_tuple );
149+ }
150+
135151bool common_hal_usb_hid_configure_usb (const mp_obj_t devices ) {
136152 // We can't change the devices once we're connected.
137153 if (tud_connected ()) {
@@ -151,20 +167,16 @@ bool common_hal_usb_hid_configure_usb(const mp_obj_t devices) {
151167 memcpy (& hid_devices [i ], device , sizeof (usb_hid_device_obj_t ));
152168 }
153169
170+ usb_hid_set_devices_from_hid_devices ();
171+
154172 return true;
155173}
156174
175+ // Called when HID devices are ready to be used, when code.py or the REPL starts running.
157176void usb_hid_setup_devices (void ) {
158- // Make up a fresh tuple containing the device objects are saved in the static
159- // devices table. Save the tuple in usb_hid.devices.
177+ usb_hid_set_devices_from_hid_devices ();
160178
161- mp_obj_t tuple_items [hid_devices_num ];
162- for (mp_int_t i = 0 ; i < hid_devices_num ; i ++ ) {
163- tuple_items [i ] = & hid_devices [i ];
164- }
165- usb_hid_set_devices (mp_obj_new_tuple (hid_devices_num , tuple_items ));
166-
167- // Create report buffers on the heap.
179+ // Create report buffers on the heap.
168180 for (mp_int_t i = 0 ; i < hid_devices_num ; i ++ ) {
169181 usb_hid_device_create_report_buffers (& hid_devices [i ]);
170182 }
@@ -174,10 +186,7 @@ void usb_hid_setup_devices(void) {
174186size_t usb_hid_report_descriptor_length (void ) {
175187 size_t total_hid_report_descriptor_length = 0 ;
176188 for (mp_int_t i = 0 ; i < hid_devices_num ; i ++ ) {
177- // hid_devices has already been validated to contain only usb_hid_device_obj_t objects.
178- usb_hid_device_obj_t * device =
179- MP_OBJ_TO_PTR (mp_obj_subscr (hid_devices , MP_OBJ_NEW_SMALL_INT (i ), MP_OBJ_SENTINEL ));
180- total_hid_report_descriptor_length += device -> report_descriptor_length ;
189+ total_hid_report_descriptor_length += hid_devices [i ].report_descriptor_length ;
181190 }
182191
183192 // Don't need space for a report id if there's only one device.
@@ -205,9 +214,15 @@ void usb_hid_build_report_descriptor(uint8_t* report_descriptor_space, size_t re
205214 // Copy the whole descriptor and fill in the report id.
206215 memcpy (report_descriptor_start , device -> report_descriptor , device -> report_descriptor_length );
207216 report_descriptor_start [device -> report_id_index ] = i + 1 ;
217+
218+ // Remember the report id that was assigned.
219+ device -> report_id = i + 1 ;
220+
221+ // Advance to the next free chunk for the next report descriptor.x
208222 report_descriptor_start += device -> report_descriptor_length ;
209223 }
210224 // Clear the heap pointer to the bytes of the descriptor.
225+ // We don't need it any more and it will get lost when the heap goes away.
211226 device -> report_descriptor = NULL ;
212227 }
213228}
@@ -220,11 +235,14 @@ void usb_hid_save_report_descriptor(uint8_t *report_descriptor_space, size_t rep
220235 // Copy the descriptor from the temporary area to a supervisor storage allocation that
221236 // will leave between VM instantiations.
222237 hid_report_descriptor_allocation =
223- allocate_memory (report_descriptor_length , /*high_address*/ false, /*movable*/ false);
238+ allocate_memory (align32_size (report_descriptor_length ),
239+ /*high_address*/ false, /*movable*/ false);
224240 memcpy ((uint8_t * ) hid_report_descriptor_allocation -> ptr , report_descriptor_space , report_descriptor_length );
225241}
226242
227243void usb_hid_gc_collect (void ) {
244+ gc_collect_ptr (hid_devices_tuple );
245+
228246 // Mark any heap pointers in the static device list as in use.
229247 for (mp_int_t i = 0 ; i < hid_devices_num ; i ++ ) {
230248 gc_collect_ptr (& hid_devices [i ]);
0 commit comments