driver-drillbit.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Copyright 2013 Luke Dashjr
  3. * Copyright 2013 Angus Gratton
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the Free
  7. * Software Foundation; either version 3 of the License, or (at your option)
  8. * any later version. See COPYING for more details.
  9. */
  10. #include <stdbool.h>
  11. #include <stdint.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "deviceapi.h"
  15. #include "logging.h"
  16. #include "lowlevel.h"
  17. #include "lowl-vcom.h"
  18. BFG_REGISTER_DRIVER(drillbit_drv)
  19. #define DRILLBIT_MIN_VERSION 2
  20. #define DRILLBIT_MAX_VERSION 3
  21. enum drillbit_capability {
  22. DBC_TEMP = 1,
  23. DBC_EXT_CLOCK = 2,
  24. };
  25. static
  26. bool drillbit_lowl_match(const struct lowlevel_device_info * const info)
  27. {
  28. if (!lowlevel_match_id(info, &lowl_vcom, 0, 0))
  29. return false;
  30. return (info->manufacturer && strstr(info->manufacturer, "Drillbit"));
  31. }
  32. static
  33. bool drillbit_detect_one(const char * const devpath)
  34. {
  35. uint8_t buf[0x10];
  36. const int fd = serial_open(devpath, 0, 1, true);
  37. if (fd == -1)
  38. applogr(false, LOG_DEBUG, "%s: %s: Failed to open", __func__, devpath);
  39. if (1 != write(fd, "I", 1))
  40. {
  41. applog(LOG_DEBUG, "%s: %s: Error writing 'I'", __func__, devpath);
  42. err:
  43. serial_close(fd);
  44. return false;
  45. }
  46. if (sizeof(buf) != serial_read(fd, buf, sizeof(buf)))
  47. {
  48. applog(LOG_DEBUG, "%s: %s: Short read in response to 'I'",
  49. __func__, devpath);
  50. goto err;
  51. }
  52. serial_close(fd);
  53. const unsigned protover = buf[0];
  54. const unsigned long serialno = (uint32_t)buf[9] | ((uint32_t)buf[0xa] << 8) | ((uint32_t)buf[0xb] << 16) | ((uint32_t)buf[0xc] << 24);
  55. char * const product = (void*)&buf[1];
  56. buf[9] = '\0'; // Ensure it is null-terminated (clobbers serial, but we already parsed it)
  57. const uint8_t chips = buf[0xd];
  58. uint16_t caps = (uint16_t)buf[0xe] | ((uint16_t)buf[0xf] << 8);
  59. if (!product[0])
  60. applogr(false, LOG_DEBUG, "%s: %s: Null product name", __func__, devpath);
  61. if (!serialno)
  62. applogr(false, LOG_DEBUG, "%s: %s: Serial number is zero", __func__, devpath);
  63. if (!chips)
  64. applogr(false, LOG_DEBUG, "%s: %s: No chips found", __func__, devpath);
  65. int loglev = LOG_WARNING;
  66. if (!strcmp(product, "DRILLBIT"))
  67. {
  68. // Hack: first production firmwares all described themselves as DRILLBIT, so fill in the gaps
  69. if (chips == 1)
  70. strcpy(product, "Thumb");
  71. else
  72. strcpy(product, "Eight");
  73. }
  74. else
  75. if (chips == 8 && !strcmp(product, "Eight"))
  76. {} // Known device
  77. else
  78. if (chips == 1 && !strcmp(product, "Thumb"))
  79. {} // Known device
  80. else
  81. loglev = LOG_DEBUG;
  82. if (protover < DRILLBIT_MIN_VERSION || (loglev == LOG_DEBUG && protover > DRILLBIT_MAX_VERSION))
  83. applogr(false, loglev, "%s: %s: Unknown device protocol version %u.",
  84. __func__, devpath, protover);
  85. if (protover > DRILLBIT_MAX_VERSION)
  86. applogr(false, loglev, "%s: %s: Device firmware uses newer Drillbit protocol %u. We only support up to %u. Find a newer BFGMiner!",
  87. __func__, devpath, protover, (unsigned)DRILLBIT_MAX_VERSION);
  88. if (protover == 2 && chips == 1)
  89. // Production firmware Thumbs don't set any capability bits, so fill in the EXT_CLOCK one
  90. caps |= DBC_EXT_CLOCK;
  91. char *serno = malloc(9);
  92. snprintf(serno, 9, "%08lx", serialno);
  93. struct cgpu_info * const cgpu = malloc(sizeof(*cgpu));
  94. *cgpu = (struct cgpu_info){
  95. .drv = &drillbit_drv,
  96. .device_path = strdup(devpath),
  97. .dev_product = strdup(product),
  98. .dev_serial = serno,
  99. .deven = DEV_ENABLED,
  100. .procs = chips,
  101. .threads = 1,
  102. //.device_data = ,
  103. };
  104. return add_cgpu(cgpu);
  105. }
  106. static
  107. bool drillbit_lowl_probe(const struct lowlevel_device_info * const info)
  108. {
  109. return vcom_lowl_probe_wrapper(info, drillbit_detect_one);
  110. }
  111. struct device_drv drillbit_drv = {
  112. .dname = "drillbit",
  113. .name = "DRB",
  114. .lowl_match = drillbit_lowl_match,
  115. .lowl_probe = drillbit_lowl_probe,
  116. // .thread_init = drillbit_init,
  117. // .minerloop = minerloop_async,
  118. // .job_prepare = hashfast_job_prepare,
  119. // .job_start = hashfast_noop_job_start,
  120. // .job_process_results = hashfast_job_process_results,
  121. // .poll = hashfast_poll,
  122. };