Change in osmo-e1-hardware[master]: icE1usb fw: Expose error conditions from E1 driver

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Tue Jan 5 22:39:20 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-e1-hardware/+/21715 )

Change subject: icE1usb fw: Expose error conditions from E1 driver
......................................................................

icE1usb fw: Expose error conditions from E1 driver

This will allow the USB interface code to report the errors to the
host PC.

Related: OS#4674
Change-Id: Iba3e00a2b28a2fef6dbd986bfc706c1619c3a3ed
---
M firmware/ice40-riscv/icE1usb/e1.c
M firmware/ice40-riscv/icE1usb/e1.h
M firmware/ice40-riscv/icE1usb/ice1usb_proto.h
M firmware/ice40-riscv/icE1usb/usb_desc_app.c
M firmware/ice40-riscv/icE1usb/usb_e1.c
5 files changed, 108 insertions(+), 4 deletions(-)

Approvals:
  Jenkins Builder: Verified
  tnt: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved



diff --git a/firmware/ice40-riscv/icE1usb/e1.c b/firmware/ice40-riscv/icE1usb/e1.c
index 16c8c80..5e57480 100644
--- a/firmware/ice40-riscv/icE1usb/e1.c
+++ b/firmware/ice40-riscv/icE1usb/e1.c
@@ -232,6 +232,7 @@
 		int in_flight;
 		enum e1_pipe_state state;
 	} tx;
+	struct e1_error_count errors;
 } g_e1;
 
 
@@ -360,6 +361,12 @@
 	return e1f_valid_frames(&g_e1.rx.fifo);
 }
 
+const struct e1_error_count *
+e1_get_error_count(void)
+{
+	return &g_e1.errors;
+}
+
 void
 e1_poll(void)
 {
@@ -374,10 +381,12 @@
 	if (e1_regs->rx.csr & E1_RX_SR_ALIGNED) {
 		e1_platform_led_set(0, E1P_LED_GREEN, E1P_LED_ST_ON);
 		led_color(0, 48, 0);
+		g_e1.errors.flags &= ~(E1_ERR_F_LOS|E1_ERR_F_ALIGN_ERR);
 	} else {
 		e1_platform_led_set(0, E1P_LED_GREEN, E1P_LED_ST_BLINK);
-		/* TODO: completely off if rx tick counter not incrementing */
 		led_color(48, 0, 0);
+		g_e1.errors.flags |= E1_ERR_F_ALIGN_ERR;
+		/* TODO: completely off if rx tick counter not incrementing */
 	}
 
 	/* Recover any done TX BD */
@@ -390,8 +399,10 @@
 	while ( (bd = e1_regs->rx.bd) & E1_BD_VALID ) {
 		/* FIXME: CRC status ? */
 		e1f_multiframe_write_commit(&g_e1.rx.fifo);
-		if ((bd & (E1_BD_CRC0 | E1_BD_CRC1)) != (E1_BD_CRC0 | E1_BD_CRC1))
+		if ((bd & (E1_BD_CRC0 | E1_BD_CRC1)) != (E1_BD_CRC0 | E1_BD_CRC1)) {
 			printf("b: %03x\n", bd);
+			g_e1.errors.crc++;
+		}
 		g_e1.rx.in_flight--;
 	}
 
@@ -410,6 +421,7 @@
 		if (!(e1_regs->rx.csr & E1_RX_SR_ALIGNED)) {
 			printf("[!] E1 rx misalign\n");
 			g_e1.rx.state = RECOVER;
+			g_e1.errors.align++;
 		}
 	}
 
@@ -418,6 +430,7 @@
 		if (e1_regs->rx.csr & E1_RX_SR_OVFL) {
 			printf("[!] E1 overflow %d\n", g_e1.rx.in_flight);
 			g_e1.rx.state = RECOVER;
+			g_e1.errors.ovfl++;
 		}
 	}
 
@@ -449,6 +462,7 @@
 		if (e1_regs->tx.csr & E1_TX_SR_UNFL) {
 			printf("[!] E1 underflow %d\n", g_e1.tx.in_flight);
 			g_e1.tx.state = RECOVER;
+			g_e1.errors.unfl++;
 		}
 	}
 
diff --git a/firmware/ice40-riscv/icE1usb/e1.h b/firmware/ice40-riscv/icE1usb/e1.h
index fcd4284..8ba9838 100644
--- a/firmware/ice40-riscv/icE1usb/e1.h
+++ b/firmware/ice40-riscv/icE1usb/e1.h
@@ -14,6 +14,19 @@
 void e1_tx_config(uint16_t cr);
 void e1_rx_config(uint16_t cr);
 
+#define E1_ERR_F_ALIGN_ERR	0x01
+#define E1_ERR_F_LOS		0x02
+
+struct e1_error_count {
+	uint16_t crc;
+	uint16_t align;
+	uint16_t ovfl;
+	uint16_t unfl;
+	uint8_t flags;
+};
+
+const struct e1_error_count *e1_get_error_count(void);
+
 volatile uint8_t *e1_data_ptr(int mf, int frame, int ts);
 unsigned int e1_data_ofs(int mf, int frame, int ts);
 
diff --git a/firmware/ice40-riscv/icE1usb/ice1usb_proto.h b/firmware/ice40-riscv/icE1usb/ice1usb_proto.h
index 61e12ad..71f7236 100644
--- a/firmware/ice40-riscv/icE1usb/ice1usb_proto.h
+++ b/firmware/ice40-riscv/icE1usb/ice1usb_proto.h
@@ -75,3 +75,32 @@
 struct ice1usb_rx_config {
 	uint8_t mode;		/*!< enum ice1usb_rx_mode */
 } __attribute__((packed));
+
+
+/***********************************************************************
+ * Interrupt Endpoint
+ ***********************************************************************/
+
+enum ice1usb_irq_type {
+	ICE1USB_IRQ_T_ERRCNT		= 1,
+};
+
+/* Ensue ro keep those in sync with e1.h */
+#define ICE1USB_ERR_F_ALIGN_ERR	0x01
+#define ICE1USB_ERR_F_LOS	0x02
+
+struct ice1usb_irq_err {
+	/* 16-bit little-endian counters */
+	uint16_t crc;
+	uint16_t align;
+	uint16_t ovfl;
+	uint16_t unfl;
+	uint8_t flags;
+} __attribute__((packed));
+
+struct ice1usb_irq {
+	uint8_t type; 		/*!< enum ice1usb_irq_type */
+	union {
+		struct ice1usb_irq_err errors;
+	} u;
+} __attribute__((packed));
diff --git a/firmware/ice40-riscv/icE1usb/usb_desc_app.c b/firmware/ice40-riscv/icE1usb/usb_desc_app.c
index 9fe3968..153d70e 100644
--- a/firmware/ice40-riscv/icE1usb/usb_desc_app.c
+++ b/firmware/ice40-riscv/icE1usb/usb_desc_app.c
@@ -28,12 +28,14 @@
 			struct usb_ep_desc ep_data_in;
 			struct usb_ep_desc ep_data_out;
 			struct usb_ep_desc ep_fb;
+			struct usb_ep_desc ep_interrupt;
 		} __attribute__ ((packed)) off;
 		struct {
 			struct usb_intf_desc intf;
 			struct usb_ep_desc ep_data_in;
 			struct usb_ep_desc ep_data_out;
 			struct usb_ep_desc ep_fb;
+			struct usb_ep_desc ep_interrupt;
 		} __attribute__ ((packed)) on;
 	} __attribute__ ((packed)) e1;
 
@@ -79,7 +81,7 @@
 				.bDescriptorType	= USB_DT_INTF,
 				.bInterfaceNumber	= 0,
 				.bAlternateSetting	= 0,
-				.bNumEndpoints		= 3,
+				.bNumEndpoints		= 4,
 				.bInterfaceClass	= 0xff,
 				.bInterfaceSubClass	= 0xe1,
 				.bInterfaceProtocol	= 0x00,
@@ -109,6 +111,14 @@
 				.wMaxPacketSize		= 0,
 				.bInterval		= 3,
 			},
+			.ep_interrupt = {
+				.bLength		= sizeof(struct usb_ep_desc),
+				.bDescriptorType	= USB_DT_EP,
+				.bEndpointAddress	= 0x83,
+				.bmAttributes		= 0x03,
+				.wMaxPacketSize		= 10,
+				.bInterval		= 3,
+			},
 		},
 		.on = {
 			.intf = {
@@ -116,7 +126,7 @@
 				.bDescriptorType	= USB_DT_INTF,
 				.bInterfaceNumber	= 0,
 				.bAlternateSetting	= 1,
-				.bNumEndpoints		= 3,
+				.bNumEndpoints		= 4,
 				.bInterfaceClass	= 0xff,
 				.bInterfaceSubClass	= 0xe1,
 				.bInterfaceProtocol	= 0x00,
@@ -146,6 +156,14 @@
 				.wMaxPacketSize		= 8,
 				.bInterval		= 3,
 			},
+			.ep_interrupt = {
+				.bLength		= sizeof(struct usb_ep_desc),
+				.bDescriptorType	= USB_DT_EP,
+				.bEndpointAddress	= 0x83,
+				.bmAttributes		= 0x03,
+				.wMaxPacketSize		= 10,
+				.bInterval		= 3,
+			},
 		},
 	},
 #if 0
diff --git a/firmware/ice40-riscv/icE1usb/usb_e1.c b/firmware/ice40-riscv/icE1usb/usb_e1.c
index 0698de5..bbbb24e 100644
--- a/firmware/ice40-riscv/icE1usb/usb_e1.c
+++ b/firmware/ice40-riscv/icE1usb/usb_e1.c
@@ -25,6 +25,7 @@
 	int in_bdi;		/* buffer descriptor index for IN EP */
 	struct ice1usb_tx_config tx_cfg;
 	struct ice1usb_rx_config rx_cfg;
+	struct e1_error_count last_err;
 } g_usb_e1;
 
 /* default configuration at power-up */
@@ -87,6 +88,29 @@
 	if (!g_usb_e1.running)
 		return;
 
+	/* EP3 IRQ */
+	if ((usb_ep_regs[3].in.bd[0].csr & USB_BD_STATE_MSK) != USB_BD_STATE_RDY_DATA) {
+		const struct e1_error_count *cur_err = e1_get_error_count();
+		if (memcmp(cur_err, &g_usb_e1.last_err, sizeof(*cur_err))) {
+			struct ice1usb_irq errmsg = {
+				.type = ICE1USB_IRQ_T_ERRCNT,
+				.u = {
+					.errors = {
+						.crc = cur_err->crc,
+						.align = cur_err->align,
+						.ovfl = cur_err->ovfl,
+						.unfl = cur_err->unfl,
+						.flags = cur_err->flags,
+					}
+				}
+			};
+			printf("E");
+			usb_data_write(usb_ep_regs[3].in.bd[0].ptr, &errmsg, sizeof(errmsg));
+			usb_ep_regs[3].in.bd[0].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(sizeof(errmsg));
+			g_usb_e1.last_err = *cur_err;
+		}
+	}
+
 	/* EP2 IN */
 	bdi = g_usb_e1.in_bdi;
 
@@ -213,6 +237,7 @@
 	usb_ep_boot(intf, 0x01, true);
 	usb_ep_boot(intf, 0x81, true);
 	usb_ep_boot(intf, 0x82, true);
+	usb_ep_boot(intf, 0x83, true);
 
 	return USB_FND_SUCCESS;
 }
@@ -274,6 +299,11 @@
 	/* EP1 IN: Queue buffer */
 	_usb_fill_feedback_ep();
 
+	/* EP3 IN: Interrupt */
+	usb_ep_regs[3].in.status = USB_EP_TYPE_INT;
+	usb_ep_regs[3].in.bd[0].ptr = 68;
+	usb_ep_regs[3].in.bd[0].csr = 0;
+
 	return USB_FND_SUCCESS;
 }
 

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-e1-hardware/+/21715
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-e1-hardware
Gerrit-Branch: master
Gerrit-Change-Id: Iba3e00a2b28a2fef6dbd986bfc706c1619c3a3ed
Gerrit-Change-Number: 21715
Gerrit-PatchSet: 8
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: tnt <tnt at 246tNt.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210105/b8c6d683/attachment.htm>


More information about the gerrit-log mailing list