int main() { uint64_t u, v, w; uint64_t seed = time(0); RAND_NR_INIT(u, v, w, seed); for (int i = 0; i < 100; i++) printf("rand number = %llx\n", (unsigned long long)RAND_NR_NEXT(u, v, w)); uint64_t r = RAND_NR_NEXT(u, v, w); uint64_t s = BIN_TO_GRAYCODE(r); uint64_t t = BIN_TO_GRAYCODE(r + 1); assert(hweight64(t ^ s) == 1); GRAYCODE_TO_BIN64(s); assert(rev8(5) == 160); assert(rev8_hakmem(5) == 160); uint64_t hi, lo; MULQ(0x1234567887654321ul, 0x77665544332211fful, lo, hi); assert(hi == 611815671993850618UL); assert(lo == 14353276178066116319UL); if (s != r) fprintf(stderr, "expected %016llx, acutal %016llx\n", (unsigned long long)r, (unsigned long long)s); else printf("passed\n"); return 0; }
int main(int argc, char **argv) { struct ftdi_context ftdi; uint8_t buf[4]; uint8_t conf_buf[] = {SET_BITS_LOW, 0x08, 0x0b, SET_BITS_HIGH, 0x00, 0x00, TCK_DIVISOR, 0x00, 0x00, LOOPBACK_END}; if (argc < 2) { usage(argv[0]); return 1; } if (strcmp (argv[1], "idcode") && strcmp (argv[1], "reset") && strcmp (argv[1], "load") && strcmp (argv[1], "readreg") && strcmp (argv[1], "read") && strcmp (argv[1], "write") ) { usage(argv[0]); return 1; } /* Init */ ftdi_init(&ftdi); if (ftdi_usb_open_desc(&ftdi, VENDOR, PRODUCT, 0, 0) < 0) { fprintf(stderr, "Can't open device %04x:%04x\n", VENDOR, PRODUCT); return 1; } ftdi_usb_reset(&ftdi); ftdi_set_interface(&ftdi, INTERFACE_A); ftdi_set_latency_timer(&ftdi, 1); ftdi_set_bitmode(&ftdi, 0xfb, BITMODE_MPSSE); if (ftdi_write_data(&ftdi, conf_buf, 10) != 10) { fprintf(stderr, "Can't configure device %04x:%04x\n", VENDOR, PRODUCT); return 1; } buf[0] = GET_BITS_LOW; buf[1] = SEND_IMMEDIATE; if (ftdi_write_data(&ftdi, buf, 2) != 2) { fprintf(stderr, "Can't send command to device\n"); return 1; } ftdi_read_data(&ftdi, &buf[2], 1); if (!(buf[2] & 0x10)) { fprintf(stderr, "Vref not detected. Please power on target board\n"); return 1; } if (!strcmp(argv[1], "idcode")) { uint8_t out[4]; tap_reset_rti(&ftdi); tap_shift_dr_bits(&ftdi, NULL, 32, out); rev_dump(out, 4); printf("\n"); } if (!strcmp (argv[1], "reset")) brd_reset(&ftdi); if (!strcmp (argv[1], "load")) { int i; struct load_bits *bs; FILE *fp; uint8_t *dr_data; uint32_t u; if(argc < 3) { usage(argv[0]); goto exit; } if (!strcmp(argv[2], "-")) fp = stdin; else { fp = fopen(argv[2], "r"); if (!fp) { perror("Unable to open file"); goto exit; } } bs = calloc(1, sizeof(*bs)); if (!bs) { perror("memory allocation failed"); goto exit; } if (load_bits(fp, bs) != 0) { fprintf(stderr, "%s not supported\n", argv[2]); goto free_bs; } printf("Bitstream information:\n"); printf("\tDesign: %s\n", bs->design); printf("\tPart name: %s\n", bs->part_name); printf("\tDate: %s\n", bs->date); printf("\tTime: %s\n", bs->time); printf("\tBitstream length: %d\n", bs->length); /* copy data into shift register */ dr_data = calloc(1, bs->length); if (!dr_data) { perror("memory allocation failed"); goto free_bs; } for (u = 0; u < bs->length; u++) dr_data[u] = rev8(bs->data[u]); brd_reset(&ftdi); tap_shift_ir(&ftdi, CFG_IN); tap_shift_dr_bits(&ftdi, dr_data, bs->length * 8, NULL); /* ug380.pdf * P161: a minimum of 16 clock cycles to the TCK */ tap_shift_ir(&ftdi, JSTART); for (i = 0; i < 32; i++) tap_tms(&ftdi, 0, 0); tap_reset_rti(&ftdi); free(dr_data); free_bs: bits_free(bs); fclose(fp); } if (!strcmp(argv[1], "readreg") && argc == 3) { int i; char *err; uint8_t reg; uint8_t out[2]; uint8_t dr_in[14]; uint8_t in[14] = { 0xaa, 0x99, 0x55, 0x66, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00 }; uint16_t cmd = 0x2801; /* type 1 packet (word count = 1) */ reg = strtol(argv[2], &err, 0); if((*err != 0x00) || (reg < 0) || (reg > 0x22)) { fprintf(stderr, "Invalid register, use a decimal or hexadecimal(0x...) number between 0x0 and 0x22\n"); goto exit; } cmd |= ((reg & 0x3f) << 5); in[4] = (cmd & 0xff00) >> 8; in[5] = cmd & 0xff; tap_reset_rti(&ftdi); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 0, 0); tap_tms(&ftdi, 0, 0); /* Goto shift IR */ tap_shift_ir_only(&ftdi, CFG_IN); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 0, 0); tap_tms(&ftdi, 0, 0); /* Goto SHIFT-DR */ for (i = 0; i < 14; i++) dr_in[i] = rev8(in[i]); tap_shift_dr_bits_only(&ftdi, dr_in, 14 * 8, NULL); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 1, 0); /* Goto SELECT-IR */ tap_tms(&ftdi, 0, 0); tap_tms(&ftdi, 0, 0); /* Goto SHIFT-IR */ tap_shift_ir_only(&ftdi, CFG_OUT); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 0, 0); tap_tms(&ftdi, 0, 0); /* Goto SHIFT-IR */ tap_shift_dr_bits_only(&ftdi, NULL, 2 * 8, out); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 1, 0); tap_tms(&ftdi, 1, 0); /* Goto SELECT-IR */ tap_tms(&ftdi, 0, 0); tap_tms(&ftdi, 0, 0); /* Goto SHIFT-IR */ tap_reset_rti(&ftdi); out[0] = rev8(out[0]); out[1] = rev8(out[1]); printf("REG[%d]: 0x%02x%02x\n", reg, out[0], out[1]); }
/* http://www.onsemi.com/pub_link/Collateral/ADP3208D.PDF */ static inline uint32_t encode_voltage(uint32_t v) { return rev8((0x78 - v / 125) << 1 | 1) << 8; }
static int64_t avalon2_scanhash(struct thr_info *thr) { struct avalon2_pkg send_pkg; struct pool *pool; struct cgpu_info *avalon2 = thr->cgpu; struct avalon2_info *info = avalon2->device_data; int64_t h; uint32_t tmp, range, start; int i; if (thr->work_restart || thr->work_update || info->first) { info->new_stratum = true; applog(LOG_DEBUG, "Avalon2: New stratum: restart: %d, update: %d, first: %d", thr->work_restart, thr->work_update, info->first); thr->work_update = false; thr->work_restart = false; if (unlikely(info->first)) info->first = false; get_work(thr, thr->id); /* Make sure pool is ready */ pool = current_pool(); if (!pool->has_stratum) quit(1, "Avalon2: Miner Manager have to use stratum pool"); if (pool->swork.cb_len > AVA2_P_COINBASE_SIZE) quit(1, "Avalon2: Miner Manager pool coinbase length have to less then %d", AVA2_P_COINBASE_SIZE); if (pool->swork.merkles > AVA2_P_MERKLES_COUNT) quit(1, "Avalon2: Miner Manager merkles have to less then %d", AVA2_P_MERKLES_COUNT); info->diff = (int)pool->swork.diff - 1; info->pool_no = pool->pool_no; cg_wlock(&pool->data_lock); avalon2_stratum_pkgs(info->fd, pool, thr); cg_wunlock(&pool->data_lock); /* Configuer the parameter from outside */ info->fan_pwm = opt_avalon2_fan_min; info->set_voltage = opt_avalon2_voltage_min; info->set_frequency = opt_avalon2_freq_min; /* Set the Fan, Voltage and Frequency */ memset(send_pkg.data, 0, AVA2_P_DATA_LEN); tmp = be32toh(info->fan_pwm); memcpy(send_pkg.data, &tmp, 4); /* http://www.onsemi.com/pub_link/Collateral/ADP3208D.PDF */ tmp = rev8((0x78 - info->set_voltage / 125) << 1 | 1) << 8; tmp = be32toh(tmp); memcpy(send_pkg.data + 4, &tmp, 4); tmp = be32toh(info->set_frequency); memcpy(send_pkg.data + 8, &tmp, 4); /* Configure the nonce2 offset and range */ range = 0xffffffff / total_devices; start = range * avalon2->device_id; tmp = be32toh(start); memcpy(send_pkg.data + 12, &tmp, 4); tmp = be32toh(range); memcpy(send_pkg.data + 16, &tmp, 4); /* Package the data */ avalon2_init_pkg(&send_pkg, AVA2_P_SET, 1, 1); while (avalon2_send_pkg(info->fd, &send_pkg, thr) != AVA2_SEND_OK) ; info->new_stratum = false; } polling(thr); h = 0; for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) { h += info->local_work[i]; } return h * 0xffffffff; }