From 52a20cf3bbbed517644171a326b6937db56113c3 Mon Sep 17 00:00:00 2001 From: sago35 Date: Sat, 20 Feb 2021 00:16:16 +0900 Subject: [PATCH] atsamd2x: avoid infinite loop when USBCDC is disconnected --- src/machine/machine_atsamd21.go | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/machine/machine_atsamd21.go b/src/machine/machine_atsamd21.go index 830608bd0..4914ef08e 100644 --- a/src/machine/machine_atsamd21.go +++ b/src/machine/machine_atsamd21.go @@ -1465,17 +1465,19 @@ func (pwm PWM) setChannel(timer *sam.TCC_Type, val uint32) { // USBCDC is the USB CDC aka serial over USB interface on the SAMD21. type USBCDC struct { - Buffer *RingBuffer - TxIdx volatile.Register8 - waitTxc bool - sent bool + Buffer *RingBuffer + TxIdx volatile.Register8 + waitTxc bool + waitTxcRetryCount uint8 + sent bool } const ( - usbcdcTxSizeMask uint8 = 0x3F - usbcdcTxBankMask uint8 = ^usbcdcTxSizeMask - usbcdcTxBank1st uint8 = 0x00 - usbcdcTxBank2nd uint8 = usbcdcTxSizeMask + 1 + usbcdcTxSizeMask uint8 = 0x3F + usbcdcTxBankMask uint8 = ^usbcdcTxSizeMask + usbcdcTxBank1st uint8 = 0x00 + usbcdcTxBank2nd uint8 = usbcdcTxSizeMask + 1 + usbcdcTxMaxRetriesAllowed uint8 = 5 ) // Flush flushes buffered data. @@ -1491,6 +1493,7 @@ func (usbcdc *USBCDC) Flush() error { return nil } usbcdc.waitTxc = true + usbcdc.waitTxcRetryCount = 0 // set the data usbEndpointDescriptors[usb_CDC_ENDPOINT_IN].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[usb_CDC_ENDPOINT_IN][bk])))) @@ -1537,6 +1540,14 @@ func (usbcdc *USBCDC) WriteByte(c byte) error { if ok { break + } else if usbcdcTxMaxRetriesAllowed < UART0.waitTxcRetryCount { + mask := interrupt.Disable() + UART0.waitTxc = false + UART0.waitTxcRetryCount = 0 + usbcdc.TxIdx.Set(0) + usbLineInfo.lineState = 0 + interrupt.Restore(mask) + break } else { mask := interrupt.Disable() if UART0.sent { @@ -1764,6 +1775,10 @@ func handleUSB(intr interrupt.Interrupt) { } } } + + if i == usb_CDC_ENDPOINT_IN && UART0.waitTxc { + UART0.waitTxcRetryCount++ + } } UART0.Flush()