driver-antminer.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * Copyright 2013-2015 Luke Dashjr
  3. * Copyright 2013-2014 Nate Woolls
  4. * Copyright 2013 Lingchao Xu
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the Free
  8. * Software Foundation; either version 3 of the License, or (at your option)
  9. * any later version. See COPYING for more details.
  10. */
  11. #include "config.h"
  12. #include <stdbool.h>
  13. #include <stdint.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <strings.h>
  18. #include "miner.h"
  19. #include "driver-icarus.h"
  20. #include "lowlevel.h"
  21. #include "lowl-vcom.h"
  22. #include "deviceapi.h"
  23. #include "logging.h"
  24. #include "util.h"
  25. #define ANTMINER_IO_SPEED 115200
  26. // ANTMINER_HASH_TIME is for U1/U2 only
  27. #define ANTMINER_HASH_TIME 0.0000000004761
  28. #define ANTMINER_STATUS_LEN 5
  29. #define ANTMINER_COMMAND_PREFIX 128
  30. #define ANTMINER_COMMAND_LED 1
  31. #define ANTMINER_COMMAND_ON 1
  32. #define ANTMINER_COMMAND_OFFSET 32
  33. BFG_REGISTER_DRIVER(antminer_drv)
  34. BFG_REGISTER_DRIVER(compac_drv)
  35. static
  36. const struct bfg_set_device_definition antminer_set_device_funcs[];
  37. static const char *bm1382_chips[] = {
  38. "BM1382",
  39. "BM1384",
  40. NULL
  41. };
  42. static bool antminer_chip_has_bm1382_freq_register(const char * const prodstr)
  43. {
  44. if (!prodstr)
  45. return false;
  46. for (const char **chipname = bm1382_chips; *chipname; ++chipname) {
  47. if (strstr(prodstr, *chipname)) {
  48. return true;
  49. }
  50. }
  51. return false;
  52. }
  53. static
  54. bool antminer_detect_one_with_drv(const char * const devpath, struct device_drv * const drv)
  55. {
  56. struct ICARUS_INFO *info = calloc(1, sizeof(struct ICARUS_INFO));
  57. if (unlikely(!info))
  58. quit(1, "Failed to malloc ICARUS_INFO");
  59. *info = (struct ICARUS_INFO){
  60. .baud = ANTMINER_IO_SPEED,
  61. .Hs = ANTMINER_HASH_TIME,
  62. .timing_mode = MODE_LONG,
  63. .do_icarus_timing = true,
  64. .read_size = 5,
  65. .reopen_mode = IRM_NEVER,
  66. .has_bm1382_freq_register = antminer_chip_has_bm1382_freq_register(detectone_meta_info.product),
  67. };
  68. struct cgpu_info * const dev = icarus_detect_custom(devpath, drv, info);
  69. if (!dev)
  70. {
  71. free(info);
  72. return false;
  73. }
  74. dev->set_device_funcs = antminer_set_device_funcs;
  75. info->read_timeout_ms = 75;
  76. return true;
  77. }
  78. static bool antminer_detect_one(const char * const devpath)
  79. {
  80. return antminer_detect_one_with_drv(devpath, &antminer_drv);
  81. }
  82. static
  83. bool antminer_lowl_match(const struct lowlevel_device_info * const info)
  84. {
  85. return lowlevel_match_lowlproduct(info, &lowl_vcom, "Antminer");
  86. }
  87. static
  88. bool antminer_lowl_probe(const struct lowlevel_device_info * const info)
  89. {
  90. return vcom_lowl_probe_wrapper(info, antminer_detect_one);
  91. }
  92. // Not used for anything, and needs to read a result for every chip
  93. #if 0
  94. static
  95. char *antminer_get_clock(struct cgpu_info *cgpu, char *replybuf)
  96. {
  97. uint8_t rdreg_buf[4] = {0};
  98. unsigned char rebuf[ANTMINER_STATUS_LEN] = {0};
  99. struct timeval tv_now;
  100. struct timeval tv_timeout, tv_finish;
  101. rdreg_buf[0] = 4;
  102. rdreg_buf[0] |= 0x80;
  103. rdreg_buf[1] = 0; //16-23
  104. rdreg_buf[2] = 0x04; // 8-15
  105. rdreg_buf[3] = crc5usb(rdreg_buf, 27);
  106. applog(LOG_DEBUG, "%"PRIpreprv": Get clock: %02x%02x%02x%02x", cgpu->proc_repr, rdreg_buf[0], rdreg_buf[1], rdreg_buf[2], rdreg_buf[3]);
  107. timer_set_now(&tv_now);
  108. int err = icarus_write(cgpu->proc_repr, cgpu->device_fd, rdreg_buf, sizeof(rdreg_buf));
  109. if (err != 0)
  110. {
  111. sprintf(replybuf, "invalid send get clock: comms error (err=%d)", err);
  112. return replybuf;
  113. }
  114. applog(LOG_DEBUG, "%"PRIpreprv": Get clock: OK", cgpu->proc_repr);
  115. memset(rebuf, 0, sizeof(rebuf));
  116. timer_set_delay(&tv_timeout, &tv_now, 1000000);
  117. err = icarus_read(cgpu->proc_repr, rebuf, cgpu->device_fd, &tv_finish, NULL, &tv_timeout, &tv_now, ANTMINER_STATUS_LEN);
  118. // Timeout is ok - checking specifically for an error here
  119. if (err == ICA_GETS_ERROR)
  120. {
  121. sprintf(replybuf, "invalid recv get clock: comms error (err=%d)", err);
  122. return replybuf;
  123. }
  124. applog(LOG_DEBUG, "%"PRIpreprv": Get clock: %02x%02x%02x%02x%02x", cgpu->proc_repr, rebuf[0], rebuf[1], rebuf[2], rebuf[3], rebuf[4]);
  125. return NULL;
  126. }
  127. #endif
  128. static
  129. const char *antminer_set_clock(struct cgpu_info * const cgpu, const char * const optname, const char * const setting, char * const replybuf, enum bfg_set_device_replytype * const out_success)
  130. {
  131. struct ICARUS_INFO * const info = cgpu->device_data;
  132. if (!setting || !*setting)
  133. return "missing clock setting";
  134. uint8_t reg_data[2];
  135. if (setting[0] == 'x')
  136. {
  137. // remove leading character
  138. const char * const hex_setting = &setting[1];
  139. if (!hex2bin(reg_data, hex_setting, sizeof(reg_data)))
  140. {
  141. sprintf(replybuf, "invalid clock: '%s' data must be a hexadecimal value", hex_setting);
  142. return replybuf;
  143. }
  144. }
  145. else
  146. if (info->has_bm1382_freq_register)
  147. {
  148. const double mhz = atof(setting);
  149. if (!bm1382_freq_to_reg_data(reg_data, mhz)) {
  150. return "invalid clock";
  151. }
  152. }
  153. else
  154. {
  155. sprintf(replybuf, "invalid clock: '%s' data must be prefixed with an x", setting);
  156. return replybuf;
  157. }
  158. uint8_t cmd_buf[4] = {0};
  159. cmd_buf[0] = 2;
  160. cmd_buf[0] |= 0x80;
  161. cmd_buf[1] = reg_data[0]; //16-23
  162. cmd_buf[2] = reg_data[1]; // 8-15
  163. cmd_buf[3] = crc5usb(cmd_buf, 27);
  164. applog(LOG_DEBUG, "%"PRIpreprv": Set clock: %02x%02x%02x%02x", cgpu->proc_repr, cmd_buf[0], cmd_buf[1], cmd_buf[2], cmd_buf[3]);
  165. int err = icarus_write(cgpu->proc_repr, cgpu->device_fd, cmd_buf, sizeof(cmd_buf));
  166. if (err != 0)
  167. {
  168. sprintf(replybuf, "invalid send clock: '%s' comms error (err=%d)", setting, err);
  169. return replybuf;
  170. }
  171. applog(LOG_DEBUG, "%"PRIpreprv": Set clock: OK", cgpu->proc_repr);
  172. // This is confirmed required in order for the clock change to "take"
  173. cgsleep_ms(500);
  174. return NULL;
  175. }
  176. static
  177. const char *antminer_set_voltage(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
  178. {
  179. if (!(newvalue && *newvalue))
  180. return "Missing voltage value";
  181. // For now we only allow hex values that use BITMAINtech's lookup table
  182. // This means values should be prefixed with an x so that later we can
  183. // accept and distinguish decimal values
  184. if (newvalue[0] != 'x' || strlen(newvalue) != 4)
  185. invalid_voltage:
  186. return "Only raw voltage configurations are currently supported using 'x' followed by 3 hexadecimal digits";
  187. char voltagecfg_hex[5];
  188. voltagecfg_hex[0] = '0';
  189. memcpy(&voltagecfg_hex[1], &newvalue[1], 3);
  190. voltagecfg_hex[4] = '\0';
  191. uint8_t cmd[4];
  192. if (!hex2bin(&cmd[1], voltagecfg_hex, 2))
  193. goto invalid_voltage;
  194. cmd[0] = 0xaa;
  195. cmd[1] |= 0xb0;
  196. cmd[3] = 0;
  197. cmd[3] = crc5usb(cmd, (4 * 8) - 5);
  198. cmd[3] |= 0xc0;
  199. if (opt_debug)
  200. {
  201. char hex[(4 * 2) + 1];
  202. bin2hex(hex, cmd, 4);
  203. applog(LOG_DEBUG, "%"PRIpreprv": Set voltage: %s", proc->proc_repr, hex);
  204. }
  205. const int err = icarus_write(proc->proc_repr, proc->device_fd, cmd, sizeof(cmd));
  206. if (err)
  207. {
  208. sprintf(replybuf, "Error sending set voltage (err=%d)", err);
  209. return replybuf;
  210. }
  211. applog(LOG_DEBUG, "%"PRIpreprv": Set voltage: OK", proc->proc_repr);
  212. return NULL;
  213. }
  214. static
  215. const char *antminer_set_chip(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
  216. {
  217. struct ICARUS_INFO * const info = proc->device_data;
  218. info->has_bm1382_freq_register = antminer_chip_has_bm1382_freq_register(newvalue);
  219. return NULL;
  220. }
  221. static
  222. void antminer_flash_led(const struct cgpu_info *antminer)
  223. {
  224. const int offset = ANTMINER_COMMAND_OFFSET;
  225. uint8_t cmd_buf[4 + offset];
  226. memset(cmd_buf, 0, sizeof(cmd_buf));
  227. cmd_buf[offset + 0] = ANTMINER_COMMAND_PREFIX;
  228. cmd_buf[offset + 1] = ANTMINER_COMMAND_LED;
  229. cmd_buf[offset + 2] = ANTMINER_COMMAND_ON;
  230. cmd_buf[offset + 3] = crc5usb(cmd_buf, sizeof(cmd_buf));
  231. const int fd = antminer->device_fd;
  232. icarus_write(antminer->proc_repr, fd, (char *)(&cmd_buf), sizeof(cmd_buf));
  233. }
  234. static
  235. bool antminer_identify(struct cgpu_info *antminer)
  236. {
  237. for (int i = 0; i < 10; i++)
  238. {
  239. antminer_flash_led(antminer);
  240. cgsleep_ms(250);
  241. }
  242. return true;
  243. }
  244. static
  245. const struct bfg_set_device_definition antminer_set_device_funcs[] = {
  246. {"chip", antminer_set_chip, "chip unit is based on (BM1380, BM1382, etc)"},
  247. {"baud" , icarus_set_baud , "serial baud rate"},
  248. {"work_division", icarus_set_work_division, "number of pieces work is split into"},
  249. {"reopen" , icarus_set_reopen , "how often to reopen device: never, timeout, cycle, (or now for a one-shot reopen)"},
  250. {"timing" , icarus_set_timing , "timing of device; see README.FPGA"},
  251. {"clock", antminer_set_clock, "clock frequency"},
  252. {"voltage", antminer_set_voltage, "voltage ('x' followed by 3 digit hex code)"},
  253. {NULL},
  254. };
  255. #ifdef HAVE_CURSES
  256. static
  257. void antminer_tui_wlogprint_choices(struct cgpu_info * const proc)
  258. {
  259. struct ICARUS_INFO * const info = proc->device_data;
  260. if (info->has_bm1382_freq_register)
  261. wlogprint("[C]lock speed ");
  262. }
  263. static
  264. const char *antminer_tui_handle_choice(struct cgpu_info * const proc, const int input)
  265. {
  266. switch (input)
  267. {
  268. case 'c': case 'C':
  269. return proc_set_device_tui_wrapper(proc, NULL, antminer_set_clock, "Set clock speed", NULL);
  270. }
  271. return NULL;
  272. }
  273. #endif
  274. static
  275. bool compac_lowl_match(const struct lowlevel_device_info * const info)
  276. {
  277. return lowlevel_match_lowlproduct(info, &lowl_vcom, "Compac", "Bitcoin");
  278. }
  279. static bool compac_detect_one(const char * const devpath)
  280. {
  281. return antminer_detect_one_with_drv(devpath, &compac_drv);
  282. }
  283. static
  284. bool compac_lowl_probe(const struct lowlevel_device_info * const info)
  285. {
  286. return vcom_lowl_probe_wrapper(info, compac_detect_one);
  287. }
  288. static
  289. void antminer_drv_init()
  290. {
  291. antminer_drv = icarus_drv;
  292. antminer_drv.dname = "antminer";
  293. antminer_drv.name = "AMU";
  294. antminer_drv.lowl_match = antminer_lowl_match;
  295. antminer_drv.lowl_probe = antminer_lowl_probe;
  296. antminer_drv.identify_device = antminer_identify;
  297. #ifdef HAVE_CURSES
  298. antminer_drv.proc_tui_wlogprint_choices = antminer_tui_wlogprint_choices;
  299. antminer_drv.proc_tui_handle_choice = antminer_tui_handle_choice;
  300. #endif
  301. ++antminer_drv.probe_priority;
  302. compac_drv = antminer_drv;
  303. compac_drv.dname = "compac";
  304. compac_drv.name = "CBM";
  305. compac_drv.lowl_match = compac_lowl_match;
  306. compac_drv.lowl_probe = compac_lowl_probe;
  307. ++compac_drv.probe_priority;
  308. }
  309. struct device_drv antminer_drv = {
  310. .drv_init = antminer_drv_init,
  311. };
  312. struct device_drv compac_drv = {
  313. .drv_init = antminer_drv_init,
  314. };