icarus AMU config transfers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
diff --git a/driver-icarus.c b/driver-icarus.c
index 12b0ca2..3c66c2f 100644
--- a/driver-icarus.c
+++ b/driver-icarus.c
@@ -218,17 +218,20 @@ static int option_offset = -1;
struct device_drv icarus_drv;
-static void transfer(struct cgpu_info *icarus, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, enum usb_cmds cmd)
+static void _transfer(struct cgpu_info *icarus, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, enum usb_cmds cmd)
{
int err;
- err = usb_transfer(icarus, request_type, bRequest, wValue, wIndex, cmd);
+ err = usb_transfer_data(icarus, request_type, bRequest, wValue, wIndex, data, siz, cmd);
applog(LOG_DEBUG, "%s%i: %s got err %d",
icarus->drv->name, icarus->device_id,
usb_cmdname(cmd), err);
}
+#define transfer(icarus, request_type, bRequest, wValue, wIndex, cmd) \
+ _transfer(icarus, request_type, bRequest, wValue, wIndex, NULL, 0, cmd)
+
// TODO: handle baud
static void icarus_initialise(struct cgpu_info *icarus, __maybe_unused int baud)
{
@@ -296,6 +299,19 @@ static void icarus_initialise(struct cgpu_info *icarus, __maybe_unused int baud)
case IDENT_ICA:
break;
case IDENT_AMU:
+ // Set data control
+ transfer(icarus, CP210X_TYPE_OUT, CP210X_REQUEST_DATA, CP210X_VALUE_DATA,
+ icarus->usbdev->found->interface, C_SETDATA);
+
+ if (icarus->usbinfo.nodev)
+ return;
+
+ // Set the baud
+ uint32_t data = CP210X_DATA_BAUD;
+ _transfer(icarus, CP210X_TYPE_OUT, CP210X_REQUEST_BAUD, 0,
+ icarus->usbdev->found->interface,
+ &data, sizeof(data), C_SETBAUD);
+
break;
case IDENT_CMR:
break;
diff --git a/usbutils.c b/usbutils.c
index ae34eb9..fb1be64 100644
--- a/usbutils.c
+++ b/usbutils.c
@@ -2160,15 +2160,16 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr
return err;
}
-int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned int timeout, enum usb_cmds cmd)
+int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, unsigned int timeout, enum usb_cmds cmd)
{
struct cg_usb_device *usbdev = cgpu->usbdev;
#if DO_USB_STATS
struct timeval tv_start, tv_finish;
#endif
- int err;
+ uint32_t *buf = NULL;
+ int err, i;
- USBDEBUG("USB debug: _usb_transfer(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, timeout, usb_cmdname(cmd));
+ USBDEBUG("USB debug: _usb_transfer(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",siz=%d,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, siz, timeout, usb_cmdname(cmd));
if (cgpu->usbinfo.nodev) {
#if DO_USB_STATS
@@ -2177,15 +2178,34 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest
return LIBUSB_ERROR_NO_DEVICE;
}
+ USBDEBUG("USB debug: @_usb_transfer() data=%s", bin2hex((unsigned char *)data, (size_t)siz));
+
+ if (siz > 0) {
+ siz--;
+ siz >>= 2;
+ siz++;
+ buf = malloc(siz << 2);
+ if (unlikely(!buf))
+ quit(1, "Failed to malloc in _usb_transfer");
+ for (i = 0; i < siz; i++)
+ buf[i] = htole32(data[i]);
+ }
+
+ USBDEBUG("USB debug: @_usb_transfer() buf=%s", bin2hex((unsigned char *)buf, (size_t)(siz << 2)));
+
STATS_TIMEVAL(&tv_start);
err = libusb_control_transfer(usbdev->handle, request_type,
- bRequest, htole16(wValue), htole16(wIndex), NULL, 0,
+ bRequest, htole16(wValue), htole16(wIndex),
+ (unsigned char *)buf, (uint16_t)(siz << 2),
timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout);
STATS_TIMEVAL(&tv_finish);
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0);
USBDEBUG("USB debug: @_usb_transfer(%s (nodev=%s)) err=%d%s", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err));
+ if (buf)
+ free(buf);
+
if (NODEV(err))
release_cgpu(cgpu);
diff --git a/usbutils.h b/usbutils.h
index 3553385..7273e9f 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -12,7 +12,8 @@
#include <libusb.h>
-// for 0x0403/0x6014 FT232H (and possibly others?)
+
+// For 0x0403:0x6014/0x6001 FT232H (and possibly others?)
#define FTDI_TYPE_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT)
#define FTDI_REQUEST_RESET ((uint8_t)0)
@@ -45,6 +46,16 @@
#define FTDI_VALUE_FLOW 0
#define FTDI_VALUE_MODEM 0x0303
+
+// For 0x10c4:0xea60 USB cp210x chip
+#define CP210X_TYPE_OUT 0x41
+
+#define CP210X_REQUEST_DATA 0x07
+#define CP210X_REQUEST_BAUD 0x1e
+
+#define CP210X_VALUE_DATA 0x0303
+#define CP210X_DATA_BAUD 0x0001c200
+
// Use the device defined timeout
#define DEVTIMEOUT 0
@@ -189,7 +200,7 @@ struct api_data *api_usb_stats(int *count);
void update_usb_stats(struct cgpu_info *cgpu);
int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce);
int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds);
-int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned int timeout, enum usb_cmds cmd);
+int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, unsigned int timeout, enum usb_cmds cmd);
void usb_cleanup();
void usb_initialise();
@@ -227,6 +238,9 @@ void usb_initialise();
_usb_write(cgpu, ep, buf, bufsiz, wrote, timeout, cmd)
#define usb_transfer(cgpu, typ, req, val, idx, cmd) \
- _usb_transfer(cgpu, typ, req, val, idx, DEVTIMEOUT, cmd)
+ _usb_transfer(cgpu, typ, req, val, idx, NULL, 0, DEVTIMEOUT, cmd)
+
+#define usb_transfer_data(cgpu, typ, req, val, idx, data, len, cmd) \
+ _usb_transfer(cgpu, typ, req, val, idx, data, len, DEVTIMEOUT, cmd)
#endif