gc3355.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. /*
  2. * Copyright 2014 Nate Woolls
  3. * Copyright 2014 Luke Dashjr
  4. * Copyright 2014 GridSeed Team
  5. * Copyright 2014 Dualminer Team
  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. #include "config.h"
  13. #include "gc3355.h"
  14. #include <stdint.h>
  15. #include <string.h>
  16. #include "miner.h"
  17. #include "driver-icarus.h"
  18. #include "logging.h"
  19. #include "lowl-vcom.h"
  20. #ifndef WIN32
  21. #include <sys/ioctl.h>
  22. #else
  23. #include <io.h>
  24. #endif
  25. // options configurable by the end-user
  26. int opt_sha2_units = -1;
  27. int opt_pll_freq = 0; // default is set in gc3355_set_pll_freq
  28. #define GC3355_CHIP_NAME "gc3355"
  29. #define GC3355_COMMAND_DELAY_MS 20
  30. #define GC3355_WRITE_DELAY_MS 10
  31. // General GC3355 commands
  32. static
  33. const char *firmware_request_cmd[] =
  34. {
  35. "55AAC000909090900000000001000000", // get firmware version of GC3355
  36. NULL
  37. };
  38. // SHA-2 commands
  39. static
  40. const char *sha2_gating_cmd[] =
  41. {
  42. "55AAEF0200000000", // Chip 1 - power down SHA-2 (unless masked w/PLL)
  43. "55AAEF0300000000", // Chip 2
  44. "55AAEF0400000000", // Chip 3
  45. "55AAEF0500000000", // Chip 4
  46. "55AAEF0600000000", // Chip 5
  47. NULL
  48. };
  49. // maps the above SHA chip gating with SHA-2 units
  50. static
  51. const char *sha2_open_cmd[] =
  52. {
  53. "55AAEF0200000001",
  54. "55AAEF0200000003",
  55. "55AAEF0200000007",
  56. "55AAEF020000000F",
  57. "55AAEF020000001F",
  58. "55AAEF020000003F",
  59. "55AAEF020000007F",
  60. "55AAEF02000000FF",
  61. "55AAEF02000001FF",
  62. "55AAEF02000003FF",
  63. "55AAEF02000007FF",
  64. "55AAEF0200000FFF",
  65. "55AAEF0200001FFF",
  66. "55AAEF0200003FFF",
  67. "55AAEF0200007FFF",
  68. "55AAEF020000FFFF",
  69. "55AAEF020001FFFF",
  70. "55AAEF020003FFFF",
  71. "55AAEF020007FFFF",
  72. "55AAEF02000FFFFF",
  73. "55AAEF02001FFFFF",
  74. "55AAEF02003FFFFF",
  75. "55AAEF02007FFFFF",
  76. "55AAEF0200FFFFFF",
  77. "55AAEF0201FFFFFF",
  78. "55AAEF0203FFFFFF",
  79. "55AAEF0207FFFFFF",
  80. "55AAEF020FFFFFFF",
  81. "55AAEF021FFFFFFF",
  82. "55AAEF023FFFFFFF",
  83. "55AAEF027FFFFFFF",
  84. "55AAEF02FFFFFFFF",
  85. "55AAEF0300000001",
  86. "55AAEF0300000003",
  87. "55AAEF0300000007",
  88. "55AAEF030000000F",
  89. "55AAEF030000001F",
  90. "55AAEF030000003F",
  91. "55AAEF030000007F",
  92. "55AAEF03000000FF",
  93. "55AAEF03000001FF",
  94. "55AAEF03000003FF",
  95. "55AAEF03000007FF",
  96. "55AAEF0300000FFF",
  97. "55AAEF0300001FFF",
  98. "55AAEF0300003FFF",
  99. "55AAEF0300007FFF",
  100. "55AAEF030000FFFF",
  101. "55AAEF030001FFFF",
  102. "55AAEF030003FFFF",
  103. "55AAEF030007FFFF",
  104. "55AAEF03000FFFFF",
  105. "55AAEF03001FFFFF",
  106. "55AAEF03003FFFFF",
  107. "55AAEF03007FFFFF",
  108. "55AAEF0300FFFFFF",
  109. "55AAEF0301FFFFFF",
  110. "55AAEF0303FFFFFF",
  111. "55AAEF0307FFFFFF",
  112. "55AAEF030FFFFFFF",
  113. "55AAEF031FFFFFFF",
  114. "55AAEF033FFFFFFF",
  115. "55AAEF037FFFFFFF",
  116. "55AAEF03FFFFFFFF",
  117. "55AAEF0400000001",
  118. "55AAEF0400000003",
  119. "55AAEF0400000007",
  120. "55AAEF040000000F",
  121. "55AAEF040000001F",
  122. "55AAEF040000003F",
  123. "55AAEF040000007F",
  124. "55AAEF04000000FF",
  125. "55AAEF04000001FF",
  126. "55AAEF04000003FF",
  127. "55AAEF04000007FF",
  128. "55AAEF0400000FFF",
  129. "55AAEF0400001FFF",
  130. "55AAEF0400003FFF",
  131. "55AAEF0400007FFF",
  132. "55AAEF040000FFFF",
  133. "55AAEF040001FFFF",
  134. "55AAEF040003FFFF",
  135. "55AAEF040007FFFF",
  136. "55AAEF04000FFFFF",
  137. "55AAEF04001FFFFF",
  138. "55AAEF04003FFFFF",
  139. "55AAEF04007FFFFF",
  140. "55AAEF0400FFFFFF",
  141. "55AAEF0401FFFFFF",
  142. "55AAEF0403FFFFFF",
  143. "55AAEF0407FFFFFF",
  144. "55AAEF040FFFFFFF",
  145. "55AAEF041FFFFFFF",
  146. "55AAEF043FFFFFFF",
  147. "55AAEF047FFFFFFF",
  148. "55AAEF04FFFFFFFF",
  149. "55AAEF0500000001",
  150. "55AAEF0500000003",
  151. "55AAEF0500000007",
  152. "55AAEF050000000F",
  153. "55AAEF050000001F",
  154. "55AAEF050000003F",
  155. "55AAEF050000007F",
  156. "55AAEF05000000FF",
  157. "55AAEF05000001FF",
  158. "55AAEF05000003FF",
  159. "55AAEF05000007FF",
  160. "55AAEF0500000FFF",
  161. "55AAEF0500001FFF",
  162. "55AAEF0500003FFF",
  163. "55AAEF0500007FFF",
  164. "55AAEF050000FFFF",
  165. "55AAEF050001FFFF",
  166. "55AAEF050003FFFF",
  167. "55AAEF050007FFFF",
  168. "55AAEF05000FFFFF",
  169. "55AAEF05001FFFFF",
  170. "55AAEF05003FFFFF",
  171. "55AAEF05007FFFFF",
  172. "55AAEF0500FFFFFF",
  173. "55AAEF0501FFFFFF",
  174. "55AAEF0503FFFFFF",
  175. "55AAEF0507FFFFFF",
  176. "55AAEF050FFFFFFF",
  177. "55AAEF051FFFFFFF",
  178. "55AAEF053FFFFFFF",
  179. "55AAEF057FFFFFFF",
  180. "55AAEF05FFFFFFFF",
  181. "55AAEF0600000001",
  182. "55AAEF0600000003",
  183. "55AAEF0600000007",
  184. "55AAEF060000000F",
  185. "55AAEF060000001F",
  186. "55AAEF060000003F",
  187. "55AAEF060000007F",
  188. "55AAEF06000000FF",
  189. "55AAEF06000001FF",
  190. "55AAEF06000003FF",
  191. "55AAEF06000007FF",
  192. "55AAEF0600000FFF",
  193. "55AAEF0600001FFF",
  194. "55AAEF0600003FFF",
  195. "55AAEF0600007FFF",
  196. "55AAEF060000FFFF",
  197. "55AAEF060001FFFF",
  198. "55AAEF060003FFFF",
  199. "55AAEF060007FFFF",
  200. "55AAEF06000FFFFF",
  201. "55AAEF06001FFFFF",
  202. "55AAEF06003FFFFF",
  203. "55AAEF06007FFFFF",
  204. "55AAEF0600FFFFFF",
  205. "55AAEF0601FFFFFF",
  206. "55AAEF0603FFFFFF",
  207. "55AAEF0607FFFFFF",
  208. "55AAEF060FFFFFFF",
  209. "55AAEF061FFFFFFF",
  210. "55AAEF063FFFFFFF",
  211. "55AAEF067FFFFFFF",
  212. "55AAEF06FFFFFFFF",
  213. NULL
  214. };
  215. static
  216. const char *multichip_init_cmd[] =
  217. {
  218. "55AAC000C0C0C0C00500000001000000", // set number of sub-chips (05 in this case)
  219. "55AAEF020000000000000000000000000000000000000000", // power down all SHA-2 modules
  220. "55AAEF3020000000", // Enable SHA-2 OR NOT - NO SCRYPT ACCEPTS WITHOUT THIS???
  221. NULL
  222. };
  223. static
  224. const char *sha2_init_cmd[] =
  225. {
  226. "55AAEF3020000000", // Enable SHA-2
  227. "55AA1F2817000000", // Enable GCP
  228. NULL
  229. };
  230. // called when initializing GridSeed device
  231. // called while initializing DualMiner when mining in scrypt+sha (dual-mode)
  232. static
  233. const char *scrypt_init_cmd[] =
  234. {
  235. "55AA1F2814000000", // Enable Scrypt
  236. "55AA1F2817000000", // Enable GCP
  237. NULL
  238. };
  239. // called before job start by GridSeed when mining scrypt
  240. // called before job start by DualMiner when mining scrypt in scrypt+sha (dual-mode)
  241. static
  242. const char *scrypt_reset_cmd[] =
  243. {
  244. // faster, for start of each job:
  245. "55AA1F2816000000", // Reset Scrypt(?)
  246. "55AA1F2817000000", // Enable GCP(?)
  247. NULL
  248. };
  249. // called while initializing DualMiner when mining scrypt in scrypt-only (not dual-mode)
  250. static
  251. const char *scrypt_only_init_cmd[] =
  252. {
  253. "55AAEF0200000000",
  254. "55AAEF0300000000",
  255. "55AAEF0400000000",
  256. "55AAEF0500000000",
  257. "55AAEF0600000000",
  258. "55AAEF3040000000",
  259. "55AA1F2810000000",
  260. "55AA1F2813000000",
  261. NULL
  262. };
  263. // called before job start by DualMiner when mining scrypt in scrypt-only (not dual-mode)
  264. // called while initializing DualMiner when mining scrypt in scrypt-only (not dual-mode)
  265. static
  266. const char *scrypt_only_reset_cmd[] =
  267. {
  268. "55AA1F2810000000", // Close Scrypt(?)
  269. "55AA1F2813000000", // Open Scrypt(?)
  270. NULL
  271. };
  272. static
  273. const char *gcp_chip_reset_cmd[] =
  274. {
  275. "55AAC000808080800000000001000000", // GCP (GridChip) reset
  276. NULL
  277. };
  278. static
  279. const char *sha2_chip_reset_cmd[] =
  280. {
  281. "55AAC000E0E0E0E00000000001000000", // SHA2 reset
  282. NULL
  283. };
  284. void gc3355_reset_dtr(int fd)
  285. {
  286. // set data terminal ready (DTR) status
  287. set_serial_dtr(fd, BGV_HIGH);
  288. cgsleep_ms(GC3355_COMMAND_DELAY_MS);
  289. set_serial_dtr(fd, BGV_LOW);
  290. }
  291. static
  292. void gc3355_set_register(uint8_t * const buf, const uint8_t clusaddr, const uint8_t chipaddr, const uint8_t regaddr, const uint32_t val)
  293. {
  294. buf[0] = 0x55;
  295. buf[1] = 0xaa;
  296. buf[2] = (clusaddr << 4) | chipaddr;
  297. buf[3] = regaddr;
  298. buf[4] = (val >> 0) & 0xff;
  299. buf[5] = (val >> 8) & 0xff;
  300. buf[6] = (val >> 0x10) & 0xff;
  301. buf[7] = (val >> 0x18) & 0xff;
  302. }
  303. static
  304. void gc3355_config_cpm(uint8_t * const buf, const uint8_t chipaddr, const float mhz)
  305. {
  306. // See https://github.com/gridseed/gc3355-doc/blob/master/GC3355_Register_Spec.pdf
  307. const uint8_t pll_bypass = 1;
  308. const uint8_t pll_bandselect = 0;
  309. const uint8_t pll_outdiv = 0;
  310. uint8_t freq_div, freq_mult, last_freq_mult = 0; // mhz = (25 / freq_div * freq_mult)
  311. float actual_mhz, last_actual_mhz = -1;
  312. for (freq_div = 1; freq_div <= 32; ++freq_div)
  313. {
  314. freq_mult = mhz * freq_div / 25;
  315. if (freq_mult > 0x80)
  316. freq_mult = 0x80;
  317. actual_mhz = 25. / freq_div * freq_mult;
  318. if (last_actual_mhz > actual_mhz)
  319. {
  320. --freq_div;
  321. freq_mult = last_freq_mult;
  322. if (opt_debug)
  323. actual_mhz = 25. / freq_div * freq_mult;
  324. break;
  325. }
  326. if (actual_mhz > mhz - .5)
  327. break;
  328. last_actual_mhz = actual_mhz;
  329. last_freq_mult = freq_mult;
  330. }
  331. const uint8_t pll_F = freq_mult - 1;
  332. const uint8_t pll_R = freq_div - 1;
  333. const uint8_t core_clk_out1_diven = 0;
  334. const uint8_t core_clk_sel1 = 0;
  335. const uint8_t core_clk_sel0 = 0;
  336. const uint8_t pll_clk_gate = 0;
  337. const uint8_t pll_recfg = 1;
  338. const uint8_t cfg_cpm = 1;
  339. const uint32_t cfg = (pll_bypass << 31) | (pll_bandselect << 30) | (pll_outdiv << 28) | (pll_F << 21) | (pll_R << 16) | (core_clk_out1_diven << 6) | (core_clk_sel1 << 5) | (core_clk_sel0 << 4) | (pll_clk_gate << 3) | (pll_recfg << 2) | (cfg_cpm << 0);
  340. gc3355_set_register(buf, 0xe, chipaddr, 0, cfg);
  341. }
  342. // NOTE: MHz must match CPM config
  343. static
  344. void gc3355_config_sha256d(uint8_t * const buf, const uint8_t chipaddr, const float mhz, const uint32_t baud)
  345. {
  346. // See https://github.com/gridseed/gc3355-doc/blob/master/GC3355_Register_Spec.pdf
  347. const uint8_t force_start = 1;
  348. const uint8_t uart_enable = 1;
  349. const uint8_t uart_debug = 0;
  350. const uint8_t byte_order = 0;
  351. const uint16_t rpt_cycle = (mhz * 1000000 / baud);
  352. const uint32_t cfg = (force_start << 31) | (uart_enable << 30) | (uart_debug << 29) | (byte_order << 28) | rpt_cycle;
  353. gc3355_set_register(buf, 0, chipaddr, 0xff, cfg);
  354. }
  355. static
  356. void gc3355_log_protocol(int fd, const char *buf, size_t size, const char *prefix)
  357. {
  358. char hex[(size * 2) + 1];
  359. bin2hex(hex, buf, size);
  360. applog(LOG_DEBUG, "%s fd=%d: DEVPROTO: %s(%3lu) %s",
  361. GC3355_CHIP_NAME, fd, prefix, (unsigned long)size, hex);
  362. }
  363. ssize_t gc3355_read(int fd, char *buf, size_t size)
  364. {
  365. size_t read = serial_read(fd, buf, size);
  366. if ((read > 0) && opt_dev_protocol)
  367. gc3355_log_protocol(fd, buf, read, "RECV");
  368. return read;
  369. }
  370. ssize_t gc3355_write(int fd, const void * const buf, const size_t size)
  371. {
  372. if (opt_dev_protocol)
  373. gc3355_log_protocol(fd, buf, size, "SEND");
  374. ssize_t result = write(fd, buf, size);
  375. // gc3355 can suffer register corruption if multiple writes are
  376. // made in a short period of time.
  377. // This is not possible to reproduce on Mac OS X where the serial
  378. // drivers seem to carry an additional overhead / latency.
  379. // This is reproducable on Linux though by removing the following:
  380. cgsleep_ms(GC3355_WRITE_DELAY_MS);
  381. return result;
  382. }
  383. static
  384. void gc3355_send_cmds(int fd, const char *cmds[])
  385. {
  386. int i = 0;
  387. unsigned char ob_bin[512];
  388. for (i = 0; ; i++)
  389. {
  390. const char *cmd = cmds[i];
  391. if (cmd == NULL)
  392. break;
  393. int bin_size = strlen(cmd) / 2;
  394. hex2bin(ob_bin, cmd, bin_size);
  395. gc3355_write(fd, ob_bin, bin_size);
  396. cgsleep_ms(GC3355_COMMAND_DELAY_MS);
  397. }
  398. }
  399. void gc3355_scrypt_only_reset(int fd)
  400. {
  401. gc3355_send_cmds(fd, scrypt_only_reset_cmd);
  402. }
  403. void gc3355_set_pll_freq(int fd, int pll_freq)
  404. {
  405. const uint8_t chipaddr = 0xf;
  406. const uint32_t baud = 115200; // FIXME: Make this configurable
  407. uint8_t buf[8];
  408. gc3355_config_cpm(buf, chipaddr, pll_freq);
  409. gc3355_write(fd, buf, sizeof(buf));
  410. cgsleep_ms(GC3355_COMMAND_DELAY_MS);
  411. gc3355_config_sha256d(buf, chipaddr, pll_freq, baud);
  412. gc3355_write(fd, buf, sizeof(buf));
  413. }
  414. static
  415. void gc3355_open_sha2_units(int fd, int sha2_units)
  416. {
  417. int unit_count = 0;
  418. unsigned char ob_bin[8];
  419. int i;
  420. // should be 0 - 160
  421. unit_count = sha2_units < 0 ? 0 : sha2_units > 160 ? 160 : sha2_units;
  422. if (unit_count > 0)
  423. {
  424. for(i = 0; i <= unit_count; i++)
  425. {
  426. hex2bin(ob_bin, sha2_open_cmd[i], sizeof(ob_bin));
  427. gc3355_write(fd, ob_bin, 8);
  428. cgsleep_ms(GC3355_COMMAND_DELAY_MS);
  429. }
  430. }
  431. else if (unit_count == 0)
  432. gc3355_send_cmds(fd, sha2_gating_cmd);
  433. }
  434. void gc3355_scrypt_init(int fd)
  435. {
  436. gc3355_send_cmds(fd, scrypt_init_cmd);
  437. }
  438. static
  439. void gc3355_scrypt_only_init(int fd)
  440. {
  441. gc3355_send_cmds(fd, sha2_gating_cmd);
  442. gc3355_send_cmds(fd, scrypt_only_init_cmd);
  443. gc3355_scrypt_only_reset(fd);
  444. }
  445. void gc3355_sha2_init(int fd)
  446. {
  447. gc3355_send_cmds(fd, sha2_gating_cmd);
  448. gc3355_send_cmds(fd, sha2_init_cmd);
  449. }
  450. void gc3355_init_miner(int fd, int pll_freq)
  451. {
  452. gc3355_send_cmds(fd, gcp_chip_reset_cmd);
  453. // zzz
  454. cgsleep_ms(GC3355_COMMAND_DELAY_MS);
  455. // initialize units
  456. gc3355_send_cmds(fd, multichip_init_cmd);
  457. gc3355_scrypt_init(fd);
  458. //set freq
  459. gc3355_set_pll_freq(fd, pll_freq);
  460. }
  461. void gc3355_init_dualminer(int fd, int pll_freq, bool scrypt_only, bool detect_only)
  462. {
  463. gc3355_send_cmds(fd, gcp_chip_reset_cmd);
  464. // zzz
  465. cgsleep_ms(GC3355_COMMAND_DELAY_MS);
  466. gc3355_send_cmds(fd, sha2_chip_reset_cmd);
  467. // initialize units
  468. gc3355_reset_dtr(fd);
  469. if (opt_scrypt && scrypt_only)
  470. gc3355_scrypt_only_init(fd);
  471. else
  472. {
  473. gc3355_sha2_init(fd);
  474. gc3355_scrypt_init(fd);
  475. }
  476. //set freq
  477. gc3355_set_pll_freq(fd, pll_freq);
  478. // zzz
  479. cgsleep_ms(GC3355_COMMAND_DELAY_MS);
  480. if (!detect_only)
  481. {
  482. if (!opt_scrypt)
  483. // open sha2 units
  484. gc3355_open_sha2_units(fd, opt_sha2_units);
  485. // set request to send (RTS) status
  486. set_serial_rts(fd, BGV_HIGH);
  487. }
  488. }
  489. void gc3355_scrypt_reset(int fd)
  490. {
  491. gc3355_send_cmds(fd, scrypt_reset_cmd);
  492. }
  493. void gc3355_scrypt_prepare_work(unsigned char cmd[156], struct work *work)
  494. {
  495. // See https://github.com/gridseed/gc3355-doc/blob/master/GC3355_Register_Spec.pdf
  496. // command header
  497. cmd[0] = 0x55; // static header
  498. cmd[1] = 0xaa; // static header
  499. cmd[2] = 0x1f; // 0x1 (for Scrypt) | chip_id (0xf for broadcast)
  500. cmd[3] = 0x00; // identifies the following task data, beginning with 0x00
  501. // gc3355 supports sending batches of work at once
  502. // in which case this would be incremented for each batch
  503. // task data - starts at 0x0 (with 4 byte offset for header)
  504. memcpy(cmd + 4, work->target, 32);
  505. memcpy(cmd + 36, work->midstate, 32);
  506. memcpy(cmd + 68, work->data, 80);
  507. // nonce min - starts at 0x23 (with 4 byte offset for header)
  508. cmd[144] = 0x00;
  509. cmd[145] = 0x00;
  510. cmd[146] = 0x00;
  511. cmd[147] = 0x00;
  512. // nonce max - starts at 0x24 (with 4 byte offset for header)
  513. cmd[148] = 0xff;
  514. cmd[149] = 0xff;
  515. cmd[150] = 0xff;
  516. cmd[151] = 0xff;
  517. // 0x25 - 0x28 are for specific Scrypt unit configs, don't set without reason
  518. }
  519. void gc3355_sha2_prepare_work(unsigned char cmd[52], struct work *work)
  520. {
  521. // See https://github.com/gridseed/gc3355-doc/blob/master/GC3355_Register_Spec.pdf
  522. // command header
  523. cmd[0] = 0x55; // static header
  524. cmd[1] = 0xaa; // static header
  525. cmd[2] = 0x0f; // 0x0 (for SHA2) | chip_id (0xf for broadcast)
  526. cmd[3] = 0x00; // identifies the following task data, beginning with 0x00
  527. // gc3355 supports sending batches of work at once
  528. // in which case this would be incremented for each batch
  529. // initial nonce - starts at 0x0 (with 4 byte offset for header)
  530. cmd[4] = 0x00;
  531. cmd[5] = 0x00;
  532. cmd[6] = 0x00;
  533. cmd[7] = 0x00;
  534. // task data - starts at 0x1 (with 4 byte offset for header)
  535. memcpy(cmd + 8, work->midstate, 32);
  536. memcpy(cmd + 40, work->data + 64, 12);
  537. // 0x1e - 0xff are for specific SHA2 unit configs, don't set without reason
  538. }
  539. int64_t gc3355_get_firmware_version(int fd)
  540. {
  541. gc3355_send_cmds(fd, firmware_request_cmd);
  542. char buf[GC3355_READ_SIZE];
  543. int read = gc3355_read(fd, buf, GC3355_READ_SIZE);
  544. if (read != GC3355_READ_SIZE)
  545. {
  546. applog(LOG_DEBUG, "%s: Failed reading work from %d", GC3355_CHIP_NAME, fd);
  547. return -1;
  548. }
  549. // firmware response begins with 55aac000 90909090
  550. if (memcmp(buf, "\x55\xaa\xc0\x00\x90\x90\x90\x90", GC3355_READ_SIZE - 4) != 0)
  551. return -1;
  552. uint32_t fw_version = be32toh(*(uint32_t *)(buf + 8));
  553. return fw_version;
  554. }