stk500.c, term.c, doc/avrdude.texi, avrdude.1: added "sck"-command to the terminal mode. This command allows slowing down of the SCK of STK500-programmers.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@427 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
10272c5a55
commit
bcb78e8e05
|
@ -1,3 +1,9 @@
|
|||
2004-07-07 Jan-Hinnerk Reichert <hinni@despammed.com>
|
||||
* stk500.c, term.c, doc/avrdude.texi, avrdude.1:
|
||||
added "sck"-command to the terminal mode.
|
||||
This command allows slowing down of the SCK of
|
||||
STK500-programmers.
|
||||
|
||||
2004-07-05 Jan-Hinnerk Reichert <hinni@despammed.com>
|
||||
* *.c, *.h: Removed unnecessary includes of
|
||||
config.h
|
||||
|
|
|
@ -434,6 +434,11 @@ by 1E3.
|
|||
.It Ar fosc off
|
||||
Turn the master oscillator off.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar sck period
|
||||
Set the SCK clock period to
|
||||
.Ar period
|
||||
microseconds.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar parms
|
||||
Display the current voltage and master oscillator parameters.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
|
|
|
@ -753,6 +753,9 @@ multiplies by 1E6, a trailing letter @var{k} by 1E3.
|
|||
@item fosc off
|
||||
Turn the master oscillator off.
|
||||
|
||||
@item sck @var{period}
|
||||
Set the SCK clock period to @var{period} microseconds.
|
||||
|
||||
@item parms
|
||||
Display the current voltage and master oscillator parameters.
|
||||
|
||||
|
|
1
pgm.h
1
pgm.h
|
@ -79,6 +79,7 @@ typedef struct programmer_t {
|
|||
int (*set_vtarget) (struct programmer_t * pgm, double v);
|
||||
int (*set_varef) (struct programmer_t * pgm, double v);
|
||||
int (*set_fosc) (struct programmer_t * pgm, double v);
|
||||
int (*set_sck_period) (struct programmer_t * pgm, double v);
|
||||
char config_file[PATH_MAX]; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
} PROGRAMMER;
|
||||
|
|
54
stk500.c
54
stk500.c
|
@ -41,6 +41,7 @@
|
|||
#include "stk500_private.h"
|
||||
#include "serial.h"
|
||||
|
||||
#define STK500_XTAL 7372800U
|
||||
|
||||
extern int verbose;
|
||||
extern char * progname;
|
||||
|
@ -889,7 +890,6 @@ static int stk500_set_varef(PROGRAMMER * pgm, double v)
|
|||
|
||||
static int stk500_set_fosc(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
#define fbase 7372800U
|
||||
unsigned prescale, cmatch, fosc;
|
||||
static unsigned ps[] = {
|
||||
1, 8, 32, 64, 128, 256, 1024
|
||||
|
@ -898,7 +898,7 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
|
|||
|
||||
prescale = cmatch = 0;
|
||||
if (v > 0.0) {
|
||||
if (v > fbase / 2) {
|
||||
if (v > STK500_XTAL / 2) {
|
||||
const char *unit;
|
||||
if (v > 1e6) {
|
||||
v /= 1e6;
|
||||
|
@ -910,22 +910,22 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
|
|||
unit = "Hz";
|
||||
fprintf(stderr,
|
||||
"%s: stk500_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",
|
||||
progname, v, unit, fbase / 2e6);
|
||||
fosc = fbase / 2;
|
||||
progname, v, unit, STK500_XTAL / 2e6);
|
||||
fosc = STK500_XTAL / 2;
|
||||
} else
|
||||
fosc = (unsigned)v;
|
||||
|
||||
for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
|
||||
if (fosc >= fbase / (256 * ps[idx] * 2)) {
|
||||
if (fosc >= STK500_XTAL / (256 * ps[idx] * 2)) {
|
||||
/* this prescaler value can handle our frequency */
|
||||
prescale = idx + 1;
|
||||
cmatch = (unsigned)(fbase / (2 * fosc * ps[idx])) - 1;
|
||||
cmatch = (unsigned)(STK500_XTAL / (2 * fosc * ps[idx])) - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx == sizeof(ps) / sizeof(ps[0])) {
|
||||
fprintf(stderr, "%s: stk500_set_fosc(): f = %u Hz too low, %u Hz min\n",
|
||||
progname, fosc, fbase / (256 * 1024 * 2));
|
||||
progname, fosc, STK500_XTAL / (256 * 1024 * 2));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -938,6 +938,38 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
|
|||
}
|
||||
|
||||
|
||||
/* This code assumes that each count of the SCK duration parameter
|
||||
represents 8/f, where f is the clock frequency of the STK500 master
|
||||
processors (not the target). This number comes from Atmel
|
||||
application note AVR061. It appears that the STK500 bit bangs SCK.
|
||||
For small duration values, the actual SCK width is larger than
|
||||
expected. As the duration value increases, the SCK width error
|
||||
diminishes. */
|
||||
static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
int dur;
|
||||
double min, max;
|
||||
|
||||
min = 8.0 / STK500_XTAL;
|
||||
max = 255 * min;
|
||||
dur = v / min + 0.5;
|
||||
|
||||
if (v < min) {
|
||||
dur = 1;
|
||||
fprintf(stderr,
|
||||
"%s: stk500_set_sck_period(): p = %.1f us too small, using %.1f us\n",
|
||||
progname, v / 1e-6, dur * min / 1e-6);
|
||||
} else if (v > max) {
|
||||
dur = 255;
|
||||
fprintf(stderr,
|
||||
"%s: stk500_set_sck_period(): p = %.1f us too large, using %.1f us\n",
|
||||
progname, v / 1e-6, dur * min / 1e-6);
|
||||
}
|
||||
|
||||
return stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur);
|
||||
}
|
||||
|
||||
|
||||
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
|
@ -1081,12 +1113,13 @@ static void stk500_display(PROGRAMMER * pgm, char * p)
|
|||
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
unsigned vtarget, vadjust, osc_pscale, osc_cmatch;
|
||||
unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
|
||||
|
||||
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
|
||||
stk500_getparm(pgm, Parm_STK_VADJUST, &vadjust);
|
||||
stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
|
||||
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
|
||||
stk500_getparm(pgm, Parm_STK_SCK_DURATION, &sck_duration);
|
||||
|
||||
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
|
||||
fprintf(stderr, "%sVaref : %.1f V\n", p, vadjust / 10.0);
|
||||
|
@ -1095,7 +1128,7 @@ static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
|
|||
fprintf(stderr, "Off\n");
|
||||
else {
|
||||
int prescale = 1;
|
||||
double f = 3.6864e6;
|
||||
double f = STK500_XTAL / 2;
|
||||
const char *unit;
|
||||
|
||||
switch (osc_pscale) {
|
||||
|
@ -1118,6 +1151,8 @@ static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
|
|||
unit = "Hz";
|
||||
fprintf(stderr, "%.3f %s\n", f, unit);
|
||||
}
|
||||
fprintf(stderr, "%sSCK period : %.1f us\n", p,
|
||||
sck_duration * 8.0e6 / STK500_XTAL + 0.05);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1155,5 +1190,6 @@ void stk500_initpgm(PROGRAMMER * pgm)
|
|||
pgm->set_vtarget = stk500_set_vtarget;
|
||||
pgm->set_varef = stk500_set_varef;
|
||||
pgm->set_fosc = stk500_set_fosc;
|
||||
pgm->set_sck_period = stk500_set_sck_period;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
|
35
term.c
35
term.c
|
@ -78,6 +78,8 @@ int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
|||
|
||||
int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
int cmd_sck (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
|
||||
|
||||
struct command cmd[] = {
|
||||
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
|
||||
|
@ -91,6 +93,7 @@ struct command cmd[] = {
|
|||
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
|
||||
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
|
||||
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
|
||||
{ "sck", cmd_sck, "set <SCK period> (STK500 only)" },
|
||||
{ "help", cmd_help, "help" },
|
||||
{ "?", cmd_help, "help" },
|
||||
{ "quit", cmd_quit, "quit" }
|
||||
|
@ -597,6 +600,38 @@ int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
|||
}
|
||||
|
||||
|
||||
int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: sck <value>\n");
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (sck): can't parse period \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
v *= 1e-6; /* Convert from microseconds to seconds. */
|
||||
if (pgm->set_sck_period == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s (sck): the %s programmer cannot set SCK period\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_sck_period(pgm, v)) != 0) {
|
||||
fprintf(stderr, "%s (sck): failed to set SCK period (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
|
|
Loading…
Reference in New Issue