Merge pull request #859 from dl8dtl/safemode-removal
Remove the "safemode" feature.
This commit is contained in:
commit
b6a6c681df
5
NEWS
5
NEWS
|
@ -13,6 +13,11 @@ Changes since version 6.4:
|
||||||
- Started to add CMake (by now, parallel with autoconf/automake)
|
- Started to add CMake (by now, parallel with autoconf/automake)
|
||||||
- New-architecture devices (AVR8X mega and tiny) can access all
|
- New-architecture devices (AVR8X mega and tiny) can access all
|
||||||
fuses, and memory display shows meaningful alias names
|
fuses, and memory display shows meaningful alias names
|
||||||
|
- The "safemode" feature has been removed. The major class of
|
||||||
|
programmers it has been designed for (lowlevel bitbang
|
||||||
|
programmers on parallel or serial ports) virtually doesn't exist
|
||||||
|
anymore, and the fuse combination that was covered by it do not
|
||||||
|
match the fuses of modern AVR devices anyway.
|
||||||
|
|
||||||
* New devices supported:
|
* New devices supported:
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,6 @@ add_library(libavrdude
|
||||||
ppi.c
|
ppi.c
|
||||||
ppi.h
|
ppi.h
|
||||||
ppiwin.c
|
ppiwin.c
|
||||||
safemode.c
|
|
||||||
serbb.h
|
serbb.h
|
||||||
serbb_posix.c
|
serbb_posix.c
|
||||||
serbb_win32.c
|
serbb_win32.c
|
||||||
|
|
|
@ -148,7 +148,6 @@ libavrdude_a_SOURCES = \
|
||||||
ppi.c \
|
ppi.c \
|
||||||
ppi.h \
|
ppi.h \
|
||||||
ppiwin.c \
|
ppiwin.c \
|
||||||
safemode.c \
|
|
||||||
serbb.h \
|
serbb.h \
|
||||||
serbb_posix.c \
|
serbb_posix.c \
|
||||||
serbb_win32.c \
|
serbb_win32.c \
|
||||||
|
|
24
src/avr.c
24
src/avr.c
|
@ -791,30 +791,6 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
unsigned long addr, unsigned char data)
|
unsigned long addr, unsigned char data)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned char safemode_lfuse;
|
|
||||||
unsigned char safemode_hfuse;
|
|
||||||
unsigned char safemode_efuse;
|
|
||||||
unsigned char safemode_fuse;
|
|
||||||
|
|
||||||
/* If we write the fuses, then we need to tell safemode that they *should* change */
|
|
||||||
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
|
||||||
|
|
||||||
if (strcmp(mem->desc, "fuse")==0) {
|
|
||||||
safemode_fuse = data;
|
|
||||||
}
|
|
||||||
if (strcmp(mem->desc, "lfuse")==0) {
|
|
||||||
safemode_lfuse = data;
|
|
||||||
}
|
|
||||||
if (strcmp(mem->desc, "hfuse")==0) {
|
|
||||||
safemode_hfuse = data;
|
|
||||||
}
|
|
||||||
if (strcmp(mem->desc, "efuse")==0) {
|
|
||||||
safemode_efuse = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
|
||||||
|
|
||||||
return pgm->write_byte(pgm, p, mem, addr, data);
|
return pgm->write_byte(pgm, p, mem, addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -607,40 +607,11 @@ Posix systems (by now).
|
||||||
.It Fl q
|
.It Fl q
|
||||||
Disable (or quell) output of the progress bar while reading or writing
|
Disable (or quell) output of the progress bar while reading or writing
|
||||||
to the device. Specify it a second time for even quieter operation.
|
to the device. Specify it a second time for even quieter operation.
|
||||||
.It Fl s
|
|
||||||
Disable safemode prompting. When safemode discovers that one or more
|
|
||||||
fuse bits have unintentionally changed, it will prompt for
|
|
||||||
confirmation regarding whether or not it should attempt to recover the
|
|
||||||
fuse bit(s). Specifying this flag disables the prompt and assumes
|
|
||||||
that the fuse bit(s) should be recovered without asking for
|
|
||||||
confirmation first.
|
|
||||||
.It Fl t
|
.It Fl t
|
||||||
Tells
|
Tells
|
||||||
.Nm
|
.Nm
|
||||||
to enter the interactive ``terminal'' mode instead of up- or downloading
|
to enter the interactive ``terminal'' mode instead of up- or downloading
|
||||||
files. See below for a detailed description of the terminal mode.
|
files. See below for a detailed description of the terminal mode.
|
||||||
.It Fl u
|
|
||||||
Disable the safemode fuse bit checks. Safemode is enabled by default
|
|
||||||
and is intended to prevent unintentional fuse bit changes. When
|
|
||||||
enabled, safemode will issue a warning if the any fuse bits are found
|
|
||||||
to be different at program exit than they were when
|
|
||||||
.Nm
|
|
||||||
was invoked. Safemode won't alter fuse bits itself, but rather will
|
|
||||||
prompt for instructions, unless the terminal is non-interactive, in
|
|
||||||
which case safemode is disabled. See the
|
|
||||||
.Fl s
|
|
||||||
option to disable safemode prompting.
|
|
||||||
.Pp
|
|
||||||
If one of the configuration files has a line
|
|
||||||
.Dl "default_safemode = no;"
|
|
||||||
safemode is disabled by default.
|
|
||||||
The
|
|
||||||
.Fl u
|
|
||||||
option's effect is negated in that case, i. e. it
|
|
||||||
.Em enables
|
|
||||||
safemode.
|
|
||||||
.Pp
|
|
||||||
Safemode is always disabled for AVR32, Xmega and TPI devices.
|
|
||||||
.It Xo Fl U Ar memtype Ns
|
.It Xo Fl U Ar memtype Ns
|
||||||
.Ar \&: Ns Ar op Ns
|
.Ar \&: Ns Ar op Ns
|
||||||
.Ar \&: Ns Ar filename Ns
|
.Ar \&: Ns Ar filename Ns
|
||||||
|
|
|
@ -339,10 +339,6 @@ default_parallel = "@DEFAULT_PAR_PORT@";
|
||||||
default_serial = "@DEFAULT_SER_PORT@";
|
default_serial = "@DEFAULT_SER_PORT@";
|
||||||
# default_bitclock = 2.5;
|
# default_bitclock = 2.5;
|
||||||
|
|
||||||
# Turn off safemode by default
|
|
||||||
#default_safemode = no;
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# PROGRAMMER DEFINITIONS
|
# PROGRAMMER DEFINITIONS
|
||||||
#
|
#
|
||||||
|
|
|
@ -36,7 +36,6 @@ char default_programmer[MAX_STR_CONST];
|
||||||
char default_parallel[PATH_MAX];
|
char default_parallel[PATH_MAX];
|
||||||
char default_serial[PATH_MAX];
|
char default_serial[PATH_MAX];
|
||||||
double default_bitclock;
|
double default_bitclock;
|
||||||
int default_safemode;
|
|
||||||
|
|
||||||
char string_buf[MAX_STR_CONST];
|
char string_buf[MAX_STR_CONST];
|
||||||
char *string_buf_ptr;
|
char *string_buf_ptr;
|
||||||
|
|
|
@ -77,7 +77,6 @@ static int pin_name;
|
||||||
%token K_DEFAULT_BITCLOCK
|
%token K_DEFAULT_BITCLOCK
|
||||||
%token K_DEFAULT_PARALLEL
|
%token K_DEFAULT_PARALLEL
|
||||||
%token K_DEFAULT_PROGRAMMER
|
%token K_DEFAULT_PROGRAMMER
|
||||||
%token K_DEFAULT_SAFEMODE
|
|
||||||
%token K_DEFAULT_SERIAL
|
%token K_DEFAULT_SERIAL
|
||||||
%token K_DESC
|
%token K_DESC
|
||||||
%token K_FAMILY_ID
|
%token K_FAMILY_ID
|
||||||
|
@ -257,14 +256,6 @@ def :
|
||||||
K_DEFAULT_BITCLOCK TKN_EQUAL number_real TKN_SEMI {
|
K_DEFAULT_BITCLOCK TKN_EQUAL number_real TKN_SEMI {
|
||||||
default_bitclock = $3->value.number_real;
|
default_bitclock = $3->value.number_real;
|
||||||
free_token($3);
|
free_token($3);
|
||||||
} |
|
|
||||||
|
|
||||||
K_DEFAULT_SAFEMODE TKN_EQUAL yesno TKN_SEMI {
|
|
||||||
if ($3->primary == K_YES)
|
|
||||||
default_safemode = 1;
|
|
||||||
else if ($3->primary == K_NO)
|
|
||||||
default_safemode = 0;
|
|
||||||
free_token($3);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -681,32 +681,6 @@ Posix systems (by now).
|
||||||
Disable (or quell) output of the progress bar while reading or writing
|
Disable (or quell) output of the progress bar while reading or writing
|
||||||
to the device. Specify it a second time for even quieter operation.
|
to the device. Specify it a second time for even quieter operation.
|
||||||
|
|
||||||
@item -u
|
|
||||||
Disables the default behaviour of reading out the fuses three times before
|
|
||||||
programming, then verifying at the end of programming that the fuses have not
|
|
||||||
changed. If you want to change fuses you will need to specify this option,
|
|
||||||
as avrdude will see the fuses have changed (even though you wanted to) and
|
|
||||||
will change them back for your "safety". This option was designed to
|
|
||||||
prevent cases of fuse bits magically changing (usually called @emph{safemode}).
|
|
||||||
|
|
||||||
If one of the configuration files contains a line
|
|
||||||
|
|
||||||
@code{default_safemode = no;}
|
|
||||||
|
|
||||||
safemode is disabled by default.
|
|
||||||
The @option{-u} option's effect is negated in that case, i. e. it
|
|
||||||
@emph{enables} safemode.
|
|
||||||
|
|
||||||
Safemode is always disabled for AVR32, Xmega and TPI devices.
|
|
||||||
|
|
||||||
@item -s
|
|
||||||
Disable safemode prompting. When safemode discovers that one or more
|
|
||||||
fuse bits have unintentionally changed, it will prompt for
|
|
||||||
confirmation regarding whether or not it should attempt to recover the
|
|
||||||
fuse bit(s). Specifying this flag disables the prompt and assumes
|
|
||||||
that the fuse bit(s) should be recovered without asking for
|
|
||||||
confirmation first.
|
|
||||||
|
|
||||||
@item -t
|
@item -t
|
||||||
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
|
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
|
||||||
or downloading files. See below for a detailed description of the
|
or downloading files. See below for a detailed description of the
|
||||||
|
@ -1133,8 +1107,6 @@ Reading | ################################################## | 100% 6.83s
|
||||||
avrdude: verifying ...
|
avrdude: verifying ...
|
||||||
avrdude: 19278 bytes of flash verified
|
avrdude: 19278 bytes of flash verified
|
||||||
|
|
||||||
avrdude: safemode: Fuses OK
|
|
||||||
|
|
||||||
avrdude done. Thank you.
|
avrdude done. Thank you.
|
||||||
|
|
||||||
%
|
%
|
||||||
|
@ -1162,8 +1134,6 @@ Reading | ################################################## | 100% 46.10s
|
||||||
|
|
||||||
avrdude: writing output file "c:/diag flash.bin"
|
avrdude: writing output file "c:/diag flash.bin"
|
||||||
|
|
||||||
avrdude: safemode: Fuses OK
|
|
||||||
|
|
||||||
avrdude done. Thank you.
|
avrdude done. Thank you.
|
||||||
|
|
||||||
%
|
%
|
||||||
|
@ -1845,9 +1815,6 @@ flash pages of the application section.
|
||||||
|
|
||||||
Reading fuse and lock bits is fully supported.
|
Reading fuse and lock bits is fully supported.
|
||||||
|
|
||||||
Note that due to the inability to write the fuse bits, the safemode
|
|
||||||
functionality does not make sense for these boot loaders.
|
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@c
|
@c
|
||||||
|
@ -2021,9 +1988,6 @@ fuse, extended fuse) have no meaning whatsoever, as they have been
|
||||||
simply replaced by array of fuses: fuse0..9. Therefore you can simply
|
simply replaced by array of fuses: fuse0..9. Therefore you can simply
|
||||||
ignore this particular line of AVRDUDE output.
|
ignore this particular line of AVRDUDE output.
|
||||||
|
|
||||||
In connection to the above, @emph{safemode} has no meaning in context
|
|
||||||
of UPDI devices and should be ignored.
|
|
||||||
|
|
||||||
Currently available devices support only UPDI NVM programming model 0
|
Currently available devices support only UPDI NVM programming model 0
|
||||||
and 2, but there is also experimental implementation of model 3 - not
|
and 2, but there is also experimental implementation of model 3 - not
|
||||||
yet tested.
|
yet tested.
|
||||||
|
|
|
@ -137,7 +137,6 @@ dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
|
||||||
default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; }
|
default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; }
|
||||||
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
||||||
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
||||||
default_safemode { yylval=NULL; return K_DEFAULT_SAFEMODE; }
|
|
||||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||||
delay { yylval=NULL; return K_DELAY; }
|
delay { yylval=NULL; return K_DELAY; }
|
||||||
desc { yylval=NULL; return K_DESC; }
|
desc { yylval=NULL; return K_DESC; }
|
||||||
|
|
|
@ -831,30 +831,6 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* formerly safemode.h */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or "efuse") and verifies it. Will try up to tries
|
|
||||||
amount of times before giving up */
|
|
||||||
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm, AVRPART * p, int tries);
|
|
||||||
|
|
||||||
/* Reads the fuses three times, checking that all readings are the same. This will ensure that the before values aren't in error! */
|
|
||||||
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse, PROGRAMMER * pgm, AVRPART * p);
|
|
||||||
|
|
||||||
/* This routine will store the current values pointed to by lfuse, hfuse, and efuse into an internal buffer in this routine
|
|
||||||
when save is set to 1. When save is 0 (or not 1 really) it will copy the values from the internal buffer into the locations
|
|
||||||
pointed to be lfuse, hfuse, and efuse. This allows you to change the fuse bits if needed from another routine (ie: have it so
|
|
||||||
if user requests fuse bits are changed, the requested value is now verified */
|
|
||||||
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* formerly update.h */
|
/* formerly update.h */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -926,7 +902,6 @@ extern char default_programmer[];
|
||||||
extern char default_parallel[];
|
extern char default_parallel[];
|
||||||
extern char default_serial[];
|
extern char default_serial[];
|
||||||
extern double default_bitclock;
|
extern double default_bitclock;
|
||||||
extern int default_safemode;
|
|
||||||
|
|
||||||
/* This name is fixed, it's only here for symmetry with
|
/* This name is fixed, it's only here for symmetry with
|
||||||
* default_parallel and default_serial. */
|
* default_parallel and default_serial. */
|
||||||
|
|
239
src/main.c
239
src/main.c
|
@ -122,9 +122,6 @@ static void usage(void)
|
||||||
" is performed in the order specified.\n"
|
" is performed in the order specified.\n"
|
||||||
" -n Do not write anything to the device.\n"
|
" -n Do not write anything to the device.\n"
|
||||||
" -V Do not verify.\n"
|
" -V Do not verify.\n"
|
||||||
" -u Disable safemode, default when running from a script.\n"
|
|
||||||
" -s Silent safemode operation, will not ask you if\n"
|
|
||||||
" fuses should be changed back.\n"
|
|
||||||
" -t Enter terminal mode.\n"
|
" -t Enter terminal mode.\n"
|
||||||
" -E <exitspec>[,<exitspec>] List programmer exit specifications.\n"
|
" -E <exitspec>[,<exitspec>] List programmer exit specifications.\n"
|
||||||
" -x <extended_param> Pass <extended_param> to programmer.\n"
|
" -x <extended_param> Pass <extended_param> to programmer.\n"
|
||||||
|
@ -349,19 +346,11 @@ int main(int argc, char * argv [])
|
||||||
int baudrate; /* override default programmer baud rate */
|
int baudrate; /* override default programmer baud rate */
|
||||||
double bitclock; /* Specify programmer bit clock (JTAG ICE) */
|
double bitclock; /* Specify programmer bit clock (JTAG ICE) */
|
||||||
int ispdelay; /* Specify the delay for ISP clock */
|
int ispdelay; /* Specify the delay for ISP clock */
|
||||||
int safemode; /* Enable safemode, 1=safemode on, 0=normal */
|
|
||||||
int silentsafe; /* Don't ask about fuses, 1=silent, 0=normal */
|
|
||||||
int init_ok; /* Device initialization worked well */
|
int init_ok; /* Device initialization worked well */
|
||||||
int is_open; /* Device open succeeded */
|
int is_open; /* Device open succeeded */
|
||||||
char * logfile; /* Use logfile rather than stderr for diagnostics */
|
char * logfile; /* Use logfile rather than stderr for diagnostics */
|
||||||
enum updateflags uflags = UF_AUTO_ERASE; /* Flags for do_op() */
|
enum updateflags uflags = UF_AUTO_ERASE; /* Flags for do_op() */
|
||||||
unsigned char safemode_lfuse = 0xff;
|
|
||||||
unsigned char safemode_hfuse = 0xff;
|
|
||||||
unsigned char safemode_efuse = 0xff;
|
|
||||||
unsigned char safemode_fuse = 0xff;
|
|
||||||
|
|
||||||
char * safemode_response;
|
|
||||||
int fuses_updated = 0;
|
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
char * homedir;
|
char * homedir;
|
||||||
#endif
|
#endif
|
||||||
|
@ -394,7 +383,6 @@ int main(int argc, char * argv [])
|
||||||
default_parallel[0] = 0;
|
default_parallel[0] = 0;
|
||||||
default_serial[0] = 0;
|
default_serial[0] = 0;
|
||||||
default_bitclock = 0.0;
|
default_bitclock = 0.0;
|
||||||
default_safemode = -1;
|
|
||||||
|
|
||||||
init_config();
|
init_config();
|
||||||
|
|
||||||
|
@ -434,8 +422,6 @@ int main(int argc, char * argv [])
|
||||||
baudrate = 0;
|
baudrate = 0;
|
||||||
bitclock = 0.0;
|
bitclock = 0.0;
|
||||||
ispdelay = 0;
|
ispdelay = 0;
|
||||||
safemode = 1; /* Safemode on by default */
|
|
||||||
silentsafe = 0; /* Ask by default */
|
|
||||||
is_open = 0;
|
is_open = 0;
|
||||||
logfile = NULL;
|
logfile = NULL;
|
||||||
|
|
||||||
|
@ -581,19 +567,10 @@ int main(int argc, char * argv [])
|
||||||
quell_progress++ ;
|
quell_progress++ ;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's' : /* Silent safemode */
|
|
||||||
silentsafe = 1;
|
|
||||||
safemode = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 't': /* enter terminal mode */
|
case 't': /* enter terminal mode */
|
||||||
terminal = 1;
|
terminal = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u' : /* Disable safemode */
|
|
||||||
safemode = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'U':
|
case 'U':
|
||||||
upd = parse_op(optarg);
|
upd = parse_op(optarg);
|
||||||
if (upd == NULL) {
|
if (upd == NULL) {
|
||||||
|
@ -975,29 +952,6 @@ int main(int argc, char * argv [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (default_safemode == 0) {
|
|
||||||
/* configuration disables safemode: revert meaning of -u */
|
|
||||||
if (safemode == 0)
|
|
||||||
/* -u was given: enable safemode */
|
|
||||||
safemode = 1;
|
|
||||||
else
|
|
||||||
/* -u not given: turn off */
|
|
||||||
safemode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isatty(STDIN_FILENO) == 0 && silentsafe == 0)
|
|
||||||
safemode = 0; /* Turn off safemode if this isn't a terminal */
|
|
||||||
|
|
||||||
|
|
||||||
if(p->flags & AVRPART_AVR32) {
|
|
||||||
safemode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) {
|
|
||||||
safemode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (avr_initmem(p) != 0)
|
if (avr_initmem(p) != 0)
|
||||||
{
|
{
|
||||||
avrdude_message(MSG_INFO, "\n%s: failed to initialize memories\n",
|
avrdude_message(MSG_INFO, "\n%s: failed to initialize memories\n",
|
||||||
|
@ -1281,36 +1235,6 @@ int main(int argc, char * argv [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init_ok && safemode == 1) {
|
|
||||||
/* If safemode is enabled, go ahead and read the current low, high,
|
|
||||||
and extended fuse bytes as needed */
|
|
||||||
|
|
||||||
rc = safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
|
|
||||||
&safemode_efuse, &safemode_fuse, pgm, p);
|
|
||||||
|
|
||||||
if (rc != 0) {
|
|
||||||
|
|
||||||
//Check if the programmer just doesn't support reading
|
|
||||||
if (rc == -5)
|
|
||||||
{
|
|
||||||
avrdude_message(MSG_NOTICE, "%s: safemode: Fuse reading not supported by programmer.\n"
|
|
||||||
" Safemode disabled.\n", progname);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: To protect your AVR the programming "
|
|
||||||
"will be aborted\n",
|
|
||||||
progname);
|
|
||||||
exitrc = 1;
|
|
||||||
goto main_exit;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//Save the fuses as default
|
|
||||||
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uflags & UF_AUTO_ERASE) {
|
if (uflags & UF_AUTO_ERASE) {
|
||||||
if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL &&
|
if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL &&
|
||||||
lsize(updates) > 0) {
|
lsize(updates) > 0) {
|
||||||
|
@ -1386,169 +1310,6 @@ int main(int argc, char * argv [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Right before we exit programming mode, which will make the fuse
|
|
||||||
bits active, check to make sure they are still correct */
|
|
||||||
if (safemode == 1) {
|
|
||||||
/* If safemode is enabled, go ahead and read the current low,
|
|
||||||
* high, and extended fuse bytes as needed */
|
|
||||||
unsigned char safemodeafter_lfuse = 0xff;
|
|
||||||
unsigned char safemodeafter_hfuse = 0xff;
|
|
||||||
unsigned char safemodeafter_efuse = 0xff;
|
|
||||||
unsigned char safemodeafter_fuse = 0xff;
|
|
||||||
unsigned char failures = 0;
|
|
||||||
char yes[1] = {'y'};
|
|
||||||
|
|
||||||
if (quell_progress < 2) {
|
|
||||||
avrdude_message(MSG_INFO, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Restore the default fuse values
|
|
||||||
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
|
||||||
|
|
||||||
/* Try reading back fuses, make sure they are reliable to read back */
|
|
||||||
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
|
|
||||||
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
|
|
||||||
/* Uh-oh.. try once more to read back fuses */
|
|
||||||
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
|
|
||||||
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: Sorry, reading back fuses was unreliable. "
|
|
||||||
"I have given up and exited programming mode\n",
|
|
||||||
progname);
|
|
||||||
exitrc = 1;
|
|
||||||
goto main_exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AVRMEM * m;
|
|
||||||
|
|
||||||
/* Now check what fuses are against what they should be */
|
|
||||||
m = avr_locate_mem(p, "fuse");
|
|
||||||
if (compare_memory_masked(m, safemodeafter_fuse, safemode_fuse)) {
|
|
||||||
fuses_updated = 1;
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
|
|
||||||
progname, safemode_fuse, safemodeafter_fuse);
|
|
||||||
|
|
||||||
|
|
||||||
/* Ask user - should we change them */
|
|
||||||
|
|
||||||
if (silentsafe == 0)
|
|
||||||
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
|
|
||||||
else
|
|
||||||
safemode_response = yes;
|
|
||||||
|
|
||||||
if (tolower((int)(safemode_response[0])) == 'y') {
|
|
||||||
|
|
||||||
/* Enough chit-chat, time to program some fuses and check them */
|
|
||||||
if (safemode_writefuse (safemode_fuse, "fuse", pgm, p,
|
|
||||||
10) == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
|
|
||||||
failures++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now check what fuses are against what they should be */
|
|
||||||
m = avr_locate_mem(p, "lfuse");
|
|
||||||
if (compare_memory_masked(m, safemodeafter_lfuse, safemode_lfuse)) {
|
|
||||||
fuses_updated = 1;
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
|
|
||||||
progname, safemode_lfuse, safemodeafter_lfuse);
|
|
||||||
|
|
||||||
|
|
||||||
/* Ask user - should we change them */
|
|
||||||
|
|
||||||
if (silentsafe == 0)
|
|
||||||
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
|
|
||||||
else
|
|
||||||
safemode_response = yes;
|
|
||||||
|
|
||||||
if (tolower((int)(safemode_response[0])) == 'y') {
|
|
||||||
|
|
||||||
/* Enough chit-chat, time to program some fuses and check them */
|
|
||||||
if (safemode_writefuse (safemode_lfuse, "lfuse", pgm, p,
|
|
||||||
10) == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
|
|
||||||
failures++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now check what fuses are against what they should be */
|
|
||||||
m = avr_locate_mem(p, "hfuse");
|
|
||||||
if (compare_memory_masked(m, safemodeafter_hfuse, safemode_hfuse)) {
|
|
||||||
fuses_updated = 1;
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
|
|
||||||
progname, safemode_hfuse, safemodeafter_hfuse);
|
|
||||||
|
|
||||||
/* Ask user - should we change them */
|
|
||||||
if (silentsafe == 0)
|
|
||||||
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
|
|
||||||
else
|
|
||||||
safemode_response = yes;
|
|
||||||
if (tolower((int)(safemode_response[0])) == 'y') {
|
|
||||||
|
|
||||||
/* Enough chit-chat, time to program some fuses and check them */
|
|
||||||
if (safemode_writefuse(safemode_hfuse, "hfuse", pgm, p,
|
|
||||||
10) == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
|
|
||||||
failures++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now check what fuses are against what they should be */
|
|
||||||
m = avr_locate_mem(p, "efuse");
|
|
||||||
if (compare_memory_masked(m, safemodeafter_efuse, safemode_efuse)) {
|
|
||||||
fuses_updated = 1;
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
|
|
||||||
progname, safemode_efuse, safemodeafter_efuse);
|
|
||||||
|
|
||||||
/* Ask user - should we change them */
|
|
||||||
if (silentsafe == 0)
|
|
||||||
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
|
|
||||||
else
|
|
||||||
safemode_response = yes;
|
|
||||||
if (tolower((int)(safemode_response[0])) == 'y') {
|
|
||||||
|
|
||||||
/* Enough chit-chat, time to program some fuses and check them */
|
|
||||||
if (safemode_writefuse (safemode_efuse, "efuse", pgm, p,
|
|
||||||
10) == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
|
|
||||||
failures++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quell_progress < 2) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: ", progname);
|
|
||||||
if (failures == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "Fuses OK (E:%02X, H:%02X, L:%02X)\n",
|
|
||||||
safemodeafter_efuse, safemodeafter_hfuse, safemodeafter_lfuse);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fuses_updated) {
|
|
||||||
exitrc = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main_exit:
|
main_exit:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
318
src/safemode.c
318
src/safemode.c
|
@ -1,318 +0,0 @@
|
||||||
/*
|
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
|
||||||
* avrdude is Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
|
||||||
*
|
|
||||||
* This file: Copyright (C) 2005-2007 Colin O'Flynn <coflynn@newae.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "ac_cfg.h"
|
|
||||||
|
|
||||||
#include "avrdude.h"
|
|
||||||
#include "libavrdude.h"
|
|
||||||
|
|
||||||
/* This value from ac_cfg.h */
|
|
||||||
/*
|
|
||||||
* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or
|
|
||||||
* "efuse") and verifies it. Will try up to tries amount of times
|
|
||||||
* before giving up
|
|
||||||
*/
|
|
||||||
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm,
|
|
||||||
AVRPART * p, int tries)
|
|
||||||
{
|
|
||||||
AVRMEM * m;
|
|
||||||
unsigned char fuseread;
|
|
||||||
int returnvalue = -1;
|
|
||||||
|
|
||||||
m = avr_locate_mem(p, fusename);
|
|
||||||
if (m == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Keep trying to write then read back the fuse values */
|
|
||||||
while (tries > 0) {
|
|
||||||
if (avr_write_byte(pgm, p, m, 0, fuse) != 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &fuseread) != 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Report information to user if needed */
|
|
||||||
avrdude_message(MSG_NOTICE, "%s: safemode: Wrote %s to %x, read as %x. %d attempts left\n",
|
|
||||||
progname, fusename, fuse, fuseread, tries-1);
|
|
||||||
|
|
||||||
/* If fuse wrote OK, no need to keep going */
|
|
||||||
if (fuse == fuseread) {
|
|
||||||
tries = 0;
|
|
||||||
returnvalue = 0;
|
|
||||||
}
|
|
||||||
tries--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnvalue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reads the fuses three times, checking that all readings are the
|
|
||||||
* same. This will ensure that the before values aren't in error!
|
|
||||||
*/
|
|
||||||
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
|
|
||||||
unsigned char * efuse, unsigned char * fuse,
|
|
||||||
PROGRAMMER * pgm, AVRPART * p)
|
|
||||||
{
|
|
||||||
|
|
||||||
unsigned char value;
|
|
||||||
unsigned char fusegood = 0;
|
|
||||||
unsigned char allowfuseread = 1;
|
|
||||||
unsigned char safemode_lfuse;
|
|
||||||
unsigned char safemode_hfuse;
|
|
||||||
unsigned char safemode_efuse;
|
|
||||||
unsigned char safemode_fuse;
|
|
||||||
AVRMEM * m;
|
|
||||||
|
|
||||||
safemode_lfuse = *lfuse;
|
|
||||||
safemode_hfuse = *hfuse;
|
|
||||||
safemode_efuse = *efuse;
|
|
||||||
safemode_fuse = *fuse;
|
|
||||||
|
|
||||||
|
|
||||||
/* Read fuse three times */
|
|
||||||
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
|
|
||||||
to generate a verify error */
|
|
||||||
m = avr_locate_mem(p, "fuse");
|
|
||||||
if (m != NULL) {
|
|
||||||
fusegood = 0; /* By default fuse is a failure */
|
|
||||||
if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 1, fuse value: %x\n",progname, safemode_fuse);
|
|
||||||
if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 2, fuse value: %x\n",progname, value);
|
|
||||||
if (value == safemode_fuse) {
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 3, fuse value: %x\n",progname, value);
|
|
||||||
if (value == safemode_fuse)
|
|
||||||
{
|
|
||||||
fusegood = 1; /* Fuse read OK three times */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Programmer does not allow fuse reading.... no point trying anymore
|
|
||||||
if (allowfuseread == 0)
|
|
||||||
{
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fusegood == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read fuse properly. "
|
|
||||||
"Programmer may not be reliable.\n", progname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (fusegood == 1) {
|
|
||||||
avrdude_message(MSG_NOTICE, "%s: safemode: fuse reads as %X\n", progname, safemode_fuse);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Read lfuse three times */
|
|
||||||
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
|
|
||||||
to generate a verify error */
|
|
||||||
m = avr_locate_mem(p, "lfuse");
|
|
||||||
if (m != NULL) {
|
|
||||||
fusegood = 0; /* By default fuse is a failure */
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 1, lfuse value: %x\n",progname, safemode_lfuse);
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 2, lfuse value: %x\n",progname, value);
|
|
||||||
if (value == safemode_lfuse) {
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 3, lfuse value: %x\n",progname, value);
|
|
||||||
if (value == safemode_lfuse){
|
|
||||||
fusegood = 1; /* Fuse read OK three times */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Programmer does not allow fuse reading.... no point trying anymore
|
|
||||||
if (allowfuseread == 0)
|
|
||||||
{
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (fusegood == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read lfuse properly. "
|
|
||||||
"Programmer may not be reliable.\n", progname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (fusegood == 1) {
|
|
||||||
avrdude_message(MSG_NOTICE, "%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read hfuse three times */
|
|
||||||
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
|
|
||||||
to generate a verify error */
|
|
||||||
m = avr_locate_mem(p, "hfuse");
|
|
||||||
if (m != NULL) {
|
|
||||||
fusegood = 0; /* By default fuse is a failure */
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 1, hfuse value: %x\n",progname, safemode_hfuse);
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 2, hfuse value: %x\n",progname, value);
|
|
||||||
if (value == safemode_hfuse) {
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 3, hfuse value: %x\n",progname, value);
|
|
||||||
if (value == safemode_hfuse){
|
|
||||||
fusegood = 1; /* Fuse read OK three times */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Programmer does not allow fuse reading.... no point trying anymore
|
|
||||||
if (allowfuseread == 0)
|
|
||||||
{
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fusegood == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read hfuse properly. "
|
|
||||||
"Programmer may not be reliable.\n", progname);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
else if (fusegood == 1){
|
|
||||||
avrdude_message(MSG_NOTICE, "%s: safemode: hfuse reads as %X\n", progname, safemode_hfuse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read efuse three times */
|
|
||||||
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
|
|
||||||
to generate a verify error */
|
|
||||||
m = avr_locate_mem(p, "efuse");
|
|
||||||
if (m != NULL) {
|
|
||||||
fusegood = 0; /* By default fuse is a failure */
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 2, efuse value: %x\n",progname, value);
|
|
||||||
if (value == safemode_efuse) {
|
|
||||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
|
||||||
{
|
|
||||||
allowfuseread = 0;
|
|
||||||
}
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: safemode read 3, efuse value: %x\n",progname, value);
|
|
||||||
if (value == safemode_efuse){
|
|
||||||
fusegood = 1; /* Fuse read OK three times */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Programmer does not allow fuse reading.... no point trying anymore
|
|
||||||
if (allowfuseread == 0)
|
|
||||||
{
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fusegood == 0) {
|
|
||||||
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read efuse properly. "
|
|
||||||
"Programmer may not be reliable.\n", progname);
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
else if (fusegood == 1) {
|
|
||||||
avrdude_message(MSG_NOTICE, "%s: safemode: efuse reads as %X\n", progname, safemode_efuse);
|
|
||||||
}
|
|
||||||
|
|
||||||
*lfuse = safemode_lfuse;
|
|
||||||
*hfuse = safemode_hfuse;
|
|
||||||
*efuse = safemode_efuse;
|
|
||||||
*fuse = safemode_fuse;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This routine will store the current values pointed to by lfuse,
|
|
||||||
* hfuse, and efuse into an internal buffer in this routine when save
|
|
||||||
* is set to 1. When save is 0 (or not 1 really) it will copy the
|
|
||||||
* values from the internal buffer into the locations pointed to be
|
|
||||||
* lfuse, hfuse, and efuse. This allows you to change the fuse bits if
|
|
||||||
* needed from another routine (ie: have it so if user requests fuse
|
|
||||||
* bits are changed, the requested value is now verified
|
|
||||||
*/
|
|
||||||
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse,
|
|
||||||
unsigned char * efuse, unsigned char * fuse)
|
|
||||||
{
|
|
||||||
static unsigned char safemode_lfuse = 0xff;
|
|
||||||
static unsigned char safemode_hfuse = 0xff;
|
|
||||||
static unsigned char safemode_efuse = 0xff;
|
|
||||||
static unsigned char safemode_fuse = 0xff;
|
|
||||||
|
|
||||||
switch (save) {
|
|
||||||
|
|
||||||
/* Save the fuses as safemode setting */
|
|
||||||
case 1:
|
|
||||||
safemode_lfuse = *lfuse;
|
|
||||||
safemode_hfuse = *hfuse;
|
|
||||||
safemode_efuse = *efuse;
|
|
||||||
safemode_fuse = *fuse;
|
|
||||||
|
|
||||||
break;
|
|
||||||
/* Read back the fuses */
|
|
||||||
default:
|
|
||||||
*lfuse = safemode_lfuse;
|
|
||||||
*hfuse = safemode_hfuse;
|
|
||||||
*efuse = safemode_efuse;
|
|
||||||
*fuse = safemode_fuse;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue