Пример #1
0
// finishes up writing to the flash, including adding the tinyVector tables at the end of memory
// TODO: can this be simplified? EG: currentAddress = PROGMEM_SIZE; fillFlashWithVectors();
static inline void tiny85FinishWriting(void) {
    // make sure remainder of flash is erased and write checksum and application reset vectors
    if (didWriteSomething) {
        while (currentAddress < BOOTLOADER_ADDRESS) {
            fillFlashWithVectors();
        }
    }
}
Пример #2
0
static inline void tiny85FlashWrites(void) {
    _delay_us(2000); // TODO: why is this here? - it just adds pointless two level deep loops seems like?
    // write page to flash, interrupts will be disabled for > 4.5ms including erase
    
    if (currentAddress % SPM_PAGESIZE) { // when we aren't perfectly aligned to a flash page boundary
        fillFlashWithVectors(); // fill up the rest of the page with 0xFFFF (unprogrammed) bits
    } else {
        writeFlashPage(); // otherwise just write it
    }
}
Пример #3
0
static inline void tiny85FlashInit(void) {
    // check for erased first page (no bootloader interrupt vectors), add vectors if missing
    // this needs to happen for usb communication to work later - essential to first run after bootloader
    // being installed
    if(pgm_read_word(RESET_VECTOR_OFFSET * 2) != 0xC000 + (BOOTLOADER_ADDRESS/2) - 1 ||
            pgm_read_word(USBPLUS_VECTOR_OFFSET * 2) != 0xC000 + (BOOTLOADER_ADDRESS/2) - 1) {

        fillFlashWithVectors();
    }

    // TODO: necessary to reset currentAddress?
    currentAddress = 0;
}
Пример #4
0
static void eraseApplication(void)
{
    // erase all pages starting from end of application section down to page 1 (leaving page 0)
    CURRENT_ADDRESS = BOOTLOADER_ADDRESS - SPM_PAGESIZE;
    while(CURRENT_ADDRESS != 0x0000)
    {
        boot_page_erase(CURRENT_ADDRESS);
        boot_spm_busy_wait();

        CURRENT_ADDRESS -= SPM_PAGESIZE;
    }

    // erase and load page 0 with vectors
    fillFlashWithVectors();
}
Пример #5
0
// erase any existing application and write in jumps for usb interrupt and reset to bootloader
//  - Because flash can be erased once and programmed several times, we can write the bootloader
//  - vectors in now, and write in the application stuff around them later.
//  - if vectors weren't written back in immidately, usb would fail.
static inline void eraseApplication(void) {
    // erase all pages until bootloader, in reverse order (so our vectors stay in place for as long as possible)
    // while the vectors don't matter for usb comms as interrupts are disabled during erase, it's important
    // to minimise the chance of leaving the device in a state where the bootloader wont run, if there's power failure
    // during upload
    currentAddress = BOOTLOADER_ADDRESS;
    cli();
    while (currentAddress) {
        currentAddress -= SPM_PAGESIZE;
        
        boot_page_erase(currentAddress);
        boot_spm_busy_wait();
    }
    
    fillFlashWithVectors();
    sei();
}
Пример #6
0
static inline __attribute__((noreturn)) void leaveBootloader(void)
{
    DBG1(0x01, 0, 0);
    bootLoaderExit();
    cli();
    USB_INTR_ENABLE = 0;
    USB_INTR_CFG = 0;       /* also reset config bits */

#ifdef TINY85MODE
	// make sure remainder of flash is erased and write checksum and application reset vectors
    if(appWriteComplete)
    {
        CURRENT_ADDRESS = writeSize;
        while(CURRENT_ADDRESS < BOOTLOADER_ADDRESS)
        {
            fillFlashWithVectors();
        }
    }
#else
    GICR = (1 << IVCE);     /* enable change of interrupt vectors */
    GICR = (0 << IVSEL);    /* move interrupts to application flash section */
#endif

    // TODO: watchdog reset instead to reset registers?
#ifdef APPCHECKSUM
    if(!testForValidApplication())
        asm volatile ("rjmp __vectors");
#endif

#ifdef TINY85MODE
    // clear magic word from bottom of stack before jumping to the app
    *(uint8_t*)(RAMEND) = 0x00;
    *(uint8_t*)(RAMEND-1) = 0x00;

    // jump to application reset vector at end of flash
    asm volatile ("rjmp __vectors - 4");
#else
/* 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
 * handled correctly by the assembler.
 */
    nullVector();
#endif
}
Пример #7
0
static inline void tiny85FlashInit(void)
{
    // check for erased first page (no bootloader interrupt vectors), add vectors if missing
    if(pgm_read_word(RESET_VECTOR_OFFSET * 2) != 0xC000 + (BOOTLOADER_ADDRESS/2) - 1 ||
            pgm_read_word(USBPLUS_VECTOR_OFFSET * 2) != 0xC000 + (BOOTLOADER_ADDRESS/2) - 1)
    {
        // TODO: actually need to erase here?  how could we end up with missing vectors but application data higher up?
#	if HAVE_CHIP_ERASE
        eraseApplication();
#	else
        fillFlashWithVectors();
#	endif
    }

    // TODO: necessary to reset CURRENT_ADDRESS?
    CURRENT_ADDRESS = 0;
#   ifdef APPCHECKSUM
        checksum = 0;
#   endif
}
Пример #8
0
static inline void tiny85FlashWrites(void)
{
#if HAVE_CHIP_ERASE
    if(eraseRequested)
    {
        _delay_ms(2);
        cli();
        eraseApplication();
        sei();

#ifdef APPCHECKSUM
        checksum = 0;
#endif
        eraseRequested = 0;
    }
#endif
    if(flashPageLoaded)
    {
        _delay_ms(2);
        // write page to flash, interrupts will be disabled for several milliseconds
        cli();

        if(CURRENT_ADDRESS % SPM_PAGESIZE)
            fillFlashWithVectors();
        else
            writeFlashPage();

        sei();

        flashPageLoaded = 0;
        if(isLastPage)
        {
            // store number of bytes written so rest of flash can be filled later
            writeSize = CURRENT_ADDRESS;
            appWriteComplete = 1;
        }
    }
}