Update knc-asic to current version, fixing next_state response bit decoding
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 136 137 138 139 140 141 142 143 144 145 146
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