Skip to content

Commit 0e73fca

Browse files
nkarstensdlech
authored andcommitted
pbdrv/usb: Periodically send status.
Implement Pybricks status reporting over USB. TODO: this should only be enabled if the USB host subscribes. Current implementation is always on. Signed-off-by: Nate Karstens <[email protected]>
1 parent caa1fbf commit 0e73fca

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

lib/pbio/drv/usb/usb_stm32.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
3333
static 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);
3536
static volatile uint32_t usb_in_sz;
3637
static volatile uint32_t usb_response_sz;
38+
static volatile uint32_t usb_status_sz;
3739
static volatile bool transmitting;
3840

3941
static 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

Comments
 (0)