From da03595c32f3822d0b8c96ab61ec7b65131196ee Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Thu, 27 Oct 2011 10:23:06 -0400 Subject: brought nuevo_diskloader changes over to diskloader Moved nuevo_diskloader files into diskloader directory. Changed back to real PID for Leonardo --- bootloaders/diskloader/src/DiskLoader.cpp | 333 +++++++++++++++++------------- 1 file changed, 187 insertions(+), 146 deletions(-) (limited to 'bootloaders/diskloader/src/DiskLoader.cpp') diff --git a/bootloaders/diskloader/src/DiskLoader.cpp b/bootloaders/diskloader/src/DiskLoader.cpp index 6580618..216ddc6 100644 --- a/bootloaders/diskloader/src/DiskLoader.cpp +++ b/bootloaders/diskloader/src/DiskLoader.cpp @@ -1,65 +1,56 @@ - +/* + * DiskLoader.cpp + */ #include "Platform.h" +//#include "USBCore.h" -// This bootloader creates a composite Serial device -// -// The serial interface supports a STK500v1 protocol that is very similar to optiboot -// -// The bootloader will timeout and start the firmware after a few hundred milliseconds -// if a usb connection is not detected. -// -// The tweakier code is to keep the bootloader below 2k (no interrupt table, for example) extern "C" void entrypoint(void) __attribute__ ((naked)) __attribute__ ((section (".vectors"))); void entrypoint(void) { asm volatile ( - "eor r1, r1\n" // Zero register - "out 0x3F, r1\n" // SREG - "ldi r28, 0xFF\n" - "ldi r29, 0x0A\n" - "out 0x3E, r29\n" // SPH - "out 0x3D, r28\n" // SPL - "rjmp main" // Stack is all set up, start the main code - ::); + "eor r1, r1\n" // Zero register + "out 0x3F, r1\n" // SREG + "ldi r28, 0xFF\n" // Y-register + "ldi r29, 0x0A\n" // Y-register + "out 0x3E, r29\n" // SPH + "out 0x3D, r28\n" // SPL + "rjmp main" // Stack is all set up, start the main code + ::); } u8 _flashbuf[128]; u8 _inSync; u8 _ok; -extern volatile u8 _ejected; -extern volatile u16 _timeout; +u16 do_reset = 0; +volatile u16 _timeout; void Program(u8 ep, u16 page, u8 count) { - u8 write = page < 30*1024; // Don't write over firmware please + u8 write = page < 28*1024; // Don't write over bootloader please if (write) boot_page_erase(page); - - Recv(ep,_flashbuf,count); // Read while page is erasing - + + USB_Recv_block(ep,_flashbuf,count); // Read while page is erasing + if (!write) return; - + boot_spm_busy_wait(); // Wait until the memory is erased. - + count >>= 1; u16* p = (u16*)page; u16* b = (u16*)_flashbuf; for (u8 i = 0; i < count; i++) boot_page_fill(p++, b[i]); - + boot_page_write(page); boot_spm_busy_wait(); boot_rww_enable (); } - -int USBGetChar(); -#define getch USBGetChar - #define HW_VER 0x02 #define SW_MAJOR 0x01 #define SW_MINOR 0x10 @@ -104,136 +95,186 @@ const u8 _consts[] = 0x00, // }; +//int getch(void) +//{ +// u16 timeout; +// u8 c; +// for (timeout = 0; timeout; timeout--) +// { +// c = USB_Recv(CDC_RX); +// if (c != -1) +// return c; +// } +// return -1; +//} + + +void start_sketch() +{ + UDCON = 1; // Detatch USB + UDIEN = 0; + asm volatile ( // Reset vector to run firmware + "clr r30\n" + "clr r31\n" + "ijmp\n" + ::); +} -void USBInit(void); int main(void) __attribute__ ((naked)); - -// STK500v1 main loop, very similar to optiboot in protocol and implementation -int main() -{ +int main() +{ wdt_disable(); - TXLED0; - RXLED0; - LED0; BOARD_INIT(); - USBInit(); - + /* move interrupts to boot section: + * uses inline assembly because the procedure must be completed in four cycles. + * seems to fail if called before disabling WDT and calling BOARD_INIT() + */ + asm volatile ( + "ldi r16, 0x01\n" // (1< 2) + i = (i==0x18) ? 3 : 4; // 0x80:HW_VER,0x81:SW_MAJOR,0x82:SW_MINOR,0x18:3 or 0 + pgm = _consts + i + 3; + send = 1; + } + else if (STK_UNIVERSAL == cmd) + { + if (packet[0] == 0x30) + pgm = _consts + packet[2]; + send = 1; + } + else if (STK_READ_SIGN == cmd) + { + pgm = _consts; + send = 3; + } + else if (STK_LOAD_ADDRESS == cmd) + { + address = *((u16*)packet); // word address + address += address; + } + else if (STK_PROG_PAGE == cmd) + { + Program(CDC_RX, address, packet[1]); + } + else if (STK_READ_PAGE == cmd) + { + send = packet[1]; + pgm = (const u8*)address; + address += send; + } + + // Check sync + // if (Serial.available() > 0 && Serial.read() != ' ') + // break; + // if (USB_Available(CDC_RX) && USB_Recv(CDC_RX) != ' ') + + // u8 countdown = 10; + // while (!USB_Available(CDC_RX)) + // { + // if (countdown-- == 0) + // break; + // } + // u8 x = USB_Recv(CDC_RX); + // if (x != -1 && x != ' ') + // { + // L_LED_ON(); + // break; + // } + + // if (getch() != ' ') + // break; + + // while (!USB_Available(CDC_RX)) + // ; + // + // int x = USB_Recv(CDC_RX); + // if (x == -1) + // { + // UEINTX = 0x6B; + // break; + // } + // else if (x != ' ') + // { + //// UEINTX = 0x6B; + // break; + // } + + u16 countdown = 5000; + while (countdown-- > 10 && !USB_Available(CDC_RX)) + ; + int x = USB_Recv(CDC_RX); + if (x != -1 && x != ' ') break; + + USB_Send(CDC_TX, &_inSync, 1); + + if (send) + USB_Send(CDC_TX|TRANSFER_PGM, pgm, send); + + // Send ok + USB_Send(CDC_TX|TRANSFER_RELEASE, &_ok, 1); + + if ('Q' == cmd) + { + _delay_ms(100); + /* move interrupts to application section: + * uses inline assembly because the procedure must be completed in four cycles. + */ + asm volatile ( + "ldi r16, 0x01\n" // (1< 2) - i = (i == 0x18) ? 3 : 4; // 0x80:HW_VER,0x81:SW_MAJOR,0x82:SW_MINOR,0x18:3 or 0 - pgm = _consts + i + 3; - send = 1; - } - - else if (STK_UNIVERSAL == cmd) - { - if (packet[0] == 0x30) - pgm = _consts + packet[2]; // read signature - send = 1; - } - - // Read signature bytes - else if (STK_READ_SIGN == cmd) - { - pgm = _consts; - send = 3; - } - - else if (STK_LOAD_ADDRESS == cmd) - { - address = *((u16*)packet); // word addresses - address += address; - } - - else if (STK_PROG_PAGE == cmd) - { - Program(CDC_RX,address,packet[1]); - } - - else if (STK_READ_PAGE == cmd) - { - send = packet[1]; - pgm = (const u8*)address; - address += send; // not sure of this is required - } - - // Check sync - if (getch() != ' ') - break; - Transfer(CDC_TX,&_inSync,1); - - // Send result - if (send) - Transfer(CDC_TX|TRANSFER_PGM,pgm,send); // All from pgm memory - - // Send ok - Transfer(CDC_TX|TRANSFER_RELEASE,&_ok,1); - - if (cmd == 'Q') - break; } - _timeout = 500; // wait a moment before exiting the bootloader - may need to finish responding to 'Q' for example - _ejected = 1; } } - -// Nice breathing LED indicates we are in the firmware -u16 _pulse; -void LEDPulse() -{ - _pulse += 4; - u8 p = _pulse >> 9; - if (p > 63) - p = 127-p; - p += p; - if (((u8)_pulse) > p) - LED0; - else - LED1; -} - -void Reboot() -{ - TXLED0; // switch off the RX and TX LEDs before starting the user sketch - RXLED0; - UDCON = 1; // Detatch USB - UDIEN = 0; - asm volatile ( // Reset vector to run firmware - "clr r30\n" - "clr r31\n" - "ijmp\n" - ::); -} -- cgit v1.2.3-18-g5258