Commit d70b8ef21a93fe3840b2d60560b8730b23cd9957

Henrik Nordstrom 2014-06-26T15:22:05

Update knc-asic to current version adding knc_decode_report

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);