int USBGetChar() { for(;;) { USBSetupInterrupt(); USBGeneralInterrupt(); // Read a char if (HasData(CDC_RX)) { u8 c = Recv8(); if (!ReadWriteAllowed()) ReleaseRX(); return c; } if (!--_timeout) { Reboot(); // USB not connected, run firmware } _delay_us(100); // stretch out the bootloader period to about 5 seconds after enumeration LEDPulse(); } return -1; }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint16_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR = 0; // clear all reset flags /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ wdt_disable(); #if DEVICE_PID == 0x606C // Only on the BlinkyTape // Put the user button (B6) in input_pullup mode, so we can read the button state DDRB &= ~(1<<DDB6); PORTB |= (1<<DDB6); #endif if (mcusr_state & (1<<EXTRF)) { // External reset - we should continue to self-programming mode. #if DEVICE_PID == 0x606C // Only on the BlinkyTape } else if (!(PINB & (1<<DDB6))) { // User button held low- Jump into the bootloader, in case the application is borked. #endif } else if ((mcusr_state & (1<<PORF)) && (pgm_read_word(0) != 0xFFFF)) { // After a power-on reset skip the bootloader and jump straight to sketch // if one exists. StartSketch(); } else if ((mcusr_state & (1<<WDRF)) && (bootKeyPtrVal != bootKey) && (pgm_read_word(0) != 0xFFFF)) { // If it looks like an "accidental" watchdog reset then start the sketch. StartSketch(); } /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; LEDPulse(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint16_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR = 0; // clear all reset flags /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ wdt_disable(); // init HWB pin, wait a ms to allow caps to charge HWB_SETUP(); _delay_ms(1); if ((mcusr_state & (1<<EXTRF)) && HWB_STATUS() && (pgm_read_word(0) != 0xFFFF)) { // External reset - start the sketch if there is one and HWB jumper is not installed (HWB pin is read high) StartSketch(); } else if ((mcusr_state & (1<<PORF)) && (pgm_read_word(0) != 0xFFFF)) { // After a power-on reset skip the bootloader and jump straight to sketch // if one exists. StartSketch(); } else if ((mcusr_state & (1<<WDRF)) && (bootKeyPtrVal != bootKey) && (pgm_read_word(0) != 0xFFFF)) { // If it looks like an "accidental" watchdog reset then start the sketch. StartSketch(); } // so only start programmimg mode when reset came from autoreset = watchdog reset and bootkey matches /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; LEDPulse(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint16_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR = 0; // clear all reset flags /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ wdt_disable(); /* Jump to bootloader only if correct key is present in eeprom */ if ((eeprom_read_word((uint16_t*)EEP_BOOTKEY_ADDR) != BOOTLOADER_BOOTKEY) && (eeprom_read_word((uint16_t*)EEP_BACKUP_BOOTKEY_ADDR) != BOOTLOADER_BOOTKEY)) { StartSketch(); } /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; LEDPulse(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint16_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR &= ~((1 << PORF) | (1 << EXTRF) | (1 << WDRF)); // clear reset flags that are used by the bootloader /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ wdt_disable(); if (pgm_read_word(0) != 0xFFFF) { // There is a sketch (otherwise, skip these checks and just run the bootloader). if (mcusr_state & (1 << PORF)) { // After power-on reset, clear BORF so sketch can tell it wasn't a brown-out reset, // then start the sketch. MCUSR &= ~(1 << BORF); StartSketch(); } else if (mcusr_state & (1 << EXTRF)) { // External reset. if (bootKeyPtrVal != bootKey) { // First reset button press. Set boot key for 750 ms so second reset button press // can be detected, then start the sketch if there isn't another reset. *bootKeyPtr = bootKey; _delay_ms(750); *bootKeyPtr = 0; StartSketch(); } else { // Second reset button press; boot key was already set. Fall through to bootloader. } } else if ((mcusr_state & (1 << WDRF)) && (bootKeyPtrVal == bootKey)) { // Watchdog reset triggered by sketch to start bootloader. Fall through. } else { // Reset happened for some other reason; start the sketch. StartSketch(); } } // Clear remaining reset flags so the sketch doesn't see info about an old reset when it runs later. MCUSR = 0; /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; LEDPulse(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }