mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-28 03:56:26 +03:00
Add -xfosc
This commit is contained in:
86
src/stk500.c
86
src/stk500.c
@@ -45,6 +45,18 @@
|
||||
#define STK500_XTAL 7372800U
|
||||
#define MAX_SYNC_ATTEMPTS 10
|
||||
|
||||
static double f_to_kHz_MHz(double f, const char **unit) {
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
*unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
*unit = "kHz";
|
||||
} else
|
||||
*unit = "Hz";
|
||||
return f;
|
||||
}
|
||||
|
||||
static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value);
|
||||
static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value);
|
||||
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
|
||||
@@ -586,7 +598,42 @@ static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
if(pgm->set_varef(pgm, 0, PDATA(pgm)->varef_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Read or write clock generator frequency
|
||||
if (PDATA(pgm)->fosc_get || PDATA(pgm)->fosc_set) {
|
||||
// Read current target voltage set value
|
||||
unsigned int osc_pscale;
|
||||
unsigned int osc_cmatch;
|
||||
const char *unit_get = {"Hz"};
|
||||
double f_get;
|
||||
stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
|
||||
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
|
||||
if(osc_pscale) {
|
||||
int prescale = 1;
|
||||
f_get = STK500_XTAL / 2;
|
||||
switch (osc_pscale) {
|
||||
case 2: prescale = 8; break;
|
||||
case 3: prescale = 32; break;
|
||||
case 4: prescale = 64; break;
|
||||
case 5: prescale = 128; break;
|
||||
case 6: prescale = 256; break;
|
||||
case 7: prescale = 1024; break;
|
||||
}
|
||||
f_get /= prescale;
|
||||
f_get /= (osc_cmatch + 1);
|
||||
f_get = f_to_kHz_MHz(f_get, &unit_get);
|
||||
}
|
||||
if (PDATA(pgm)->fosc_get)
|
||||
msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get);
|
||||
// Write target voltage value
|
||||
else {
|
||||
const char *unit_set;
|
||||
double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set);
|
||||
msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set);
|
||||
if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return pgm->program_enable(pgm, p);
|
||||
@@ -664,6 +711,43 @@ static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms)
|
||||
}
|
||||
}
|
||||
|
||||
else if (str_starts(extended_param, "fosc")) {
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ) {
|
||||
// Set clock generator frequency
|
||||
if (str_starts(extended_param, "fosc=")) {
|
||||
char fosc_str[16] = {0};
|
||||
int sscanf_success = sscanf(extended_param, "fosc=%10s", fosc_str);
|
||||
if (sscanf_success < 1) {
|
||||
pmsg_error("invalid fosc value '%s'\n", extended_param);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
char *endp;
|
||||
double v = strtod(fosc_str, &endp);
|
||||
if (endp == fosc_str){
|
||||
if (str_eq(fosc_str, "off"))
|
||||
PDATA(pgm)->fosc_data = 0.0;
|
||||
else {
|
||||
pmsg_error("cannot parse fosc value %s\n", fosc_str);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*endp == 'm' || *endp == 'M')
|
||||
PDATA(pgm)->fosc_data = v * 1e6;
|
||||
else if (*endp == 'k' || *endp == 'K')
|
||||
PDATA(pgm)->fosc_data = v * 1e3;
|
||||
PDATA(pgm)->fosc_set = true;
|
||||
continue;
|
||||
}
|
||||
// Get clock generator frequency
|
||||
else if(str_eq(extended_param, "fosc")) {
|
||||
PDATA(pgm)->fosc_get = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (str_eq(extended_param, "help")) {
|
||||
char *prg = (char *)ldata(lfirst(pgm->id));
|
||||
msg_error("%s -c %s extended options:\n", progname, prg);
|
||||
|
||||
@@ -52,6 +52,11 @@ struct pdata {
|
||||
bool varef_get;
|
||||
bool varef_set;
|
||||
double varef_data;
|
||||
|
||||
// Get/set flags for programmable clock generator
|
||||
bool fosc_get;
|
||||
bool fosc_set;
|
||||
double fosc_data;
|
||||
};
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
|
||||
199
src/stk500v2.c
199
src/stk500v2.c
@@ -384,6 +384,21 @@ u16_to_b2(unsigned char *b, unsigned short l)
|
||||
b[1] = (l >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static double
|
||||
f_to_kHz_MHz(double f, const char **unit)
|
||||
{
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
*unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
*unit = "kHz";
|
||||
} else
|
||||
*unit = "Hz";
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static int stk500v2_send_mk2(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
|
||||
if (serial_send(&pgm->fd, data, len) != 0) {
|
||||
pmsg_error("unable to send command to serial port\n");
|
||||
@@ -1276,6 +1291,63 @@ static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
}
|
||||
}
|
||||
|
||||
// Read or write clock generator frequency
|
||||
if (PDATA(pgm)->fosc_get || PDATA(pgm)->fosc_set) {
|
||||
if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) {
|
||||
// Read current target voltage set value
|
||||
unsigned char osc_pscale;
|
||||
unsigned char osc_cmatch;
|
||||
const char *unit_get = {"Hz"};
|
||||
double f_get;
|
||||
stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
|
||||
stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
|
||||
if(osc_pscale) {
|
||||
int prescale = 1;
|
||||
f_get = STK500V2_XTAL / 2;
|
||||
switch (osc_pscale) {
|
||||
case 2: prescale = 8; break;
|
||||
case 3: prescale = 32; break;
|
||||
case 4: prescale = 64; break;
|
||||
case 5: prescale = 128; break;
|
||||
case 6: prescale = 256; break;
|
||||
case 7: prescale = 1024; break;
|
||||
}
|
||||
f_get /= prescale;
|
||||
f_get /= (osc_cmatch + 1);
|
||||
f_get = f_to_kHz_MHz(f_get, &unit_get);
|
||||
}
|
||||
if (PDATA(pgm)->fosc_get)
|
||||
msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get);
|
||||
// Write target voltage value
|
||||
else {
|
||||
const char *unit_set;
|
||||
double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set);
|
||||
msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set);
|
||||
if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
} else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) {
|
||||
// Read current target voltage set value
|
||||
unsigned int clock_conf;
|
||||
stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf);
|
||||
unsigned int oct = (clock_conf & 0xf000) >> 12u;
|
||||
unsigned int dac = (clock_conf & 0x0ffc) >> 2u;
|
||||
double f_get = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0);
|
||||
const char *unit_get = {"Hz"};
|
||||
f_get = f_to_kHz_MHz(f_get, &unit_get);
|
||||
if (PDATA(pgm)->fosc_get)
|
||||
msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get);
|
||||
// Write target voltage value
|
||||
else {
|
||||
const char *unit_set;
|
||||
double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set);
|
||||
msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set);
|
||||
if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Examine the avrpart's memory definitions, and initialize the page
|
||||
* caches. For devices/memory that are not page oriented, treat
|
||||
@@ -1534,6 +1606,82 @@ static int stk500hv_initialize(const PROGRAMMER *pgm, const AVRPART *p, enum hvm
|
||||
}
|
||||
}
|
||||
|
||||
// Read or write clock generator frequency
|
||||
if (PDATA(pgm)->fosc_get || PDATA(pgm)->fosc_set) {
|
||||
if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) {
|
||||
// Read current target voltage set value
|
||||
unsigned char osc_pscale;
|
||||
unsigned char osc_cmatch;
|
||||
const char *unit_get = {"Hz"};
|
||||
double f_get;
|
||||
stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
|
||||
stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
|
||||
if(osc_pscale) {
|
||||
int prescale = 1;
|
||||
f_get = STK500V2_XTAL / 2;
|
||||
switch (osc_pscale) {
|
||||
case 2: prescale = 8; break;
|
||||
case 3: prescale = 32; break;
|
||||
case 4: prescale = 64; break;
|
||||
case 5: prescale = 128; break;
|
||||
case 6: prescale = 256; break;
|
||||
case 7: prescale = 1024; break;
|
||||
}
|
||||
f_get /= prescale;
|
||||
f_get /= (osc_cmatch + 1);
|
||||
f_get = f_to_kHz_MHz(f_get, &unit_get);
|
||||
}
|
||||
if (PDATA(pgm)->fosc_get)
|
||||
msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get);
|
||||
// Write target voltage value
|
||||
else {
|
||||
const char *unit_set;
|
||||
double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set);
|
||||
msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set);
|
||||
if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
} else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) {
|
||||
// Read current target voltage set value
|
||||
unsigned int clock_conf;
|
||||
stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf);
|
||||
unsigned int oct = (clock_conf & 0xf000) >> 12u;
|
||||
unsigned int dac = (clock_conf & 0x0ffc) >> 2u;
|
||||
double f_get = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0);
|
||||
const char *unit_get = {"Hz"};
|
||||
f_get = f_to_kHz_MHz(f_get, &unit_get);
|
||||
if (PDATA(pgm)->fosc_get)
|
||||
msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get);
|
||||
// Write target voltage value
|
||||
else {
|
||||
const char *unit_set;
|
||||
double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set);
|
||||
msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set);
|
||||
if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static int stk600_set_fosc(const PROGRAMMER *pgm, double v) {
|
||||
unsigned int oct, dac;
|
||||
|
||||
oct = 1.443 * log(v / 1039.0);
|
||||
dac = 2048 - (2078.0 * pow(2, (double)(10 + oct))) / v;
|
||||
|
||||
return stk500v2_setparm2(pgm, PARAM2_CLOCK_CONF, (oct << 12) | (dac << 2));
|
||||
}
|
||||
|
||||
stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf);
|
||||
oct = (clock_conf & 0xf000) >> 12u;
|
||||
dac = (clock_conf & 0x0ffc) >> 2u;
|
||||
f = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0);
|
||||
f = f_to_kHz_MHz(f, &unit);
|
||||
fmsg_out(fp, "%sOscillator : %.3f %s\n",
|
||||
p, f, unit);
|
||||
*/
|
||||
|
||||
/*
|
||||
* Examine the avrpart's memory definitions, and initialize the page
|
||||
* caches. For devices/memory that are not page oriented, treat
|
||||
@@ -1761,6 +1909,43 @@ static int stk500v2_parseextparms(const PROGRAMMER *pgm, const LISTID extparms)
|
||||
}
|
||||
}
|
||||
|
||||
else if (str_starts(extended_param, "fosc")) {
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ) {
|
||||
// Set clock generator frequency
|
||||
if (str_starts(extended_param, "fosc=")) {
|
||||
char fosc_str[16] = {0};
|
||||
int sscanf_success = sscanf(extended_param, "fosc=%10s", fosc_str);
|
||||
if (sscanf_success < 1) {
|
||||
pmsg_error("invalid fosc value '%s'\n", extended_param);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
char *endp;
|
||||
double v = strtod(fosc_str, &endp);
|
||||
if (endp == fosc_str){
|
||||
if (str_eq(fosc_str, "off"))
|
||||
PDATA(pgm)->fosc_data = 0.0;
|
||||
else {
|
||||
pmsg_error("cannot parse fosc value %s\n", fosc_str);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*endp == 'm' || *endp == 'M')
|
||||
PDATA(pgm)->fosc_data = v * 1e6;
|
||||
else if (*endp == 'k' || *endp == 'K')
|
||||
PDATA(pgm)->fosc_data = v * 1e3;
|
||||
PDATA(pgm)->fosc_set = true;
|
||||
continue;
|
||||
}
|
||||
// Get clock generator frequency
|
||||
else if(str_eq(extended_param, "fosc")) {
|
||||
PDATA(pgm)->fosc_get = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pmsg_error("invalid extended parameter '%s'\n", extended_param);
|
||||
rv = -1;
|
||||
}
|
||||
@@ -3439,20 +3624,6 @@ static void stk500v2_display(const PROGRAMMER *pgm, const char *p) {
|
||||
return;
|
||||
}
|
||||
|
||||
static double
|
||||
f_to_kHz_MHz(double f, const char **unit)
|
||||
{
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
*unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
*unit = "kHz";
|
||||
} else
|
||||
*unit = "Hz";
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
|
||||
unsigned char vtarget = 0, vadjust = 0, osc_pscale = 0, osc_cmatch = 0, sck_duration =0; //XXX 0 is not correct, check caller
|
||||
|
||||
@@ -291,6 +291,11 @@ struct pdata
|
||||
int varef_channel;
|
||||
double varef_data;
|
||||
|
||||
/* Get/set flags for programmable clock generator */
|
||||
bool fosc_get;
|
||||
bool fosc_set;
|
||||
double fosc_data;
|
||||
|
||||
const AVRPART *lastpart;
|
||||
|
||||
/* Start address of Xmega boot area */
|
||||
|
||||
Reference in New Issue
Block a user