@@ -79,7 +79,7 @@ const usb_hid_device_obj_t usb_hid_device_keyboard_obj = {
79
79
.usage = 0x06 ,
80
80
.num_report_ids = 1 ,
81
81
.report_ids = { 0x01 , },
82
- .in_report_lengths = { 8 , 0 , 0 , 0 , },
82
+ .in_report_lengths = { 8 , 0 , 0 , 0 , 0 , 0 , },
83
83
.out_report_lengths = { 1 , },
84
84
};
85
85
@@ -129,7 +129,7 @@ const usb_hid_device_obj_t usb_hid_device_mouse_obj = {
129
129
.usage = 0x02 ,
130
130
.num_report_ids = 1 ,
131
131
.report_ids = { 0x02 , },
132
- .in_report_lengths = { 4 , 0 , 0 , 0 , },
132
+ .in_report_lengths = { 4 , 0 , 0 , 0 , 0 , 0 , },
133
133
.out_report_lengths = { 0 , },
134
134
};
135
135
@@ -158,18 +158,30 @@ const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = {
158
158
.usage = 0x01 ,
159
159
.num_report_ids = 1 ,
160
160
.report_ids = { 0x03 },
161
- .in_report_lengths = { 2 , 0 , 0 , 0 },
162
- .out_report_lengths = { 0 },
161
+ .in_report_lengths = { 2 , 0 , 0 , 0 , 0 , 0 , },
162
+ .out_report_lengths = { 0 , },
163
163
};
164
164
165
-
166
- bool common_hal_usb_hid_device_valid_report_id (usb_hid_device_obj_t * self , uint8_t report_id ) {
165
+ STATIC size_t get_report_id_idx (usb_hid_device_obj_t * self , size_t report_id ) {
167
166
for (size_t i = 0 ; i < self -> num_report_ids ; i ++ ) {
168
167
if (report_id == self -> report_ids [i ]) {
169
- return true ;
168
+ return i ;
170
169
}
171
170
}
172
- return false;
171
+ return MAX_REPORT_IDS_PER_DESCRIPTOR ;
172
+ }
173
+
174
+ // See if report_id is used by this device. If it is -1, then return the sole report id used by this device,
175
+ // which might be 0 if no report_id was supplied.
176
+ uint8_t common_hal_usb_hid_device_validate_report_id (usb_hid_device_obj_t * self , mp_int_t report_id_arg ) {
177
+ if (report_id_arg == -1 && self -> num_report_ids == 1 ) {
178
+ return self -> report_ids [0 ];
179
+ }
180
+ if (!(report_id_arg >= 0 &&
181
+ get_report_id_idx (self , (size_t )report_id_arg ) < MAX_REPORT_IDS_PER_DESCRIPTOR )) {
182
+ mp_raise_ValueError_varg (translate ("Invalid %q" ), MP_QSTR_report_id );
183
+ }
184
+ return (uint8_t )report_id_arg ;
173
185
}
174
186
175
187
void common_hal_usb_hid_device_construct (usb_hid_device_obj_t * self , mp_obj_t report_descriptor , uint8_t usage_page , uint8_t usage , size_t num_report_ids , uint8_t * report_ids , uint8_t * in_report_lengths , uint8_t * out_report_lengths ) {
@@ -183,7 +195,7 @@ void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t re
183
195
mp_get_buffer_raise (report_descriptor , & bufinfo , MP_BUFFER_READ );
184
196
self -> report_descriptor_length = bufinfo .len ;
185
197
186
- // Copy the raw the descriptor bytes into a heap obj. We don't keep the Python descriptor object.
198
+ // Copy the raw descriptor bytes into a heap obj. We don't keep the Python descriptor object.
187
199
188
200
uint8_t * descriptor_bytes = gc_alloc (bufinfo .len , false, false);
189
201
memcpy (descriptor_bytes , bufinfo .buf , bufinfo .len );
@@ -206,8 +218,12 @@ uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) {
206
218
}
207
219
208
220
void common_hal_usb_hid_device_send_report (usb_hid_device_obj_t * self , uint8_t * report , uint8_t len , uint8_t report_id ) {
209
- if (len != self -> in_report_length ) {
210
- mp_raise_ValueError_varg (translate ("Buffer incorrect size. Should be %d bytes." ), self -> in_report_length );
221
+ // report_id and len have already been validated for this device.
222
+ size_t id_idx = get_report_id_idx (self , report_id );
223
+
224
+ if (len != self -> in_report_lengths [id_idx ]) {
225
+ mp_raise_ValueError_varg (translate ("Buffer incorrect size. Should be %d bytes." ),
226
+ self -> in_report_lengths [id_idx ]);
211
227
}
212
228
213
229
// Wait until interface is ready, timeout = 2 seconds
@@ -225,14 +241,25 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *
225
241
}
226
242
}
227
243
244
+ mp_obj_t common_hal_usb_hid_device_get_last_received_report (usb_hid_device_obj_t * self , uint8_t report_id ) {
245
+ // report_id has already been validated for this deveice.
246
+ size_t id_idx = get_report_id_idx (self , report_id );
247
+ return mp_obj_new_bytes (self -> out_report_buffers [id_idx ], self -> out_report_lengths [id_idx ]);
248
+ }
228
249
229
250
void usb_hid_device_create_report_buffers (usb_hid_device_obj_t * self ) {
230
- for (size_t i = 0 ; i < self -> num_report_ids ; count ++ ) {
231
- if (self -> out_report_length > 0 ) {
232
- self -> out_report_buffers [i ] = self -> out_report_lengths [i ] > 0
233
- ? gc_alloc (self -> out_report_length , false, true /*long-lived*/ )
234
- : NULL ;
235
- }
251
+ for (size_t i = 0 ; i < self -> num_report_ids ; i ++ ) {
252
+ // The IN buffers are used only for tud_hid_get_report_cb(),
253
+ // which is an unusual case. Normally we can just pass the data directly with tud_hid_report().
254
+ self -> in_report_buffers [i ] =
255
+ self -> in_report_lengths [i ] > 0
256
+ ? gc_alloc (self -> in_report_lengths [i ], false, true /*long-lived*/ )
257
+ : NULL ;
258
+
259
+ self -> out_report_buffers [i ] =
260
+ self -> out_report_lengths [i ] > 0
261
+ ? gc_alloc (self -> out_report_lengths [i ], false, true /*long-lived*/ )
262
+ : NULL ;
236
263
}
237
264
}
238
265
@@ -254,25 +281,27 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
254
281
memcpy (buffer , hid_device -> in_report_buffers [id_idx ], reqlen );
255
282
return reqlen ;
256
283
}
284
+ return 0 ;
285
+ }
257
286
258
287
// Callbacks invoked when we received Set_Report request through control endpoint
259
- void tud_hid_set_report_cb (uint8_t itf , uint8_t report_id , hid_report_type_t report_type , uint8_t const * buffer , uint16_t bufsize ) {
260
- (void )itf ;
261
- if (report_type == HID_REPORT_TYPE_INVALID ) {
262
- report_id = buffer [0 ];
263
- buffer ++ ;
264
- bufsize -- ;
265
- } else if (report_type != HID_REPORT_TYPE_OUTPUT ) {
266
- return ;
267
- }
288
+ void tud_hid_set_report_cb (uint8_t itf , uint8_t report_id , hid_report_type_t report_type , uint8_t const * buffer , uint16_t bufsize ) {
289
+ (void )itf ;
290
+ if (report_type == HID_REPORT_TYPE_INVALID ) {
291
+ report_id = buffer [0 ];
292
+ buffer ++ ;
293
+ bufsize -- ;
294
+ } else if (report_type != HID_REPORT_TYPE_OUTPUT ) {
295
+ return ;
296
+ }
268
297
269
- usb_hid_device_obj_t * hid_device ;
270
- size_t id_idx ;
271
- // Find device with this report id, and get the report id index.
272
- if (usb_hid_get_device_with_report_id (report_id , & hid_device , & id_idx )) {
273
- // If a report of the correct size has been read, save it in the proper OUT report buffer.
274
- if (hid_device && hid_device -> out_report_lengths [id_idx ] >= bufsize ) {
275
- memcpy (hid_device -> out_report_buffers [id_idx ], buffer , bufsize );
276
- }
298
+ usb_hid_device_obj_t * hid_device ;
299
+ size_t id_idx ;
300
+ // Find device with this report id, and get the report id index.
301
+ if (usb_hid_get_device_with_report_id (report_id , & hid_device , & id_idx )) {
302
+ // If a report of the correct size has been read, save it in the proper OUT report buffer.
303
+ if (hid_device && hid_device -> out_report_lengths [id_idx ] >= bufsize ) {
304
+ memcpy (hid_device -> out_report_buffers [id_idx ], buffer , bufsize );
277
305
}
278
306
}
307
+ }
0 commit comments