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.orglaforge 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>