optiboot.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. /**********************************************************/
  2. /* Optiboot bootloader for Arduino */
  3. /* */
  4. /* http://optiboot.googlecode.com */
  5. /* */
  6. /* Arduino-maintained version : See README.TXT */
  7. /* http://code.google.com/p/arduino/ */
  8. /* It is the intent that changes not relevant to the */
  9. /* Arduino production envionment get moved from the */
  10. /* optiboot project to the arduino project in "lumps." */
  11. /* */
  12. /* Heavily optimised bootloader that is faster and */
  13. /* smaller than the Arduino standard bootloader */
  14. /* */
  15. /* Enhancements: */
  16. /* Fits in 512 bytes, saving 1.5K of code space */
  17. /* Background page erasing speeds up programming */
  18. /* Higher baud rate speeds up programming */
  19. /* Written almost entirely in C */
  20. /* Customisable timeout with accurate timeconstant */
  21. /* Optional virtual UART. No hardware UART required. */
  22. /* Optional virtual boot partition for devices without. */
  23. /* */
  24. /* What you lose: */
  25. /* Implements a skeleton STK500 protocol which is */
  26. /* missing several features including EEPROM */
  27. /* programming and non-page-aligned writes */
  28. /* High baud rate breaks compatibility with standard */
  29. /* Arduino flash settings */
  30. /* */
  31. /* Fully supported: */
  32. /* ATmega168 based devices (Diecimila etc) */
  33. /* ATmega328P based devices (Duemilanove etc) */
  34. /* */
  35. /* Beta test (believed working.) */
  36. /* ATmega8 based devices (Arduino legacy) */
  37. /* ATmega328 non-picopower devices */
  38. /* ATmega644P based devices (Sanguino) */
  39. /* ATmega1284P based devices */
  40. /* ATmega1280 based devices (Arduino Mega) */
  41. /* */
  42. /* Alpha test */
  43. /* ATmega32 */
  44. /* */
  45. /* Work in progress: */
  46. /* ATtiny84 based devices (Luminet) */
  47. /* */
  48. /* Does not support: */
  49. /* USB based devices (eg. Teensy, Leonardo) */
  50. /* */
  51. /* Assumptions: */
  52. /* The code makes several assumptions that reduce the */
  53. /* code size. They are all true after a hardware reset, */
  54. /* but may not be true if the bootloader is called by */
  55. /* other means or on other hardware. */
  56. /* No interrupts can occur */
  57. /* UART and Timer 1 are set to their reset state */
  58. /* SP points to RAMEND */
  59. /* */
  60. /* Code builds on code, libraries and optimisations from: */
  61. /* stk500boot.c by Jason P. Kyle */
  62. /* Arduino bootloader http://arduino.cc */
  63. /* Spiff's 1K bootloader http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml */
  64. /* avr-libc project http://nongnu.org/avr-libc */
  65. /* Adaboot http://www.ladyada.net/library/arduino/bootloader.html */
  66. /* AVR305 Atmel Application Note */
  67. /* */
  68. /* This program is free software; you can redistribute it */
  69. /* and/or modify it under the terms of the GNU General */
  70. /* Public License as published by the Free Software */
  71. /* Foundation; either version 2 of the License, or */
  72. /* (at your option) any later version. */
  73. /* */
  74. /* This program is distributed in the hope that it will */
  75. /* be useful, but WITHOUT ANY WARRANTY; without even the */
  76. /* implied warranty of MERCHANTABILITY or FITNESS FOR A */
  77. /* PARTICULAR PURPOSE. See the GNU General Public */
  78. /* License for more details. */
  79. /* */
  80. /* You should have received a copy of the GNU General */
  81. /* Public License along with this program; if not, write */
  82. /* to the Free Software Foundation, Inc., */
  83. /* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
  84. /* */
  85. /* Licence can be viewed at */
  86. /* http://www.fsf.org/licenses/gpl.txt */
  87. /* */
  88. /**********************************************************/
  89. /**********************************************************/
  90. /* */
  91. /* Optional defines: */
  92. /* */
  93. /**********************************************************/
  94. /* */
  95. /* BIG_BOOT: */
  96. /* Build a 1k bootloader, not 512 bytes. This turns on */
  97. /* extra functionality. */
  98. /* */
  99. /* BAUD_RATE: */
  100. /* Set bootloader baud rate. */
  101. /* */
  102. /* LUDICROUS_SPEED: */
  103. /* 230400 baud :-) */
  104. /* */
  105. /* SOFT_UART: */
  106. /* Use AVR305 soft-UART instead of hardware UART. */
  107. /* */
  108. /* LED_START_FLASHES: */
  109. /* Number of LED flashes on bootup. */
  110. /* */
  111. /* LED_DATA_FLASH: */
  112. /* Flash LED when transferring data. For boards without */
  113. /* TX or RX LEDs, or for people who like blinky lights. */
  114. /* */
  115. /* SUPPORT_EEPROM: */
  116. /* Support reading and writing from EEPROM. This is not */
  117. /* used by Arduino, so off by default. */
  118. /* */
  119. /* TIMEOUT_MS: */
  120. /* Bootloader timeout period, in milliseconds. */
  121. /* 500,1000,2000,4000,8000 supported. */
  122. /* */
  123. /* UART: */
  124. /* UART number (0..n) for devices with more than */
  125. /* one hardware uart (644P, 1284P, etc) */
  126. /* */
  127. /**********************************************************/
  128. /**********************************************************/
  129. /* Version Numbers! */
  130. /* */
  131. /* Arduino Optiboot now includes this Version number in */
  132. /* the source and object code. */
  133. /* */
  134. /* Version 3 was released as zip from the optiboot */
  135. /* repository and was distributed with Arduino 0022. */
  136. /* Version 4 starts with the arduino repository commit */
  137. /* that brought the arduino repository up-to-date with */
  138. /* the optiboot source tree changes since v3. */
  139. /* It would be good if versions implemented outside the */
  140. /* official repository used an out-of-seqeunce version */
  141. /* number (like 104.6 if based on based on 4.5) to */
  142. /* prevent collisions. */
  143. /* */
  144. /**********************************************************/
  145. /**********************************************************/
  146. /* Edit History: */
  147. /* */
  148. /* Jan 2013 */
  149. /* 4.6 WestfW/dkinzer: use autoincrement lpm for read */
  150. /* 4.6 WestfW/dkinzer: pass reset cause to app in R2 */
  151. /* Mar 2012 */
  152. /* 4.5 WestfW: add infrastructure for non-zero UARTS. */
  153. /* 4.5 WestfW: fix SIGNATURE_2 for m644 (bad in avr-libc) */
  154. /* Jan 2012: */
  155. /* 4.5 WestfW: fix NRWW value for m1284. */
  156. /* 4.4 WestfW: use attribute OS_main instead of naked for */
  157. /* main(). This allows optimizations that we */
  158. /* count on, which are prohibited in naked */
  159. /* functions due to PR42240. (keeps us less */
  160. /* than 512 bytes when compiler is gcc4.5 */
  161. /* (code from 4.3.2 remains the same.) */
  162. /* 4.4 WestfW and Maniacbug: Add m1284 support. This */
  163. /* does not change the 328 binary, so the */
  164. /* version number didn't change either. (?) */
  165. /* June 2011: */
  166. /* 4.4 WestfW: remove automatic soft_uart detect (didn't */
  167. /* know what it was doing or why.) Added a */
  168. /* check of the calculated BRG value instead. */
  169. /* Version stays 4.4; existing binaries are */
  170. /* not changed. */
  171. /* 4.4 WestfW: add initialization of address to keep */
  172. /* the compiler happy. Change SC'ed targets. */
  173. /* Return the SW version via READ PARAM */
  174. /* 4.3 WestfW: catch framing errors in getch(), so that */
  175. /* AVRISP works without HW kludges. */
  176. /* http://code.google.com/p/arduino/issues/detail?id=368n*/
  177. /* 4.2 WestfW: reduce code size, fix timeouts, change */
  178. /* verifySpace to use WDT instead of appstart */
  179. /* 4.1 WestfW: put version number in binary. */
  180. /**********************************************************/
  181. #define OPTIBOOT_MAJVER 4
  182. #define OPTIBOOT_MINVER 6
  183. #define MAKESTR(a) #a
  184. #define MAKEVER(a, b) MAKESTR(a*256+b)
  185. asm(" .section .version\n"
  186. "optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
  187. " .section .text\n");
  188. #include <inttypes.h>
  189. #include <avr/io.h>
  190. #include <avr/pgmspace.h>
  191. // <avr/boot.h> uses sts instructions, but this version uses out instructions
  192. // This saves cycles and program memory.
  193. #include "boot.h"
  194. // We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
  195. #include "pin_defs.h"
  196. #include "stk500.h"
  197. #ifndef LED_START_FLASHES
  198. #define LED_START_FLASHES 0
  199. #endif
  200. #ifdef LUDICROUS_SPEED
  201. #define BAUD_RATE 230400L
  202. #endif
  203. /* set the UART baud rate defaults */
  204. #ifndef BAUD_RATE
  205. #if F_CPU >= 8000000L
  206. #define BAUD_RATE 115200L // Highest rate Avrdude win32 will support
  207. #elsif F_CPU >= 1000000L
  208. #define BAUD_RATE 9600L // 19200 also supported, but with significant error
  209. #elsif F_CPU >= 128000L
  210. #define BAUD_RATE 4800L // Good for 128kHz internal RC
  211. #else
  212. #define BAUD_RATE 1200L // Good even at 32768Hz
  213. #endif
  214. #endif
  215. #ifndef UART
  216. #define UART 0
  217. #endif
  218. #if 0
  219. /* Switch in soft UART for hard baud rates */
  220. /*
  221. * I don't understand what this was supposed to accomplish, where the
  222. * constant "280" came from, or why automatically (and perhaps unexpectedly)
  223. * switching to a soft uart is a good thing, so I'm undoing this in favor
  224. * of a range check using the same calc used to config the BRG...
  225. */
  226. #if (F_CPU/BAUD_RATE) > 280 // > 57600 for 16MHz
  227. #ifndef SOFT_UART
  228. #define SOFT_UART
  229. #endif
  230. #endif
  231. #else // 0
  232. #if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
  233. #error Unachievable baud rate (too slow) BAUD_RATE
  234. #endif // baud rate slow check
  235. #if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
  236. #error Unachievable baud rate (too fast) BAUD_RATE
  237. #endif // baud rate fastn check
  238. #endif
  239. /* Watchdog settings */
  240. #define WATCHDOG_OFF (0)
  241. #define WATCHDOG_16MS (_BV(WDE))
  242. #define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE))
  243. #define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE))
  244. #define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
  245. #define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE))
  246. #define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
  247. #define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
  248. #define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
  249. #ifndef __AVR_ATmega8__
  250. #define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
  251. #define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
  252. #endif
  253. /* Function Prototypes */
  254. /* The main function is in init9, which removes the interrupt vector table */
  255. /* we don't need. It is also 'naked', which means the compiler does not */
  256. /* generate any entry or exit code itself. */
  257. int main(void) __attribute__ ((OS_main)) __attribute__ ((section (".init9")));
  258. void putch(char);
  259. uint8_t getch(void);
  260. static inline void getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */
  261. void verifySpace();
  262. static inline void flash_led(uint8_t);
  263. uint8_t getLen();
  264. static inline void watchdogReset();
  265. void watchdogConfig(uint8_t x);
  266. #ifdef SOFT_UART
  267. void uartDelay() __attribute__ ((naked));
  268. #endif
  269. void appStart(uint8_t rstFlags) __attribute__ ((naked));
  270. /*
  271. * NRWW memory
  272. * Addresses below NRWW (Non-Read-While-Write) can be programmed while
  273. * continuing to run code from flash, slightly speeding up programming
  274. * time. Beware that Atmel data sheets specify this as a WORD address,
  275. * while optiboot will be comparing against a 16-bit byte address. This
  276. * means that on a part with 128kB of memory, the upper part of the lower
  277. * 64k will get NRWW processing as well, even though it doesn't need it.
  278. * That's OK. In fact, you can disable the overlapping processing for
  279. * a part entirely by setting NRWWSTART to zero. This reduces code
  280. * space a bit, at the expense of being slightly slower, overall.
  281. *
  282. * RAMSTART should be self-explanatory. It's bigger on parts with a
  283. * lot of peripheral registers.
  284. */
  285. #if defined(__AVR_ATmega168__)
  286. #define RAMSTART (0x100)
  287. #define NRWWSTART (0x3800)
  288. #elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32__)
  289. #define RAMSTART (0x100)
  290. #define NRWWSTART (0x7000)
  291. #elif defined (__AVR_ATmega644P__)
  292. #define RAMSTART (0x100)
  293. #define NRWWSTART (0xE000)
  294. // correct for a bug in avr-libc
  295. #undef SIGNATURE_2
  296. #define SIGNATURE_2 0x0A
  297. #elif defined (__AVR_ATmega1284P__)
  298. #define RAMSTART (0x100)
  299. #define NRWWSTART (0xE000)
  300. #elif defined(__AVR_ATtiny84__)
  301. #define RAMSTART (0x100)
  302. #define NRWWSTART (0x0000)
  303. #elif defined(__AVR_ATmega1280__)
  304. #define RAMSTART (0x200)
  305. #define NRWWSTART (0xE000)
  306. #elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
  307. #define RAMSTART (0x100)
  308. #define NRWWSTART (0x1800)
  309. #endif
  310. /* C zero initialises all global variables. However, that requires */
  311. /* These definitions are NOT zero initialised, but that doesn't matter */
  312. /* This allows us to drop the zero init code, saving us memory */
  313. #define buff ((uint8_t*)(RAMSTART))
  314. #ifdef VIRTUAL_BOOT_PARTITION
  315. #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
  316. #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
  317. #endif
  318. /*
  319. * Handle devices with up to 4 uarts (eg m1280.) Rather inelegantly.
  320. * Note that mega8/m32 still needs special handling, because ubrr is handled
  321. * differently.
  322. */
  323. #if UART == 0
  324. # define UART_SRA UCSR0A
  325. # define UART_SRB UCSR0B
  326. # define UART_SRC UCSR0C
  327. # define UART_SRL UBRR0L
  328. # define UART_UDR UDR0
  329. #elif UART == 1
  330. # define UART_SRA UCSR1A
  331. # define UART_SRB UCSR1B
  332. # define UART_SRC UCSR1C
  333. # define UART_SRL UBRR1L
  334. # define UART_UDR UDR1
  335. #elif UART == 2
  336. # define UART_SRA UCSR2A
  337. # define UART_SRB UCSR2B
  338. # define UART_SRC UCSR2C
  339. # define UART_SRL UBRR2L
  340. # define UART_UDR UDR2
  341. #elif UART == 3
  342. # define UART_SRA UCSR3A
  343. # define UART_SRB UCSR3B
  344. # define UART_SRC UCSR3C
  345. # define UART_SRL UBRR3L
  346. # define UART_UDR UDR3
  347. #endif
  348. /* main program starts here */
  349. int main(void) {
  350. uint8_t ch;
  351. /*
  352. * Making these local and in registers prevents the need for initializing
  353. * them, and also saves space because code no longer stores to memory.
  354. * (initializing address keeps the compiler happy, but isn't really
  355. * necessary, and uses 4 bytes of flash.)
  356. */
  357. register uint16_t address = 0;
  358. register uint8_t length;
  359. // After the zero init loop, this is the first code to run.
  360. //
  361. // This code makes the following assumptions:
  362. // No interrupts will execute
  363. // SP points to RAMEND
  364. // r1 contains zero
  365. //
  366. // If not, uncomment the following instructions:
  367. // cli();
  368. asm volatile ("clr __zero_reg__");
  369. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  370. SP=RAMEND; // This is done by hardware reset
  371. #endif
  372. // Adaboot no-wait mod
  373. ch = MCUSR;
  374. MCUSR = 0;
  375. if (!(ch & _BV(EXTRF))) appStart(ch);
  376. #if LED_START_FLASHES > 0
  377. // Set up Timer 1 for timeout counter
  378. TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
  379. #endif
  380. #ifndef SOFT_UART
  381. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  382. UCSRA = _BV(U2X); //Double speed mode USART
  383. UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
  384. UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
  385. UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
  386. #else
  387. UART_SRA = _BV(U2X0); //Double speed mode USART0
  388. UART_SRB = _BV(RXEN0) | _BV(TXEN0);
  389. UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
  390. UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
  391. #endif
  392. #endif
  393. // Set up watchdog to trigger after 500ms
  394. watchdogConfig(WATCHDOG_1S);
  395. /* Set LED pin as output */
  396. LED_DDR |= _BV(LED);
  397. #ifdef SOFT_UART
  398. /* Set TX pin as output */
  399. UART_DDR |= _BV(UART_TX_BIT);
  400. #endif
  401. #if LED_START_FLASHES > 0
  402. /* Flash onboard LED to signal entering of bootloader */
  403. flash_led(LED_START_FLASHES * 2);
  404. #endif
  405. /* Forever loop */
  406. for (;;) {
  407. /* get character from UART */
  408. ch = getch();
  409. if(ch == STK_GET_PARAMETER) {
  410. unsigned char which = getch();
  411. verifySpace();
  412. if (which == 0x82) {
  413. /*
  414. * Send optiboot version as "minor SW version"
  415. */
  416. putch(OPTIBOOT_MINVER);
  417. } else if (which == 0x81) {
  418. putch(OPTIBOOT_MAJVER);
  419. } else {
  420. /*
  421. * GET PARAMETER returns a generic 0x03 reply for
  422. * other parameters - enough to keep Avrdude happy
  423. */
  424. putch(0x03);
  425. }
  426. }
  427. else if(ch == STK_SET_DEVICE) {
  428. // SET DEVICE is ignored
  429. getNch(20);
  430. }
  431. else if(ch == STK_SET_DEVICE_EXT) {
  432. // SET DEVICE EXT is ignored
  433. getNch(5);
  434. }
  435. else if(ch == STK_LOAD_ADDRESS) {
  436. // LOAD ADDRESS
  437. uint16_t newAddress;
  438. newAddress = getch();
  439. newAddress = (newAddress & 0xff) | (getch() << 8);
  440. #ifdef RAMPZ
  441. // Transfer top bit to RAMPZ
  442. RAMPZ = (newAddress & 0x8000) ? 1 : 0;
  443. #endif
  444. newAddress += newAddress; // Convert from word address to byte address
  445. address = newAddress;
  446. verifySpace();
  447. }
  448. else if(ch == STK_UNIVERSAL) {
  449. // UNIVERSAL command is ignored
  450. getNch(4);
  451. putch(0x00);
  452. }
  453. /* Write memory, length is big endian and is in bytes */
  454. else if(ch == STK_PROG_PAGE) {
  455. // PROGRAM PAGE - we support flash programming only, not EEPROM
  456. uint8_t *bufPtr;
  457. uint16_t addrPtr;
  458. getch(); /* getlen() */
  459. length = getch();
  460. getch();
  461. // If we are in RWW section, immediately start page erase
  462. if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
  463. // While that is going on, read in page contents
  464. bufPtr = buff;
  465. do *bufPtr++ = getch();
  466. while (--length);
  467. // If we are in NRWW section, page erase has to be delayed until now.
  468. // Todo: Take RAMPZ into account (not doing so just means that we will
  469. // treat the top of both "pages" of flash as NRWW, for a slight speed
  470. // decrease, so fixing this is not urgent.)
  471. if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
  472. // Read command terminator, start reply
  473. verifySpace();
  474. // If only a partial page is to be programmed, the erase might not be complete.
  475. // So check that here
  476. boot_spm_busy_wait();
  477. #ifdef VIRTUAL_BOOT_PARTITION
  478. if ((uint16_t)(void*)address == 0) {
  479. // This is the reset vector page. We need to live-patch the code so the
  480. // bootloader runs.
  481. //
  482. // Move RESET vector to WDT vector
  483. uint16_t vect = buff[0] | (buff[1]<<8);
  484. rstVect = vect;
  485. wdtVect = buff[8] | (buff[9]<<8);
  486. vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
  487. buff[8] = vect & 0xff;
  488. buff[9] = vect >> 8;
  489. // Add jump to bootloader at RESET vector
  490. buff[0] = 0x7f;
  491. buff[1] = 0xce; // rjmp 0x1d00 instruction
  492. }
  493. #endif
  494. // Copy buffer into programming buffer
  495. bufPtr = buff;
  496. addrPtr = (uint16_t)(void*)address;
  497. ch = SPM_PAGESIZE / 2;
  498. do {
  499. uint16_t a;
  500. a = *bufPtr++;
  501. a |= (*bufPtr++) << 8;
  502. __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
  503. addrPtr += 2;
  504. } while (--ch);
  505. // Write from programming buffer
  506. __boot_page_write_short((uint16_t)(void*)address);
  507. boot_spm_busy_wait();
  508. #if defined(RWWSRE)
  509. // Reenable read access to flash
  510. boot_rww_enable();
  511. #endif
  512. }
  513. /* Read memory block mode, length is big endian. */
  514. else if(ch == STK_READ_PAGE) {
  515. // READ PAGE - we only read flash
  516. getch(); /* getlen() */
  517. length = getch();
  518. getch();
  519. verifySpace();
  520. do {
  521. #ifdef VIRTUAL_BOOT_PARTITION
  522. // Undo vector patch in bottom page so verify passes
  523. if (address == 0) ch=rstVect & 0xff;
  524. else if (address == 1) ch=rstVect >> 8;
  525. else if (address == 8) ch=wdtVect & 0xff;
  526. else if (address == 9) ch=wdtVect >> 8;
  527. else ch = pgm_read_byte_near(address);
  528. address++;
  529. #elif defined(RAMPZ)
  530. // Since RAMPZ should already be set, we need to use EPLM directly.
  531. // Also, we can use the autoincrement version of lpm to update "address"
  532. // do putch(pgm_read_byte_near(address++));
  533. // while (--length);
  534. // read a Flash and increment the address (may increment RAMPZ)
  535. __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
  536. #else
  537. // read a Flash byte and increment the address
  538. __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
  539. #endif
  540. putch(ch);
  541. } while (--length);
  542. }
  543. /* Get device signature bytes */
  544. else if(ch == STK_READ_SIGN) {
  545. // READ SIGN - return what Avrdude wants to hear
  546. verifySpace();
  547. putch(SIGNATURE_0);
  548. putch(SIGNATURE_1);
  549. putch(SIGNATURE_2);
  550. }
  551. else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
  552. // Adaboot no-wait mod
  553. watchdogConfig(WATCHDOG_16MS);
  554. verifySpace();
  555. }
  556. else {
  557. // This covers the response to commands like STK_ENTER_PROGMODE
  558. verifySpace();
  559. }
  560. putch(STK_OK);
  561. }
  562. }
  563. void putch(char ch) {
  564. #ifndef SOFT_UART
  565. while (!(UART_SRA & _BV(UDRE0)));
  566. UART_UDR = ch;
  567. #else
  568. __asm__ __volatile__ (
  569. " com %[ch]\n" // ones complement, carry set
  570. " sec\n"
  571. "1: brcc 2f\n"
  572. " cbi %[uartPort],%[uartBit]\n"
  573. " rjmp 3f\n"
  574. "2: sbi %[uartPort],%[uartBit]\n"
  575. " nop\n"
  576. "3: rcall uartDelay\n"
  577. " rcall uartDelay\n"
  578. " lsr %[ch]\n"
  579. " dec %[bitcnt]\n"
  580. " brne 1b\n"
  581. :
  582. :
  583. [bitcnt] "d" (10),
  584. [ch] "r" (ch),
  585. [uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
  586. [uartBit] "I" (UART_TX_BIT)
  587. :
  588. "r25"
  589. );
  590. #endif
  591. }
  592. uint8_t getch(void) {
  593. uint8_t ch;
  594. #ifdef LED_DATA_FLASH
  595. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  596. LED_PORT ^= _BV(LED);
  597. #else
  598. LED_PIN |= _BV(LED);
  599. #endif
  600. #endif
  601. #ifdef SOFT_UART
  602. __asm__ __volatile__ (
  603. "1: sbic %[uartPin],%[uartBit]\n" // Wait for start edge
  604. " rjmp 1b\n"
  605. " rcall uartDelay\n" // Get to middle of start bit
  606. "2: rcall uartDelay\n" // Wait 1 bit period
  607. " rcall uartDelay\n" // Wait 1 bit period
  608. " clc\n"
  609. " sbic %[uartPin],%[uartBit]\n"
  610. " sec\n"
  611. " dec %[bitCnt]\n"
  612. " breq 3f\n"
  613. " ror %[ch]\n"
  614. " rjmp 2b\n"
  615. "3:\n"
  616. :
  617. [ch] "=r" (ch)
  618. :
  619. [bitCnt] "d" (9),
  620. [uartPin] "I" (_SFR_IO_ADDR(UART_PIN)),
  621. [uartBit] "I" (UART_RX_BIT)
  622. :
  623. "r25"
  624. );
  625. #else
  626. while(!(UART_SRA & _BV(RXC0)))
  627. ;
  628. if (!(UART_SRA & _BV(FE0))) {
  629. /*
  630. * A Framing Error indicates (probably) that something is talking
  631. * to us at the wrong bit rate. Assume that this is because it
  632. * expects to be talking to the application, and DON'T reset the
  633. * watchdog. This should cause the bootloader to abort and run
  634. * the application "soon", if it keeps happening. (Note that we
  635. * don't care that an invalid char is returned...)
  636. */
  637. watchdogReset();
  638. }
  639. ch = UART_UDR;
  640. #endif
  641. #ifdef LED_DATA_FLASH
  642. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  643. LED_PORT ^= _BV(LED);
  644. #else
  645. LED_PIN |= _BV(LED);
  646. #endif
  647. #endif
  648. return ch;
  649. }
  650. #ifdef SOFT_UART
  651. // AVR305 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6)
  652. // Adding 3 to numerator simulates nearest rounding for more accurate baud rates
  653. #define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6)
  654. #if UART_B_VALUE > 255
  655. #error Baud rate too slow for soft UART
  656. #endif
  657. void uartDelay() {
  658. __asm__ __volatile__ (
  659. "ldi r25,%[count]\n"
  660. "1:dec r25\n"
  661. "brne 1b\n"
  662. "ret\n"
  663. ::[count] "M" (UART_B_VALUE)
  664. );
  665. }
  666. #endif
  667. void getNch(uint8_t count) {
  668. do getch(); while (--count);
  669. verifySpace();
  670. }
  671. void verifySpace() {
  672. if (getch() != CRC_EOP) {
  673. watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
  674. while (1) // and busy-loop so that WD causes
  675. ; // a reset and app start.
  676. }
  677. putch(STK_INSYNC);
  678. }
  679. #if LED_START_FLASHES > 0
  680. void flash_led(uint8_t count) {
  681. do {
  682. TCNT1 = -(F_CPU/(1024*16));
  683. TIFR1 = _BV(TOV1);
  684. while(!(TIFR1 & _BV(TOV1)));
  685. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  686. LED_PORT ^= _BV(LED);
  687. #else
  688. LED_PIN |= _BV(LED);
  689. #endif
  690. watchdogReset();
  691. } while (--count);
  692. }
  693. #endif
  694. // Watchdog functions. These are only safe with interrupts turned off.
  695. void watchdogReset() {
  696. __asm__ __volatile__ (
  697. "wdr\n"
  698. );
  699. }
  700. void watchdogConfig(uint8_t x) {
  701. WDTCSR = _BV(WDCE) | _BV(WDE);
  702. WDTCSR = x;
  703. }
  704. void appStart(uint8_t rstFlags) {
  705. // save the reset flags in the designated register
  706. // This can be saved in a main program by putting code in .init0 (which
  707. // executes before normal c init code) to save R2 to a global variable.
  708. __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
  709. watchdogConfig(WATCHDOG_OFF);
  710. __asm__ __volatile__ (
  711. #ifdef VIRTUAL_BOOT_PARTITION
  712. // Jump to WDT vector
  713. "ldi r30,4\n"
  714. "clr r31\n"
  715. #else
  716. // Jump to RST vector
  717. "clr r30\n"
  718. "clr r31\n"
  719. #endif
  720. "ijmp\n"
  721. );
  722. }