From d901e0a768598f014fbb1aa0b70457eeb9853b4d Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Wed, 16 Nov 2022 00:42:36 +0000 Subject: [PATCH] Update urbootPutVersion() to reflect urboot v7.7 changes --- src/urclock.c | 20 +++++++++++--------- src/urclock_private.h | 20 ++++++++++++++------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/urclock.c b/src/urclock.c index 4ff14656..1dad925c 100644 --- a/src/urclock.c +++ b/src/urclock.c @@ -902,8 +902,8 @@ nopatch_nometa: } -// Put version string into a buffer of max 17 characters incl nul (normally 13-14 bytes incl nul) -static void urbootPutVersion(char *buf, uint16_t ver) { +// Put version string into a buffer of max 19 characters incl nul (normally 15-16 bytes incl nul) +static void urbootPutVersion(char *buf, uint16_t ver, uint16_t rjmpwp) { uint8_t hi = ver>>8, type = ver & 0xff, flags; if(ver == 0xffff) // Unknown provenance @@ -912,7 +912,7 @@ static void urbootPutVersion(char *buf, uint16_t ver) { if(hi >= 072) { // These are urboot versions sprintf(buf, "u%d.%d ", hi>>3, hi&7); buf += strlen(buf); - *buf++ = type & UR_PGMWRITEPAGE? 'w': '-'; + *buf++ = (hi < 077 && (type & UR_PGMWRITEPAGE)) || (hi >= 077 && rjmpwp != ret_opcode)? 'w': '-'; *buf++ = type & UR_EEPROM? 'e': '-'; if(hi >= 076) { // From urboot version 7.6 URPROTOCOL has its own bit *buf++ = type & UR_URPROTOCOL? 'u': 's'; @@ -927,12 +927,14 @@ static void urbootPutVersion(char *buf, uint16_t ver) { // V = VBL, patch & verify, v = VBL, patch only, j = VBL, jump only *buf++ = flags==3? 'V': flags==2? 'v': flags? 'j': 'h'; *buf++ = type & UR_PROTECTME? 'p': '-'; - *buf++ = type & UR_RESETFLAGS? 'r': '-'; + *buf++ = (hi < 077 && (type & UR_RESETFLAGS)) || hi >= 077? 'r': '-'; + *buf++ = hi >= 077 && (type & UR_AUTOBAUD)? 'a': '-'; // - means no + *buf++ = hi >= 077 && (type & UR_HAS_CE)? 'c': '.'; // . means don't know *buf = 0; } else if(hi) // Version number in binary from optiboot v4.1 - sprintf(buf, "o%d.%d -?s-?-%c", hi, type, hi>=4? 'r': '-'); + sprintf(buf, "o%d.%d -?s-?-r--", hi, type); else - sprintf(buf, "x0.0 -------"); + sprintf(buf, "x0.0 ........."); return; } @@ -1187,7 +1189,7 @@ static int ur_initstruct(const PROGRAMMER *pgm, const AVRPART *p) { if(!ur.blstart) Return("please specify -xbootsize= and, if needed, -xvectornum= or -xeepromrw"); - uint16_t v16 = 0xffff; + uint16_t v16 = 0xffff, rjmpwp = ret_opcode; // Sporting chance that we can read top flash to get intell about bootloader if(!ur.urprotocol || (ur.urfeatures & UB_READ_FLASH)) { @@ -1198,7 +1200,7 @@ static int ur_initstruct(const PROGRAMMER *pgm, const AVRPART *p) { // In a urboot bootloader (v7.2 onwards) these six are as follows uint8_t numpags = spc[0]; // Actually, these two only exist from v7.5 onwards uint8_t vectnum = spc[1]; - uint16_t rjmpwp = buf2uint16(spc+2); // rjmp to bootloader pgm_write_page() or ret opcode + rjmpwp = buf2uint16(spc+2); // rjmp to bootloader pgm_write_page() or ret opcode uint8_t cap = spc[4]; // Capability byte uint8_t urver = spc[5]; // Urboot version (low three bits are minor version: 076 is v7.6) v16 = buf2uint16(spc+4); // Combo word for neatly printed version line of urboot bootloader @@ -1316,7 +1318,7 @@ static int ur_initstruct(const PROGRAMMER *pgm, const AVRPART *p) { } vblvecfound: - urbootPutVersion(ur.desc, v16); + urbootPutVersion(ur.desc, v16, rjmpwp); ur.mcode = 0xff; if(ur.blstart) { diff --git a/src/urclock_private.h b/src/urclock_private.h index f97f08b6..fb4471d6 100644 --- a/src/urclock_private.h +++ b/src/urclock_private.h @@ -92,6 +92,7 @@ typedef struct { // Capability byte of bootloader from version 7.2 onwards #define UR_PGMWRITEPAGE 128 // pgm_write_page() can be called from application at FLASHEND+1-4 +#define UR_AUTOBAUD 128 // Bootloader has autobaud detection (from v7.7) #define UR_EEPROM 64 // EEPROM read/write support #define UR_URPROTOCOL 32 // Bootloader uses urprotocol that requires avrdude -c urclock #define UR_DUAL 16 // Dual boot @@ -102,6 +103,7 @@ typedef struct { #define UR_NO_VBL 0 // Not a vector bootloader, must set fuses to HW bootloader support #define UR_PROTECTME 2 // Bootloader safeguards against overwriting itself #define UR_RESETFLAGS 1 // Load reset flags into register R2 before starting application +#define UR_HAS_CE 1 // Bootloader has Chip Erase (from v7.7) #define verbyte_cv(capver) ((uint8_t) ((uint16_t) (capver) >> 8)) #define hascapbyte_cv(capver) ({ uint8_t _vh = verbyte_cv(capver); _vh >= 072 && _vh != 0xff; }) @@ -116,31 +118,37 @@ typedef struct { (uint8_t) (_vh >= 072 && _vh != 0xff? _vh: 0); }) #define vercapis(capver, mask) ({ uint16_t _vi = capver; !!(capabilities_cv(_vi) & (mask)); }) -#define ispgmwritepage_cv(capver) vercapis(capver, UR_PGMWRITEPAGE) +#define ispgmwritepage_cv(capver) vercapis(capver, UR_PGMWRITEPAGE) // up to v7.6 +#define isautobaud_cv(capver) vercapis(capver, UR_AUTOBAUD) // from v7.7 #define iseeprom_cv(capver) vercapis(capver, UR_EEPROM) #define isurprotocol_cv(capver) vercapis(capver, UR_URPROTOCOL) #define isdual_cv(capver) vercapis(capver, UR_DUAL) #define isvectorbl_cv(capver) vercapis(capver, UR_VBLMASK) #define isprotectme_cv(capver) vercapis(capver, UR_PROTECTME) -#define isresetflags_cv(capver) vercapis(capver, UR_RESETFLAGS) +#define isresetflags_cv(capver) vercapis(capver, UR_RESETFLAGS) // up to v7.6 +#define ishas_ce_cv(capver) vercapis(capver, UR_HAS_CE) // from v7.7 // Capability bits incl position -#define pgmwritepage_bit_cap(cap) ((cap) & UR_PGMWRITEPAGE) +#define pgmwritepage_bit_cap(cap) ((cap) & UR_PGMWRITEPAGE) // up to v7.6 +#define autibaud_bit_cap(cap) ((cap) & UR_AUTOBAUD) // from v7.7 #define eeprom_bit_cap(cap) ((cap) & UR_EEPROM) #define dual_bit_cap(cap) ((cap) & UR_DUAL) #define vector_bits_cap(cap) ((cap) & UR_VBLMASK)) #define protectme_bit_cap(cap) ((cap) & UR_PROTECTME) #define urprotocol_bit_cap(cap) ((cap) & UR_URPROTOCOL) -#define resetflags_bit_cap(cap) ((cap) & UR_RESETFLAGS) +#define resetflags_bit_cap(cap) ((cap) & UR_RESETFLAGS) // up to v7.6 +#define has_ce_bit_cap(cap) ((cap) & UR_HAS_CE) // from v7.7 // Boolean capabilities -#define ispgmwritepage_cap(cap) (!!((cap) & UR_PGMWRITEPAGE)) +#define ispgmwritepage_cap(cap) (!!((cap) & UR_PGMWRITEPAGE)) // up to v7.6 +#define isautobaud_cap(cap) (!!((cap) & UR_AUTOBAUD)) // from v7.7 #define iseeprom_cap(cap) (!!((cap) & UR_EEPROM)) #define isdual_cap(cap) (!!((cap) & UR_DUAL)) #define isvectorbl_cap(cap) (!!((cap) & UR_VBLMASK))) #define isprotectme_cap(cap) (!!((cap) & UR_PROTECTME)) #define isurprotocol_cap(cap) (!!((cap) & UR_URPROTOCOL)) -#define isresetflags_cap(cap) (!!((cap) & UR_RESETFLAGS)) +#define isresetflags_cap(cap) (!!((cap) & UR_RESETFLAGS)) // up to v7.6 +#define ishas_ce_cap(cap) (!!((cap) & UR_HAS_CE)) // from v7.7 // Capability levels 0, 1, 2 or 3 #define vectorbl_level_cap(cap) (((cap) & UR_VBLMASK)/UR_VBL)