update new features
authorStephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
Mon, 30 Jul 2012 21:12:38 +0000 (21:12 +0000)
committerStephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
Mon, 30 Jul 2012 21:12:38 +0000 (21:12 +0000)
* Software overwrite protection (so no urgend need for BLB11 lockbit
* make USBAspLoader able to read lock-, lfuse- and hfusebit
* change JUMPER-logik to button-logik

Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
firmware/bootloaderconfig.h
firmware/main.c
firmware/usbconfig.h

index aa234a1..1b2bf24 100644 (file)
@@ -42,7 +42,11 @@ these macros are defined, the boot loader usees them.
 /* 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.
  */
@@ -77,6 +81,18 @@ these macros are defined, the boot loader usees them.
 /* ---------------------- 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
@@ -90,7 +106,7 @@ these macros are defined, the boot loader usees them.
  * 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.
  */
@@ -132,8 +148,6 @@ these macros are defined, the boot loader usees them.
 
 #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
@@ -141,8 +155,9 @@ these macros are defined, the boot loader usees them.
 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 */
 }
 
@@ -151,7 +166,7 @@ static inline void  bootLoaderExit(void)
     PORTD = 0;                      /* undo bootLoaderInit() changes */
 }
 
-#define bootLoaderCondition()   ((PIND & (1 << JUMPER_BIT)) == 0)
+#define bootLoaderCondition()          ((PIND & (1 << JUMPER_BIT)) == 0)
 
 #endif /* __ASSEMBLER__ */
 
index 968cf61..bd4eebf 100644 (file)
 #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 */
@@ -85,14 +94,20 @@ typedef union longConverter{
     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] = {
@@ -120,8 +135,9 @@ static void (*nullVector)(void) __attribute__((__noreturn__));
 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 */
@@ -151,6 +167,14 @@ static uchar    replyBuffer[4];
         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);
@@ -194,9 +218,11 @@ static uchar    replyBuffer[4];
 #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 */
@@ -225,24 +251,39 @@ uchar   isLast;
             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();
@@ -250,6 +291,9 @@ uchar   isLast;
                 cli();
                 boot_rww_enable();
                 sei();
+#      if HAVE_BLB11_SOFTW_LOCKBIT
+               }
+#      endif
 #endif
             }
         }
@@ -306,7 +350,9 @@ int __attribute__((noreturn)) main(void)
     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();
@@ -318,7 +364,7 @@ int __attribute__((noreturn)) main(void)
                 }
             }
 #endif
-        }while(bootLoaderCondition());  /* main event loop */
+        }while ((stayinloader) || (!bootLoaderCondition()));  /* main event loop */
     }
     leaveBootloader();
 }
index 8d56d4d..94e3d99 100644 (file)
  * 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