Browse Source

Merge pull request #731 from jstefanop/futurebit2_driver

Futurebit2 driver
jstefanop 8 years ago
parent
commit
106390a99a
1 changed files with 155 additions and 37 deletions
  1. 155 37
      driver-futurebit.c

+ 155 - 37
driver-futurebit.c

@@ -87,17 +87,16 @@ void futurebit_reset_board(const int fd)
     applog(LOG_DEBUG, "RESET END");
 }
 
-
-int futurebit_write(const int fd,  const void *buf, size_t buflen)
+static
+bool futurebit_write(const int fd,  const void *buf, size_t buflen)
 {
 	int repeat = 0;
 	int size = 0;
-	int ret = 0;
 	int nwrite = 0;
 
-	char output[(buflen * 2) + 1];
-    bin2hex(output, buf, buflen);
-    applog(LOG_DEBUG, "WRITE BUFFER %s", output);
+	//char output[(buflen * 2) + 1];
+    //bin2hex(output, buf, buflen);
+    //applog(LOG_DEBUG, "WRITE BUFFER %s", output);
 
 	while(size < buflen)
 	{
@@ -106,7 +105,7 @@ int futurebit_write(const int fd,  const void *buf, size_t buflen)
 		if (nwrite < 0)
 		{
 			applog(LOG_ERR, "FutureBit Write error: %s", strerror(errno));
-			break;
+			return false;
 		}
 
 		size += nwrite;
@@ -118,7 +117,7 @@ int futurebit_write(const int fd,  const void *buf, size_t buflen)
 
 	}
 
-	return 0;
+	return true;
 }
 
 static
@@ -162,7 +161,7 @@ bool futurebit_read (const int fd, unsigned char *buf, int read_amount)
 }
 
 static
-char futurebit_read_register(const int fd, uint32_t chip, uint32_t moudle, uint32_t RegAddr)
+char futurebit_read_register(const int fd, uint32_t chip, uint32_t moudle, uint32_t RegAddr, int pos)
 {
 	uint8_t read_reg_data[8]={0};
 	uint8_t read_reg_cmd[16]={0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0xc3};
@@ -182,20 +181,20 @@ char futurebit_read_register(const int fd, uint32_t chip, uint32_t moudle, uint3
         applog(LOG_DEBUG, "FutureBit read register fail");
 
 
-    applog(LOG_DEBUG, "FutureBit Read Return:");
-    for (int i=0; i<8; i++)
-		{
-			applog(LOG_DEBUG,"0x%02x ", read_reg_data[i]);
-		}
-    applog(LOG_DEBUG,"\n");
+    //applog(LOG_DEBUG, "FutureBit Read Return:");
+    //for (int i=0; i<8; i++)
+	//	{
+	//		applog(LOG_DEBUG,"0x%02x ", read_reg_data[i]);
+	//	}
+    //applog(LOG_DEBUG,"\n");
 
-    return read_reg_data[0];
+    return read_reg_data[pos];
 }
 
 unsigned
 int futurebit_write_register(const int fd, uint32_t chipId, uint32_t moudle, uint32_t Regaddr, uint32_t value)
 {
-	bool ret =true;
+
 	uint8_t read_reg_cmd[16]={0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0xc3};
 
 	read_reg_cmd[1] = chipId;
@@ -207,9 +206,9 @@ int futurebit_write_register(const int fd, uint32_t chipId, uint32_t moudle, uin
 	read_reg_cmd[7] = (value>>24)&0xff;
 
 
-	futurebit_write(fd, read_reg_cmd, 9);
 
-	return  ret;
+
+	return futurebit_write(fd, read_reg_cmd, 9);
 }
 
 static
@@ -243,6 +242,104 @@ void futurebit_set_frequency(const int fd, uint32_t freq)
 
 }
 
+static
+bool futurebit_soft_reset(int fd)
+{
+    bool ret = false;
+    do
+    {
+		if(!futurebit_write_register(fd, 0xff, 0xf8, 0x1e, 0x00))
+		    break;
+		cgsleep_us(50000);
+		if(!futurebit_write_register(fd, 0xff, 0xf8, 0x1e, 0x03))
+		    break;
+		ret = true;
+    }while(0);
+    return ret;
+}
+
+unsigned char calculate_good_core(unsigned int reg_val)
+{
+
+		unsigned char goodCores=0;
+		unsigned char i;
+		unsigned int RegisterVal = reg_val;
+
+		for(i=0; i<32; i++)
+		{
+				if (RegisterVal & 0x01)
+						goodCores++;
+
+				RegisterVal = RegisterVal>>1;
+		}
+
+		return goodCores;
+}
+
+unsigned
+int futurebit_core_test(int fd, uint32_t freq_t)
+{
+	unsigned int i;
+	unsigned int bist_value = 0;
+	unsigned int goodcores0=0;
+	unsigned int goodcores1=0;
+    unsigned int  total = 0;
+    unsigned int regval=0xff;
+    int ret = -1;
+
+    futurebit_send_cmds(fd, cmd_auto_address);
+    cgsleep_us(100000);
+    futurebit_set_frequency(fd, freq_t);
+	cgsleep_us(100000);
+    futurebit_write_register(fd, 0xff, 0xf8,0x22,0x11090005);//feed through
+	cgsleep_us(100000);
+
+
+    for (i=0; i<8; i++)
+    {
+        regval = 0x0f<<(4*i);
+        if (!futurebit_write_register(fd, 0xff, 0xf8, 0x04, regval)) return ret;
+        cgsleep_us(50000);
+        if(!futurebit_write_register(fd, 0xff, 0xf8, 0x05, regval)) return ret;
+        cgsleep_us(50000);
+
+        do
+        {
+            if(!futurebit_write_register(fd, 0xff, 0x00, 0x3f, 0x00000020))//bist enable
+                return ret;
+
+            cgsleep_us(50000);
+            if(!futurebit_write_register(fd, 0xff, 0x00, 0x23, 0xD799431B))//bist start, data2
+                return ret;
+
+            cgsleep_us(50000);
+
+            goodcores0 = 0;
+            goodcores1 = 0;
+
+            bist_value = futurebit_read_register(fd, 0xff, 0x00, 0xbe, 4);
+
+            if (bist_value > 0)
+                goodcores0  = calculate_good_core(bist_value);
+
+            bist_value = futurebit_read_register(fd, 0xff, 0x00, 0xbe, 4);
+
+            if (bist_value > 0)
+                goodcores1  = calculate_good_core(bist_value);
+
+            ret += ( goodcores0+goodcores1);
+
+        }while(0);
+
+        if(!futurebit_soft_reset(fd)) return ret;//retset
+        cgsleep_us(50000);
+    }
+
+
+
+	return ret;
+}
+
 void futurebit_config_all_chip(const int fd, uint32_t freq)
 {
 	uint32_t reg_val;
@@ -256,12 +353,8 @@ void futurebit_config_all_chip(const int fd, uint32_t freq)
 	//cgsleep_us(100000);
 	futurebit_set_frequency(fd, freq);
 	cgsleep_us(100000);
-
-
-#if 1
 	futurebit_write_register(fd, 0xff, 0xf8,0x22,0x11090005);//feed through
 	cgsleep_us(100000);
-#endif
 
     //Start Nonce at zero for single chip
 	//reg_val = 0xffffffff/futurebit_max_chips;
@@ -386,12 +479,12 @@ bool futurebit_send_work(const struct thr_info * const thr, struct work * const
         szOutput[idx] = (char)strtol(acTmp, NULL, 16);
     }
     */
-    futurebit_write(device->device_fd, bin, 144);//144bytes
+
     chips[0].last_nonce = 0x00000000;
 
     work->blk.nonce = FUTUREBIT_MAX_NONCE;
 
-    return true;
+    return futurebit_write(device->device_fd, bin, 144);//144bytes
 }
 
 static
@@ -409,7 +502,7 @@ bool futurebit_detect_one(const char * const devpath)
 
     futurebit_reset_board(fd);
 
-    if(futurebit_read_register(fd, 0xff, 0xf8, 0xa6) != 0x3c)
+    if(futurebit_read_register(fd, 0xff, 0xf8, 0xa6, 0) != 0x3c)
         return_via_applog(err, , LOG_DEBUG, "%s: Failed to (%s) %s", futurebit_drv.dname, "find chip", devpath);
 
 
@@ -431,10 +524,20 @@ bool futurebit_detect_one(const char * const devpath)
     struct futurebit_chip * const chip = &chips[0];
     futurebit_chip_init(chip, 0);
     chip->freq = freq;
-    
+
+    total_cores = futurebit_core_test(fd, freq);
+
+    if(total_cores < 0)
+        return_via_applog(err, , LOG_DEBUG, "%s: %s %s", futurebit_drv.dname, "Failed core detection", devpath);
+    else if(total_cores < 60)
+        applog(LOG_DEBUG, "%s: %s %u%s", futurebit_drv.dname, "Warning:", total_cores, "/64 detected");
+    else
+        applog(LOG_DEBUG, "%s: Identified %u cores on %s", futurebit_drv.dname, total_cores, devpath);
+
+
     if (serial_claim_v(devpath, &futurebit_drv))
     goto err;
-    
+
     //serial_close(fd);
     struct cgpu_info * const cgpu = malloc(sizeof(*cgpu));
     *cgpu = (struct cgpu_info){
@@ -447,17 +550,17 @@ bool futurebit_detect_one(const char * const devpath)
     };
     // NOTE: Xcode's clang has a bug where it cannot find fields inside anonymous unions (more details in fpgautils)
     cgpu->device_fd = fd;
-    
+
     const bool ret = add_cgpu(cgpu);
-    
+
     cgsleep_ms(cgpu->device_id*200);  //add small delay for devices > 0 so all devices dont start up at once
-    
+
     //applog(LOG_DEBUG, "DEVICE ID %d", cgpu->device_id);
-    
+
     futurebit_config_all_chip(fd, freq);
     futurebit_pull_up_payload(fd);
 
-    
+
     return ret;
 
 err:
@@ -515,8 +618,8 @@ int64_t futurebit_scanhash(struct thr_info *thr, struct work *work, int64_t __ma
     struct cgpu_info *device = thr->cgpu;
     int fd = device->device_fd;
     struct futurebit_chip *chips = device->device_data;
-    struct timeval start_tv, nonce_range_tv;
-    
+    struct timeval start_tv, nonce_range_tv, last_submit_tv, now_tv;
+
 
     // amount of time it takes this device to scan a nonce range:
     uint32_t nonce_full_range_sec = FUTUREBIT_HASH_SPEED * FUTUREBIT_DEFAULT_FREQUENCY / chips[0].freq * 64.0 / chips[0].active_cores;
@@ -527,6 +630,9 @@ int64_t futurebit_scanhash(struct thr_info *thr, struct work *work, int64_t __ma
 
     // start the job
     timer_set_now(&start_tv);
+    timer_set_delay_from_now(&last_submit_tv, 10*1000000);
+
+    cgsleep_ms(device->device_id*10 + 50);  //add small delay for devices > 0 so all devices dont start up at once
 
     if (!futurebit_send_work(thr, work)) {
         applog(LOG_DEBUG, "Failed to start job");
@@ -536,19 +642,31 @@ int64_t futurebit_scanhash(struct thr_info *thr, struct work *work, int64_t __ma
     unsigned char buf[12];
     int read = 0;
     bool range_nearly_scanned = false;
+    bool no_asic_response = false;
 
-    while (!thr->work_restart                                              // true when new work is available (miner.c)
+
+    while (!thr->work_restart                                               // true when new work is available (miner.c)
+           && !(no_asic_response = timer_passed(&last_submit_tv, NULL))     // check for core stall
            && ((read = serial_read(fd, buf, 8)) >= 0)                       // only check for failure - allow 0 bytes
-           && !(range_nearly_scanned = timer_passed(&nonce_range_tv, NULL)))  // true when we've nearly scanned a nonce range
+           && !(range_nearly_scanned = timer_passed(&nonce_range_tv, NULL)))// true when we've nearly scanned a nonce range
     {
         if (read == 0)
             continue;
 
         if (read == 8) {
             futurebit_submit_nonce(thr, buf, work, start_tv);
+            timer_set_delay_from_now(&last_submit_tv, 10*1000000);
         }
         else
             applog(LOG_ERR, "%"PRIpreprv": Unrecognized response", device->proc_repr);
+
+    }
+
+    if(no_asic_response){                             //asic is dead, lets attempt to restart it
+        futurebit_reset_board(device->device_fd);
+        futurebit_config_all_chip(fd, chips[0].freq);
+        futurebit_pull_up_payload(fd);
+        applog(LOG_ERR, "%s: ASIC has stopped hashing, attempting to restart", device->dev_repr);
     }
 
     if (read == -1)