driver-technobit.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Copyright 2013 Luke Dashjr
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "config.h"
  10. #include <stdbool.h>
  11. #include <stdint.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #ifndef WIN32
  15. #include <unistd.h>
  16. #else
  17. #include <io.h>
  18. #endif
  19. #include "deviceapi.h"
  20. #include "fpgautils.h"
  21. #include "miner.h"
  22. #include "util.h"
  23. BFG_REGISTER_DRIVER(technobit_drv)
  24. #define TECHNOBIT_PKT_HEADER_SIZE (1 + 1 + 1 + 2)
  25. #define TECHNOBIT_LOWEST_ADDRESS (0x3000)
  26. #define TECHNOBIT_HIGHEST_ADDRESS (0x7000) /* ??? */
  27. #define TECHNOBIT_MAX_DATA_SIZE 510
  28. struct technobit_state {
  29. uint8_t datain[TECHNOBIT_PKT_HEADER_SIZE + (255 * 2) + 1];
  30. size_t datainlen;
  31. };
  32. static
  33. uint8_t technobit_chksum(const void * const data, const size_t datasz)
  34. {
  35. const uint8_t *bytes = data;
  36. uint8_t r = 0;
  37. size_t i;
  38. for (i = 0; i < datasz; ++i, ++bytes)
  39. r += *bytes;
  40. return r;
  41. }
  42. static
  43. bool technobit_send(const int fd, const uint8_t cmd, const uint16_t addr, const void * const data, const size_t datasz)
  44. {
  45. const size_t sz2 = TECHNOBIT_PKT_HEADER_SIZE + datasz;
  46. const size_t pktsz = sz2 + 1;
  47. uint8_t pkt[pktsz];
  48. pkt[0] = '\x53';
  49. pkt[1] = datasz / 2;
  50. pkt[2] = cmd;
  51. pkt[3] = addr & 0xff;
  52. pkt[4] = addr >> 8;
  53. memcpy(&pkt[5], data, datasz);
  54. pkt[sz2] = technobit_chksum(pkt, sz2);
  55. if (opt_dev_protocol)
  56. {
  57. char hex[(pktsz * 2) + 1];
  58. bin2hex(hex, pkt, pktsz);
  59. applog(LOG_DEBUG, "%s(%d,'%c',0x%04x,...,%u): %s",
  60. __func__, fd, (int)cmd, (unsigned)addr, (unsigned)datasz, hex);
  61. }
  62. return (write(fd, pkt, pktsz) == pktsz);
  63. }
  64. static
  65. bool technobit_recv(struct technobit_state * const state, const int fd, uint8_t * const out_cmd, uint16_t * const out_addr, void * const out_datap, size_t * const out_datasz)
  66. {
  67. void ** const out_datap2 = out_datap;
  68. int skip = 0;
  69. const ssize_t r = read(fd, &state->datain[state->datainlen], sizeof(state->datain) - state->datainlen);
  70. if (r <= 0)
  71. return false;
  72. if (opt_dev_protocol)
  73. {
  74. char hex[(r * 2) + 1];
  75. bin2hex(hex, &state->datain[state->datainlen], r);
  76. applog(LOG_DEBUG, "%s: %s", __func__, hex);
  77. }
  78. state->datainlen += r;
  79. reskip2:
  80. while (state->datain[skip] != '\x53')
  81. ++skip;
  82. state->datainlen -= skip;
  83. memmove(state->datain, &state->datain[skip], state->datainlen);
  84. if (state->datainlen <= TECHNOBIT_PKT_HEADER_SIZE)
  85. return false;
  86. const uint16_t addr = (state->datain[4] << 8) | state->datain[3];
  87. if (addr < TECHNOBIT_LOWEST_ADDRESS || addr > TECHNOBIT_HIGHEST_ADDRESS)
  88. {
  89. reskip:
  90. skip = 1;
  91. goto reskip2;
  92. }
  93. const size_t datasz = state->datain[1] * 2;
  94. const size_t pktsz = TECHNOBIT_PKT_HEADER_SIZE + datasz;
  95. if (state->datainlen <= pktsz)
  96. return false;
  97. const uint8_t chksum = technobit_chksum(state->datain, pktsz);
  98. if (state->datain[pktsz] != chksum)
  99. goto reskip;
  100. *out_cmd = state->datain[2];
  101. *out_addr = addr;
  102. *out_datap2 = &state->datain[TECHNOBIT_PKT_HEADER_SIZE];
  103. *out_datasz = datasz;
  104. return true;
  105. }
  106. static
  107. bool technobit_request_read(const int fd, const uint16_t addr, uint16_t sz)
  108. {
  109. const uint8_t data[2] = { sz & 0xff, sz >> 8 };
  110. return technobit_send(fd, 'R', addr, data, sizeof(data));
  111. }
  112. static
  113. bool technobit_detect_one(const char * const devpath)
  114. {
  115. struct cgpu_info *cgpu;
  116. // TODO
  117. cgpu = malloc(sizeof(*cgpu));
  118. *cgpu = (struct cgpu_info){
  119. .drv = &technobit_drv,
  120. .device_path = strdup(devpath),
  121. .device_fd = -1,
  122. .deven = DEV_ENABLED,
  123. .threads = 1,
  124. };
  125. return add_cgpu(cgpu);
  126. }
  127. static void technobit_detect(void)
  128. {
  129. generic_detect(&technobit_drv, technobit_detect_one, NULL, 0);
  130. }
  131. static
  132. bool technobit_init(struct thr_info * const thr)
  133. {
  134. struct cgpu_info * const cgpu = thr->cgpu;
  135. struct technobit_state *state;
  136. state = cgpu->device_data = malloc(sizeof(*state));
  137. *state = (struct technobit_state){
  138. .datainlen = 0,
  139. };
  140. // TODO
  141. // REQUEST 16 bits read from 3004
  142. // receive 16 bits read from 6800
  143. // receive 192 bits read from 3000
  144. // receive 32 bits read from 6494
  145. // receive 64 bits read from 649c
  146. // REQUEST 736 bits write to 4000
  147. // REQUEST 16 bits read from 3004
  148. // receive 16 bits read from 6800
  149. // receive confirmation of 736 bits write to 4000
  150. // recieve 16 bits read from 3004
  151. // recieve 16 bits read from 6800
  152. // REQUEST 736 bits write to 4000
  153. // REQUEST 16 bits read from 3004
  154. // recieve 16 bits read from 6800
  155. // recieve
  156. timer_set_now(&thr->tv_poll);
  157. return true;
  158. }
  159. static
  160. bool technobit_queue_append(struct thr_info * const thr, struct work * const work)
  161. {
  162. //struct cgpu_info * const cgpu = thr->cgpu;
  163. // TODO
  164. thr->queue_full = true;
  165. return false;
  166. }
  167. static
  168. void technobit_queue_flush(struct thr_info * const thr)
  169. {
  170. // TODO
  171. }
  172. static
  173. void technobit_poll(struct thr_info * const thr)
  174. {
  175. struct cgpu_info * const cgpu = thr->cgpu;
  176. struct technobit_state * const state = cgpu->device_data;
  177. int fd = cgpu->device_fd;
  178. if (unlikely(fd == -1))
  179. {
  180. fd = cgpu->device_fd = serial_open(cgpu->device_path, 38400, 0, true);
  181. if (fd == -1)
  182. applogr(, LOG_ERR, "%"PRIpreprv": Failed to open %s",
  183. cgpu->proc_repr, cgpu->device_path);
  184. technobit_request_read(fd, 0x3004, 1);
  185. }
  186. uint8_t cmd, *datap;
  187. uint16_t addr;
  188. size_t datasz;
  189. if (technobit_recv(state, fd, &cmd, &addr, &datap, &datasz))
  190. {
  191. if (opt_debug)
  192. {
  193. char hexdata[(datasz * 2) + 1];
  194. bin2hex(hexdata, datap, datasz);
  195. applog(LOG_DEBUG, "%"PRIpreprv": Received cmd=%02x addr=%04x data=%s",
  196. cgpu->proc_repr, cmd, addr, hexdata);
  197. }
  198. }
  199. timer_set_delay_from_now(&thr->tv_poll, 10000);
  200. }
  201. struct device_drv technobit_drv = {
  202. .dname = "technobit",
  203. .name = "HEX",
  204. .drv_detect = technobit_detect,
  205. .thread_init = technobit_init,
  206. .minerloop = minerloop_queue,
  207. .queue_append = technobit_queue_append,
  208. .queue_flush = technobit_queue_flush,
  209. .poll = technobit_poll,
  210. };