@@ -31,9 +31,11 @@ PROCESS(pbdrv_usb_process, "USB");
3131// These buffers need to be 32-bit aligned because the USB driver moves data
3232// to/from FIFOs in 32-bit chunks.
3333static uint8_t usb_in_buf [USBD_PYBRICKS_MAX_PACKET_SIZE ] __aligned (4 );
34- static uint8_t usb_response_buf [1 + sizeof (uint32_t )] __aligned (4 ) __aligned (4 );
34+ static uint8_t usb_response_buf [1 + sizeof (uint32_t )] __aligned (4 );
35+ static uint8_t usb_status_buf [1 + PBSYS_STATUS_REPORT_SIZE ] __aligned (4 );
3536static volatile uint32_t usb_in_sz ;
3637static volatile uint32_t usb_response_sz ;
38+ static volatile uint32_t usb_status_sz ;
3739static volatile bool transmitting ;
3840
3941static USBD_HandleTypeDef husbd ;
@@ -146,6 +148,7 @@ static USBD_StatusTypeDef Pybricks_Itf_Init(void) {
146148 USBD_Pybricks_SetRxBuffer (& husbd , usb_in_buf );
147149 usb_in_sz = 0 ;
148150 usb_response_sz = 0 ;
151+ usb_status_sz = 0 ;
149152 transmitting = false;
150153
151154 return USBD_OK ;
@@ -193,6 +196,8 @@ static USBD_StatusTypeDef Pybricks_Itf_TransmitCplt(uint8_t *Buf, uint32_t Len,
193196
194197 if (Buf == usb_response_buf ) {
195198 usb_response_sz = 0 ;
199+ } else if (Buf == usb_status_buf ) {
200+ usb_status_sz = 0 ;
196201 } else {
197202 ret = USBD_FAIL ;
198203 }
@@ -241,6 +246,9 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
241246 static PBIO_ONESHOT (pwrdn_oneshot );
242247 static bool bcd_busy ;
243248 static pbio_pybricks_error_t result ;
249+ static struct etimer timer ;
250+ static uint32_t prev_status_flags = ~0 ;
251+ static uint32_t new_status_flags ;
244252
245253 PROCESS_POLLHANDLER ({
246254 if (!bcd_busy && pbio_oneshot (!vbus_active , & no_vbus_oneshot )) {
@@ -259,6 +267,8 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
259267
260268 PROCESS_BEGIN ();
261269
270+ etimer_set (& timer , 500 );
271+
262272 for (;;) {
263273 PROCESS_WAIT_EVENT ();
264274
@@ -303,7 +313,22 @@ PROCESS_THREAD(pbdrv_usb_process, ev, data) {
303313 continue ;
304314 }
305315
306- if (usb_response_sz ) {
316+ new_status_flags = pbsys_status_get_flags ();
317+
318+ // Transmit. Give priority to status updates, then command response,
319+ // then stdout.
320+ if ((new_status_flags != prev_status_flags ) || etimer_expired (& timer )) {
321+ usb_status_buf [0 ] = USBD_PYBRICKS_IN_EP_MSG_EVENT ;
322+ _Static_assert (sizeof (usb_status_buf ) + 1 >= PBIO_PYBRICKS_EVENT_STATUS_REPORT_SIZE ,
323+ "size of status report does not match size of event" );
324+ usb_status_sz = 1 + pbsys_status_get_status_report (& usb_status_buf [1 ]);
325+
326+ etimer_restart (& timer );
327+ prev_status_flags = new_status_flags ;
328+
329+ transmitting = true;
330+ USBD_Pybricks_TransmitPacket (& husbd , usb_status_buf , usb_status_sz );
331+ } else if (usb_response_sz ) {
307332 transmitting = true;
308333 USBD_Pybricks_TransmitPacket (& husbd , usb_response_buf , usb_response_sz );
309334 }
0 commit comments