Commit 0ae0a87dfc2fa928ca03126d5f02143bcd530530

Henrik Nordstrom 2014-06-30T20:00:59

Update knc-asic to current version, fixing next_state response bit decoding

diff --git a/knc-asic.c b/knc-asic.c
index bcf48eb..b499dfa 100644
--- a/knc-asic.c
+++ b/knc-asic.c
@@ -259,6 +259,26 @@ int knc_prepare_report(uint8_t *request, int die, int core)
 	return 4;
 }
 
+int knc_prepare_info(uint8_t *request, int die, struct knc_die_info *die_info, int *response_size)
+{
+	request[0] = KNC_ASIC_CMD_GETINFO;
+	request[1] = die;
+	request[2] = 0;
+	request[3] = 0;
+	switch (die_info->version) {
+	case KNC_VERSION_JUPITER:
+		*response_size = 4;
+		break;
+	default:
+		*response_size = 12 + (KNC_MAX_CORES_PER_DIE*2 + 7) / 8;
+		break;
+	case KNC_VERSION_NEPTUNE:
+		*response_size = 12 + (die_info->cores*2 + 7) / 8;
+		break;
+	}
+	return 4;
+}
+
 int knc_prepare_neptune_setwork(uint8_t *request, int die, int core, int slot, struct work *work, int clean)
 {
 	if (!clean)
@@ -332,6 +352,43 @@ int knc_prepare_transfer(uint8_t *txbuf, int offset, int size, int channel, int 
 	return offset + len;
 }
 
+/* red, green, blue valid range 0 - 15 */
+int knc_prepare_led(uint8_t *txbuf, int offset, int size, int red, int green, int blue)
+{
+	/* 4'h1 4'red 4'green 4'blue */
+        int len = 2;
+	txbuf += offset;
+
+	if (len + offset > size) {
+		applog(LOG_DEBUG, "KnC SPI buffer full");
+		return -1;
+	}
+	txbuf[0] = 1 << 4 | red;
+	txbuf[1] = green << 4 | blue;
+
+	return offset + len;
+	
+}
+
+/* reset controller */
+int knc_prepare_reset(uint8_t *txbuf, int offset, int size)
+{
+	/* 16'h0002 16'unused */
+        int len = 4;
+	txbuf += offset;
+
+	if (len + offset > size) {
+		applog(LOG_DEBUG, "KnC SPI buffer full");
+		return -1;
+	}
+	txbuf[0] = (0x0002) >> 8;
+	txbuf[1] = (0x0002) & 0xff;
+	txbuf[2] = 0;
+	txbuf[3] = 0;
+
+	return offset + len;
+}
+
 /* request_length = 0 disables communication checks, i.e. Jupiter protocol */
 int knc_decode_response(uint8_t *rxbuf, int request_length, uint8_t **response, int response_length)
 {
@@ -430,9 +487,9 @@ int knc_decode_report(uint8_t *response, struct knc_report *report, int version)
  * nonce_slot   4 bits
  * nonce        32 bits
  */
-	report->next_state = (response[0] >> 6) & 1;
+	report->next_state = (response[0] >> 5) & 1;
 	if (version != KNC_VERSION_JUPITER) {
-		report->state = (response[0] >> 5) & 1;
+		report->state = (response[0] >> 4) & 1;
 		report->next_slot = response[0] & ((1<<4)-1);
 	} else {
 		report->state = -1;
@@ -460,10 +517,13 @@ int knc_decode_report(uint8_t *response, struct knc_report *report, int version)
 
 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 };
+	uint8_t request[4];
 	int response_len = 2 + 2 + 4 + 4 + (KNC_MAX_CORES_PER_DIE*2 + 7) / 8;
 	uint8_t response[response_len];
-	int status = knc_syncronous_transfer(ctx, channel, 4, get_info, response_len, response);
+
+	int request_len = knc_prepare_info(request, die, die_info, &response_len);
+	int status = knc_syncronous_transfer(ctx, channel, request_len, request, response_len, response);
+
 	/* Workaround for pre-ASIC version */
 	int cores_in_die = response[0]<<8 | response[1];
 	int version = response[2]<<8 | response[3];
@@ -471,7 +531,7 @@ int knc_detect_die(void *ctx, int channel, int die, struct knc_die_info *die_inf
 		applog(LOG_DEBUG, "KnC %d-%d: Looks like a NEPTUNE die with %d cores", channel, die, cores_in_die);
 		/* Try again with right response size */
 		response_len = 2 + 2 + 4 + 4 + (cores_in_die*2 + 7) / 8;
-		status = knc_syncronous_transfer(ctx, channel, 4, get_info, response_len, response);
+		status = knc_syncronous_transfer(ctx, channel, request_len, request, response_len, response);
 	}
 	int rc = -1;
 	if (version == KNC_ASIC_VERSION_JUPITER || status == 0)
diff --git a/knc-asic.h b/knc-asic.h
index 6ab9906..0f80336 100644
--- a/knc-asic.h
+++ b/knc-asic.h
@@ -1,6 +1,5 @@
 #ifndef _CGMINER_NEPTUNE_H
-#define _CGMINER_NEPTUNE_H
-
+#define _CGMINER_NEPTUNE_H 
 #include <stdint.h>
 #include "miner.h"
 
@@ -53,6 +52,7 @@ struct knc_report {
 	} nonce[KNC_NONCES_PER_REPORT];
 };
 
+int knc_prepare_info(uint8_t *request, int die, struct knc_die_info *die_info, int *response_size);
 int knc_prepare_report(uint8_t *request, int die, int core);
 int knc_prepare_neptune_setwork(uint8_t *request, int die, int core, int slot, struct work *work, int clean);
 int knc_prepare_jupiter_setwork(uint8_t *request, int die, int core, int slot, struct work *work);
@@ -74,6 +74,13 @@ int knc_prepare_transfer(uint8_t *txbuf, int offset, int size, int channel, int 
 int knc_decode_response(uint8_t *rxbuf, int request_length, uint8_t **response, int response_length);
 int knc_syncronous_transfer(void *ctx, int channel, int request_length, const uint8_t *request, int response_length, uint8_t *response);
 
+/* Detect ASIC DIE version */
 int knc_detect_die(void *ctx, int channel, int die, struct knc_die_info *die_info);
 
+/* red, green, blue valid range 0 - 15. No response or checksum from controller */
+int knc_prepare_led(uint8_t *txbuf, int offset, int size, int red, int green, int blue);
+
+/* Reset controller */
+int knc_prepare_reset(uint8_t *txbuf, int offset, int size);
+
 #endif