* 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:
parent
dc1bacb7cb
commit
5dbde0ca20
|
@ -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
1
NEWS
|
@ -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
|
||||||
|
|
||||||
|
|
72
stk500v2.c
72
stk500v2.c
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue