When testing rx_pending and rx_active in a loop, the following race
can have happened:
- we test rx_pending and find it clear
- the packet's last byte finishes and rx_pending is set
- the EOP is detected and rx_active is cleared
- we test rx_active and conclude that the packet has terminated
Thus, we don't reach the test of rx_pending and miss the packet's
last byte.
This patch changes the SIE_RX_PENDING register such that it allows
both rx_active and rx_pending to be retrieved atomically.
---
cores/softusb/rtl/softusb_sie.v | 2 +-
softusb-input/main.c | 10 +++++++---
softusb-input/sie.h | 4 +++-
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/cores/softusb/rtl/softusb_sie.v b/cores/softusb/rtl/softusb_sie.v
index 7e09d1a..531aea2 100644
--- a/cores/softusb/rtl/softusb_sie.v
+++ b/cores/softusb/rtl/softusb_sie.v
@@ -96,7 +96,7 @@ always @(posedge usb_clk) begin
if(io_re)
rx_pending <= 1'b0;
end
- 6'h0a: io_do <= rx_pending;
+ 6'h0a: io_do <= { rx_pending, rx_active };
6'h0b: io_do <= rx_active;
6'h0c: begin
io_do <= rx_error_pending;
diff --git a/softusb-input/main.c b/softusb-input/main.c
index 1bb6bf8..bb052a1 100644
--- a/softusb-input/main.c
+++ b/softusb-input/main.c
@@ -137,13 +137,17 @@ static const char bitstuff_error[] PROGMEM = "RX bitstuff
error\n";
#define WAIT_RX(end) \
do { \
unsigned timeout = 0x200; \
- while(!rio8(SIE_RX_PENDING)) { \
+ unsigned char status; \
+ while(1) { \
+ status = rio8(SIE_RX_STATUS); \
+ if(status & RX_PENDING) \
+ break; \
+ if(!(status & RX_ACTIVE)) \
+ goto end; \
if(!--timeout) \
goto timeout; \
if(rio8(SIE_RX_ERROR)) \
goto error; \
- if(!rio8(SIE_RX_ACTIVE)) \
- goto end; \
} \
} while (0)
diff --git a/softusb-input/sie.h b/softusb-input/sie.h
index bdd4f4d..12cb29f 100644
--- a/softusb-input/sie.h
+++ b/softusb-input/sie.h
@@ -33,7 +33,9 @@
#define SIE_TX_BUSRESET 0x08
#define SIE_RX_DATA 0x09
-#define SIE_RX_PENDING 0x0a
+#define SIE_RX_STATUS 0x0a
+#define RX_PENDING 0x02
+#define RX_ACTIVE 0x01
#define SIE_RX_ACTIVE 0x0b
#define SIE_RX_ERROR 0x0c
--
1.7.1
_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode