Browse Source

Merge pull request #471 from kanoi/master

BTB voltage management via the API - and set default on startup
nfactor-troky
kanoi 11 years ago
parent
commit
e4e2062072
  1. 21
      API-README
  2. 76
      api.c
  3. 59
      driver-avalon.c
  4. 4
      driver-avalon.h

21
API-README

@ -393,6 +393,20 @@ The list of requests - a (*) means it requires privileged access - and replies a
asccount ASCS Count=N| <- the number of ASCs asccount ASCS Count=N| <- the number of ASCs
Always returns 0 if ASC mining is disabled Always returns 0 if ASC mining is disabled
ascset|N,opt[,val] (*)
none There is no reply section just the STATUS section
stating the results of setting ASC N with opt[,val]
This is only available if ASC mining is enabled
If the ASC does not support any set options, it will
always return a WARN stating ascset isn't supported
If opt=help it will return an INFO status with a
help message about the options available
The current options are:
BTB opt=millivolts val=1000 to 1310 - core voltage
When you enable, disable or restart a GPU, PGA or ASC, you will also get When you enable, disable or restart a GPU, PGA or ASC, you will also get
Thread messages in the cgminer status window Thread messages in the cgminer status window
@ -446,6 +460,13 @@ miner.php - an example web page to access the API
Feature Changelog for external applications using the API: Feature Changelog for external applications using the API:
API V1.27 (cgminer v3.3.2)
Added API commands:
'ascset' - with: BTB opt=millivolts val=1000 to 1310 - core voltage
----------
API V1.26 (cgminer v3.2.3) API V1.26 (cgminer v3.2.3)
Remove all CPU support (cgminer v3.0.0) Remove all CPU support (cgminer v3.0.0)

76
api.c

@ -134,7 +134,7 @@ static const char SEPARATOR = '|';
#define SEPSTR "|" #define SEPSTR "|"
static const char GPUSEP = ','; static const char GPUSEP = ',';
static const char *APIVERSION = "1.26"; static const char *APIVERSION = "1.27";
static const char *DEAD = "Dead"; static const char *DEAD = "Dead";
#if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) || defined(HAVE_AN_ASIC) #if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) || defined(HAVE_AN_ASIC)
static const char *SICK = "Sick"; static const char *SICK = "Sick";
@ -413,6 +413,14 @@ static const char *JSON_PARAMETER = "parameter";
#endif #endif
#define MSG_ASCUSBNODEV 115 #define MSG_ASCUSBNODEV 115
#ifdef HAVE_AN_ASIC
#define MSG_MISASCOPT 116
#define MSG_ASCNOSET 117
#define MSG_ASCHELP 118
#define MSG_ASCSETOK 119
#define MSG_ASCSETERR 120
#endif
enum code_severity { enum code_severity {
SEVERITY_ERR, SEVERITY_ERR,
SEVERITY_WARN, SEVERITY_WARN,
@ -608,6 +616,11 @@ struct CODES {
{ SEVERITY_ERR, MSG_ASCUNW, PARAM_ASC, "ASC %d is not flagged WELL, cannot enable" }, { SEVERITY_ERR, MSG_ASCUNW, PARAM_ASC, "ASC %d is not flagged WELL, cannot enable" },
{ SEVERITY_SUCC, MSG_ASCIDENT,PARAM_ASC, "Identify command sent to ASC%d" }, { SEVERITY_SUCC, MSG_ASCIDENT,PARAM_ASC, "Identify command sent to ASC%d" },
{ SEVERITY_WARN, MSG_ASCNOID, PARAM_ASC, "ASC%d does not support identify" }, { SEVERITY_WARN, MSG_ASCNOID, PARAM_ASC, "ASC%d does not support identify" },
{ SEVERITY_ERR, MSG_MISASCOPT, PARAM_NONE, "Missing option after ASC number" },
{ SEVERITY_WARN, MSG_ASCNOSET, PARAM_ASC, "ASC %d does not support pgaset" },
{ SEVERITY_INFO, MSG_ASCHELP, PARAM_BOTH, "ASC %d set help: %s" },
{ SEVERITY_SUCC, MSG_ASCSETOK, PARAM_BOTH, "ASC %d set OK" },
{ SEVERITY_ERR, MSG_ASCSETERR, PARAM_BOTH, "ASC %d set failed: %s" },
#endif #endif
{ SEVERITY_FAIL, 0, 0, NULL } { SEVERITY_FAIL, 0, 0, NULL }
}; };
@ -3681,6 +3694,66 @@ static void asccount(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __may
io_close(io_data); io_close(io_data);
} }
#ifdef HAVE_AN_ASIC
static void ascset(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
{
struct cgpu_info *cgpu;
struct device_drv *drv;
char buf[TMPBUFSIZ];
int numasc = numascs();
if (numasc == 0) {
message(io_data, MSG_ASCNON, 0, NULL, isjson);
return;
}
if (param == NULL || *param == '\0') {
message(io_data, MSG_MISID, 0, NULL, isjson);
return;
}
char *opt = strchr(param, ',');
if (opt)
*(opt++) = '\0';
if (!opt || !*opt) {
message(io_data, MSG_MISASCOPT, 0, NULL, isjson);
return;
}
int id = atoi(param);
if (id < 0 || id >= numasc) {
message(io_data, MSG_INVASC, id, NULL, isjson);
return;
}
int dev = ascdevice(id);
if (dev < 0) { // Should never happen
message(io_data, MSG_INVASC, id, NULL, isjson);
return;
}
cgpu = get_devices(dev);
drv = cgpu->drv;
char *set = strchr(opt, ',');
if (set)
*(set++) = '\0';
if (!drv->set_device)
message(io_data, MSG_ASCNOSET, id, NULL, isjson);
else {
char *ret = drv->set_device(cgpu, opt, set, buf);
if (ret) {
if (strcasecmp(opt, "help") == 0)
message(io_data, MSG_ASCHELP, id, ret, isjson);
else
message(io_data, MSG_ASCSETERR, id, ret, isjson);
} else
message(io_data, MSG_ASCSETOK, id, NULL, isjson);
}
}
#endif
static void checkcommand(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, char group); static void checkcommand(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, char group);
struct CMDS { struct CMDS {
@ -3743,6 +3816,7 @@ struct CMDS {
{ "ascenable", ascenable, true }, { "ascenable", ascenable, true },
{ "ascdisable", ascdisable, true }, { "ascdisable", ascdisable, true },
{ "ascidentify", ascidentify, true }, { "ascidentify", ascidentify, true },
{ "ascset", ascset, true },
#endif #endif
{ "asccount", asccount, false }, { "asccount", asccount, false },
{ NULL, NULL, false } { NULL, NULL, false }

59
driver-avalon.c

@ -602,7 +602,7 @@ static void avalon_initialise(struct cgpu_info *avalon)
avalon->drv->name, avalon->device_id, err); avalon->drv->name, avalon->device_id, err);
} }
static void bitburner_set_core_voltage(struct cgpu_info *avalon, int core_voltage) static bool bitburner_set_core_voltage(struct cgpu_info *avalon, int core_voltage)
{ {
uint8_t buf[2]; uint8_t buf[2];
int err; int err;
@ -616,12 +616,15 @@ static void bitburner_set_core_voltage(struct cgpu_info *avalon, int core_voltag
if (unlikely(err < 0)) { if (unlikely(err < 0)) {
applog(LOG_ERR, "%s%i: SetCoreVoltage failed: err = %d", applog(LOG_ERR, "%s%i: SetCoreVoltage failed: err = %d",
avalon->drv->name, avalon->device_id, err); avalon->drv->name, avalon->device_id, err);
return false;
} else { } else {
applog(LOG_WARNING, "%s%i: Core voltage set to %d millivolts", applog(LOG_WARNING, "%s%i: Core voltage set to %d millivolts",
avalon->drv->name, avalon->device_id, avalon->drv->name, avalon->device_id,
core_voltage); core_voltage);
} }
return true;
} }
return false;
} }
static int bitburner_get_core_voltage(struct cgpu_info *avalon) static int bitburner_get_core_voltage(struct cgpu_info *avalon)
@ -718,9 +721,16 @@ static bool avalon_detect_one(libusb_device *dev, struct usb_find_devices *found
avalon->device_path, info->miner_count, info->asic_count, info->timeout, avalon->device_path, info->miner_count, info->asic_count, info->timeout,
info->frequency); info->frequency);
if (usb_ident(avalon) == IDENT_BTB && if (usb_ident(avalon) == IDENT_BTB) {
opt_bitburner_core_voltage != BITBURNER_DEFAULT_CORE_VOLTAGE) if (opt_bitburner_core_voltage < BITBURNER_MIN_COREMV ||
bitburner_set_core_voltage(avalon, opt_bitburner_core_voltage); opt_bitburner_core_voltage > BITBURNER_MAX_COREMV) {
quit(1, "Invalid bitburner-voltage %d must be %dmv - %dmv",
opt_bitburner_core_voltage,
BITBURNER_MIN_COREMV,
BITBURNER_MAX_COREMV);
} else
bitburner_set_core_voltage(avalon, opt_bitburner_core_voltage);
}
return true; return true;
@ -1362,6 +1372,46 @@ static void avalon_shutdown(struct thr_info *thr)
do_avalon_close(thr); do_avalon_close(thr);
} }
static char *avalon_set_device(struct cgpu_info *avalon, char *option, char *setting, char *replybuf)
{
int val;
if (usb_ident(avalon) != IDENT_BTB) {
sprintf(replybuf, "%s has no set options", avalon->drv->name);
return replybuf;
}
if (strcasecmp(option, "help") == 0) {
sprintf(replybuf, "millivolts: range %d-%d",
BITBURNER_MIN_COREMV, BITBURNER_MAX_COREMV);
return replybuf;
}
if (strcasecmp(option, "millivolts") == 0 || strcasecmp(option, "mv") == 0) {
if (!setting || !*setting) {
sprintf(replybuf, "missing millivolts setting");
return replybuf;
}
val = atoi(setting);
if (val < BITBURNER_MIN_COREMV || val > BITBURNER_MAX_COREMV) {
sprintf(replybuf, "invalid millivolts: '%s' valid range %d-%d",
setting, BITBURNER_MIN_COREMV, BITBURNER_MAX_COREMV);
return replybuf;
}
if (bitburner_set_core_voltage(avalon, val))
return NULL;
else {
sprintf(replybuf, "Set millivolts failed");
return replybuf;
}
}
sprintf(replybuf, "Unknown option: %s", option);
return replybuf;
}
struct device_drv avalon_drv = { struct device_drv avalon_drv = {
.drv_id = DRIVER_AVALON, .drv_id = DRIVER_AVALON,
.dname = "avalon", .dname = "avalon",
@ -1374,6 +1424,7 @@ struct device_drv avalon_drv = {
.flush_work = avalon_flush_work, .flush_work = avalon_flush_work,
.get_api_stats = avalon_api_stats, .get_api_stats = avalon_api_stats,
.get_statline_before = get_avalon_statline_before, .get_statline_before = get_avalon_statline_before,
.set_device = avalon_set_device,
.reinit_device = avalon_init, .reinit_device = avalon_init,
.thread_shutdown = avalon_shutdown, .thread_shutdown = avalon_shutdown,
}; };

4
driver-avalon.h

@ -34,6 +34,10 @@
#define AVALON_TEMP_OVERHEAT 60 #define AVALON_TEMP_OVERHEAT 60
#define BITBURNER_DEFAULT_CORE_VOLTAGE 1200 /* in millivolts */ #define BITBURNER_DEFAULT_CORE_VOLTAGE 1200 /* in millivolts */
#define BITBURNER_MIN_COREMV 1000
/* change here if you want to risk killing it :) */
#define BITBURNER_MAX_COREMV 1310
#define AVALON_DEFAULT_TIMEOUT 0x2D #define AVALON_DEFAULT_TIMEOUT 0x2D
#define AVALON_MIN_FREQUENCY 256 #define AVALON_MIN_FREQUENCY 256

Loading…
Cancel
Save