Skip to content

Commit c70fa81

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 5e5ca1d commit c70fa81

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

lib/pbio/drv/usb/usb_stm32.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ PROCESS(pbdrv_usb_process, "USB");
3131
// to/from FIFOs in 32-bit chunks.
3232
static uint8_t usb_in_buf[USBD_PYBRICKS_MAX_PACKET_SIZE] __aligned(4);
3333
static 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);
3435
static volatile uint32_t usb_in_sz;
3536
static volatile uint32_t usb_response_sz;
37+
static volatile uint32_t usb_status_sz;
3638
static volatile bool transmitting;
3739

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

Comments
 (0)