* stk500v2.c (stk500v2_set_sck_period): Revamp this to match the

description/pseudo-code in appnote AVR068.



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1229 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Joerg Wunsch 2013-09-13 21:32:00 +00:00
parent dc1bacb7cb
commit 5dbde0ca20
3 changed files with 54 additions and 24 deletions

View File

@ -1,3 +1,8 @@
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* stk500v2.c (stk500v2_set_sck_period): Revamp this to match the
description/pseudo-code in appnote AVR068.
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de> 2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by Stephen Roe: Submitted by Stephen Roe:

1
NEWS
View File

@ -112,6 +112,7 @@ Current:
- patch #7657: Add ATmega406 support for avrdude using DRAGON + JTAG - patch #7657: Add ATmega406 support for avrdude using DRAGON + JTAG
- bug #35474: Feature request: print fuse values in safemode output. - bug #35474: Feature request: print fuse values in safemode output.
- patch #7710: usb_libusb: Check VID/PID before opening device - patch #7710: usb_libusb: Check VID/PID before opening device
- [no-id]: Fix SCK period adjustment for STK500v2
* Keep track of input file contents * Keep track of input file contents

View File

@ -281,6 +281,7 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize); static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize);
static double stk500v2_sck_to_us(PROGRAMMER * pgm, unsigned char dur);
static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v); static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v);
static int stk600_set_sck_period(PROGRAMMER * pgm, double v); static int stk600_set_sck_period(PROGRAMMER * pgm, double v);
@ -2860,37 +2861,60 @@ static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize)
exit(1); exit(1);
} }
/* This code assumes that each count of the SCK duration parameter /*
represents 8/f, where f is the clock frequency of the STK500V2 master * See pseudo-code in AVR068
processors (not the target). This number comes from Atmel *
application note AVR061. It appears that the STK500V2 bit bangs SCK. * This algorithm only fits for the STK500 itself. For the (old)
For small duration values, the actual SCK width is larger than * AVRISP, the resulting ISP clock is only half. While this would be
expected. As the duration value increases, the SCK width error * easy to fix in the algorithm, we'd need to add another
diminishes. */ * configuration flag for this to the config file. Given the old
* AVRISP devices are virtually no longer around (and the AVRISPmkII
* uses a different algorithm below), it's probably not worth the
* hassle.
*/
static int stk500v2_set_sck_period(PROGRAMMER * pgm, double v) static int stk500v2_set_sck_period(PROGRAMMER * pgm, double v)
{ {
unsigned int d;
unsigned char dur; unsigned char dur;
double min, max; double f = 1 / v;
min = 8.0 / STK500V2_XTAL; if (f >= 1.8432E6)
max = 255 * min; d = 0;
dur = v / min + 0.5; else if (f > 460.8E3)
d = 1;
if (v < min) { else if (f > 115.2E3)
dur = 1; d = 2;
fprintf(stderr, else if (f > 57.6E3)
"%s: stk500v2_set_sck_period(): p = %.1f us too small, using %.1f us\n", d = 3;
progname, v / 1e-6, dur * min / 1e-6); else
} else if (v > max) { d = (unsigned int)ceil(1 / (24 * f / (double)STK500V2_XTAL) - 10.0 / 12.0);
dur = 255; if (d >= 255)
fprintf(stderr, d = 254;
"%s: stk500v2_set_sck_period(): p = %.1f us too large, using %.1f us\n", dur = d;
progname, v / 1e-6, dur * min / 1e-6);
}
return stk500v2_setparm(pgm, PARAM_SCK_DURATION, dur); return stk500v2_setparm(pgm, PARAM_SCK_DURATION, dur);
} }
static double stk500v2_sck_to_us(PROGRAMMER * pgm, unsigned char dur)
{
double x;
if (dur == 0)
return 0.5425;
if (dur == 1)
return 2.17;
if (dur == 2)
return 8.68;
if (dur == 3)
return 17.36;
x = (double)dur + 10.0 / 12.0;
x = 1.0 / x;
x /= 24.0;
x *= (double)STK500V2_XTAL;
return 1E6 / x;
}
static int stk600_set_vtarget(PROGRAMMER * pgm, double v) static int stk600_set_vtarget(PROGRAMMER * pgm, double v)
{ {
@ -3255,7 +3279,7 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale); stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch); stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
fprintf(stderr, "%sSCK period : %.1f us\n", p, fprintf(stderr, "%sSCK period : %.1f us\n", p,
sck_duration * 8.0e6 / STK500V2_XTAL + 0.05); stk500v2_sck_to_us(pgm, sck_duration));
fprintf(stderr, "%sVaref : %.1f V\n", p, vadjust / 10.0); fprintf(stderr, "%sVaref : %.1f V\n", p, vadjust / 10.0);
fprintf(stderr, "%sOscillator : ", p); fprintf(stderr, "%sOscillator : ", p);
if (osc_pscale == 0) if (osc_pscale == 0)