| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- /*
- * Copyright 2013 Luke Dashjr
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version. See COPYING for more details.
- */
- #include "config.h"
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #ifndef WIN32
- #include <unistd.h>
- #else
- #include <io.h>
- #endif
- #include "deviceapi.h"
- #include "fpgautils.h"
- #include "miner.h"
- #include "util.h"
- BFG_REGISTER_DRIVER(technobit_drv)
- #define TECHNOBIT_PKT_HEADER_SIZE (1 + 1 + 1 + 2)
- #define TECHNOBIT_LOWEST_ADDRESS (0x3000)
- #define TECHNOBIT_HIGHEST_ADDRESS (0x7000) /* ??? */
- #define TECHNOBIT_MAX_DATA_SIZE 510
- struct technobit_state {
- uint8_t datain[TECHNOBIT_PKT_HEADER_SIZE + (255 * 2) + 1];
- size_t datainlen;
- };
- static
- uint8_t technobit_chksum(const void * const data, const size_t datasz)
- {
- const uint8_t *bytes = data;
- uint8_t r = 0;
- size_t i;
-
- for (i = 0; i < datasz; ++i, ++bytes)
- r += *bytes;
-
- return r;
- }
- static
- bool technobit_send(const int fd, const uint8_t cmd, const uint16_t addr, const void * const data, const size_t datasz)
- {
- const size_t sz2 = TECHNOBIT_PKT_HEADER_SIZE + datasz;
- const size_t pktsz = sz2 + 1;
- uint8_t pkt[pktsz];
- pkt[0] = '\x53';
- pkt[1] = datasz / 2;
- pkt[2] = cmd;
- pkt[3] = addr & 0xff;
- pkt[4] = addr >> 8;
- memcpy(&pkt[5], data, datasz);
- pkt[sz2] = technobit_chksum(pkt, sz2);
-
- if (opt_dev_protocol)
- {
- char hex[(pktsz * 2) + 1];
- bin2hex(hex, pkt, pktsz);
- applog(LOG_DEBUG, "%s(%d,'%c',0x%04x,...,%u): %s",
- __func__, fd, (int)cmd, (unsigned)addr, (unsigned)datasz, hex);
- }
-
- return (write(fd, pkt, pktsz) == pktsz);
- }
- static
- 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)
- {
- void ** const out_datap2 = out_datap;
- int skip = 0;
- const ssize_t r = read(fd, &state->datain[state->datainlen], sizeof(state->datain) - state->datainlen);
- if (r <= 0)
- return false;
- if (opt_dev_protocol)
- {
- char hex[(r * 2) + 1];
- bin2hex(hex, &state->datain[state->datainlen], r);
- applog(LOG_DEBUG, "%s: %s", __func__, hex);
- }
- state->datainlen += r;
-
- reskip2:
- while (state->datain[skip] != '\x53')
- ++skip;
- state->datainlen -= skip;
- memmove(state->datain, &state->datain[skip], state->datainlen);
-
- if (state->datainlen <= TECHNOBIT_PKT_HEADER_SIZE)
- return false;
-
- const uint16_t addr = (state->datain[4] << 8) | state->datain[3];
- if (addr < TECHNOBIT_LOWEST_ADDRESS || addr > TECHNOBIT_HIGHEST_ADDRESS)
- {
- reskip:
- skip = 1;
- goto reskip2;
- }
-
- const size_t datasz = state->datain[1] * 2;
- const size_t pktsz = TECHNOBIT_PKT_HEADER_SIZE + datasz;
- if (state->datainlen <= pktsz)
- return false;
-
- const uint8_t chksum = technobit_chksum(state->datain, pktsz);
- if (state->datain[pktsz] != chksum)
- goto reskip;
-
- *out_cmd = state->datain[2];
- *out_addr = addr;
- *out_datap2 = &state->datain[TECHNOBIT_PKT_HEADER_SIZE];
- *out_datasz = datasz;
- return true;
- }
- static
- bool technobit_request_read(const int fd, const uint16_t addr, uint16_t sz)
- {
- const uint8_t data[2] = { sz & 0xff, sz >> 8 };
- return technobit_send(fd, 'R', addr, data, sizeof(data));
- }
- static
- bool technobit_detect_one(const char * const devpath)
- {
- struct cgpu_info *cgpu;
-
- // TODO
-
- cgpu = malloc(sizeof(*cgpu));
- *cgpu = (struct cgpu_info){
- .drv = &technobit_drv,
- .device_path = strdup(devpath),
- .device_fd = -1,
- .deven = DEV_ENABLED,
- .threads = 1,
- };
- return add_cgpu(cgpu);
- }
- static void technobit_detect(void)
- {
- generic_detect(&technobit_drv, technobit_detect_one, NULL, 0);
- }
- static
- bool technobit_init(struct thr_info * const thr)
- {
- struct cgpu_info * const cgpu = thr->cgpu;
- struct technobit_state *state;
-
- state = cgpu->device_data = malloc(sizeof(*state));
- *state = (struct technobit_state){
- .datainlen = 0,
- };
-
- // TODO
- // REQUEST 16 bits read from 3004
- // receive 16 bits read from 6800
- // receive 192 bits read from 3000
- // receive 32 bits read from 6494
- // receive 64 bits read from 649c
- // REQUEST 736 bits write to 4000
- // REQUEST 16 bits read from 3004
- // receive 16 bits read from 6800
- // receive confirmation of 736 bits write to 4000
- // recieve 16 bits read from 3004
- // recieve 16 bits read from 6800
- // REQUEST 736 bits write to 4000
- // REQUEST 16 bits read from 3004
- // recieve 16 bits read from 6800
- // recieve
-
- timer_set_now(&thr->tv_poll);
- return true;
- }
- static
- bool technobit_queue_append(struct thr_info * const thr, struct work * const work)
- {
- //struct cgpu_info * const cgpu = thr->cgpu;
- // TODO
- thr->queue_full = true;
- return false;
- }
- static
- void technobit_queue_flush(struct thr_info * const thr)
- {
- // TODO
- }
- static
- void technobit_poll(struct thr_info * const thr)
- {
- struct cgpu_info * const cgpu = thr->cgpu;
- struct technobit_state * const state = cgpu->device_data;
- int fd = cgpu->device_fd;
-
- if (unlikely(fd == -1))
- {
- fd = cgpu->device_fd = serial_open(cgpu->device_path, 38400, 0, true);
- if (fd == -1)
- applogr(, LOG_ERR, "%"PRIpreprv": Failed to open %s",
- cgpu->proc_repr, cgpu->device_path);
- technobit_request_read(fd, 0x3004, 1);
- }
-
- uint8_t cmd, *datap;
- uint16_t addr;
- size_t datasz;
-
- if (technobit_recv(state, fd, &cmd, &addr, &datap, &datasz))
- {
- if (opt_debug)
- {
- char hexdata[(datasz * 2) + 1];
- bin2hex(hexdata, datap, datasz);
- applog(LOG_DEBUG, "%"PRIpreprv": Received cmd=%02x addr=%04x data=%s",
- cgpu->proc_repr, cmd, addr, hexdata);
- }
- }
-
- timer_set_delay_from_now(&thr->tv_poll, 10000);
- }
- struct device_drv technobit_drv = {
- .dname = "technobit",
- .name = "HEX",
- .drv_detect = technobit_detect,
-
- .thread_init = technobit_init,
-
- .minerloop = minerloop_queue,
- .queue_append = technobit_queue_append,
- .queue_flush = technobit_queue_flush,
- .poll = technobit_poll,
- };
|