diff --git a/NEWS b/NEWS index 6b09b724..079f8f7c 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,11 @@ Changes since version 6.4: - Started to add CMake (by now, parallel with autoconf/automake) - New-architecture devices (AVR8X mega and tiny) can access all 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: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b32934f5..21ae27d3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -173,7 +173,6 @@ add_library(libavrdude ppi.c ppi.h ppiwin.c - safemode.c serbb.h serbb_posix.c serbb_win32.c diff --git a/src/Makefile.am b/src/Makefile.am index dd7adb57..15162224 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -148,7 +148,6 @@ libavrdude_a_SOURCES = \ ppi.c \ ppi.h \ ppiwin.c \ - safemode.c \ serbb.h \ serbb_posix.c \ serbb_win32.c \ diff --git a/src/avr.c b/src/avr.c index 68ecc9a4..d6e78bb5 100644 --- a/src/avr.c +++ b/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, 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); } diff --git a/src/avrdude.1 b/src/avrdude.1 index f73a4689..cc05cf4c 100644 --- a/src/avrdude.1 +++ b/src/avrdude.1 @@ -607,40 +607,11 @@ Posix systems (by now). .It Fl q Disable (or quell) output of the progress bar while reading or writing 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 Tells .Nm to enter the interactive ``terminal'' mode instead of up- or downloading 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 .Ar \&: Ns Ar op Ns .Ar \&: Ns Ar filename Ns diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in index 46076088..c38d2f46 100644 --- a/src/avrdude.conf.in +++ b/src/avrdude.conf.in @@ -339,10 +339,6 @@ default_parallel = "@DEFAULT_PAR_PORT@"; default_serial = "@DEFAULT_SER_PORT@"; # default_bitclock = 2.5; -# Turn off safemode by default -#default_safemode = no; - - # # PROGRAMMER DEFINITIONS # diff --git a/src/config.c b/src/config.c index 9402e4bb..a384f50f 100644 --- a/src/config.c +++ b/src/config.c @@ -36,7 +36,6 @@ char default_programmer[MAX_STR_CONST]; char default_parallel[PATH_MAX]; char default_serial[PATH_MAX]; double default_bitclock; -int default_safemode; char string_buf[MAX_STR_CONST]; char *string_buf_ptr; diff --git a/src/config_gram.y b/src/config_gram.y index e2a935cf..d04e84f5 100644 --- a/src/config_gram.y +++ b/src/config_gram.y @@ -77,7 +77,6 @@ static int pin_name; %token K_DEFAULT_BITCLOCK %token K_DEFAULT_PARALLEL %token K_DEFAULT_PROGRAMMER -%token K_DEFAULT_SAFEMODE %token K_DEFAULT_SERIAL %token K_DESC %token K_FAMILY_ID @@ -257,14 +256,6 @@ def : K_DEFAULT_BITCLOCK TKN_EQUAL number_real TKN_SEMI { default_bitclock = $3->value.number_real; 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); } ; diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index 5761b908..1ddd55b2 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -681,32 +681,6 @@ Posix systems (by now). Disable (or quell) output of the progress bar while reading or writing 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 Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up- or downloading files. See below for a detailed description of the @@ -1133,8 +1107,6 @@ Reading | ################################################## | 100% 6.83s avrdude: verifying ... avrdude: 19278 bytes of flash verified -avrdude: safemode: Fuses OK - avrdude done. Thank you. % @@ -1162,8 +1134,6 @@ Reading | ################################################## | 100% 46.10s avrdude: writing output file "c:/diag flash.bin" -avrdude: safemode: Fuses OK - avrdude done. Thank you. % @@ -1845,9 +1815,6 @@ flash pages of the application section. 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 @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 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 and 2, but there is also experimental implementation of model 3 - not yet tested. diff --git a/src/lexer.l b/src/lexer.l index 2e27a5d4..9aab9d4a 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -137,7 +137,6 @@ dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; } default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; } default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; } default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; } -default_safemode { yylval=NULL; return K_DEFAULT_SAFEMODE; } default_serial { yylval=NULL; return K_DEFAULT_SERIAL; } delay { yylval=NULL; return K_DELAY; } desc { yylval=NULL; return K_DESC; } diff --git a/src/libavrdude.h b/src/libavrdude.h index eebdf5a9..e44e5f48 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -831,30 +831,6 @@ int fileio(int op, char * filename, FILEFMT format, #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 */ enum { @@ -926,7 +902,6 @@ extern char default_programmer[]; extern char default_parallel[]; extern char default_serial[]; extern double default_bitclock; -extern int default_safemode; /* This name is fixed, it's only here for symmetry with * default_parallel and default_serial. */ diff --git a/src/main.c b/src/main.c index 35cdb1d5..7adc4b4c 100644 --- a/src/main.c +++ b/src/main.c @@ -122,9 +122,6 @@ static void usage(void) " is performed in the order specified.\n" " -n Do not write anything to the device.\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" " -E [,] List programmer exit specifications.\n" " -x Pass to programmer.\n" @@ -349,19 +346,11 @@ int main(int argc, char * argv []) int baudrate; /* override default programmer baud rate */ double bitclock; /* Specify programmer bit clock (JTAG ICE) */ 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 is_open; /* Device open succeeded */ char * logfile; /* Use logfile rather than stderr for diagnostics */ 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) char * homedir; #endif @@ -394,7 +383,6 @@ int main(int argc, char * argv []) default_parallel[0] = 0; default_serial[0] = 0; default_bitclock = 0.0; - default_safemode = -1; init_config(); @@ -434,8 +422,6 @@ int main(int argc, char * argv []) baudrate = 0; bitclock = 0.0; ispdelay = 0; - safemode = 1; /* Safemode on by default */ - silentsafe = 0; /* Ask by default */ is_open = 0; logfile = NULL; @@ -581,19 +567,10 @@ int main(int argc, char * argv []) quell_progress++ ; break; - case 's' : /* Silent safemode */ - silentsafe = 1; - safemode = 1; - break; - case 't': /* enter terminal mode */ terminal = 1; break; - case 'u' : /* Disable safemode */ - safemode = 0; - break; - case 'U': upd = parse_op(optarg); 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) { 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 ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL && 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: /* diff --git a/src/safemode.c b/src/safemode.c deleted file mode 100644 index 41012c12..00000000 --- a/src/safemode.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * avrdude - A Downloader/Uploader for AVR device programmers - * avrdude is Copyright (C) 2000-2004 Brian S. Dean - * - * This file: Copyright (C) 2005-2007 Colin O'Flynn - * - * 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 . - */ - - -#include - -#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; -}