driver-gekko.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227
  1. /*
  2. * Copyright 2012-2013 Andrew Smith
  3. * Copyright 2012 Xiangfu <xiangfu@openmobilefree.com>
  4. * Copyright 2013-2015 Con Kolivas <kernel@kolivas.org>
  5. * Copyright 2015 David McKinnon
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the Free
  9. * Software Foundation; either version 3 of the License, or (at your option)
  10. * any later version. See COPYING for more details.
  11. */
  12. /*
  13. * This is a driver for GekkoScience hardware, based initially off of the icarus driver.
  14. * I have been cutting out a lot of garbage but it's still pretty crappy.
  15. * Supported hardware:
  16. * - GekkoScience Compac USB stick
  17. *
  18. * Todo: Currently, most stuff. Gut out a lot of broken functionality and leave only "u3"
  19. * support as the compac runs well as a U3. It will need more work to drive multiple
  20. * chips.
  21. */
  22. #include <float.h>
  23. #include <limits.h>
  24. #include <pthread.h>
  25. #include <stdint.h>
  26. #include <stdio.h>
  27. #include <strings.h>
  28. #include <sys/time.h>
  29. #include <unistd.h>
  30. #include <math.h>
  31. #include "config.h"
  32. #include "driver-gekko.h"
  33. #include "crc.h"
  34. #ifdef WIN32
  35. #include <windows.h>
  36. #endif
  37. #include "compat.h"
  38. #include <unistd.h>
  39. #include "miner.h"
  40. #include "usbutils.h"
  41. // The serial I/O speed - Linux uses a define 'B115200' in bits/termios.h
  42. //#define GEKKO_IO_SPEED 115200
  43. static bool compac_prepare(struct thr_info *thr);
  44. uint32_t bmcrc(unsigned char *ptr, uint32_t len)
  45. {
  46. unsigned char c[5] = {1, 1, 1, 1, 1};
  47. uint32_t i, c1, ptr_idx = 0;
  48. for (i = 0; i < len; i++) {
  49. c1 = c[1];
  50. c[1] = c[0];
  51. c[0] = c[4] ^ ((ptr[ptr_idx] & (0x80 >> (i % 8))) ? 1 : 0);
  52. c[4] = c[3];
  53. c[3] = c[2];
  54. c[2] = c1 ^ c[0];
  55. if (((i + 1) % 8) == 0)
  56. ptr_idx++;
  57. }
  58. return (c[4] * 0x10) | (c[3] * 0x08) | (c[2] * 0x04) | (c[1] * 0x02) | (c[0] * 0x01);
  59. }
  60. void dumpbuffer(struct cgpu_info *compac, int LOG_LEVEL, char *note, unsigned char *ptr, uint32_t len)
  61. {
  62. struct COMPAC_INFO *info = compac->device_data;
  63. if (opt_log_output || LOG_LEVEL <= opt_log_level) {
  64. char str[1024];
  65. const char * hex = "0123456789ABCDEF";
  66. char * pout = str;
  67. int i = 0;
  68. for(; i < 0xFF && i < len - 1; ++i){
  69. *pout++ = hex[(*ptr>>4)&0xF];
  70. *pout++ = hex[(*ptr++)&0xF];
  71. *pout++ = ':';
  72. }
  73. *pout++ = hex[(*ptr>>4)&0xF];
  74. *pout++ = hex[(*ptr)&0xF];
  75. *pout = 0;
  76. applog(LOG_LEVEL, "%s %i: %s: %s", compac->drv->name, compac->device_id, note, str);
  77. }
  78. }
  79. static int compac_micro_send(struct cgpu_info *compac, uint8_t cmd, uint8_t channel, uint8_t value)
  80. {
  81. struct COMPAC_INFO *info = compac->device_data;
  82. int bytes = 1;
  83. int read_bytes = 1;
  84. int micro_temp;
  85. uint8_t temp;
  86. unsigned short usb_val;
  87. char null[255];
  88. // synchronous : safe to run in the listen thread.
  89. if (!info->micro_found) {
  90. return 0;
  91. }
  92. // Baud Rate : 500,000
  93. usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF3; // low byte: bitmask - 1111 0011 - CB1(HI), CB0(HI)
  94. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
  95. cgsleep_ms(2);
  96. //usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, 0x06, (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
  97. info->cmd[0] = cmd | channel;
  98. info->cmd[1] = value;
  99. if (value != 0x00 || cmd == M2_SET_VCORE) {
  100. bytes = 2;
  101. }
  102. usb_read_timeout(compac, (char *)info->rx, 255, &read_bytes, 1, C_GETRESULTS);
  103. dumpbuffer(compac, LOG_INFO, "(micro) TX", info->cmd, bytes);
  104. usb_write(compac, (char *)info->cmd, bytes, &read_bytes, C_REQUESTRESULTS);
  105. memset(info->rx, 0, info->rx_len);
  106. usb_read_timeout(compac, (char *)info->rx, 1, &read_bytes, 5, C_GETRESULTS);
  107. if (read_bytes > 0) {
  108. dumpbuffer(compac, LOG_INFO, "(micro) RX", info->rx, read_bytes);
  109. switch (cmd) {
  110. case 0x20:
  111. temp = info->rx[0];
  112. micro_temp = 32 + 1.8 * temp;
  113. if (micro_temp != info->micro_temp) {
  114. info->micro_temp = micro_temp;
  115. applog(LOG_WARNING, "%s %d: micro temp changed to %d°C / %.1f°F", compac->drv->name, compac->device_id, temp, info->micro_temp);
  116. }
  117. break;
  118. default:
  119. break;
  120. }
  121. }
  122. // Restore Baud Rate
  123. //usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, (info->bauddiv + 1), (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
  124. usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF2; // low byte: bitmask - 1111 0010 - CB1(HI), CB0(LO)
  125. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
  126. cgsleep_ms(2);
  127. return read_bytes;
  128. }
  129. static void compac_send(struct cgpu_info *compac, unsigned char *req_tx, uint32_t bytes, uint32_t crc_bits)
  130. {
  131. struct COMPAC_INFO *info = compac->device_data;
  132. int read_bytes = 1;
  133. int read_wait = 0;
  134. int i;
  135. //leave original buffer intact
  136. for (i = 0; i < bytes; i++) {
  137. info->cmd[i] = req_tx[i];
  138. }
  139. info->cmd[bytes - 1] |= bmcrc(req_tx, crc_bits);
  140. cgsleep_ms(1);
  141. dumpbuffer(compac, LOG_INFO, "TX", info->cmd, bytes);
  142. usb_write(compac, (char *)info->cmd, bytes, &read_bytes, C_REQUESTRESULTS);
  143. }
  144. static void compac_send_chain_inactive(struct cgpu_info *compac)
  145. {
  146. struct COMPAC_INFO *info = compac->device_data;
  147. int i;
  148. applog(LOG_INFO,"%s %d: sending chain inactive for %d chip(s)", compac->drv->name, compac->device_id, info->chips);
  149. if (info->asic_type == BM1387) {
  150. unsigned char buffer[5] = {0x55, 0x05, 0x00, 0x00, 0x00};
  151. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);; // chain inactive
  152. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);; // chain inactive
  153. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);; // chain inactive
  154. for (i = 0; i < info->chips; i++) {
  155. buffer[0] = 0x41;
  156. buffer[1] = 0x05;
  157. buffer[2] = (0x100 / info->chips) * i;
  158. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);;
  159. }
  160. unsigned char gateblk[9] = {0x58, 0x09, 0x00, 0x1C, 0x40, 0x20, 0x99, 0x80, 0x01};
  161. gateblk[6] = 0x80 | info->bauddiv;
  162. compac_send(compac, gateblk, sizeof(gateblk), 8 * sizeof(gateblk) - 8);; // chain inactive
  163. } else if (info->asic_type == BM1384) {
  164. unsigned char buffer[] = {0x85, 0x00, 0x00, 0x00};
  165. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5); // chain inactive
  166. for (i = 0; i < info->chips; i++) {
  167. buffer[0] = 0x01;
  168. buffer[1] = (0x100 / info->chips) * i;
  169. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  170. }
  171. buffer[0] = 0x86; // GATEBLK
  172. buffer[1] = 0x00;
  173. buffer[2] = 0x9a; // 0x80 | 0x1a;
  174. //compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  175. }
  176. if (info->mining_state != MINER_MINING) {
  177. applog(info->log_startup, "%s %d: open cores @ %.2fMHz", compac->drv->name, compac->device_id, info->frequency);
  178. info->zero_check = 0;
  179. info->task_hcn = 0;
  180. info->mining_state = MINER_OPEN_CORE;
  181. }
  182. }
  183. static void compac_set_frequency(struct cgpu_info *compac, float frequency)
  184. {
  185. struct COMPAC_INFO *info = compac->device_data;
  186. uint32_t i, r, r1, r2, r3, p1, p2, pll;
  187. if (info->asic_type == BM1387) {
  188. unsigned char buffer[] = {0x58, 0x09, 0x00, 0x0C, 0x00, 0x50, 0x02, 0x41, 0x00}; //250MHz -- osc of 25MHz
  189. frequency = bound(frequency, 50, 900);
  190. frequency = ceil(100 * (frequency) / 625.0) * 6.25;
  191. if (frequency < 400) {
  192. buffer[7] = 0x41;
  193. buffer[5] = (frequency * 8) / 25;
  194. } else if (frequency < 600) {
  195. buffer[7] = 0x21;
  196. buffer[5] = (frequency * 4) / 25;
  197. } else {
  198. buffer[7] = 0x11;
  199. buffer[5] = (frequency * 2) / 25;
  200. }
  201. applog(LOG_WARNING, "%s %d: setting frequency to %.2fMHz", compac->drv->name, compac->device_id, frequency);
  202. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
  203. info->frequency = frequency;
  204. } else if (info->asic_type == BM1384) {
  205. unsigned char buffer[] = {0x82, 0x0b, 0x83, 0x00};
  206. frequency = bound(frequency, 6, 500);
  207. frequency = ceil(100 * (frequency) / 625.0) * 6.25;
  208. info->frequency = frequency;
  209. r = floor(log(info->frequency/25) / log(2));
  210. r1 = 0x0785 - r;
  211. r2 = 0x200 / pow(2, r);
  212. r3 = 25 * pow(2, r);
  213. p1 = r1 + r2 * (info->frequency - r3) / 6.25;
  214. p2 = p1 * 2 + (0x7f + r);
  215. pll = ((uint32_t)(info->frequency) % 25 == 0 ? p1 : p2);
  216. if (info->frequency < 100) {
  217. pll = 0x0783 - 0x80 * (100 - info->frequency) / 6.25;
  218. }
  219. buffer[1] = (pll >> 8) & 0xff;
  220. buffer[2] = (pll) & 0xff;
  221. applog(LOG_WARNING, "%s %d: setting frequency to %.2fMHz", compac->drv->name, compac->device_id, frequency);
  222. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  223. buffer[0] = 0x84;
  224. buffer[1] = 0x00;
  225. buffer[2] = 0x00;
  226. // compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  227. buffer[2] = 0x04;
  228. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  229. }
  230. info->hashrate = info->chips * info->frequency * info->cores * 1000000;
  231. info->fullscan_ms = 1000.0 * 0xffffffffull / info->hashrate;
  232. info->scanhash_ms = bound(info->fullscan_ms / 2, 1, 100);
  233. info->ticket_mask = bound(pow(2, ceil(log(info->hashrate / (2.0 * 0xffffffffull)) / log(2))) - 1, 0, 4000);
  234. info->ticket_mask = (info->asic_type == BM1387) ? 0 : info->ticket_mask;
  235. info->difficulty = info->ticket_mask + 1;
  236. }
  237. static uint64_t compac_check_nonce(struct cgpu_info *compac)
  238. {
  239. struct COMPAC_INFO *info = compac->device_data;
  240. uint32_t nonce = (info->rx[3] << 0) | (info->rx[2] << 8) | (info->rx[1] << 16) | (info->rx[0] << 24);
  241. uint32_t hwe = compac->hw_errors;
  242. uint32_t job_id, i;
  243. uint64_t hashes = 0;
  244. struct timeval now;
  245. if (info->asic_type == BM1387) {
  246. job_id = info->rx[5] & 0xff;
  247. } else if (info->asic_type == BM1384) {
  248. job_id = info->rx[4] ^ 0x80;
  249. }
  250. if (job_id > info->max_job_id || (abs(info->job_id - job_id) > 3 && abs(info->max_job_id - job_id + info->job_id) > 3)) {
  251. return hashes;
  252. }
  253. if (!info->active_work[job_id] &&
  254. !(job_id > 0 && info->active_work[job_id - 1]) &&
  255. !(job_id > 1 && info->active_work[job_id - 2]) &&
  256. !(job_id > 2 && info->active_work[job_id - 3])) {
  257. return hashes;
  258. }
  259. cgtime(&now);
  260. info->nonces++;
  261. info->nonceless = 0;
  262. if (nonce == info->prev_nonce) {
  263. applog(LOG_INFO, "%s %d: Duplicate Nonce : %08x @ %02x [%02x %02x %02x %02x %02x %02x %02x]", compac->drv->name, compac->device_id, nonce, job_id,
  264. info->rx[0], info->rx[1], info->rx[2], info->rx[3], info->rx[4], info->rx[5], info->rx[6]);
  265. info->dups++;
  266. if (info->dups == 1) {
  267. info->mining_state = MINER_MINING_DUPS;
  268. }
  269. return hashes;
  270. } else {
  271. info->dups = 0;
  272. }
  273. hashes = info->difficulty * 0xffffffffull;
  274. info->prev_nonce = nonce;
  275. applog(LOG_INFO, "%s %d: Device reported nonce: %08x @ %02x", compac->drv->name, compac->device_id, nonce, job_id);
  276. struct work *work = info->work[job_id];
  277. bool active_work = info->active_work[job_id];
  278. if (info->vmask) {
  279. // force check last few nonces by [job_id - 1]
  280. if (info->asic_type == BM1387) {
  281. for (i = 0; i <= 3; i++) {
  282. if (job_id >= i) {
  283. if (info->active_work[job_id - i]) {
  284. work = info->work[job_id - i];
  285. active_work = info->active_work[job_id - i];
  286. if (active_work && work) {
  287. work->micro_job_id = pow(2, i);
  288. memcpy(work->data, &(work->pool->vmask_001[work->micro_job_id]), 4);
  289. if (test_nonce(work, nonce)) {
  290. applog(LOG_INFO, "%s %d: AsicBoost nonce found : midstate%d", compac->drv->name, compac->device_id, i);
  291. break;
  292. }
  293. }
  294. }
  295. }
  296. }
  297. }
  298. }
  299. if (!active_work || !work) {
  300. return hashes;
  301. }
  302. work->device_diff = info->difficulty;
  303. if (submit_nonce(info->thr, work, nonce)) {
  304. cgtime(&info->last_nonce);
  305. info->accepted++;
  306. info->failing = false;
  307. } else {
  308. if (hwe != compac->hw_errors) {
  309. cgtime(&info->last_hwerror);
  310. }
  311. }
  312. return hashes;
  313. }
  314. static void compac_update_work(struct cgpu_info *compac)
  315. {
  316. struct COMPAC_INFO *info = compac->device_data;
  317. int i;
  318. for (i = 0; i < JOB_MAX; i++) {
  319. info->active_work[i] = false;
  320. }
  321. info->update_work = 1;
  322. }
  323. static void compac_flush_buffer(struct cgpu_info *compac)
  324. {
  325. int read_bytes = 1;
  326. unsigned char resp[32];
  327. while (read_bytes) {
  328. usb_read_timeout(compac, (char *)resp, 32, &read_bytes, 1, C_REQUESTRESULTS);
  329. }
  330. }
  331. static void compac_flush_work(struct cgpu_info *compac)
  332. {
  333. compac_flush_buffer(compac);
  334. compac_update_work(compac);
  335. }
  336. static void compac_toggle_reset(struct cgpu_info *compac)
  337. {
  338. struct COMPAC_INFO *info = compac->device_data;
  339. unsigned short usb_val;
  340. applog(LOG_WARNING,"%s %d: Toggling ASIC nRST to reset", compac->drv->name, compac->device_id);
  341. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_RESET, info->interface, C_RESET);
  342. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_DATA, FTDI_VALUE_DATA_BTS, info->interface, C_SETDATA);
  343. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD_BTS, (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
  344. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW, FTDI_VALUE_FLOW, info->interface, C_SETFLOW);
  345. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_PURGE_TX, info->interface, C_PURGETX);
  346. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_PURGE_RX, info->interface, C_PURGERX);
  347. usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF2; // low byte: bitmask - 1111 0010 - CB1(HI)
  348. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
  349. cgsleep_ms(30);
  350. usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF0; // low byte: bitmask - 1111 0000 - CB1(LO)
  351. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
  352. cgsleep_ms(30);
  353. usb_val = (FTDI_BITMODE_CBUS << 8) | 0xF2; // low byte: bitmask - 1111 0010 - CB1(HI)
  354. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BITMODE, usb_val, info->interface, C_SETMODEM);
  355. cgsleep_ms(30);
  356. cgtime(&info->last_reset);
  357. }
  358. static void busy_work(struct COMPAC_INFO *info)
  359. {
  360. memset(info->task, 0, info->task_len);
  361. if (info->asic_type == BM1387) {
  362. info->task[0] = 0x21;
  363. info->task[1] = info->task_len;
  364. info->task[2] = info->job_id & 0xff;
  365. info->task[3] = ((opt_gekko_boost) ? 0x04 : 0x01);
  366. memset(info->task + 8, 0xff, 12);
  367. unsigned short crc = crc16_false(info->task, info->task_len - 2);
  368. info->task[info->task_len - 2] = (crc >> 8) & 0xff;
  369. info->task[info->task_len - 1] = crc & 0xff;
  370. } else if (info->asic_type == BM1384) {
  371. if (info->mining_state == MINER_MINING) {
  372. info->task[39] = info->ticket_mask & 0xff;
  373. stuff_msb(info->task + 40, info->task_hcn);
  374. }
  375. info->task[51] = info->job_id & 0xff;
  376. }
  377. }
  378. static void init_task(struct COMPAC_INFO *info)
  379. {
  380. struct work *work = info->work[info->job_id];
  381. memset(info->task, 0, info->task_len);
  382. if (info->asic_type == BM1387) {
  383. info->task[0] = 0x21;
  384. info->task[1] = info->task_len;
  385. info->task[2] = info->job_id & 0xff;
  386. info->task[3] = ((opt_gekko_boost) ? 0x04 : 0x01);
  387. if (info->mining_state == MINER_MINING) {
  388. stuff_reverse(info->task + 8, work->data + 64, 12);
  389. stuff_reverse(info->task + 20, work->midstate, 32);
  390. if (opt_gekko_boost) {
  391. stuff_reverse(info->task + 20 + 32, work->midstate1, 32);
  392. stuff_reverse(info->task + 20 + 32 + 32, work->midstate2, 32);
  393. stuff_reverse(info->task + 20 + 32 + 32 + 32, work->midstate3, 32);
  394. }
  395. } else {
  396. memset(info->task + 8, 0xff, 12);
  397. }
  398. unsigned short crc = crc16_false(info->task, info->task_len - 2);
  399. info->task[info->task_len - 2] = (crc >> 8) & 0xff;
  400. info->task[info->task_len - 1] = crc & 0xff;
  401. } else if (info->asic_type == BM1384) {
  402. if (info->mining_state == MINER_MINING) {
  403. stuff_reverse(info->task, work->midstate, 32);
  404. stuff_reverse(info->task + 52, work->data + 64, 12);
  405. info->task[39] = info->ticket_mask & 0xff;
  406. stuff_msb(info->task + 40, info->task_hcn);
  407. }
  408. info->task[51] = info->job_id & 0xff;
  409. }
  410. }
  411. static void *compac_mine(void *object)
  412. {
  413. struct cgpu_info *compac = (struct cgpu_info *)object;
  414. struct COMPAC_INFO *info = compac->device_data;
  415. struct work *work = NULL;
  416. struct work *old_work = NULL;
  417. struct timeval now;
  418. struct sched_param param;
  419. int i, read_bytes, sleep_ms, policy, ret_nice;
  420. uint32_t err = 0;
  421. uint64_t hashes = 0;
  422. uint64_t max_task_wait = 0;
  423. float wait_factor = ((opt_gekko_boost && info->asic_type == BM1387) ? 1.8 : 0.6);
  424. #ifndef WIN32
  425. ret_nice = nice(-15);
  426. #else /* WIN32 */
  427. pthread_getschedparam(pthread_self(), &policy, &param);
  428. param.sched_priority = sched_get_priority_max(policy);
  429. pthread_setschedparam(pthread_self(), policy, &param);
  430. ret_nice = param.sched_priority;
  431. #endif /* WIN32 */
  432. applog(LOG_INFO, "%s %d: work thread niceness (%d)", compac->drv->name, compac->device_id, ret_nice);
  433. max_task_wait = bound(wait_factor * info->fullscan_ms, 1, 3 * info->fullscan_ms);
  434. sleep_ms = bound(ceil(max_task_wait/8.0), 1, 200);
  435. while (info->mining_state != MINER_SHUTDOWN) {
  436. cgtime(&now);
  437. if (compac->deven == DEV_DISABLED || compac->usbinfo.nodev || info->mining_state != MINER_MINING) {
  438. cgsleep_ms(10);
  439. } else if (info->update_work || (ms_tdiff(&now, &info->last_task) > max_task_wait)) {
  440. info->update_work = 0;
  441. max_task_wait = bound(wait_factor * info->fullscan_ms, 1, 3 * info->fullscan_ms);
  442. sleep_ms = bound(ceil(max_task_wait/15.0), 1, 200);
  443. if (info->asic_type == BM1387 && ms_tdiff(&now, &info->monitor_time) > 30000) {
  444. int max_nononce = 3000.0 * (200.0 / info->frequency_requested);
  445. if (ms_tdiff(&now, &info->last_nonce) > max_nononce) {
  446. applog(LOG_WARNING,"%s %d: missing nonces", compac->drv->name, compac->device_id);
  447. info->mining_state = MINER_RESET;
  448. continue;
  449. }
  450. }
  451. if (ms_tdiff(&now, &info->last_frequency_ping) > 5000) {
  452. if (info->asic_type == BM1387) {
  453. unsigned char buffer[] = {0x54, 0x05, 0x00, 0x0C, 0x00}; // PLL_PARAMETER
  454. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
  455. } else if (info->asic_type == BM1384) {
  456. unsigned char buffer[] = {0x84, 0x00, 0x04, 0x00};
  457. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  458. }
  459. cgtime(&info->last_frequency_ping);
  460. if (info->asic_type == BM1384 || info->asic_type == BM1387) {
  461. uint64_t hashrate_5m, hashrate_1m;
  462. hashrate_1m = (double)compac->rolling1 * 1000000ull;
  463. hashrate_5m = (double)compac->rolling5 * 1000000ull;
  464. if ((hashrate_1m < (info->healthy * info->hashrate)) && ms_tdiff(&now, &info->monitor_time) > (3 * 60 * 1000)) {
  465. applog(LOG_WARNING, "%" PRIu64 " : %" PRIu64 " : %" PRIu64, hashrate_1m, hashrate_5m, info->hashrate);
  466. applog(LOG_WARNING,"%s %d: unhealthy miner", compac->drv->name, compac->device_id);
  467. info->mining_state = MINER_RESET;
  468. continue;
  469. }
  470. if (ms_tdiff(&now, &info->last_frequency_report) > (30 + 7500 * 3)) {
  471. applog(LOG_WARNING,"%s %d: asic(s) went offline", compac->drv->name, compac->device_id);
  472. info->mining_state = MINER_RESET;
  473. continue;
  474. }
  475. }
  476. }
  477. if (info->accepted > 10 && ms_tdiff(&now, &info->last_frequency_ping) > 100 &&
  478. ms_tdiff(&info->last_nonce, &info->last_frequency_adjust) > 0 &&
  479. ms_tdiff(&now, &info->last_frequency_adjust) >= bound(opt_gekko_step_delay, 1, 600) * 1000) {
  480. if (info->frequency != info->frequency_requested) {
  481. float new_frequency;
  482. if (info->frequency < info->frequency_requested) {
  483. new_frequency = info->frequency + opt_gekko_step_freq;
  484. if (new_frequency > info->frequency_requested) {
  485. new_frequency = info->frequency_requested;
  486. }
  487. } else {
  488. new_frequency = info->frequency - opt_gekko_step_freq;
  489. if (new_frequency < info->frequency_requested) {
  490. new_frequency = info->frequency_requested;
  491. }
  492. }
  493. compac_set_frequency(compac, new_frequency);
  494. compac_send_chain_inactive(compac);
  495. info->update_work = 1;
  496. info->accepted = 0;
  497. }
  498. cgtime(&info->last_frequency_adjust);
  499. }
  500. work = get_queued(compac);
  501. if (work) {
  502. info->job_id = (info->job_id + 1) % (info->max_job_id - 3);
  503. old_work = info->work[info->job_id];
  504. info->work[info->job_id] = work;
  505. info->active_work[info->job_id] = 1;
  506. info->vmask = work->pool->vmask;
  507. init_task(info);
  508. } else {
  509. busy_work(info);
  510. cgtime(&info->monitor_time);
  511. }
  512. err = usb_write(compac, (char *)info->task, info->task_len, &read_bytes, C_SENDWORK);
  513. if (err != LIBUSB_SUCCESS) {
  514. applog(LOG_WARNING,"%s %d: usb failure (%d)", compac->drv->name, compac->device_id, err);
  515. info->mining_state = MINER_RESET;
  516. continue;
  517. }
  518. if (read_bytes != info->task_len) {
  519. if (ms_tdiff(&now, &info->last_write_error) > (5 * 1000)) {
  520. applog(LOG_WARNING,"%s %d: usb write error [%d:%d]", compac->drv->name, compac->device_id, read_bytes, info->task_len);
  521. cgtime(&info->last_write_error);
  522. }
  523. }
  524. thread_yield();
  525. if (old_work) {
  526. mutex_lock(&info->lock);
  527. work_completed(compac, old_work);
  528. mutex_unlock(&info->lock);
  529. old_work = NULL;
  530. }
  531. info->task_ms = (info->task_ms * 9 + ms_tdiff(&now, &info->last_task)) / 10;
  532. cgtime(&info->last_task);
  533. }
  534. cgsleep_ms(sleep_ms);
  535. }
  536. }
  537. static void *compac_listen(void *object)
  538. {
  539. struct cgpu_info *compac = (struct cgpu_info *)object;
  540. struct COMPAC_INFO *info = compac->device_data;
  541. int read_bytes, crc_ok, cmd_resp;
  542. uint32_t err = 0;
  543. struct timeval now;
  544. while (info->mining_state != MINER_SHUTDOWN) {
  545. memset(info->rx, 0, info->rx_len);
  546. thread_yield();
  547. err = usb_read_timeout(compac, (char *)info->rx, info->rx_len, &read_bytes, 200, C_GETRESULTS);
  548. cgtime(&now);
  549. if (read_bytes > 0) {
  550. cmd_resp = (info->rx[read_bytes - 1] <= 0x1F && bmcrc(info->rx, 8 * read_bytes - 5) == info->rx[read_bytes - 1]) ? 1 : 0;
  551. dumpbuffer(compac, LOG_INFO, "RX", info->rx, read_bytes);
  552. if (cmd_resp && info->rx[0] == 0x80) {
  553. float frequency;
  554. cgtime(&info->last_frequency_report);
  555. if (info->asic_type == BM1387 && (info->rx[2] == 0 || (info->rx[3] >> 4) == 0 || (info->rx[3] & 0x0f) == 0)) {
  556. dumpbuffer(compac, LOG_WARNING, "RX", info->rx, read_bytes);
  557. applog(LOG_WARNING,"%s %d: bad frequency", compac->drv->name, compac->device_id);
  558. } else {
  559. if (info->asic_type == BM1387) {
  560. frequency = 25.0 * info->rx[1] / (info->rx[2] * (info->rx[3] >> 4) * (info->rx[3] & 0x0f));
  561. } else if (info->asic_type == BM1384) {
  562. frequency = (info->rx[1] + 1) * 6.25 / (1 + info->rx[2] & 0x0f) * pow(2, (3 - info->rx[3])) + ((info->rx[2] >> 4) * 6.25);
  563. }
  564. if (frequency != info->frequency) {
  565. applog(LOG_WARNING,"%s %d: frequency changed %.2fMHz -> %.2fMHz", compac->drv->name, compac->device_id, info->frequency, frequency);
  566. } else {
  567. applog(LOG_INFO,"%s %d: chip reported frequency of %.2fMHz", compac->drv->name, compac->device_id, frequency);
  568. }
  569. info->frequency = frequency;
  570. info->hashrate = info->chips * info->frequency * info->cores * 1000000;
  571. info->fullscan_ms = 1000.0 * 0xffffffffull / info->hashrate;
  572. info->scanhash_ms = bound(info->fullscan_ms / 2, 1, 100);
  573. info->ticket_mask = bound(pow(2, ceil(log(info->hashrate / (2.0 * 0xffffffffull)) / log(2))) - 1, 0, 4000);
  574. info->ticket_mask = (info->asic_type == BM1387) ? 0 : info->ticket_mask;
  575. info->difficulty = info->ticket_mask + 1;
  576. }
  577. }
  578. switch (info->mining_state) {
  579. case MINER_CHIP_COUNT:
  580. case MINER_CHIP_COUNT_XX:
  581. if (cmd_resp && info->rx[0] == 0x13) {
  582. info->chips++;
  583. info->mining_state = MINER_CHIP_COUNT_XX;
  584. }
  585. break;
  586. case MINER_OPEN_CORE:
  587. if ((info->rx[0] == 0x72 && info->rx[1] == 0x03 && info->rx[2] == 0xEA && info->rx[3] == 0x83) ||
  588. (info->rx[0] == 0xE1 && info->rx[0] == 0x6B && info->rx[0] == 0xF8 && info->rx[0] == 0x09)) {
  589. //open core nonces = healthy chips.
  590. info->zero_check++;
  591. }
  592. break;
  593. case MINER_MINING:
  594. if (!cmd_resp) {
  595. thread_yield();
  596. mutex_lock(&info->lock);
  597. info->hashes += compac_check_nonce(compac);
  598. mutex_unlock(&info->lock);
  599. }
  600. break;
  601. default:
  602. break;
  603. }
  604. } else {
  605. // RX line is idle, let's squeeze in a command to the micro if needed.
  606. if (info->asic_type == BM1387) {
  607. if (ms_tdiff(&now, &info->last_micro_ping) > 5000 && ms_tdiff(&now, &info->last_task) > 1 && ms_tdiff(&now, &info->last_task) < 3) {
  608. compac_micro_send(compac, M1_GET_TEMP, 0x00, 0x00);
  609. cgtime(&info->last_micro_ping);
  610. }
  611. }
  612. switch (info->mining_state) {
  613. case MINER_CHIP_COUNT_XX:
  614. applog(info->log_startup, "%s %d: found %d chip(s)", compac->drv->name, compac->device_id, info->chips);
  615. info->mining_state = MINER_CHIP_COUNT_OK;
  616. break;
  617. default:
  618. break;
  619. }
  620. }
  621. }
  622. }
  623. static bool compac_init(struct thr_info *thr)
  624. {
  625. int i;
  626. struct cgpu_info *compac = thr->cgpu;
  627. struct COMPAC_INFO *info = compac->device_data;
  628. info->prev_nonce = 0;
  629. info->fail_count = 0;
  630. info->scanhash_ms = 10;
  631. info->log_startup = LOG_WARNING;
  632. memset(info->rx, 0, BUFFER_MAX);
  633. memset(info->tx, 0, BUFFER_MAX);
  634. memset(info->cmd, 0, BUFFER_MAX);
  635. memset(info->end, 0, BUFFER_MAX);
  636. memset(info->task, 0, BUFFER_MAX);
  637. for (i = 0; i < JOB_MAX; i++) {
  638. info->active_work[i] = false;
  639. info->work[i] = NULL;
  640. }
  641. cgtime(&info->last_write_error);
  642. cgtime(&info->last_frequency_adjust);
  643. cgtime(&info->last_frequency_ping);
  644. cgtime(&info->last_micro_ping);
  645. cgtime(&info->last_scanhash);
  646. cgtime(&info->last_reset);
  647. cgtime(&info->last_task);
  648. cgtime(&info->start_time);
  649. cgtime(&info->monitor_time);
  650. switch (info->ident) {
  651. case IDENT_BSC:
  652. case IDENT_GSC:
  653. info->frequency_requested = opt_gekko_gsc_freq;
  654. info->frequency_start = info->frequency_requested;
  655. break;
  656. case IDENT_BSD:
  657. case IDENT_GSD:
  658. info->frequency_requested = opt_gekko_gsd_freq;
  659. info->frequency_start = opt_gekko_start_freq;
  660. break;
  661. case IDENT_BSE:
  662. case IDENT_GSE:
  663. info->frequency_requested = opt_gekko_gse_freq;
  664. info->frequency_start = opt_gekko_start_freq;
  665. break;
  666. case IDENT_GSH:
  667. info->frequency_requested = opt_gekko_gsh_freq;
  668. info->frequency_start = opt_gekko_gsh_freq;
  669. break;
  670. default:
  671. info->frequency_requested = 200;
  672. info->frequency_start = info->frequency_requested;
  673. break;
  674. }
  675. if (info->frequency_start > info->frequency_requested) {
  676. info->frequency_start = info->frequency_requested;
  677. }
  678. info->frequency_requested = ceil(100 * (info->frequency_requested) / 625.0) * 6.25;
  679. info->frequency_start = ceil(100 * (info->frequency_start) / 625.0) * 6.25;
  680. if (!info->rthr.pth) {
  681. pthread_mutex_init(&info->lock, NULL);
  682. pthread_mutex_init(&info->wlock, NULL);
  683. if (thr_info_create(&(info->rthr), NULL, compac_listen, (void *)compac)) {
  684. applog(LOG_ERR, "%s %i: read thread create failed", compac->drv->name, compac->device_id);
  685. return false;
  686. } else {
  687. applog(LOG_INFO, "%s %i: read thread created", compac->drv->name, compac->device_id);
  688. }
  689. if (thr_info_create(&(info->wthr), NULL, compac_mine, (void *)compac)) {
  690. applog(LOG_ERR, "%s %i: write thread create failed", compac->drv->name, compac->device_id);
  691. return false;
  692. } else {
  693. applog(LOG_INFO, "%s %i: write thread created", compac->drv->name, compac->device_id);
  694. }
  695. pthread_detach(info->rthr.pth);
  696. pthread_detach(info->wthr.pth);
  697. }
  698. return true;
  699. }
  700. static int64_t compac_scanwork(struct thr_info *thr)
  701. {
  702. struct cgpu_info *compac = thr->cgpu;
  703. struct COMPAC_INFO *info = compac->device_data;
  704. struct timeval now;
  705. int read_bytes;
  706. uint32_t err = 0;
  707. uint64_t hashes = 0;
  708. if (compac->usbinfo.nodev)
  709. return -1;
  710. thread_yield();
  711. cgtime(&now);
  712. switch (info->mining_state) {
  713. case MINER_INIT:
  714. info->mining_state = MINER_CHIP_COUNT;
  715. info->chips = 0;
  716. info->ramping = 0;
  717. if (info->asic_type == BM1387) {
  718. unsigned char buffer[] = {0x54, 0x05, 0x00, 0x00, 0x00};
  719. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
  720. } else if (info->asic_type == BM1384) {
  721. unsigned char buffer[] = {0x84, 0x00, 0x00, 0x00};
  722. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  723. }
  724. return 0;
  725. break;
  726. case MINER_CHIP_COUNT:
  727. if (ms_tdiff(&now, &info->last_reset) > 5000) {
  728. applog(LOG_WARNING, "%s %d: found 0 chip(s)", compac->drv->name, compac->device_id);
  729. info->mining_state = MINER_RESET;
  730. return 0;
  731. }
  732. break;
  733. case MINER_CHIP_COUNT_OK:
  734. cgsleep_ms(50);
  735. compac_set_frequency(compac, info->frequency_start);
  736. compac_send_chain_inactive(compac);
  737. return 0;
  738. break;
  739. case MINER_OPEN_CORE:
  740. info->job_id = info->ramping % info->max_job_id;
  741. //info->task_hcn = (0xffffffff / info->chips) * (1 + info->ramping) / info->cores;
  742. init_task(info);
  743. dumpbuffer(compac, LOG_DEBUG, "RAMP", info->task, info->task_len);
  744. usb_write(compac, (char *)info->task, info->task_len, &read_bytes, C_SENDWORK);
  745. if (info->ramping > info->cores) {
  746. //info->job_id = 0;
  747. info->mining_state = MINER_OPEN_CORE_OK;
  748. info->task_hcn = (0xffffffff / info->chips);
  749. return 0;
  750. }
  751. info->ramping++;
  752. info->task_ms = (info->task_ms * 9 + ms_tdiff(&now, &info->last_task)) / 10;
  753. cgtime(&info->last_task);
  754. cgsleep_ms(10);
  755. return 0;
  756. break;
  757. case MINER_OPEN_CORE_OK:
  758. applog(info->log_startup, "%s %d: start work @ %.2fMHz", compac->drv->name, compac->device_id, info->frequency);
  759. cgtime(&info->start_time);
  760. cgtime(&info->monitor_time);
  761. cgtime(&info->last_frequency_adjust);
  762. cgtime(&info->last_frequency_ping);
  763. cgtime(&info->last_frequency_report);
  764. cgtime(&info->last_micro_ping);
  765. cgtime(&info->last_nonce);
  766. compac_flush_buffer(compac);
  767. info->log_startup = LOG_WARNING;
  768. info->mining_state = MINER_MINING;
  769. return 0;
  770. break;
  771. case MINER_MINING:
  772. if (ms_tdiff(&now, &info->start_time) > ( 15 * 1000 )) {
  773. info->log_startup = LOG_INFO;
  774. }
  775. break;
  776. case MINER_RESET:
  777. if (info->asic_type == BM1387) {
  778. compac_flush_work(compac);
  779. compac_toggle_reset(compac);
  780. compac_prepare(thr);
  781. info->fail_count++;
  782. info->mining_state = MINER_INIT;
  783. return 0;
  784. } else {
  785. usb_nodev(compac);
  786. return -1;
  787. }
  788. break;
  789. case MINER_MINING_DUPS:
  790. info->mining_state = MINER_MINING;
  791. if ((int)info->frequency == 200) {
  792. //possible terminus reset condition.
  793. compac_set_frequency(compac, info->frequency);
  794. compac_send_chain_inactive(compac);
  795. cgtime(&info->last_frequency_adjust);
  796. } else {
  797. //check for reset condition
  798. if (info->asic_type == BM1384) {
  799. unsigned char buffer[] = {0x84, 0x00, 0x04, 0x00};
  800. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  801. }
  802. cgtime(&info->last_frequency_ping);
  803. }
  804. break;
  805. default:
  806. break;
  807. }
  808. hashes = info->hashes;
  809. info->hashes -= hashes;
  810. cgsleep_ms(info->scanhash_ms);
  811. return hashes;
  812. }
  813. static struct cgpu_info *compac_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
  814. {
  815. struct cgpu_info *compac;
  816. struct COMPAC_INFO *info;
  817. int err, i;
  818. bool exclude_me = 0;
  819. uint32_t baudrate = CP210X_DATA_BAUD;
  820. unsigned int bits = CP210X_BITS_DATA_8 | CP210X_BITS_PARITY_MARK;
  821. compac = usb_alloc_cgpu(&gekko_drv, 1);
  822. if (!usb_init(compac, dev, found)) {
  823. applog(LOG_INFO, "failed usb_init");
  824. compac = usb_free_cgpu(compac);
  825. return NULL;
  826. }
  827. info = cgcalloc(1, sizeof(struct COMPAC_INFO));
  828. compac->device_data = (void *)info;
  829. info->ident = usb_ident(compac);
  830. if (opt_gekko_gsc_detect || opt_gekko_gsd_detect || opt_gekko_gse_detect || opt_gekko_gsh_detect) {
  831. exclude_me = (info->ident == IDENT_BSC && !opt_gekko_gsc_detect);
  832. exclude_me |= (info->ident == IDENT_GSC && !opt_gekko_gsc_detect);
  833. exclude_me |= (info->ident == IDENT_BSD && !opt_gekko_gsd_detect);
  834. exclude_me |= (info->ident == IDENT_GSD && !opt_gekko_gsd_detect);
  835. exclude_me |= (info->ident == IDENT_BSE && !opt_gekko_gse_detect);
  836. exclude_me |= (info->ident == IDENT_GSE && !opt_gekko_gse_detect);
  837. exclude_me |= (info->ident == IDENT_GSH && !opt_gekko_gsh_detect);
  838. }
  839. if (opt_gekko_serial != NULL && (strstr(opt_gekko_serial, compac->usbdev->serial_string) == NULL)) {
  840. exclude_me = true;
  841. }
  842. if (exclude_me) {
  843. usb_uninit(compac);
  844. free(info);
  845. compac->device_data = NULL;
  846. return NULL;
  847. }
  848. switch (info->ident) {
  849. case IDENT_BSC:
  850. case IDENT_GSC:
  851. case IDENT_BSD:
  852. case IDENT_GSD:
  853. case IDENT_BSE:
  854. case IDENT_GSE:
  855. info->asic_type = BM1384;
  856. info->cores = 55;
  857. info->max_job_id = 0x1f;
  858. info->rx_len = 5;
  859. info->task_len = 64;
  860. info->tx_len = 4;
  861. info->healthy = 0.33;
  862. usb_transfer_data(compac, CP210X_TYPE_OUT, CP210X_REQUEST_IFC_ENABLE, CP210X_VALUE_UART_ENABLE, info->interface, NULL, 0, C_ENABLE_UART);
  863. usb_transfer_data(compac, CP210X_TYPE_OUT, CP210X_REQUEST_DATA, CP210X_VALUE_DATA, info->interface, NULL, 0, C_SETDATA);
  864. usb_transfer_data(compac, CP210X_TYPE_OUT, CP210X_REQUEST_BAUD, 0, info->interface, &baudrate, sizeof (baudrate), C_SETBAUD);
  865. usb_transfer_data(compac, CP210X_TYPE_OUT, CP210X_SET_LINE_CTL, bits, info->interface, NULL, 0, C_SETPARITY);
  866. break;
  867. case IDENT_GSH:
  868. info->asic_type = BM1387;
  869. info->rx_len = 7;
  870. info->task_len = 54;
  871. if (opt_gekko_boost) {
  872. info->task_len += 96;
  873. }
  874. info->cores = 114;
  875. info->max_job_id = 0x7f;
  876. info->healthy = 0.75;
  877. compac_toggle_reset(compac);
  878. break;
  879. default:
  880. quit(1, "%s compac_detect_one() invalid %s ident=%d",
  881. compac->drv->dname, compac->drv->dname, info->ident);
  882. }
  883. info->interface = usb_interface(compac);
  884. info->mining_state = MINER_INIT;
  885. applog(LOG_DEBUG, "Using interface %d", info->interface);
  886. if (!add_cgpu(compac))
  887. quit(1, "Failed to add_cgpu in compac_detect_one");
  888. update_usb_stats(compac);
  889. for (i = 0; i < 8; i++) {
  890. compac->unique_id[i] = compac->unique_id[i+3];
  891. }
  892. compac->unique_id[8] = 0;
  893. applog(LOG_WARNING, "%s %d: %s (%s)", compac->drv->name, compac->device_id, compac->usbdev->prod_string, compac->unique_id);
  894. return compac;
  895. }
  896. static void compac_detect(bool __maybe_unused hotplug)
  897. {
  898. usb_detect(&gekko_drv, compac_detect_one);
  899. }
  900. static bool compac_prepare(struct thr_info *thr)
  901. {
  902. struct cgpu_info *compac = thr->cgpu;
  903. struct COMPAC_INFO *info = compac->device_data;
  904. int i;
  905. int read_bytes = 1;
  906. bool miner_ok = true;
  907. info->thr = thr;
  908. info->bauddiv = 0x19; // 115200
  909. //info->bauddiv = 0x0D; // 214286
  910. //info->bauddiv = 0x07; // 375000
  911. //Sanity check and abort to prevent miner thread from being created.
  912. if (info->asic_type == BM1387) {
  913. unsigned char buffer[] = { 0x58, 0x09, 0x00, 0x1C, 0x00, 0x20, 0x07, 0x00, 0x19 };
  914. info->bauddiv = 0x01; // 1.5Mbps baud.
  915. buffer[6] = info->bauddiv;
  916. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
  917. cgsleep_ms(1);
  918. usb_transfer(compac, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, (info->bauddiv + 1), (FTDI_INDEX_BAUD_BTS & 0xff00) | info->interface, C_SETBAUD);
  919. cgsleep_ms(1);
  920. // Ping Micro
  921. if (info->asic_type == BM1387) {
  922. info->vcore = bound(opt_gekko_gsh_vcore, 300, 810);
  923. info->micro_found = 1;
  924. if (!compac_micro_send(compac, M1_GET_TEMP, 0x00, 0x00)) {
  925. info->micro_found = 0;
  926. applog(LOG_INFO, "%s %d: micro not found : dummy mode", compac->drv->name, compac->device_id);
  927. } else {
  928. uint8_t vcc = (info->vcore / 1000.0 - 0.3) / 0.002;
  929. applog(LOG_INFO, "%s %d: requesting vcore of %dmV (%x)", compac->drv->name, compac->device_id, info->vcore, vcc);
  930. compac_micro_send(compac, M2_SET_VCORE, 0x00, vcc); // Default 400mV
  931. }
  932. }
  933. }
  934. if (info->mining_state == MINER_INIT) {
  935. if (info->asic_type == BM1387) {
  936. unsigned char buffer[] = {0x54, 0x05, 0x00, 0x00, 0x00};
  937. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
  938. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 8);
  939. } else if (info->asic_type == BM1384) {
  940. unsigned char buffer[] = {0x84, 0x00, 0x00, 0x00};
  941. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  942. compac_send(compac, buffer, sizeof(buffer), 8 * sizeof(buffer) - 5);
  943. }
  944. miner_ok = false;
  945. while (read_bytes) {
  946. memset(info->rx, 0, info->rx_len);
  947. usb_read_timeout(compac, (char *)info->rx, info->rx_len, &read_bytes, 50, C_GETRESULTS);
  948. if (read_bytes > 0 && info->rx[0] == 0x13) {
  949. dumpbuffer(compac, LOG_INFO, "RX", info->rx, read_bytes);
  950. miner_ok = true;
  951. }
  952. }
  953. if (!miner_ok) {
  954. applog(LOG_WARNING, "%s %d: found 0 chip(s)", compac->drv->name, compac->device_id);
  955. if (info->ident == IDENT_BSD || info->ident == IDENT_GSD) {
  956. //Don't bother retyring, will just waste resources.
  957. compac->deven = DEV_DISABLED;
  958. }
  959. }
  960. }
  961. return true;
  962. }
  963. static void compac_statline(char *buf, size_t bufsiz, struct cgpu_info *compac)
  964. {
  965. struct COMPAC_INFO *info = compac->device_data;
  966. if (info->chips == 0) {
  967. return;
  968. }
  969. if (info->asic_type == BM1387) {
  970. if (info->micro_found) {
  971. tailsprintf(buf, bufsiz, "BM1387:%i %.2fMHz (%d/%d/%d/%.0fF)", info->chips, info->frequency, info->scanhash_ms, info->task_ms, info->fullscan_ms, info->micro_temp);
  972. } else {
  973. if (opt_log_output) {
  974. tailsprintf(buf, bufsiz, "BM1387:%i %.2fMHz (%d/%d/%d)", info->chips, info->frequency, info->scanhash_ms, info->task_ms, info->fullscan_ms);
  975. } else {
  976. tailsprintf(buf, bufsiz, "BM1387:%i %.2fMHz", info->chips, info->frequency);
  977. }
  978. }
  979. } else {
  980. if (opt_log_output) {
  981. tailsprintf(buf, bufsiz, "BM1384:%i %.2fMHz (%d/%d/%d)", info->chips, info->frequency, info->scanhash_ms, info->task_ms, info->fullscan_ms);
  982. } else {
  983. tailsprintf(buf, bufsiz, "BM1384:%i %.2fMHz", info->chips, info->frequency_requested);
  984. }
  985. }
  986. }
  987. static struct api_data *compac_api_stats(struct cgpu_info *compac)
  988. {
  989. struct COMPAC_INFO *info = compac->device_data;
  990. struct api_data *root = NULL;
  991. root = api_add_int(root, "Nonces", &info->nonces, false);
  992. root = api_add_int(root, "Accepted", &info->accepted, false);
  993. //root = api_add_temp(root, "Temp", &info->micro_temp, false);
  994. return root;
  995. }
  996. static void compac_shutdown(struct thr_info *thr)
  997. {
  998. struct cgpu_info *compac = thr->cgpu;
  999. struct COMPAC_INFO *info = compac->device_data;
  1000. if (!compac->usbinfo.nodev) {
  1001. if (info->asic_type == BM1387) {
  1002. compac_micro_send(compac, M2_SET_VCORE, 0x00, 0x00); // 300mV
  1003. compac_toggle_reset(compac);
  1004. } else if (info->asic_type == BM1384 && info->frequency != 100) {
  1005. compac_set_frequency(compac, 100);
  1006. }
  1007. }
  1008. info->mining_state = MINER_SHUTDOWN;
  1009. pthread_join(info->rthr.pth, NULL); // Let thread close.
  1010. pthread_join(info->wthr.pth, NULL); // Let thread close.
  1011. PTH(thr) = 0L;
  1012. }
  1013. uint64_t bound(uint64_t value, uint64_t lower_bound, uint64_t upper_bound)
  1014. {
  1015. if (value < lower_bound)
  1016. return lower_bound;
  1017. if (value > upper_bound)
  1018. return upper_bound;
  1019. return value;
  1020. }
  1021. void stuff_reverse(unsigned char *dst, unsigned char *src, uint32_t len)
  1022. {
  1023. uint32_t i;
  1024. for (i = 0; i < len; i++) {
  1025. dst[i] = src[len - i - 1];
  1026. }
  1027. }
  1028. void stuff_lsb(unsigned char *dst, uint32_t x)
  1029. {
  1030. dst[0] = (x >> 0) & 0xff;
  1031. dst[1] = (x >> 8) & 0xff;
  1032. dst[2] = (x >> 16) & 0xff;
  1033. dst[3] = (x >> 24) & 0xff;
  1034. }
  1035. void stuff_msb(unsigned char *dst, uint32_t x)
  1036. {
  1037. dst[0] = (x >> 24) & 0xff;
  1038. dst[1] = (x >> 16) & 0xff;
  1039. dst[2] = (x >> 8) & 0xff;
  1040. dst[3] = (x >> 0) & 0xff;
  1041. }
  1042. struct device_drv gekko_drv = {
  1043. .drv_id = DRIVER_gekko,
  1044. .dname = "GekkoScience",
  1045. .name = "GSX",
  1046. .hash_work = hash_queued_work,
  1047. .get_api_stats = compac_api_stats,
  1048. .get_statline_before = compac_statline,
  1049. .drv_detect = compac_detect,
  1050. .scanwork = compac_scanwork,
  1051. .flush_work = compac_flush_work,
  1052. .update_work = compac_update_work,
  1053. .thread_prepare = compac_prepare,
  1054. .thread_init = compac_init,
  1055. .thread_shutdown = compac_shutdown,
  1056. };