@@ -31,8 +31,10 @@ PROCESS(pbdrv_usb_process, "USB");
3131// to/from FIFOs in 32-bit chunks.
3232static uint8_t usb_in_buf [USBD_PYBRICKS_MAX_PACKET_SIZE ] __aligned (4 );
3333static uint8_t usb_response_buf [1 + sizeof (uint32_t )] __aligned (4 );
34+ static uint8_t usb_status_buf [1 + PBSYS_STATUS_REPORT_SIZE ] __aligned (4 );
3435static volatile uint32_t usb_in_sz ;
3536static volatile uint32_t usb_response_sz ;
37+ static volatile uint32_t usb_status_sz ;
3638static volatile bool transmitting ;
3739
3840static USBD_HandleTypeDef husbd ;
@@ -145,6 +147,7 @@ static USBD_StatusTypeDef Pybricks_Itf_Init(void) {
145147 USBD_Pybricks_SetRxBuffer (& husbd , usb_in_buf );
146148 usb_in_sz = 0 ;
147149 usb_response_sz = 0 ;
150+ usb_status_sz = 0 ;
148151 transmitting = false;
149152
150153 return USBD_OK ;
@@ -192,6 +195,8 @@ static USBD_StatusTypeDef Pybricks_Itf_TransmitCplt(uint8_t *Buf, uint32_t Len,
192195
193196 if (Buf == usb_response_buf ) {
194197 usb_response_sz = 0 ;
198+ } else if (Buf == usb_status_buf ) {
199+ usb_status_sz = 0 ;
195200 } else {
196201 ret = USBD_FAIL ;
197202 }
@@ -240,6 +245,9 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
240245 static PBIO_ONESHOT (pwrdn_oneshot );
241246 static bool bcd_busy ;
242247 static pbio_pybricks_error_t result ;
248+ static struct etimer timer ;
249+ static uint32_t prev_status_flags = ~0 ;
250+ static uint32_t new_status_flags ;
243251
244252 PROCESS_POLLHANDLER ({
245253 if (!bcd_busy && pbio_oneshot (!vbus_active , & no_vbus_oneshot )) {
@@ -258,6 +266,8 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
258266
259267 PROCESS_BEGIN ();
260268
269+ etimer_set (& timer , 500 );
270+
261271 for (;;) {
262272 PROCESS_WAIT_EVENT ();
263273
@@ -302,9 +312,23 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
302312 continue ;
303313 }
304314
315+ new_status_flags = pbsys_status_get_flags ();
316+
317+ // Transmit. Give priority to response, then status updates.
305318 if (usb_response_sz ) {
306319 transmitting = true;
307320 USBD_Pybricks_TransmitPacket (& husbd , usb_response_buf , usb_response_sz );
321+ } else if ((new_status_flags != prev_status_flags ) || etimer_expired (& timer )) {
322+ usb_status_buf [0 ] = USBD_PYBRICKS_IN_EP_MSG_EVENT ;
323+ _Static_assert (sizeof (usb_status_buf ) + 1 >= PBIO_PYBRICKS_EVENT_STATUS_REPORT_SIZE ,
324+ "size of status report does not match size of event" );
325+ usb_status_sz = 1 + pbsys_status_get_status_report (& usb_status_buf [1 ]);
326+
327+ etimer_restart (& timer );
328+ prev_status_flags = new_status_flags ;
329+
330+ transmitting = true;
331+ USBD_Pybricks_TransmitPacket (& husbd , usb_status_buf , usb_status_sz );
308332 }
309333 }
310334
0 commit comments