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 submitted this change. ( 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 --- M firmware/ice40-riscv/icE1usb/e1.c M firmware/ice40-riscv/icE1usb/e1.h M firmware/ice40-riscv/icE1usb/fw_app.c A firmware/ice40-riscv/icE1usb/ice1usb_proto.h M firmware/ice40-riscv/icE1usb/usb_e1.c 5 files changed, 224 insertions(+), 18 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 1d8fd30..16c8c80 100644 --- a/firmware/ice40-riscv/icE1usb/e1.c +++ b/firmware/ice40-riscv/icE1usb/e1.c @@ -238,7 +238,7 @@ void -e1_init(bool clk_mode) +e1_init(uint16_t rx_cr, uint16_t tx_cr) { /* Global state init */ memset(&g_e1, 0x00, sizeof(g_e1)); @@ -248,14 +248,11 @@ e1f_reset(&g_e1.tx.fifo, 128, 128); /* Enable Rx */ - g_e1.rx.cr = E1_RX_CR_MODE_MFA | - E1_RX_CR_ENABLE; + g_e1.rx.cr = E1_RX_CR_ENABLE | rx_cr; e1_regs->rx.csr = E1_RX_CR_OVFL_CLR | g_e1.rx.cr; /* Enable Tx */ - g_e1.tx.cr = (clk_mode ? E1_TX_CR_TICK_REMOTE : E1_TX_CR_TICK_LOCAL) | - E1_TX_CR_MODE_TS0_CRC_E | - E1_TX_CR_ENABLE; + g_e1.tx.cr = E1_TX_CR_ENABLE | tx_cr; e1_regs->tx.csr = E1_TX_CR_UNFL_CLR | g_e1.tx.cr; /* State */ diff --git a/firmware/ice40-riscv/icE1usb/e1.h b/firmware/ice40-riscv/icE1usb/e1.h index 05ce19a..fcd4284 100644 --- a/firmware/ice40-riscv/icE1usb/e1.h +++ b/firmware/ice40-riscv/icE1usb/e1.h @@ -7,7 +7,7 @@ #pragma once -void e1_init(bool clk_mode); +void e1_init(uint16_t rx_cr, uint16_t tx_cr); void e1_poll(void); void e1_debug_print(bool data); diff --git a/firmware/ice40-riscv/icE1usb/fw_app.c b/firmware/ice40-riscv/icE1usb/fw_app.c index 62f4b0e..eebc21f 100644 --- a/firmware/ice40-riscv/icE1usb/fw_app.c +++ b/firmware/ice40-riscv/icE1usb/fw_app.c @@ -102,7 +102,7 @@ usb_e1_init(); /* Start */ - e1_init(false); // local tick + e1_init(0, 0); e1_active = true; led_state(true); usb_connect(); @@ -138,16 +138,6 @@ case 'O': e1_debug_print(true); break; - case 'e': - e1_init(true); - e1_active = true; - led_state(true); - break; - case 'E': - e1_init(false); - e1_active = true; - led_state(true); - break; case 'c': usb_connect(); break; diff --git a/firmware/ice40-riscv/icE1usb/ice1usb_proto.h b/firmware/ice40-riscv/icE1usb/ice1usb_proto.h new file mode 100644 index 0000000..61e12ad --- /dev/null +++ b/firmware/ice40-riscv/icE1usb/ice1usb_proto.h @@ -0,0 +1,77 @@ +/* + * ice1usb_proto.h + * + * Copyright (C) 2020 Harald Welte <laforge at osmocom.org> + * SPDX-License-Identifier: MIT + * + * Header file describing the USB protocol between the icE1usb firmware and the host + * software (currently really only osmo-e1d) + */ + +#pragma once + +/*********************************************************************** + * 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 e37edc3..0698de5 100644 --- a/firmware/ice40-riscv/icE1usb/usb_e1.c +++ b/firmware/ice40-riscv/icE1usb/usb_e1.c @@ -15,13 +15,30 @@ #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 */ + struct ice1usb_tx_config tx_cfg; + struct ice1usb_rx_config rx_cfg; } g_usb_e1; +/* default configuration at power-up */ +static const struct ice1usb_tx_config tx_cfg_default = { + .mode = ICE1USB_TX_MODE_TS0_CRC4_E, + .timing = ICE1USB_TX_TIME_SRC_LOCAL, + .ext_loopback = ICE1USB_TX_EXT_LOOPBACK_OFF, + .alarm = 0, +}; + +static const struct ice1usb_rx_config rx_cfg_default = { + .mode = ICE1USB_RX_MODE_MULTIFRAME, +}; + /* Hack */ unsigned int e1_rx_need_data(unsigned int usb_addr, unsigned int max_len, unsigned int *pos); @@ -200,6 +217,21 @@ return USB_FND_SUCCESS; } +static void _perform_tx_config(void) +{ + const struct ice1usb_tx_config *cfg = &g_usb_e1.tx_cfg; + e1_tx_config( ((cfg->mode & 3) << 1) | + ((cfg->timing & 1) << 3) | + ((cfg->alarm & 1) << 4) | + ((cfg->ext_loopback & 3) << 5) ); +} + +static void _perform_rx_config(void) +{ + const struct ice1usb_rx_config *cfg = &g_usb_e1.rx_cfg; + e1_rx_config((cfg->mode << 1)); +} + static enum usb_fnd_resp _e1_set_intf(const struct usb_intf_desc *base, const struct usb_intf_desc *sel) { @@ -213,6 +245,9 @@ if (g_usb_e1.running) return USB_FND_SUCCESS; + _perform_rx_config(); + _perform_tx_config(); + g_usb_e1.running = true; /* Configure EP1 OUT / EP2 IN */ @@ -253,15 +288,122 @@ 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; + _perform_tx_config(); + 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; + _perform_rx_config(); + 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 usb_e1_init(void) { memset(&g_usb_e1, 0x00, sizeof(g_usb_e1)); + g_usb_e1.tx_cfg = tx_cfg_default; + g_usb_e1.rx_cfg = rx_cfg_default; usb_register_function_driver(&_e1_drv); } -- 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: 6 Gerrit-Owner: laforge <laforge at osmocom.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge at osmocom.org> 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/ffa47047/attachment.htm>