#include <avr/eeprom.h>
#include <util/delay.h>
+
+#if 0
+/*
+ * 29.09.2012 / 30.09.2012
+ *
+ * Since cpufunc.h is not needed in this context and
+ * since it is not available in all toolchains, this include
+ * becomes deactivated by github issue-report.
+ * (In case of trouble it remains in sourcecode for reactivation.)
+ *
+ * The autor would like to thank Lena-M for reporting this
+ * issue (https://github.com/baerwolf/USBaspLoader/issues/1).
+ */
#include <avr/cpufunc.h>
+#endif
+
+#include <avr/boot.h>
#include <string.h>
#define USBASP_FUNC_WRITEEEPROM 8
#define USBASP_FUNC_SETLONGADDRESS 9
+// additional USBasp Commands
+#define USBASP_FUNC_SETISPSCK 10
+#define USBASP_FUNC_TPI_CONNECT 11
+#define USBASP_FUNC_TPI_DISCONNECT 12
+#define USBASP_FUNC_TPI_RAWREAD 13
+#define USBASP_FUNC_TPI_RAWWRITE 14
+#define USBASP_FUNC_TPI_READBLOCK 15
+#define USBASP_FUNC_TPI_WRITEBLOCK 16
+#define USBASP_FUNC_GETCAPABILITIES 127
/* ------------------------------------------------------------------------ */
#ifndef ulong
static const uchar currentRequest = 0;
#endif
-static unsigned char wdtstatus;
-
static const uchar signatureBytes[4] = {
#ifdef SIGNATURE_BYTES
SIGNATURE_BYTES
-#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__)
+#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
0x1e, 0x93, 0x07, 0
-#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48P__)
+#elif defined (__AVR_ATmega32__)
+ 0x1e, 0x95, 0x02, 0
+#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48A__) || defined (__AVR_ATmega48P__)
+ #error ATmega48 does not support bootloaders!
0x1e, 0x92, 0x05, 0
-#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88P__)
+#elif defined (__AVR_ATmega48PA__)
+ #error ATmega48 does not support bootloaders!
+ 0x1e, 0x92, 0x0A, 0
+#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88A__) || defined (__AVR_ATmega88P__)
0x1e, 0x93, 0x0a, 0
-#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__)
+#elif defined (__AVR_ATmega88PA__)
+ 0x1e, 0x93, 0x0F, 0
+#elif defined (__AVR_ATmega164A__)
+ 0x1e, 0x94, 0x0f, 0
+#elif defined (__AVR_ATmega164P__)
+ 0x1e, 0x94, 0x0a, 0
+#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega168P__)
0x1e, 0x94, 0x06, 0
+#elif defined (__AVR_ATmega168PA__)
+ 0x1e, 0x94, 0x0B, 0
+#elif defined (__AVR_ATmega324A__)
+ 0x1e, 0x95, 0x15, 0
+#elif defined (__AVR_ATmega324P__)
+ 0x1e, 0x95, 0x08, 0
+#elif defined (__AVR_ATmega328__)
+ 0x1e, 0x95, 0x14, 0
#elif defined (__AVR_ATmega328P__)
0x1e, 0x95, 0x0f, 0
+#elif defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__)
+ 0x1e, 0x96, 0x09, 0
+#elif defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__)
+ 0x1e, 0x96, 0x0a, 0
+#elif defined (__AVR_ATmega128__)
+ 0x1e, 0x97, 0x02, 0
+#elif defined (__AVR_ATmega1284__)
+ 0x1e, 0x97, 0x06, 0
+#elif defined (__AVR_ATmega1284P__)
+ 0x1e, 0x97, 0x05, 0
#else
# error "Device signature is not known, please edit main.c!"
#endif
GICR = (1 << IVCE); /* enable change of interrupt vectors */
GICR = (0 << IVSEL); /* move interrupts to application flash section */
- WDTCR = wdtstatus;
-
/* We must go through a global function pointer variable instead of writing
* ((void (*)(void))0)();
* because the compiler optimizes a constant 0 to "rcall 0" which is not
rval = rq->wIndex.bytes[0] & 3;
rval = signatureBytes[rval];
#if HAVE_READ_LOCK_FUSE
-#if defined (__AVR_ATmega8__)
+#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega32__)
}else if(rq->wValue.bytes[0] == 0x58 && rq->wValue.bytes[1] == 0x00){ /* read lock bits */
rval = boot_lock_fuse_bits_get(GET_LOCK_BITS);
}else if(rq->wValue.bytes[0] == 0x50 && rq->wValue.bytes[1] == 0x00){ /* read lfuse bits */
rval = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS);
}else if(rq->wValue.bytes[0] == 0x58 && rq->wValue.bytes[1] == 0x08){ /* read hfuse bits */
rval = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
+
+#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48A__) || defined (__AVR_ATmega48P__) || defined (__AVR_ATmega48PA__) || \
+ defined (__AVR_ATmega88__) || defined (__AVR_ATmega88A__) || defined (__AVR_ATmega88P__) || defined (__AVR_ATmega88PA__) || \
+ defined (__AVR_ATmega164A__) || defined (__AVR_ATmega164P__) || \
+ defined (__AVR_ATmega168__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega168P__) || defined (__AVR_ATmega168PA__) || \
+ defined (__AVR_ATmega324A__) || defined (__AVR_ATmega324P__) || \
+ defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) || \
+ defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__) || \
+ defined (__AVR_ATmega128__) || \
+ defined (__AVR_ATmega1284__) || defined (__AVR_ATmega1284P__)
+ }else if(rq->wValue.bytes[0] == 0x58 && rq->wValue.bytes[1] == 0x00){ /* read lock bits */
+ rval = boot_lock_fuse_bits_get(GET_LOCK_BITS);
+ }else if(rq->wValue.bytes[0] == 0x50 && rq->wValue.bytes[1] == 0x00){ /* read lfuse bits */
+ rval = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS);
+ }else if(rq->wValue.bytes[0] == 0x58 && rq->wValue.bytes[1] == 0x08){ /* read hfuse bits */
+ rval = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
+ }else if(rq->wValue.bytes[0] == 0x50 && rq->wValue.bytes[1] == 0x08){ /* read efuse bits */
+ rval = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS );
+#else
+ #warning "HAVE_READ_LOCK_FUSE is activated but MCU unknown -> will not support this feature"
#endif
#endif
#if HAVE_EEPROM_BYTE_ACCESS
}
replyBuffer[3] = rval;
len = 4;
- }else if(rq->bRequest == USBASP_FUNC_ENABLEPROG){
+ }else if((rq->bRequest == USBASP_FUNC_ENABLEPROG) || (rq->bRequest == USBASP_FUNC_SETISPSCK)){
/* replyBuffer[0] = 0; is never touched and thus always 0 which means success */
len = 1;
}else if(rq->bRequest >= USBASP_FUNC_READFLASH && rq->bRequest <= USBASP_FUNC_SETLONGADDRESS){
for(i = 0; i < len;){
#if HAVE_BLB11_SOFTW_LOCKBIT
if (CURRENT_ADDRESS >= (addr_t)(BOOTLOADER_ADDRESS)) {
+ return 1;
}
#endif
i += 2;
int __attribute__((noreturn)) main(void)
{
/* initialize */
- wdtstatus = WDTCR;
- wdt_disable(); /* main app may have enabled watchdog */
bootLoaderInit();
odDebugInit();
DBG1(0x00, 0, 0);
GICR = (1 << IVSEL); /* move interrupts to boot flash section */
#endif
if(bootLoaderCondition()){
+ wdt_disable(); /* main app may have enabled watchdog */
#if BOOTLOADER_CAN_EXIT
uchar i = 0, j = 0;
#endif