/* This is the port where the USB bus is connected. When you configure it to
* "B", the registers PORTB, PINB and DDRB will be used.
*/
-#define USB_CFG_DMINUS_BIT 4
+#define JUMPER_BIT 7 /* old value was 0 */
+/*
+ * jumper is connected to this bit in port D, active low
+ */
+#define USB_CFG_DMINUS_BIT 6 /* old value was 4 */
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
* This may be any bit in the port.
*/
/* ---------------------- feature / code size options ---------------------- */
/* ------------------------------------------------------------------------- */
+#define HAVE_READ_LOCK_FUSE 1
+/*
+ * enable the loaders capability to load its lfuse, hfuse and lockbits
+ * ...However, programming of these is prohibited...
+ */
+
+#define HAVE_BLB11_SOFTW_LOCKBIT 1
+/*
+ * The IC itself do not need to prgra BLB11, but the bootloader will avaoid
+ * to erase itself from the bootregion
+ */
+
#define HAVE_EEPROM_PAGED_ACCESS 1
/* If HAVE_EEPROM_PAGED_ACCESS is defined to 1, page mode access to EEPROM is
* compiled in. Whether page mode or byte mode access is used by AVRDUDE
* signature) does not support page mode for EEPROM. It is required for
* accessing the EEPROM on the ATMega8. Costs ~54 bytes.
*/
-#define BOOTLOADER_CAN_EXIT 1
+#define BOOTLOADER_CAN_EXIT 0
/* If this macro is defined to 1, the boot loader will exit shortly after the
* programmer closes the connection to the device. Costs ~36 bytes.
*/
#ifndef __ASSEMBLER__ /* assembler cannot parse function definitions */
-#define JUMPER_BIT 7 /* jumper is connected to this bit in port D, active low */
-
#ifndef MCUCSR /* compatibility between ATMega8 and ATMega88 */
# define MCUCSR MCUSR
#endif
static inline void bootLoaderInit(void)
{
PORTD |= (1 << JUMPER_BIT); /* activate pull-up */
- if(!(MCUCSR & (1 << EXTRF))) /* If this was not an external reset, ignore */
- leaveBootloader();
+// deactivated by Stephan - reset after each avrdude op is annoing!
+// if(!(MCUCSR & (1 << EXTRF))) /* If this was not an external reset, ignore */
+// leaveBootloader();
MCUCSR = 0; /* clear all reset flags for next time */
}
PORTD = 0; /* undo bootLoaderInit() changes */
}
-#define bootLoaderCondition() ((PIND & (1 << JUMPER_BIT)) == 0)
+#define bootLoaderCondition() ((PIND & (1 << JUMPER_BIT)) == 0)
#endif /* __ASSEMBLER__ */
#include <avr/boot.h>
#include <avr/eeprom.h>
#include <util/delay.h>
+
+#include <avr/cpufunc.h>
+
#include <string.h>
+
+
static void leaveBootloader() __attribute__((__noreturn__));
#include "bootloaderconfig.h"
#include "usbdrv/usbdrv.c"
+#ifndef BOOTLOADER_ADDRESS
+ #error need to know the bootloaders flash address!
+#endif
+
/* ------------------------------------------------------------------------ */
/* Request constants used by USBasp */
uchar b[sizeof(addr_t)];
}longConverter_t;
-static uchar requestBootLoaderExit;
-static longConverter_t currentAddress; /* in bytes */
-static uchar bytesRemaining;
-static uchar isLastPage;
+
+
+#if BOOTLOADER_CAN_EXIT
+static uchar requestBootLoaderExit;
+#endif
+static volatile unsigned char stayinloader = 1;
+
+static longConverter_t currentAddress; /* in bytes */
+static uchar bytesRemaining;
+static uchar isLastPage;
#if HAVE_EEPROM_PAGED_ACCESS
-static uchar currentRequest;
+static uchar currentRequest;
#else
-static const uchar currentRequest = 0;
+static const uchar currentRequest = 0;
#endif
static const uchar signatureBytes[4] = {
static void leaveBootloader()
{
DBG1(0x01, 0, 0);
- bootLoaderExit();
cli();
+ usbDeviceDisconnect();
+ bootLoaderExit();
USB_INTR_ENABLE = 0;
USB_INTR_CFG = 0; /* also reset config bits */
GICR = (1 << IVCE); /* enable change of interrupt vectors */
if(rq->wValue.bytes[0] == 0x30){ /* read signature */
rval = rq->wIndex.bytes[0] & 3;
rval = signatureBytes[rval];
+#if HAVE_READ_LOCK_FUSE
+ }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);
+#endif
#if HAVE_EEPROM_BYTE_ACCESS
}else if(rq->wValue.bytes[0] == 0xa0){ /* read EEPROM byte */
rval = eeprom_read_byte((void *)address.word);
#endif
len = 0xff; /* hand over to usbFunctionRead() / usbFunctionWrite() */
}
-#if BOOTLOADER_CAN_EXIT
+
}else if(rq->bRequest == USBASP_FUNC_DISCONNECT){
- requestBootLoaderExit = 1; /* allow proper shutdown/close of connection */
+ stayinloader = 0;
+#if BOOTLOADER_CAN_EXIT
+ requestBootLoaderExit = 1; /* allow proper shutdown/close of connection */
#endif
}else{
/* ignore: USBASP_FUNC_CONNECT */
if((currentAddress.w[0] & (SPM_PAGESIZE - 1)) == 0){ /* if page start: erase */
DBG1(0x33, 0, 0);
# ifndef NO_FLASH_WRITE
+# if HAVE_BLB11_SOFTW_LOCKBIT
+ if (CURRENT_ADDRESS < (addr_t)(BOOTLOADER_ADDRESS)) {
+# endif
cli();
boot_page_erase(CURRENT_ADDRESS); /* erase page */
sei();
boot_spm_busy_wait(); /* wait until page is erased */
+# if HAVE_BLB11_SOFTW_LOCKBIT
+ }
+# endif
# endif
}
#endif
i += 2;
DBG1(0x32, 0, 0);
+# if HAVE_BLB11_SOFTW_LOCKBIT
+ if (CURRENT_ADDRESS < (addr_t)(BOOTLOADER_ADDRESS)) {
+# endif
cli();
boot_page_fill(CURRENT_ADDRESS, *(short *)data);
sei();
+# if HAVE_BLB11_SOFTW_LOCKBIT
+ }
+# endif
CURRENT_ADDRESS += 2;
data += 2;
/* write page when we cross page boundary or we have the last partial page */
if((currentAddress.w[0] & (SPM_PAGESIZE - 1)) == 0 || (isLast && i >= len && isLastPage)){
DBG1(0x34, 0, 0);
#ifndef NO_FLASH_WRITE
+# if HAVE_BLB11_SOFTW_LOCKBIT
+ if ((CURRENT_ADDRESS - (addr_t)2) < (addr_t)(BOOTLOADER_ADDRESS)) {
+# endif
cli();
boot_page_write(CURRENT_ADDRESS - 2);
sei();
cli();
boot_rww_enable();
sei();
+# if HAVE_BLB11_SOFTW_LOCKBIT
+ }
+# endif
#endif
}
}
GICR = (1 << IVSEL); /* move interrupts to boot flash section */
#endif
if(bootLoaderCondition()){
+#if BOOTLOADER_CAN_EXIT
uchar i = 0, j = 0;
+#endif
initForUsbConnectivity();
do{
usbPoll();
}
}
#endif
- }while(bootLoaderCondition()); /* main event loop */
+ }while ((stayinloader) || (!bootLoaderCondition())); /* main event loop */
}
leaveBootloader();
}
* the macros. See the file USB-IDs-for-free.txt before you assign a name if
* you use a shared VID/PID.
*/
-/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
-/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
+// #define USB_CFG_SERIAL_NUMBER '2', '0', '1', '2', '0', '7', '2', '1', '0', '1', '0', '0'
+// #define USB_CFG_SERIAL_NUMBER_LEN 12
/* Same as above for the serial number. If you don't want a serial number,
* undefine the macros.
* It may be useful to provide the serial number through other means than at