Skip to content

Commit 0198f7b

Browse files
ArcaneNibblelaurensvalk
authored andcommitted
pbio/drv/usb/usb_ev3.c: Implement status keepalive timer
Without this timer, if the hub state doesn't change and the user program doesn't output anything, the hub won't be able to detect that the host software has closed (because it never sends anything which could time out). Keeping this state reasonably up-to-date is important for the hub auto-power-off functionality.
1 parent e6ead10 commit 0198f7b

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

lib/pbio/drv/usb/usb_ev3.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,7 @@ static pbio_os_process_t pbdrv_usb_ev3_process;
883883
static pbio_error_t pbdrv_usb_ev3_process_thread(pbio_os_state_t *state, void *context) {
884884
static pbio_os_timer_t delay_timer;
885885
static pbio_os_timer_t tx_timeout_timer;
886+
static pbio_os_timer_t keepalive_timer;
886887
static bool was_transmitting = false;
887888
static bool is_transmitting = false;
888889
static uint32_t prev_status_flags = ~0;
@@ -910,6 +911,7 @@ static pbio_error_t pbdrv_usb_ev3_process_thread(pbio_os_state_t *state, void *c
910911
if (usb_rx_sz && !usb_tx_response_is_not_ready) {
911912
switch (ep1_rx_buf[0]) {
912913
case PBIO_PYBRICKS_OUT_EP_MSG_SUBSCRIBE:
914+
pbio_os_timer_set(&keepalive_timer, 1000);
913915
pbdrv_usb_is_events_subscribed = ep1_rx_buf[1];
914916
ep1_tx_response_buf[0] = PBIO_PYBRICKS_IN_EP_MSG_RESPONSE;
915917
pbio_set_uint32_le(&ep1_tx_response_buf[1], PBIO_PYBRICKS_ERROR_OK);
@@ -936,14 +938,24 @@ static pbio_error_t pbdrv_usb_ev3_process_thread(pbio_os_state_t *state, void *c
936938

937939
// Send status flags if they've changed (and we can)
938940
new_status_flags = pbsys_status_get_flags();
939-
if (pbdrv_usb_is_events_subscribed && !usb_tx_status_is_not_ready && new_status_flags != prev_status_flags) {
941+
if (pbdrv_usb_is_events_subscribed && !usb_tx_status_is_not_ready &&
942+
(new_status_flags != prev_status_flags || pbio_os_timer_is_expired(&keepalive_timer))) {
940943
ep1_tx_status_buf[0] = PBIO_PYBRICKS_IN_EP_MSG_EVENT;
941944
uint32_t usb_status_sz = PBIO_PYBRICKS_USB_MESSAGE_SIZE(pbsys_status_get_status_report(&ep1_tx_status_buf[1]));
942945

943946
usb_tx_status_is_not_ready = true;
944947
usb_setup_tx_dma_desc(CPPI_DESC_TX_STATUS, ep1_tx_status_buf, usb_status_sz);
945948

946949
prev_status_flags = new_status_flags;
950+
951+
if (new_status_flags != prev_status_flags) {
952+
// If we are sending a status because the flags have changed,
953+
// we can bump out the keepalive timer.
954+
pbio_os_timer_set(&keepalive_timer, 1000);
955+
} else {
956+
// Otherwise, we want to send keepalives at a particular rate.
957+
pbio_os_timer_extend(&keepalive_timer);
958+
}
947959
}
948960

949961
// Handle timeouts

0 commit comments

Comments
 (0)