diff --git a/klippy/chelper/serialqueue.c b/klippy/chelper/serialqueue.c index b6500fe621d5..e6810933aabc 100644 --- a/klippy/chelper/serialqueue.c +++ b/klippy/chelper/serialqueue.c @@ -62,6 +62,7 @@ struct serialqueue { int ready_bytes, upcoming_bytes, need_ack_bytes, last_ack_bytes; uint64_t need_kick_clock; struct list_head notify_queue; + double last_write_fail_time; // Received messages struct list_head receive_queue; // Fastreader support @@ -376,8 +377,16 @@ do_write(struct serialqueue *sq, void *buf, int buflen) int ret = write(sq->serial_fd, &cf, sizeof(cf)); if (ret < 0) { report_errno("can write", ret); + double curtime = get_monotonic(); + if (!sq->last_write_fail_time) { + sq->last_write_fail_time = curtime; + } else if (curtime > sq->last_write_fail_time + 10.0) { + errorf("Halting reads due to CAN write errors."); + pollreactor_do_exit(sq->pr); + } return; } + sq->last_write_fail_time = 0.0; buf += size; buflen -= size; } diff --git a/src/stm32/usbfs.c b/src/stm32/usbfs.c index d166fbb7ace9..ad2e7b3eb56e 100644 --- a/src/stm32/usbfs.c +++ b/src/stm32/usbfs.c @@ -236,7 +236,8 @@ usb_read_bulk_out(void *data, uint_fast8_t max_len) return count; } -static uint32_t bulk_in_push_count, bulk_in_pop_flag; +static uint32_t bulk_in_push_pos, bulk_in_pop_flag; +#define BI_START 2 int_fast8_t usb_send_bulk_in(void *data, uint_fast8_t len) @@ -245,8 +246,8 @@ usb_send_bulk_in(void *data, uint_fast8_t len) // No buffer space available return -1; uint32_t ep = USB_CDC_EP_BULK_IN; - int bufnum = bulk_in_push_count & 1; - bulk_in_push_count++; + uint32_t bipp = bulk_in_push_pos, bufnum = bipp & 1; + bulk_in_push_pos = bipp ^ 1; btable_write_packet(ep, bufnum, data, len); writel(&bulk_in_pop_flag, USB_EP_DTOG_RX); @@ -254,7 +255,18 @@ usb_send_bulk_in(void *data, uint_fast8_t len) uint32_t epr = USB_EPR[ep]; if (epr_is_dbuf_blocking(epr) && readl(&bulk_in_pop_flag)) { writel(&bulk_in_pop_flag, 0); - USB_EPR[ep] = calc_epr_bits(epr, 0, 0) | USB_EP_DTOG_RX; + if (unlikely(bipp & BI_START)) { + // Two packets are always sent when starting in double + // buffering mode, so wait for second packet before starting. + if (bipp == (BI_START | 1)) { + bulk_in_push_pos = 0; + writel(&bulk_in_pop_flag, USB_EP_KIND); // Dummy flag + USB_EPR[ep] = calc_epr_bits(epr, USB_EPTX_STAT + , USB_EP_TX_VALID); + } + } else { + USB_EPR[ep] = calc_epr_bits(epr, 0, 0) | USB_EP_DTOG_RX; + } } return len; @@ -319,9 +331,8 @@ usb_set_configure(void) USB_EPR[ep] = calc_epr_bits(USB_EPR[ep], USB_EPRX_STAT, USB_EP_RX_VALID); ep = USB_CDC_EP_BULK_IN; - bulk_in_push_count = 0; + bulk_in_push_pos = BI_START; writel(&bulk_in_pop_flag, 0); - USB_EPR[ep] = calc_epr_bits(USB_EPR[ep], USB_EPTX_STAT, USB_EP_TX_VALID); } @@ -342,12 +353,12 @@ usb_reset(void) ep = USB_CDC_EP_BULK_OUT; USB_EPR[ep] = (USB_CDC_EP_BULK_OUT | USB_EP_BULK | USB_EP_KIND - | USB_EP_RX_VALID | USB_EP_TX_NAK | USB_EP_DTOG_TX); + | USB_EP_RX_NAK | USB_EP_DTOG_TX); bulk_out_push_flag = USB_EP_DTOG_TX; ep = USB_CDC_EP_BULK_IN; USB_EPR[ep] = (USB_CDC_EP_BULK_IN | USB_EP_BULK | USB_EP_KIND - | USB_EP_RX_NAK | USB_EP_TX_NAK); + | USB_EP_TX_NAK); bulk_in_pop_flag = USB_EP_DTOG_RX; USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM;