Change in osmo-e1-hardware[master]: icE1usb fw: USB control request handling

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
Thu Dec 17 17:02:57 UTC 2020


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-e1-hardware/+/21775 )


Change subject: icE1usb fw: USB control request handling
......................................................................

icE1usb fw: USB control request handling

This introduces a number of vendor-specific control requests for
configuration of the icE1usb from the host software.

Closes: OS#4675
Change-Id: I9d28566ba21a2a78def5e4a0ba07ecbc4a583aa9
---
A firmware/ice40-riscv/icE1usb/ice1usb_proto.h
M firmware/ice40-riscv/icE1usb/usb_e1.c
2 files changed, 196 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-e1-hardware refs/changes/75/21775/1

diff --git a/firmware/ice40-riscv/icE1usb/ice1usb_proto.h b/firmware/ice40-riscv/icE1usb/ice1usb_proto.h
new file mode 100644
index 0000000..b636ec6
--- /dev/null
+++ b/firmware/ice40-riscv/icE1usb/ice1usb_proto.h
@@ -0,0 +1,70 @@
+#pragma once
+
+/* Header file describing the USB protocol between the icE1usb firmware and the host
+ * software (currently really only osmo-e1d) */
+
+/***********************************************************************
+ * Control Endpoint / Device Requests
+ ***********************************************************************/
+
+/*! returns a bit-mask of optional device capabilities (see enum e1usb_dev_capability) */
+#define ICE1USB_DEV_GET_CAPABILITIES	0x01
+#define ICE1USB_DEV_GET_FW_BUILD	0x02
+
+enum e1usb_dev_capability {
+	/*! Does this board have a GPS-DO */
+	ICE1USB_DEV_CAP_GPSDO,
+};
+
+
+/* Interface Requests */
+
+/*! returns a bit-mask of optional device capabilities (see enum e1usb_intf_capability) */
+#define ICE1USB_INTF_GET_CAPABILITIES	0x01
+#define ICE1USB_INTF_SET_TX_CFG		0x02	/*!< struct ice1usb_tx_config */
+#define ICE1USB_INTF_GET_TX_CFG		0x03	/*!< struct ice1usb_tx_config */
+#define ICE1USB_INTF_SET_RX_CFG		0x04	/*!< struct ice1usb_rx_config */
+#define ICE1USB_INTF_GET_RX_CFG		0x05	/*!< struct ice1usb_rx_config */
+
+//enum e1usb_intf_capability { };
+
+enum ice1usb_tx_mode {
+	ICE1USB_TX_MODE_TRANSP		= 0,
+	ICE1USB_TX_MODE_TS0		= 1,
+	ICE1USB_TX_MODE_TS0_CRC4	= 2,
+	ICE1USB_TX_MODE_TS0_CRC4_E	= 3,
+};
+
+enum ice1usb_tx_timing {
+	ICE1USB_TX_TIME_SRC_LOCAL	= 0,
+	ICE1USB_TX_TIME_SRC_REMOTE	= 1,
+};
+
+enum ice1usb_tx_ext_loopback {
+	ICE1USB_TX_EXT_LOOPBACK_OFF	= 0,
+	ICE1USB_TX_EXT_LOOPBACK_SAME	= 1,
+	ICE1USB_TX_EXT_LOOPBACK_CROSS	= 2,
+};
+
+/* ICE1USB_INTF_{GET,SET}_TX_CFG */
+struct ice1usb_tx_config {
+	uint8_t mode;		/*!< enum ice1usb_tx_mode */
+	uint8_t timing;		/*!< enum ice1usb_tx_timing */
+	uint8_t ext_loopback;	/*!< enum ice1usb_tx_ext_loopback */
+	uint8_t alarm;		/*!< 1 = transmit alarm; 0 = don't */
+} __attribute__((packed));
+
+
+enum ice1usb_rx_mode {
+	/*! transparent, unaligned bitstream */
+	ICE1USB_RX_MODE_TRANSP		= 0,
+	/*! alignment to E1 frame */
+	ICE1USB_RX_MODE_FRAME		= 2,
+	/*! alignment to E1 multiframe */
+	ICE1USB_RX_MODE_MULTIFRAME	= 3,
+};
+
+/* ICE1USB_INTF_{GET,SET}_RX_CFG */
+struct ice1usb_rx_config {
+	uint8_t mode;		/*!< enum ice1usb_rx_mode */
+} __attribute__((packed));
diff --git a/firmware/ice40-riscv/icE1usb/usb_e1.c b/firmware/ice40-riscv/icE1usb/usb_e1.c
index e594a99..e910852 100644
--- a/firmware/ice40-riscv/icE1usb/usb_e1.c
+++ b/firmware/ice40-riscv/icE1usb/usb_e1.c
@@ -15,12 +15,28 @@
 #include "console.h"
 #include "misc.h"
 #include "e1.h"
+#include "e1_hw.h"
+
+#include "ice1usb_proto.h"
 
 struct {
 	bool running;		/* are we running (transceiving USB data)? */
 	int out_bdi;		/* buffer descriptor index for OUT EP */
 	int in_bdi;		/* buffer descriptor index for IN EP */
-} g_usb_e1;
+	struct ice1usb_tx_config tx_cfg;
+	struct ice1usb_rx_config rx_cfg;
+} g_usb_e1 = {
+	/* default configuration at power-up */
+	.tx_cfg = {
+		.mode		= ICE1USB_TX_MODE_TS0_CRC4_E,
+		.timing		= ICE1USB_TX_TIME_SRC_REMOTE,
+		.ext_loopback	= ICE1USB_TX_EXT_LOOPBACK_OFF,
+		.alarm		= 0,
+	},
+	.rx_cfg = {
+		.mode		= ICE1USB_RX_MODE_MULTIFRAME,
+	},
+};
 
 
 /* Hack */
@@ -253,10 +269,119 @@
 	return USB_FND_SUCCESS;
 }
 
+static bool
+_set_tx_mode_done(struct usb_xfer *xfer)
+{
+	const struct ice1usb_tx_config *cfg = (const struct ice1usb_tx_config *) xfer->data;
+	printf("set_tx_mode %02x%02x%02x%02x\r\n",
+		xfer->data[0], xfer->data[1], xfer->data[2], xfer->data[3]);
+	g_usb_e1.tx_cfg = *cfg;
+	e1_tx_config(E1_TX_CR_ENABLE |
+			((cfg->mode & 2) << 1) |
+			((cfg->timing & 1) << 3) |
+			((cfg->alarm & 1) << 4) |
+			((cfg->ext_loopback & 2) << 5) );
+	return true;
+}
+
+static bool
+_set_rx_mode_done(struct usb_xfer *xfer)
+{
+	const struct ice1usb_rx_config *cfg = (const struct ice1usb_rx_config *) xfer->data;
+	printf("set_rx_mode %02x\r\n", xfer->data[0]);
+	g_usb_e1.rx_cfg = *cfg;
+	e1_rx_config(E1_RX_CR_ENABLE | (cfg->mode << 1));
+	return true;
+}
+
+/* per-interface requests */
+static enum usb_fnd_resp
+_e1_ctrl_req_intf(struct usb_ctrl_req *req, struct usb_xfer *xfer)
+{
+	unsigned int i;
+
+	switch (req->bRequest) {
+	case ICE1USB_INTF_GET_CAPABILITIES:
+		/* no optional capabilities yet */
+		xfer->len = 0;
+		break;
+	case ICE1USB_INTF_SET_TX_CFG:
+		if (req->wLength < sizeof(struct ice1usb_tx_config))
+			return USB_FND_ERROR;
+		xfer->cb_done = _set_tx_mode_done;
+		xfer->cb_ctx = req;
+		xfer->len = sizeof(struct ice1usb_tx_config);
+		break;
+	case ICE1USB_INTF_GET_TX_CFG:
+		if (req->wLength < sizeof(struct ice1usb_tx_config))
+			return USB_FND_ERROR;
+		memcpy(xfer->data, &g_usb_e1.tx_cfg, sizeof(struct ice1usb_tx_config));
+		xfer->len = sizeof(struct ice1usb_tx_config);
+		break;
+	case ICE1USB_INTF_SET_RX_CFG:
+		if (req->wLength < sizeof(struct ice1usb_rx_config))
+			return USB_FND_ERROR;
+		xfer->cb_done = _set_rx_mode_done;
+		xfer->cb_ctx = req;
+		xfer->len = sizeof(struct ice1usb_rx_config);
+		break;
+	case ICE1USB_INTF_GET_RX_CFG:
+		if (req->wLength < sizeof(struct ice1usb_rx_config))
+			return USB_FND_ERROR;
+		memcpy(xfer->data, &g_usb_e1.rx_cfg, sizeof(struct ice1usb_rx_config));
+		xfer->len = sizeof(struct ice1usb_rx_config);
+		break;
+	default:
+		return USB_FND_ERROR;
+	}
+
+	return USB_FND_SUCCESS;
+}
+
+/* device-global requests */
+static enum usb_fnd_resp
+_e1_ctrl_req_dev(struct usb_ctrl_req *req, struct usb_xfer *xfer)
+{
+	switch (req->bRequest) {
+	case ICE1USB_DEV_GET_CAPABILITIES:
+		xfer->data[0] = (1 << ICE1USB_DEV_CAP_GPSDO);
+		xfer->len = 1;
+		break;
+	default:
+		return USB_FND_ERROR;
+	}
+
+	return USB_FND_SUCCESS;
+}
+
+
+/* USB host issues a control request to us */
+static enum usb_fnd_resp
+_e1_ctrl_req(struct usb_ctrl_req *req, struct usb_xfer *xfer)
+{
+	if (USB_REQ_TYPE(req) != USB_REQ_TYPE_VENDOR)
+		return USB_FND_CONTINUE;
+
+	switch (USB_REQ_RCPT(req)) {
+	case USB_REQ_RCPT_DEV:
+		return _e1_ctrl_req_dev(req, xfer);
+	case USB_REQ_RCPT_INTF:
+		if (req->wIndex != 0)
+			return USB_FND_ERROR;
+		return _e1_ctrl_req_intf(req, xfer);
+	case USB_REQ_RCPT_EP:
+	case USB_REQ_RCPT_OTHER:
+	default:
+		return USB_FND_ERROR;
+	}
+}
+
+
 static struct usb_fn_drv _e1_drv = {
 	.set_conf	= _e1_set_conf,
         .set_intf       = _e1_set_intf,
         .get_intf       = _e1_get_intf,
+	.ctrl_req	= _e1_ctrl_req,
 };
 
 void

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-e1-hardware/+/21775
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: I9d28566ba21a2a78def5e4a0ba07ecbc4a583aa9
Gerrit-Change-Number: 21775
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201217/18986ec2/attachment.htm>


More information about the gerrit-log mailing list