Update knc-asic to current version adding knc_decode_report
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
diff --git a/knc-asic.c b/knc-asic.c
index c5fbfab..bcf48eb 100644
--- a/knc-asic.c
+++ b/knc-asic.c
@@ -1,5 +1,5 @@
/*
- * cgminer driver for KnCminer Neptune devices
+ * library for KnCminer devices
*
* Copyright 2014 KnCminer
*
@@ -83,7 +83,12 @@
*
* cores 16 bits
* version 16 bits
- * reserved 64 bits (Neptune)
+ * reserved 60 bits (Neptune)
+ * die_status 4 bits (Neptune)
+ * 1' pll_locked
+ * 1' hash_reset_n 1 if cores have been reset since last report
+ * 1' pll_reset_n 1 if PLL have been reset since last report
+ * 1' pll_power_down
* core_status cores * 2 bits (Neptune) rounded up to bytes
* 1' want_work
* 1' has_report (unreliable)
@@ -387,6 +392,10 @@ int knc_decode_info(uint8_t *response, struct knc_die_info *die_info)
die_info->version = KNC_VERSION_JUPITER;
die_info->cores = cores_in_die;
memset(die_info->want_work, -1, cores_in_die);
+ die_info->pll_power_down = -1;
+ die_info->pll_reset_n = -1;
+ die_info->hash_reset_n = -1;
+ die_info->pll_locked = -1;
return 0;
} else if (version == KNC_ASIC_VERSION_NEPTUNE && cores_in_die <= KNC_MAX_CORES_PER_DIE) {
die_info->version = KNC_VERSION_NEPTUNE;
@@ -394,12 +403,61 @@ int knc_decode_info(uint8_t *response, struct knc_die_info *die_info)
int core;
for (core = 0; core < cores_in_die; core++)
die_info->want_work[core] = ((response[12 + core/4] >> ((3-(core % 4)) * 2)) >> 1) & 1;
+ int die_status = response[11] & 0xf;
+ die_info->pll_power_down = (die_status >> 0) & 1;
+ die_info->pll_reset_n = (die_status >> 1) & 1;
+ die_info->hash_reset_n = (die_status >> 2) & 1;
+ die_info->pll_locked = (die_status >> 3) & 1;
return 0;
} else {
return -1;
}
}
+int knc_decode_report(uint8_t *response, struct knc_report *report, int version)
+{
+/*
+ * reserved 2 bits
+ * next_state 1 bit next work state loaded
+ * state 1 bit hashing (0 on Jupiter)
+ * next_slot 4 bit slot id of next work state (0 on Jupiter)
+ * progress 8 bits upper 8 bits of nonce counter
+ * active_slot 4 bits slot id of current work state
+ * nonce_slot 4 bits slot id of found nonce
+ * nonce 32 bits
+ *
+ * reserved 4 bits
+ * nonce_slot 4 bits
+ * nonce 32 bits
+ */
+ report->next_state = (response[0] >> 6) & 1;
+ if (version != KNC_VERSION_JUPITER) {
+ report->state = (response[0] >> 5) & 1;
+ report->next_slot = response[0] & ((1<<4)-1);
+ } else {
+ report->state = -1;
+ report->next_slot = -1;
+ }
+ report->progress = (uint32_t)response[1] << 24;
+ report->active_slot = (response[2] >> 4) & ((1<<4)-1);
+ int n;
+ int n_nonces = version == KNC_VERSION_JUPITER ? 1 : 5;
+ for (n = 0; n < n_nonces; n++) {
+ report->nonce[n].slot = response[2+n*5] & ((1<<4)-1);
+ report->nonce[n].nonce =
+ (uint32_t)response[3+n*5] << 24 |
+ (uint32_t)response[4+n*5] << 16 |
+ (uint32_t)response[5+n*5] << 8 |
+ (uint32_t)response[6+n*5] << 0 |
+ 0;
+ }
+ for (; n < KNC_NONCES_PER_REPORT; n++) {
+ report->nonce[n].slot = -1;
+ report->nonce[n].nonce = 0;
+ }
+ return 0;
+}
+
int knc_detect_die(void *ctx, int channel, int die, struct knc_die_info *die_info)
{
uint8_t get_info[4] = { KNC_ASIC_CMD_GETINFO, die, 0, 0 };
diff --git a/knc-asic.h b/knc-asic.h
index f247fca..6ab9906 100644
--- a/knc-asic.h
+++ b/knc-asic.h
@@ -33,6 +33,24 @@ struct knc_die_info {
} version;
char want_work[KNC_MAX_CORES_PER_DIE];
int cores;
+ int pll_locked;
+ int hash_reset_n;
+ int pll_reset_n;
+ int pll_power_down;
+};
+
+#define KNC_NONCES_PER_REPORT 5
+
+struct knc_report {
+ int next_state;
+ int state;
+ int next_slot;
+ int active_slot;
+ uint32_t progress;
+ struct {
+ int slot;
+ uint32_t nonce;
+ } nonce[KNC_NONCES_PER_REPORT];
};
int knc_prepare_report(uint8_t *request, int die, int core);
@@ -42,6 +60,7 @@ int knc_prepare_jupiter_halt(uint8_t *request, int die, int core);
int knc_prepare_neptune_halt(uint8_t *request, int die, int core);
int knc_decode_info(uint8_t *response, struct knc_die_info *die_info);
+int knc_decode_report(uint8_t *response, struct knc_report *report, int version);
void knc_prepare_neptune_message(int request_length, const uint8_t *request, uint8_t *buffer);