1
0

optiboot.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692
  1. #define FUNC_READ 1
  2. #define FUNC_WRITE 1
  3. /**********************************************************/
  4. /* Optiboot bootloader for Arduino */
  5. /* */
  6. /* http://optiboot.googlecode.com */
  7. /* */
  8. /* Arduino-maintained version : See README.TXT */
  9. /* http://code.google.com/p/arduino/ */
  10. /* It is the intent that changes not relevant to the */
  11. /* Arduino production environment get moved from the */
  12. /* optiboot project to the arduino project in "lumps." */
  13. /* */
  14. /* Heavily optimised bootloader that is faster and */
  15. /* smaller than the Arduino standard bootloader */
  16. /* */
  17. /* Enhancements: */
  18. /* Fits in 512 bytes, saving 1.5K of code space */
  19. /* Higher baud rate speeds up programming */
  20. /* Written almost entirely in C */
  21. /* Customisable timeout with accurate timeconstant */
  22. /* Optional virtual UART. No hardware UART required. */
  23. /* Optional virtual boot partition for devices without. */
  24. /* */
  25. /* What you lose: */
  26. /* Implements a skeleton STK500 protocol which is */
  27. /* missing several features including EEPROM */
  28. /* programming and non-page-aligned writes */
  29. /* High baud rate breaks compatibility with standard */
  30. /* Arduino flash settings */
  31. /* */
  32. /* Supported Devices: */
  33. /* With the merges of Spence Konde's ATTinyCore */
  34. /* https://github.com/SpenceKonde/ATTinyCore */
  35. /* and MCUDude's MightyCore, MiniCore, MegaCore, etc */
  36. /* https://github.com/MCUdude */
  37. /* the number of supported chips and configurations */
  38. /* has become quite large. Try "make help" for a list */
  39. /* Not all chips have received the same amount of */
  40. /* overall attention. Some version may have bugs. */
  41. /* */
  42. /* Does not support: */
  43. /* USB based devices (eg. Teensy, Leonardo) */
  44. /* */
  45. /* Assumptions: */
  46. /* The code makes several assumptions that reduce the */
  47. /* code size. They are all true after a hardware reset, */
  48. /* but may not be true if the bootloader is called by */
  49. /* other means or on other hardware. */
  50. /* No interrupts can occur */
  51. /* UART and Timer 1 are set to their reset state */
  52. /* SP points to RAMEND */
  53. /* */
  54. /* Code builds on code, libraries and optimisations from: */
  55. /* stk500boot.c by Jason P. Kyle */
  56. /* Arduino bootloader http://arduino.cc */
  57. /* Spiff's 1K bootloader http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml */
  58. /* avr-libc project http://nongnu.org/avr-libc */
  59. /* Adaboot http://www.ladyada.net/library/arduino/bootloader.html */
  60. /* AVR305 Atmel Application Note */
  61. /* */
  62. /* Copyright 2013-2021 by Bill Westfield. */
  63. /* Copyright 2010 by Peter Knight. */
  64. /* Note that many others have made major contributions! */
  65. /* */
  66. /* This program is free software; you can redistribute it */
  67. /* and/or modify it under the terms of the GNU General */
  68. /* Public License as published by the Free Software */
  69. /* Foundation; either version 2 of the License, or */
  70. /* (at your option) any later version. */
  71. /* */
  72. /* This program is distributed in the hope that it will */
  73. /* be useful, but WITHOUT ANY WARRANTY; without even the */
  74. /* implied warranty of MERCHANTABILITY or FITNESS FOR A */
  75. /* PARTICULAR PURPOSE. See the GNU General Public */
  76. /* License for more details. */
  77. /* */
  78. /* You should have received a copy of the GNU General */
  79. /* Public License along with this program; if not, write */
  80. /* to the Free Software Foundation, Inc., */
  81. /* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
  82. /* */
  83. /* Licence can be viewed at */
  84. /* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */
  85. /* */
  86. /**********************************************************/
  87. /**********************************************************/
  88. /* */
  89. /* Optional defines: */
  90. /* */
  91. /**********************************************************/
  92. /* */
  93. /* BIGBOOT: */
  94. /* Build a 1k bootloader, not 512 bytes. This turns on */
  95. /* extra functionality; notably EEPROM */
  96. /* */
  97. /* NO_APP_SPM: */
  98. /* omit the code that allows applications to "call" the */
  99. /* bootloader to perform SPM operations. */
  100. /* */
  101. /* SUPPORT_EEPROM: */
  102. /* Support reading and writing from EEPROM. This is not */
  103. /* used by Arduino, so off by default. */
  104. /* */
  105. /* WDTTIME: */
  106. /* Bootloader timeout period, in seconds. */
  107. /* 1 and 2 seconds are available on all chips */
  108. /* 4 and 8 are supported on most */
  109. /* */
  110. /* NO_START_APP_ON_POR: */
  111. /* If NO_START_APP_ON_POR is set, the bootloader will */
  112. /* also run on power-on */
  113. /* */
  114. /* START_APP_ON_EXTR: */
  115. /* If START_APP_ON_EXTR is set, the bootloader will not */
  116. /* run in the event of an external reset. */
  117. /* */
  118. /* If both are set, the bootloader will only run if the */
  119. /* app jumps directly to it. */
  120. /* */
  121. /* ---------- Comm features */
  122. /* UART: */
  123. /* UART number (0..n) for devices with more than */
  124. /* one hardware uart (644P, 1284P, etc) */
  125. /* */
  126. /* BAUD_RATE: */
  127. /* Set bootloader baud rate. */
  128. /* */
  129. /* SINGLESPEED: */
  130. /* do not use "U2X" mode for UART initialization. This */
  131. /* can be useful for some bit rates. */
  132. /* */
  133. /* SOFT_UART: */
  134. /* Use AVR305 soft-UART instead of hardware UART. */
  135. /* */
  136. /* RS485: */
  137. /* Either a pin (ex: "B5") or a pin followed by _INV */
  138. /* (ex: "B5_INV") which indicates inverted polarity. */
  139. /* This pin will be held low while transmitting in order */
  140. /* to control the direction pin of an RS485 tranciever */
  141. /* (RS485 support by Vladimir Dronnikov (github.com/dvv) */
  142. /* as used in github.com/SodaqMoja/optiboot ) */
  143. /* */
  144. /* ---------- LED behavior */
  145. /* LED: */
  146. /* Which pin to use for the LED flashs. This is a pin */
  147. /* name like "B5" */
  148. /* */
  149. /* LED_START_FLASHES: */
  150. /* Number of LED flashes on bootup. */
  151. /* */
  152. /* LED_DATA_FLASH: */
  153. /* Flash LED when transferring data. For boards without */
  154. /* TX or RX LEDs, or for people who like blinky lights. */
  155. /* */
  156. /* LED_START_ON: */
  157. /* Instead of blinking, turn the LED on when we start, */
  158. /* and off when it exits. Slightly smaller code. */
  159. /* */
  160. /**********************************************************/
  161. /*
  162. * default values.
  163. */
  164. #if !defined(BIGBOOT)
  165. # define BIGBOOT 0
  166. #endif
  167. #if !defined(SUPPORT_EEPROM)
  168. # define SUPPORT_EEPROM 0
  169. #endif
  170. #if !defined(APP_NOSPM)
  171. # define APP_NOSPM 0
  172. #endif
  173. #if !defined(START_APP_ON_EXTR)
  174. # define START_APP_ON_EXTR 0
  175. #endif
  176. #if !defined(NO_START_APP_ON_POR)
  177. # define NO_START_APP_ON_POR 0
  178. #endif
  179. /* UART options */
  180. #if !defined(SOFT_UART)
  181. # define SOFT_UART 0
  182. #endif
  183. #if !defined(UART)
  184. #define UART 0
  185. #endif
  186. #if !defined(SINGLESPEED)
  187. #define SINGLESPEED 0
  188. #endif
  189. /* LED Options */
  190. #if !defined(LED_START_FLASHES)
  191. #define LED_START_FLASHES 0
  192. #endif
  193. #if !defined(LED_DATA_FLASH)
  194. # define LED_DATA_FLASH 0
  195. #endif
  196. #if !defined(LED_START_ON)
  197. # define LED_START_ON 0
  198. #endif
  199. /**********************************************************/
  200. /* Version Numbers! */
  201. /* */
  202. /* Arduino Optiboot now includes this Version number in */
  203. /* the source and object code. */
  204. /* */
  205. /* Version 3 was released as zip from the optiboot */
  206. /* repository and was distributed with Arduino 0022. */
  207. /* Version 4 starts with the arduino repository commit */
  208. /* that brought the arduino repository up-to-date with */
  209. /* the optiboot source tree changes since v3. */
  210. /* Version 5 was created at the time of the new Makefile */
  211. /* structure (Mar, 2013), even though no binaries changed*/
  212. /* Version 6 added EEPROM support, including causing an */
  213. /* error when trying to write eeprom with versions that */
  214. /* didn't have the code there. Makefiles were further */
  215. /* restructured. Overlapping SPM/download removed. */
  216. /* Version 7 straightened out the MCUSR and RESET */
  217. /* handling, did MORE Makefile mods. EEPROM support now */
  218. /* fits in 512 bytes, if you turn off LED Blinking. */
  219. /* Various bigboot and virboot targets were fixed. */
  220. /* Version 8.0 adds the do_spm code callable from Apps. */
  221. /* */
  222. /* It would be good if versions implemented outside the */
  223. /* official repository used an out-of-seqeunce version */
  224. /* number (like 104.6 if based on based on 4.5) to */
  225. /* prevent collisions. The CUSTOM_VERSION=n option */
  226. /* adds n to the high version to facilitate this. */
  227. /* */
  228. /**********************************************************/
  229. /**********************************************************/
  230. /* Edit History: */
  231. /* */
  232. /* Oct 2021 */
  233. /* 8.3 WestfW add section-start determination code to */
  234. /* the C source. In theory, this causes no changes */
  235. /* to the binary, but it's "risky", so ... bump. */
  236. /* Aug 2019 */
  237. /* 8.1 WestfW Fix bug in calculation of Vboot offset */
  238. /* Sep 2018 */
  239. /* 8.0 WestfW (and Majekw and MCUDude) */
  240. /* Include do_spm routine callable from the app */
  241. /* at BOOTSTART+2, controllable with compile option */
  242. /* July 2018 */
  243. /* 7.0 WestfW (with much input from Others) */
  244. /* Fix MCUSR treatement as per much discussion, */
  245. /* Patches by MarkG55, majekw. Preserve value */
  246. /* for the application, as much as possible. */
  247. /* see https://github.com/Optiboot/optiboot/issues/97 */
  248. /* Optimize a bit by implementing a union for the */
  249. /* various 16bit address values used (based on */
  250. /* observation by "aweatherguy", but different.) */
  251. /* Slightly optimize math in VIRTUAL_BOOT code */
  252. /* Add some virboot targets, fix some fuses. */
  253. /* Implement LED_START_ON; less code than flashes */
  254. /* Aug 2014 */
  255. /* 6.2 WestfW: make size of length variables dependent */
  256. /* on the SPM_PAGESIZE. This saves space */
  257. /* on the chips where it's most important. */
  258. /* 6.1 WestfW: Fix OPTIBOOT_CUSTOMVER (send it!) */
  259. /* Make no-wait mod less picky about */
  260. /* skipping the bootloader. */
  261. /* Remove some dead code */
  262. /* Jun 2014 */
  263. /* 6.0 WestfW: Modularize memory read/write functions */
  264. /* Remove serial/flash overlap */
  265. /* (and all references to NRWWSTART/etc) */
  266. /* Correctly handle pagesize > 255bytes */
  267. /* Add EEPROM support in BIGBOOT (1284) */
  268. /* EEPROM write on small chips now causes err */
  269. /* Split Makefile into smaller pieces */
  270. /* Add Wicked devices Wildfire */
  271. /* Move UART=n conditionals into pin_defs.h */
  272. /* Remove LUDICOUS_SPEED option */
  273. /* Replace inline assembler for .version */
  274. /* and add OPTIBOOT_CUSTOMVER for user code */
  275. /* Fix LED value for Bobuino (Makefile) */
  276. /* Make all functions explicitly inline or */
  277. /* noinline, so we fit when using gcc4.8 */
  278. /* Change optimization options for gcc4.8 */
  279. /* Make ENV=arduino work in 1.5.x trees. */
  280. /* May 2014 */
  281. /* 5.0 WestfW: Add support for 1Mbps UART */
  282. /* Mar 2013 */
  283. /* 5.0 WestfW: Major Makefile restructuring. */
  284. /* See Makefile and pin_defs.h */
  285. /* (no binary changes) */
  286. /* */
  287. /* 4.6 WestfW/Pito: Add ATmega32 support */
  288. /* 4.6 WestfW/radoni: Don't set LED_PIN as an output if */
  289. /* not used. (LED_START_FLASHES = 0) */
  290. /* Jan 2013 */
  291. /* 4.6 WestfW/dkinzer: use autoincrement lpm for read */
  292. /* 4.6 WestfW/dkinzer: pass reset cause to app in R2 */
  293. /* Mar 2012 */
  294. /* 4.5 WestfW: add infrastructure for non-zero UARTS. */
  295. /* 4.5 WestfW: fix SIGNATURE_2 for m644 (bad in avr-libc) */
  296. /* Jan 2012: */
  297. /* 4.5 WestfW: fix NRWW value for m1284. */
  298. /* 4.4 WestfW: use attribute OS_main instead of naked for */
  299. /* main(). This allows optimizations that we */
  300. /* count on, which are prohibited in naked */
  301. /* functions due to PR42240. (keeps us less */
  302. /* than 512 bytes when compiler is gcc4.5 */
  303. /* (code from 4.3.2 remains the same.) */
  304. /* 4.4 WestfW and Maniacbug: Add m1284 support. This */
  305. /* does not change the 328 binary, so the */
  306. /* version number didn't change either. (?) */
  307. /* June 2011: */
  308. /* 4.4 WestfW: remove automatic soft_uart detect (didn't */
  309. /* know what it was doing or why.) Added a */
  310. /* check of the calculated BRG value instead. */
  311. /* Version stays 4.4; existing binaries are */
  312. /* not changed. */
  313. /* 4.4 WestfW: add initialization of address to keep */
  314. /* the compiler happy. Change SC'ed targets. */
  315. /* Return the SW version via READ PARAM */
  316. /* 4.3 WestfW: catch framing errors in getch(), so that */
  317. /* AVRISP works without HW kludges. */
  318. /* http://code.google.com/p/arduino/issues/detail?id=368n*/
  319. /* 4.2 WestfW: reduce code size, fix timeouts, change */
  320. /* verifySpace to use WDT instead of appstart */
  321. /* 4.1 WestfW: put version number in binary. */
  322. /**********************************************************/
  323. #define OPTIBOOT_MAJVER 8
  324. #define OPTIBOOT_MINVER 3
  325. /*
  326. * OPTIBOOT_CUSTOMVER should be defined (by the makefile) for custom edits
  327. * of optiboot. That way you don't wind up with very different code that
  328. * matches the version number of a "released" optiboot.
  329. */
  330. #if !defined(OPTIBOOT_CUSTOMVER)
  331. #define OPTIBOOT_CUSTOMVER 0
  332. #endif
  333. unsigned const int __attribute__((section(".version")))
  334. optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER;
  335. #define __AVR_LIBC_DEPRECATED_ENABLE__ 1 // don't poison MCUSR on some chips
  336. #include <inttypes.h>
  337. #include <avr/io.h>
  338. #include <avr/pgmspace.h>
  339. #include <avr/eeprom.h>
  340. /*
  341. * optiboot uses several "address" variables that are sometimes byte pointers,
  342. * sometimes word pointers. sometimes 16bit quantities, and sometimes built
  343. * up from 8bit input characters. avr-gcc is not great at optimizing the
  344. * assembly of larger words from bytes, but we can use the usual union to
  345. * do this manually. Expanding it a little, we can also get rid of casts.
  346. */
  347. typedef union {
  348. uint8_t *bptr;
  349. uint16_t *wptr;
  350. uint16_t word;
  351. uint8_t bytes[2];
  352. } addr16_t;
  353. /*
  354. * Note that we use a replacement of "boot.h"
  355. * <avr/boot.h> uses sts instructions, but this version uses out instructions
  356. * This saves cycles and program memory, if possible.
  357. * boot_opt.h pulls in the standard boot.h for the odd target (?)
  358. */
  359. #include "boot_opt.h"
  360. // We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
  361. /*
  362. * pin_defs.h
  363. * This contains most of the rather ugly defines that implement our
  364. * ability to use UART=n and LED=D3, and some avr family bit name differences.
  365. */
  366. #include "pin_defs.h"
  367. /*
  368. * stk500.h contains the constant definitions for the stk500v1 comm protocol
  369. */
  370. #include "stk500.h"
  371. /* set the UART baud rate defaults */
  372. #ifndef BAUD_RATE
  373. #if F_CPU >= 8000000L
  374. #define BAUD_RATE 115200L // Highest rate Avrdude win32 will support
  375. #elif F_CPU >= 1000000L
  376. #define BAUD_RATE 9600L // 19200 also supported, but with significant error
  377. #elif F_CPU >= 128000L
  378. #define BAUD_RATE 4800L // Good for 128kHz internal RC
  379. #else
  380. #define BAUD_RATE 1200L // Good even at 32768Hz
  381. #endif
  382. #endif
  383. #if (SOFT_UART == 0)
  384. #if SINGLESPEED
  385. /* Single speed option */
  386. #define BAUD_SETTING (( (F_CPU + BAUD_RATE * 8L) / ((BAUD_RATE * 16L))) - 1 )
  387. #define BAUD_ACTUAL (F_CPU/(16 * ((BAUD_SETTING)+1)))
  388. #else
  389. /* Normal U2X usage */
  390. #define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 )
  391. #define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1)))
  392. #endif
  393. #if BAUD_ACTUAL <= BAUD_RATE
  394. #define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE)
  395. #if BAUD_ERROR >= 5
  396. #error BAUD_RATE off by greater than -5%
  397. #elif BAUD_ERROR >= 2 && !defined(PRODUCTION)
  398. #warning BAUD_RATE off by greater than -2%
  399. #endif
  400. #else
  401. #define BAUD_ERROR (( 100*(BAUD_ACTUAL - BAUD_RATE) ) / BAUD_RATE)
  402. #if BAUD_ERROR >= 5
  403. #error BAUD_RATE off by greater than 5%
  404. #elif BAUD_ERROR >= 2 && !defined(PRODUCTION)
  405. #warning BAUD_RATE off by greater than 2%
  406. #endif
  407. #endif
  408. #if BAUD_SETTING > 250
  409. #error Unachievable baud rate (too slow) BAUD_RATE
  410. #endif // baud rate slow check
  411. #if (BAUD_SETTING - 1) < 3
  412. #if BAUD_ERROR != 0 // permit high bitrates (ie 1Mbps@16MHz) if error is zero
  413. #error Unachievable baud rate (too fast) BAUD_RATE
  414. #endif
  415. #endif // baud rate fast check
  416. #endif // SOFT_UART
  417. /* Watchdog settings */
  418. #define WATCHDOG_OFF (0)
  419. #define WATCHDOG_16MS (_BV(WDE))
  420. #define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE))
  421. #define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE))
  422. #define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
  423. #define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE))
  424. #define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
  425. #define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
  426. #define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
  427. #ifdef WDP3
  428. #define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
  429. #define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
  430. #endif
  431. /*
  432. * Watchdog timeout translations from human readable to config vals
  433. */
  434. #ifndef WDTTIME
  435. # define WDTPERIOD WATCHDOG_1S // 1 second default
  436. #elif WDTTIME == 1
  437. # define WDTPERIOD WATCHDOG_1S // 1 second
  438. #elif WDTTIME == 2
  439. # define WDTPERIOD WATCHDOG_2S // 2 seconds
  440. #elif defined(WDP3) && (WDTTIME == 4)
  441. # define WDTPERIOD WATCHDOG_4S // 4 seconds
  442. #elif defined(WDP3) && (WDTTIME == 8)
  443. # define WDTPERIOD WATCHDOG_8S // 8 seconds
  444. #else
  445. #error Invalid TIMEOUT
  446. #endif
  447. /*
  448. * We can never load flash with more than 1 page at a time, so we can save
  449. * some code space on parts with smaller pagesize by using a smaller int.
  450. */
  451. #if SPM_PAGESIZE > 255
  452. typedef uint16_t pagelen_t ;
  453. #define GETLENGTH(len) len = getch()<<8; len |= getch()
  454. #else
  455. typedef uint8_t pagelen_t;
  456. #define GETLENGTH(len) (void) getch() /* skip high byte */; len = getch()
  457. #endif
  458. /* Function Prototypes
  459. * The main() function is in init9, which removes the interrupt vector table
  460. * we don't need. It is also 'OS_main', which means the compiler does not
  461. * generate any entry or exit code itself (but unlike 'naked', it doesn't
  462. * suppress some compile-time options we want.)
  463. */
  464. void pre_main(void) __attribute__ ((naked)) __attribute__ ((section (".init8")));
  465. int main(void) __attribute__ ((OS_main)) __attribute__ ((section (".init9"))) __attribute__((used));
  466. void __attribute__((noinline)) __attribute__((leaf)) putch(char);
  467. uint8_t __attribute__((noinline)) __attribute__((leaf)) getch(void) ;
  468. void __attribute__((noinline)) verifySpace();
  469. void __attribute__((noinline)) watchdogConfig(uint8_t x);
  470. static void getNch(uint8_t);
  471. #if LED_START_FLASHES > 0
  472. static inline void flash_led(uint8_t);
  473. #endif
  474. static inline void watchdogReset();
  475. static inline void writebuffer(int8_t memtype, addr16_t mybuff,
  476. addr16_t address, pagelen_t len);
  477. static inline void read_mem(uint8_t memtype,
  478. addr16_t, pagelen_t len);
  479. #if SOFT_UART
  480. void uartDelay() __attribute__ ((naked));
  481. #endif
  482. /*
  483. * RAMSTART should be self-explanatory. It's bigger on parts with a
  484. * lot of peripheral registers. Let 0x100 be the default
  485. * Note that RAMSTART (for optiboot) need not be exactly at the start of RAM.
  486. */
  487. #if !defined(RAMSTART) // newer versions of gcc avr-libc define RAMSTART
  488. #define RAMSTART 0x100
  489. #if defined (__AVR_ATmega644P__)
  490. // correct for a bug in avr-libc
  491. #undef SIGNATURE_2
  492. #define SIGNATURE_2 0x0A
  493. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  494. #undef RAMSTART
  495. #define RAMSTART (0x200)
  496. #endif
  497. #endif
  498. /* C zero initialises all global variables. However, that requires */
  499. /* These definitions are NOT zero initialised, but that doesn't matter */
  500. /* This allows us to drop the zero init code, saving us memory */
  501. static addr16_t buff = {(uint8_t *)(RAMSTART)};
  502. /* Virtual boot partition support */
  503. #ifdef VIRTUAL_BOOT_PARTITION
  504. // RAM locations to save vector info (temporarilly)
  505. #define rstVect0_sav (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+4))
  506. #define rstVect1_sav (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+5))
  507. #define saveVect0_sav (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+6))
  508. #define saveVect1_sav (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+7))
  509. #define RSTVEC_ADDRESS 0 // flash address where vectors start.
  510. // Vector to save original reset jump:
  511. // SPM Ready is least probably used, so it's default
  512. // if not, use old way WDT_vect_num,
  513. // or simply set custom save_vect_num in Makefile using vector name
  514. // or even raw number.
  515. #if !defined (save_vect_num)
  516. #if defined (SPM_RDY_vect_num)
  517. #define save_vect_num (SPM_RDY_vect_num)
  518. #elif defined (SPM_READY_vect_num)
  519. #define save_vect_num (SPM_READY_vect_num)
  520. #elif defined (EE_RDY_vect_num)
  521. #define save_vect_num (EE_RDY_vect_num)
  522. #elif defined (EE_READY_vect_num)
  523. #define save_vect_num (EE_READY_vect_num)
  524. #elif defined (WDT_vect_num)
  525. #define save_vect_num (WDT_vect_num)
  526. #else
  527. #error "Can't find SPM or WDT interrupt vector for this CPU"
  528. #endif
  529. #endif //save_vect_num
  530. // check if it's on the same page (code assumes that)
  531. #if FLASHEND > 8192
  532. // AVRs with more than 8k of flash have 4-byte vectors, and use jmp.
  533. // We save only 16 bits of address, so devices with more than 128KB
  534. // may behave wrong for upper part of address space.
  535. #define rstVect0 2
  536. #define rstVect1 3
  537. #define saveVect0 (save_vect_num*4+2)
  538. #define saveVect1 (save_vect_num*4+3)
  539. #define appstart_vec (save_vect_num*2)
  540. // address of page that will have the saved vector
  541. #define SAVVEC_ADDRESS (SPM_PAGESIZE*(save_vect_num/(SPM_PAGESIZE/4)))
  542. #else
  543. // AVRs with up to 8k of flash have 2-byte vectors, and use rjmp.
  544. #define rstVect0 0
  545. #define rstVect1 1
  546. #define saveVect0 (save_vect_num*2)
  547. #define saveVect1 (save_vect_num*2+1)
  548. #define appstart_vec (save_vect_num)
  549. // address of page that will have the saved vector
  550. #define SAVVEC_ADDRESS (SPM_PAGESIZE*(save_vect_num/(SPM_PAGESIZE/2)))
  551. #endif
  552. #else
  553. #define appstart_vec (0)
  554. #endif // VIRTUAL_BOOT_PARTITION
  555. void sectionOpts() __attribute__((naked));
  556. void sectionOpts() {
  557. /*
  558. * Mysterious Magic code to allow section-start addresses to be
  559. * specifed by the C code (which, after all, has access to CPP symbols
  560. * like FLASHEND, and can make a "safer" guess than putting manually
  561. * determined constants in the Makefile. This is dependent on a custom
  562. * linker script that makes use of the __BOOT_ symbols that we define.
  563. * Fortunately, that script can be used to link optiboot on any of its
  564. * usual chips.
  565. *
  566. * with some judicious use of asm directives, we can define symbols
  567. * that the linker will look at for positioning our segments (in
  568. * combination with a custom linker script) based on the flash size
  569. * defined via io.h, instead of requiring magic --section-start
  570. * constants on the build line.
  571. *
  572. * This apparently needs to be inside a function in order to pass
  573. * arguments to the asm command (even though the asm doesn't
  574. * generate any code) But we can make sure the function (which doesn't
  575. * actually contain any code) doesn't actually end up in the binary.
  576. */
  577. #if BIGBOOT
  578. /*
  579. * BIGBOOT images are easy, because they're much smaller than the
  580. * flash size that they are defined to occupy (1k)
  581. */
  582. asm(" .global __BOOT_SIZE__, __BOOT_START__, __VERSION_START__\n"
  583. " .equ __BOOT_SIZE__, 1024\n"
  584. " .equ __BOOT_START__, (%0-1023)\n"
  585. " .equ __VERSION_START__, (%0-1)\n"
  586. ::"i"((uint32_t)FLASHEND));
  587. #else
  588. /*
  589. * non-BIGBOOT images try to fit in 512bytes, but don't quite fit
  590. * on chips that don't have HW support for a boot section. We try
  591. * to guess how big the extra bits of code are, and then round up
  592. * to the next larger flash page boundry (which can be nearly 4 pages
  593. * away on chips with FOURPAGEERASE)
  594. * These numbers are determined manually by building a reference
  595. * implementation with various options and comparing sizes.
  596. */
  597. # if VIRTUAL_BOOT_PARTITION
  598. /* VIRTUAL_BOOT_PARTITION code is about 100 bytes */
  599. # define VBSIZE 110
  600. # else
  601. # define VBSIZE 0
  602. # endif
  603. # if LED_START_FLASHES==0
  604. /* if LED_START_FLASHES is 0 (eg on 8pin chips), it saves some code */
  605. # define LEDSIZE (-30)
  606. # else
  607. # define LEDSIZE 0
  608. # endif
  609. # if SOFT_UART
  610. /* But not having a hardware UART costs a bit */
  611. # define SOFTUSIZE 16
  612. # else
  613. # define SOFTUSIZE 0
  614. # endif
  615. # if FOURPAGEERASE
  616. /* FOURPAGEERASE adds some code, and also affects how we round */
  617. # define ERASESIZE 8
  618. # define PAGSIZ_B (SPM_PAGESIZE*4)
  619. # else
  620. # define PAGSIZ_B (SPM_PAGESIZE)
  621. # define ERASESIZE 0
  622. # endif
  623. /*
  624. * Round our guess up to next page size. So 560 byte images occupy 576bytes,
  625. * 600 byte images occupy 640 bytes, etc. Depending on chip.
  626. * Note that SPM_PAGESIZE is already in bytes in the .h files.
  627. */
  628. # define ROUNDTOPAGE(size) (((size + (PAGSIZ_B/2))/(PAGSIZ_B))*(PAGSIZ_B))
  629. /* use 511 here so we don't round up to the next page on normal systems. */
  630. # define BOOTSIZE (511+ERASESIZE+VBSIZE+SOFTUSIZE+LEDSIZE)
  631. asm(" .global __BOOT_SIZE__, __BOOT_START__, __VERSION_START__\n"
  632. " .equ __BOOT_SIZE__, %1\n"
  633. " .equ __BOOT_START__, ((%0+1)-%1)\n"
  634. " .equ __VERSION_START__, (%0-1)\n"
  635. ::"i"((uint32_t)FLASHEND), "i"(ROUNDTOPAGE(BOOTSIZE)));
  636. #endif
  637. /* Wasn't that FUN! */
  638. }
  639. /* everything that needs to run VERY early */
  640. void pre_main(void) {
  641. // Allow convenient way of calling do_spm function - jump table, so
  642. // entry to this function will always be here, independent of
  643. // compilation, features etc
  644. asm volatile (
  645. " rjmp 1f\n"
  646. #if APP_NOSPM
  647. " ret\n" // if do_spm isn't include, return without doing anything
  648. #else
  649. " rjmp do_spm\n"
  650. #endif
  651. "1:\n"
  652. );
  653. }
  654. /* main program starts here */
  655. void bootloader(unsigned char check_reset) {
  656. uint8_t ch;
  657. /*
  658. * Making these local and in registers prevents the need for initializing
  659. * them, and also saves space because code no longer stores to memory.
  660. * (initializing address keeps the compiler happy, but isn't really
  661. * necessary, and uses 4 bytes of flash.)
  662. */
  663. register addr16_t address;
  664. register pagelen_t length;
  665. // After the zero init loop, this is the first code to run.
  666. //
  667. // This code makes the following assumptions:
  668. // No interrupts will execute
  669. // SP points to RAMEND
  670. // r1 contains zero
  671. //
  672. // If not, uncomment the following instructions:
  673. // cli();
  674. asm volatile (" clr __zero_reg__");
  675. #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8515__) || \
  676. defined(__AVR_ATmega8535__) || defined (__AVR_ATmega16__) || \
  677. defined (__AVR_ATmega32__) || defined (__AVR_ATmega64__) || \
  678. defined (__AVR_ATmega128__) || defined (__AVR_ATmega162__)
  679. SP=RAMEND; // This is done by hardware reset on newer chips
  680. #endif
  681. #if defined(OSCCAL_VALUE)
  682. OSCCAL = OSCCAL_VALUE;
  683. #endif
  684. /*
  685. * Protect as much from MCUSR as possible for application
  686. * and still skip bootloader if not necessary
  687. *
  688. * Code by MarkG55
  689. * see discussion in https://github.com/Optiboot/optiboot/issues/97
  690. */
  691. #ifndef MCUSR // Backward compatability with old AVRs
  692. #define MCUSR MCUCSR
  693. #endif
  694. #if (START_APP_ON_EXTR == 0 && NO_START_APP_ON_POR == 0)
  695. /*
  696. * Normal behavior. Start if EXTRF in on and WDRF is off
  697. */
  698. # define APP_START_REASONS ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF))
  699. # define WDRF_CLR_REASONS (ch & _BV(EXTRF))
  700. #elif (START_APP_ON_EXTR && NO_START_APP_ON_POR)
  701. /*
  702. * If NO_START_APP_ON_POR is defined, run bootloader after POR.
  703. * This allows use with reset disabled: power on and immediately
  704. * program.
  705. */
  706. # define APP_START_REASONS ((ch & (_BV(PORF) | _BV(WDRF) | _BV(EXTRF))) != _BV(PORF))
  707. # define WDRF_CLR_REASONS ((ch & (_BV(PORF) | _BV(WDRF))) == (_BV(PORF) | _BV(WDRF)))
  708. #elif ((START_APP_ON_EXTR == 0) && NO_START_APP_ON_POR)
  709. /*
  710. * If START_APP_ON_EXTR is defined, don't run bootloader after
  711. * an external reset - only useful in combination with above,
  712. * for some unusual use cases.
  713. */
  714. # define APP_START_REASONS (ch & _BV(WDRF))
  715. # define WDRF_CLR_REASONS (ch & (_BV(PORF) | _BV(EXTRF)))
  716. #else
  717. /*
  718. * Only run bootloader via jmp to 0 with MCUSR==0.
  719. * Probably an error.
  720. */
  721. # warning "Bootloader can only start via app request because "
  722. # warning "START_APP_ON_EXTR is defined and NO_START_APP_ON_POR isn't"
  723. # define APP_START_REASONS 1 /* Always start rge App. */
  724. # define WDRF_CLR_REASONS 0 /* Never clear WDRF */
  725. #endif
  726. ch = MCUSR;
  727. // Skip all logic and run bootloader if MCUSR is cleared (application request)
  728. if (check_reset && ch != 0) {
  729. /*
  730. * To run the boot loader, External Reset Flag must be set.
  731. * If not, we could make shortcut and jump directly to application code.
  732. * Also WDRF set with EXTRF is a result of Optiboot timeout, so we
  733. * shouldn't run bootloader in loop :-) That's why:
  734. * 1. application is running if WDRF is cleared
  735. * 2. we clear WDRF if it's set with EXTRF to avoid loops
  736. * One problematic scenario: broken application code sets watchdog timer
  737. * without clearing MCUSR before and triggers it quickly. But it's
  738. * recoverable by power-on with pushed reset button.
  739. */
  740. if (APP_START_REASONS) {
  741. if (WDRF_CLR_REASONS) {
  742. /*
  743. * Clear WDRF if it was most probably set by wdr in bootloader.
  744. */
  745. if ((uint16_t)&MCUSR > 0x1F) {
  746. MCUSR = ~(_BV(WDRF)); // optimize to LDI/OUT
  747. } else {
  748. MCUSR &= ~(_BV(WDRF)); // or optimize to CBI if possible
  749. }
  750. }
  751. /*
  752. * save the reset flags in the designated register
  753. * This can be saved in a main program by putting code in .init0 (which
  754. * executes before normal c init code) to save R2 to a global variable.
  755. */
  756. __asm__ __volatile__ (" mov r2, %0\n" :: "r" (ch));
  757. // switch off watchdog
  758. watchdogConfig(WATCHDOG_OFF);
  759. // Note that appstart_vec is defined so that this works with either
  760. // real or virtual boot partitions.
  761. __asm__ __volatile__ (
  762. // Jump to 'save' or RST vector
  763. #ifdef VIRTUAL_BOOT_PARTITION
  764. // full code version for virtual boot partition
  765. " ldi r30,%[rstvec]\n"
  766. " clr r31\n"
  767. " ijmp\n"::[rstvec] "M"(appstart_vec)
  768. #else
  769. #ifdef RAMPZ
  770. // use absolute jump for devices with lot of flash
  771. " jmp 0\n"::
  772. #else
  773. // use rjmp to go around end of flash to address 0
  774. // it uses fact that optiboot_version constant is 2 bytes before end of flash
  775. " rjmp optiboot_version+2\n"
  776. #endif //RAMPZ
  777. #endif //VIRTUAL_BOOT_PARTITION
  778. );
  779. }
  780. } //end handling of MCUSR !=0
  781. #if LED_START_FLASHES > 0
  782. // Set up Timer 1 for timeout counter
  783. #if defined(__AVR_ATtiny261__)||defined(__AVR_ATtiny461__)||defined(__AVR_ATtiny861__)
  784. TCCR1B = 0x0E; //div 8196 - we could divide by less since it's a 10-bit counter, but why?
  785. #elif defined(__AVR_ATtiny25__)||defined(__AVR_ATtiny45__)||defined(__AVR_ATtiny85__)
  786. TCCR1 = 0x0E; //div 8196 - it's an 8-bit timer.
  787. #elif defined(__AVR_ATtiny43__)
  788. #error "LED flash for Tiny43 not yet supported"
  789. #else
  790. TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
  791. #endif
  792. #endif
  793. #if (SOFT_UART == 0)
  794. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega8515__) || \
  795. defined (__AVR_ATmega8535__) || defined (__AVR_ATmega16__) || \
  796. defined (__AVR_ATmega32__)
  797. #if (SINGLESPEED == 0)
  798. UCSRA = _BV(U2X); //Double speed mode USART
  799. #endif //singlespeed
  800. UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
  801. UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
  802. UBRRL = (uint8_t)BAUD_SETTING;
  803. #else // mega8/etc
  804. #ifdef LIN_UART
  805. //DDRB|=3;
  806. LINCR = (1 << LSWRES);
  807. //LINBRRL = (((F_CPU * 10L / 32L / BAUD_RATE) + 5L) / 10L) - 1;
  808. LINBRRL=(uint8_t)BAUD_SETTING;
  809. LINBTR = (1 << LDISR) | (8 << LBT0);
  810. LINCR = _BV(LENA) | _BV(LCMD2) | _BV(LCMD1) | _BV(LCMD0);
  811. LINDAT=0;
  812. #else
  813. #if (SINGLESPEED == 0)
  814. UART_SRA = _BV(U2X0); //Double speed mode USART0
  815. #endif
  816. UART_SRB = _BV(RXEN0) | _BV(TXEN0);
  817. UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
  818. UART_SRL = (uint8_t)BAUD_SETTING;
  819. #endif // LIN_UART
  820. #endif // mega8/etc
  821. #endif // soft_uart
  822. #ifdef RS485
  823. RS485_DDR |= _BV(RS485_BIT);
  824. #ifdef RS485_INVERT
  825. RS485_PORT |= _BV(RS485_BIT);
  826. #else
  827. RS485_PORT &= ~_BV(RS485_BIT);
  828. #endif
  829. #endif
  830. // Set up watchdog to trigger after desired timeout
  831. watchdogConfig(WDTPERIOD);
  832. #if (LED_START_FLASHES > 0) || LED_DATA_FLASH || LED_START_ON
  833. /* Set LED pin as output */
  834. LED_DDR |= _BV(LED);
  835. #endif
  836. /* hold POWER_ON (GPStracker) */
  837. DDRA |= _BV(PA3);
  838. PORTA |= _BV(PA3);
  839. #if SOFT_UART
  840. /* Set TX pin as HIGH output */
  841. UART_PORT |= _BV(UART_TX_BIT);
  842. UART_DDR |= _BV(UART_TX_BIT);
  843. #endif
  844. #if LED_START_FLASHES > 0
  845. /* Flash onboard LED to signal entering of bootloader */
  846. flash_led(LED_START_FLASHES * 2);
  847. #else
  848. #if LED_START_ON
  849. /* Turn on LED to indicate starting bootloader (less code!) */
  850. LED_PORT |= _BV(LED);
  851. #endif
  852. #endif
  853. /* Forever loop: exits by causing WDT reset */
  854. for (;;) {
  855. /* get character from UART */
  856. ch = getch();
  857. // putch(ch);
  858. /*continue;*/
  859. if (ch == STK_GET_SYNC) {
  860. verifySpace();
  861. }
  862. else if (ch == STK_GET_PARAMETER) {
  863. unsigned char which = getch();
  864. verifySpace();
  865. /*
  866. * Send optiboot version as "SW version"
  867. * Note that the references to memory are optimized away.
  868. */
  869. if (which == STK_SW_MINOR) {
  870. putch(optiboot_version & 0xFF);
  871. } else if (which == STK_SW_MAJOR) {
  872. putch(optiboot_version >> 8);
  873. } else {
  874. /*
  875. * GET PARAMETER returns a generic 0x03 reply for
  876. * other parameters - enough to keep Avrdude happy
  877. */
  878. putch(0x03);
  879. }
  880. }
  881. else if (ch == STK_SET_DEVICE) {
  882. // SET DEVICE is ignored
  883. getNch(20);
  884. }
  885. else if (ch == STK_SET_DEVICE_EXT) {
  886. // SET DEVICE EXT is ignored
  887. getNch(5);
  888. }
  889. else if (ch == STK_LOAD_ADDRESS) {
  890. // LOAD ADDRESS
  891. address.bytes[0] = getch();
  892. address.bytes[1] = getch();
  893. #ifdef RAMPZ
  894. // Transfer top bit to LSB in RAMPZ
  895. if (address.bytes[1] & 0x80) {
  896. RAMPZ |= 0x01;
  897. }
  898. else {
  899. RAMPZ &= 0xFE;
  900. }
  901. #endif
  902. address.word *= 2; // Convert from word address to byte address
  903. verifySpace();
  904. }
  905. else if (ch == STK_UNIVERSAL) {
  906. #ifdef RAMPZ
  907. // LOAD_EXTENDED_ADDRESS is needed in STK_UNIVERSAL for addressing more than 128kB
  908. if ( AVR_OP_LOAD_EXT_ADDR == getch() ) {
  909. // get address
  910. getch(); // get '0'
  911. RAMPZ = (RAMPZ & 0x01) | ((getch() << 1) & 0xff); // get address and put it in RAMPZ
  912. getNch(1); // get last '0'
  913. // response
  914. putch(0x00);
  915. }
  916. else {
  917. // everything else is ignored
  918. getNch(3);
  919. putch(0x00);
  920. }
  921. #else
  922. // UNIVERSAL command is ignored
  923. getNch(4);
  924. putch(0x00);
  925. #endif
  926. }
  927. /* Write memory, length is big endian and is in bytes */
  928. else if (ch == STK_PROG_PAGE) {
  929. // PROGRAM PAGE - we support flash programming only, not EEPROM
  930. uint8_t desttype;
  931. uint8_t *bufPtr;
  932. pagelen_t savelength;
  933. GETLENGTH(length);
  934. savelength = length;
  935. desttype = getch();
  936. // read a page worth of contents
  937. bufPtr = buff.bptr;
  938. do *bufPtr++ = getch();
  939. while (--length);
  940. // Read command terminator, start reply
  941. verifySpace();
  942. #ifdef VIRTUAL_BOOT_PARTITION
  943. /*
  944. * How the Virtual Boot Partition works:
  945. * At the beginning of a normal AVR program are a set of vectors that
  946. * implement the interrupt mechanism. Each vector is usually a single
  947. * instruction that dispatches to the appropriate ISR.
  948. * The instruction is normally an rjmp (on AVRs with 8k or less of flash)
  949. * or jmp instruction, and the 0th vector is executed on reset and jumps
  950. * to the start of the user program:
  951. * vectors: jmp startup
  952. * jmp ISR1
  953. * jmp ISR2
  954. * : ;; etc
  955. * jmp lastvector
  956. * To implement the "Virtual Boot Partition", Optiboot detects when the
  957. * flash page containing the vectors is being programmed, and replaces the
  958. * startup vector with a jump to te beginning of Optiboot. Then it saves
  959. * the applications's startup vector in another (must be unused by the
  960. * application), and finally programs the page with the changed vectors.
  961. * Thereafter, on reset, the vector will dispatch to the beginning of
  962. * Optiboot. When Optiboot decides that it will run the user application,
  963. * it fetches the saved start address from the unused vector, and jumps
  964. * there.
  965. * The logic is dependent on size of flash, and whether the reset vector is
  966. * on the same flash page as the saved start address.
  967. */
  968. #if FLASHEND > 8192
  969. /*
  970. * AVR with 4-byte ISR Vectors and "jmp"
  971. * WARNING: this works only up to 128KB flash!
  972. */
  973. #if FLASHEND > (128*1024)
  974. #error "Can't use VIRTUAL_BOOT_PARTITION with more than 128k of Flash"
  975. #endif
  976. if (address.word == RSTVEC_ADDRESS) {
  977. // This is the reset vector page. We need to live-patch the
  978. // code so the bootloader runs first.
  979. //
  980. // Save jmp targets (for "Verify")
  981. rstVect0_sav = buff.bptr[rstVect0];
  982. rstVect1_sav = buff.bptr[rstVect1];
  983. // Add "jump to Optiboot" at RESET vector
  984. // WARNING: this works as long as 'main' is in first section
  985. buff.bptr[rstVect0] = ((uint16_t)pre_main) & 0xFF;
  986. buff.bptr[rstVect1] = ((uint16_t)pre_main) >> 8;
  987. #if (SAVVEC_ADDRESS != RSTVEC_ADDRESS)
  988. // the save_vector is not necessarilly on the same flash page as the reset
  989. // vector. If it isn't, we've waiting to actually write it.
  990. } else if (address.word == SAVVEC_ADDRESS) {
  991. // Save old values for Verify
  992. saveVect0_sav = buff.bptr[saveVect0 - SAVVEC_ADDRESS];
  993. saveVect1_sav = buff.bptr[saveVect1 - SAVVEC_ADDRESS];
  994. // Move RESET jmp target to 'save' vector
  995. buff.bptr[saveVect0 - SAVVEC_ADDRESS] = rstVect0_sav;
  996. buff.bptr[saveVect1 - SAVVEC_ADDRESS] = rstVect1_sav;
  997. }
  998. #else
  999. // Save old values for Verify
  1000. saveVect0_sav = buff.bptr[saveVect0];
  1001. saveVect1_sav = buff.bptr[saveVect1];
  1002. // Move RESET jmp target to 'save' vector
  1003. buff.bptr[saveVect0] = rstVect0_sav;
  1004. buff.bptr[saveVect1] = rstVect1_sav;
  1005. }
  1006. #endif
  1007. #else // bigger flash
  1008. #ifdef KeepBracesMatched
  1009. {
  1010. #endif
  1011. /*
  1012. * AVR with 2-byte ISR Vectors and rjmp
  1013. */
  1014. if (address.word == rstVect0) {
  1015. // This is the reset vector page. We need to live-patch
  1016. // the code so the bootloader runs first.
  1017. //
  1018. // Move RESET vector to 'save' vector
  1019. // Save jmp targets (for "Verify")
  1020. rstVect0_sav = buff.bptr[rstVect0];
  1021. rstVect1_sav = buff.bptr[rstVect1];
  1022. addr16_t vect;
  1023. vect.word = ((uint16_t)pre_main-1);
  1024. // Instruction is a relative jump (rjmp), so recalculate.
  1025. // an RJMP instruction is 0b1100xxxx xxxxxxxx, so we should be able to
  1026. // do math on the offsets without masking it off first.
  1027. // Note that rjmp is relative to the already incremented PC, so the
  1028. // offset is one less than you might expect.
  1029. buff.bptr[0] = vect.bytes[0]; // rjmp to start of bootloader
  1030. buff.bptr[1] = vect.bytes[1] | 0xC0; // make an "rjmp"
  1031. #if (SAVVEC_ADDRESS != RSTVEC_ADDRESS)
  1032. } else if (address.word == SAVVEC_ADDRESS) {
  1033. addr16_t vect;
  1034. vect.bytes[0] = rstVect0_sav;
  1035. vect.bytes[1] = rstVect1_sav;
  1036. // Save old values for Verify
  1037. saveVect0_sav = buff.bptr[saveVect0 - SAVVEC_ADDRESS];
  1038. saveVect1_sav = buff.bptr[saveVect1 - SAVVEC_ADDRESS];
  1039. vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
  1040. // Move RESET jmp target to 'save' vector
  1041. buff.bptr[saveVect0 - SAVVEC_ADDRESS] = vect.bytes[0];
  1042. buff.bptr[saveVect1 - SAVVEC_ADDRESS] = (vect.bytes[1] & 0x0F)| 0xC0; // make an "rjmp"
  1043. }
  1044. #else
  1045. #ifdef KeepBracesMatched
  1046. {
  1047. #endif
  1048. // Save old values for Verify
  1049. saveVect0_sav = buff.bptr[saveVect0];
  1050. saveVect1_sav = buff.bptr[saveVect1];
  1051. vect.bytes[0] = rstVect0_sav;
  1052. vect.bytes[1] = rstVect1_sav;
  1053. vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
  1054. // Move RESET jmp target to 'save' vector
  1055. buff.bptr[saveVect0] = vect.bytes[0];
  1056. buff.bptr[saveVect1] = (vect.bytes[1] & 0x0F)| 0xC0; // make an "rjmp"
  1057. // Add rjmp to bootloader at RESET vector
  1058. vect.word = ((uint16_t)pre_main-1); // (main) is always <= 0x0FFF; no masking needed.
  1059. buff.bptr[0] = vect.bytes[0]; // rjmp 0x1c00 instruction
  1060. }
  1061. #endif
  1062. #endif // FLASHEND
  1063. #endif // VBP
  1064. writebuffer(desttype, buff, address, savelength);
  1065. }
  1066. /* Read memory block mode, length is big endian. */
  1067. else if (ch == STK_READ_PAGE) {
  1068. uint8_t desttype;
  1069. GETLENGTH(length);
  1070. desttype = getch();
  1071. verifySpace();
  1072. read_mem(desttype, address, length);
  1073. }
  1074. /* Get device signature bytes */
  1075. else if (ch == STK_READ_SIGN) {
  1076. // READ SIGN - return what Avrdude wants to hear
  1077. verifySpace();
  1078. putch(SIGNATURE_0);
  1079. putch(SIGNATURE_1);
  1080. putch(SIGNATURE_2);
  1081. }
  1082. else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
  1083. // Adaboot no-wait mod
  1084. watchdogConfig(WATCHDOG_16MS);
  1085. verifySpace();
  1086. }
  1087. else {
  1088. // This covers the response to commands like STK_ENTER_PROGMODE
  1089. verifySpace();
  1090. }
  1091. putch(STK_OK);
  1092. }
  1093. }
  1094. int main(void) {
  1095. bootloader(1);
  1096. }
  1097. __attribute__((section(".manualcall"))) void manual_call(void) {
  1098. bootloader(0);
  1099. }
  1100. void putch(char ch) {
  1101. #if (SOFT_UART == 0)
  1102. // Hardware UARTs.
  1103. #ifndef LIN_UART
  1104. #ifdef RS485
  1105. uint8_t x;
  1106. do {
  1107. x = UART_SRA;
  1108. } while (!(x & _BV(UDRE0)));
  1109. // clear transmitted flag
  1110. x |= _BV(TXC0);
  1111. UART_SRA = x;
  1112. // put transceiver to output mode
  1113. # ifdef RS485_INVERT
  1114. RS485_PORT &= ~_BV(RS485_BIT);
  1115. # else
  1116. RS485_PORT |= _BV(RS485_BIT);
  1117. # endif
  1118. // put char
  1119. UART_UDR = ch;
  1120. // wait for char transmitted
  1121. while (!(UART_SRA & _BV(TXC0))) { /* Spin */ }
  1122. // put transceiver to input mode
  1123. # ifdef RS485_INVERT
  1124. RS485_PORT |= _BV(RS485_BIT);
  1125. # else
  1126. RS485_PORT &= ~_BV(RS485_BIT);
  1127. # endif
  1128. #else //not RS485
  1129. while (!(UART_SRA & _BV(UDRE0))) { /* Spin */ }
  1130. UART_UDR = ch;
  1131. #endif
  1132. #else //is LIN UART
  1133. while (!(LINSIR & _BV(LTXOK))) { /* Spin */ }
  1134. UART_UDR = ch;
  1135. #endif
  1136. #else // SOFT_UART
  1137. #ifdef RS485
  1138. // put transceiver to output mode
  1139. #ifdef RS485_INVERT
  1140. RS485_PORT &= ~_BV(RS485_BIT);
  1141. #else
  1142. RS485_PORT |= _BV(RS485_BIT);
  1143. #endif
  1144. #endif
  1145. __asm__ __volatile__ (
  1146. " com %[ch]\n" // ones complement, carry set
  1147. " sec\n"
  1148. "1: brcc 2f\n"
  1149. " cbi %[uartPort],%[uartBit]\n"
  1150. " rjmp 3f\n"
  1151. "2: sbi %[uartPort],%[uartBit]\n"
  1152. " nop\n"
  1153. "3: rcall uartDelay\n"
  1154. " rcall uartDelay\n"
  1155. " lsr %[ch]\n"
  1156. " dec %[bitcnt]\n"
  1157. " brne 1b\n"
  1158. :
  1159. :
  1160. [bitcnt] "d" (10),
  1161. [ch] "r" (ch),
  1162. [uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
  1163. [uartBit] "I" (UART_TX_BIT)
  1164. :
  1165. "r25"
  1166. );
  1167. #ifdef RS485
  1168. // put transceiver to input mode
  1169. #ifdef RS485_INVERT
  1170. RS485_PORT |= _BV(RS485_BIT);
  1171. #else
  1172. RS485_PORT &= ~_BV(RS485_BIT);
  1173. #endif
  1174. #endif
  1175. #endif // SOFT_UART
  1176. }
  1177. static void inline toggle_led(void) {
  1178. #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8515__) || \
  1179. defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || \
  1180. defined(__AVR_ATmega162__) || defined(__AVR_ATmega32__) || \
  1181. defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
  1182. LED_PORT ^= _BV(LED);
  1183. #else
  1184. LED_PIN |= _BV(LED); // Newer AVRs can toggle by writing PINx
  1185. #endif
  1186. }
  1187. uint8_t getch(void) {
  1188. uint8_t ch;
  1189. #if LED_DATA_FLASH
  1190. toggle_led();
  1191. #endif
  1192. #if SOFT_UART
  1193. watchdogReset();
  1194. __asm__ __volatile__ (
  1195. "1: sbic %[uartPin],%[uartBit]\n" // Wait for start edge
  1196. " rjmp 1b\n"
  1197. " rcall uartDelay\n" // Get to middle of start bit
  1198. "2: rcall uartDelay\n" // Wait 1 bit period
  1199. " rcall uartDelay\n" // Wait 1 bit period
  1200. " clc\n"
  1201. " sbic %[uartPin],%[uartBit]\n"
  1202. " sec\n"
  1203. " dec %[bitCnt]\n"
  1204. " breq 3f\n"
  1205. " ror %[ch]\n"
  1206. " rjmp 2b\n"
  1207. "3:\n"
  1208. :
  1209. [ch] "=r" (ch)
  1210. :
  1211. [bitCnt] "d" (9),
  1212. [uartPin] "I" (_SFR_IO_ADDR(UART_PIN)),
  1213. [uartBit] "I" (UART_RX_BIT)
  1214. :
  1215. "r25"
  1216. );
  1217. #else
  1218. #ifndef LIN_UART
  1219. while (!(UART_SRA & _BV(RXC0))) { /* Spin */ }
  1220. if (!(UART_SRA & _BV(FE0))) {
  1221. /*
  1222. * A Framing Error indicates (probably) that something is talking
  1223. * to us at the wrong bit rate. Assume that this is because it
  1224. * expects to be talking to the application, and DON'T reset the
  1225. * watchdog. This should cause the bootloader to abort and run
  1226. * the application "soon", if it keeps happening. (Note that we
  1227. * don't care that an invalid char is returned...)
  1228. */
  1229. watchdogReset();
  1230. }
  1231. #else
  1232. while (!(LINSIR & _BV(LRXOK))) { /* Spin */ }
  1233. if (!(LINSIR & _BV(LFERR))) {
  1234. watchdogReset(); /* Eventually abort if wrong speed */
  1235. }
  1236. #endif
  1237. ch = UART_UDR;
  1238. #endif
  1239. #if LED_DATA_FLASH
  1240. toggle_led();
  1241. #endif
  1242. return ch;
  1243. }
  1244. #if SOFT_UART
  1245. // AVR305 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6)
  1246. // Adding 3 to numerator simulates nearest rounding for more accurate baud rates
  1247. #define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6)
  1248. #if UART_B_VALUE > 255
  1249. #error Baud rate too slow for soft UART
  1250. #endif
  1251. #if UART_B_VALUE < 6
  1252. // (this value is a "guess" at when loop/call overhead might become too
  1253. // significant for the soft uart to work. It tests OK with the popular
  1254. // "ATtinycore" chips that need SOFT_UART, at the usual clock/baud combos.)
  1255. #error Baud rate too high for soft UART
  1256. #endif
  1257. void uartDelay() {
  1258. __asm__ __volatile__ (
  1259. " ldi r25,%[count]\n"
  1260. "1: dec r25\n"
  1261. " brne 1b\n"
  1262. " ret\n"
  1263. ::[count] "M" (UART_B_VALUE)
  1264. );
  1265. }
  1266. #endif
  1267. void getNch(uint8_t count) {
  1268. do getch(); while (--count);
  1269. verifySpace();
  1270. }
  1271. void verifySpace() {
  1272. if (getch() != CRC_EOP) {
  1273. watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
  1274. while (1) // and busy-loop so that WD causes
  1275. ; // a reset and app start.
  1276. }
  1277. putch(STK_INSYNC);
  1278. }
  1279. #if LED_START_FLASHES > 0
  1280. void flash_led(uint8_t count) {
  1281. do {
  1282. #if defined(__AVR_ATtiny261__)||defined(__AVR_ATtiny461__)||defined(__AVR_ATtiny861__) || defined(__AVR_ATtiny25__)||defined(__AVR_ATtiny45__)||defined(__AVR_ATtiny85__)
  1283. TCNT1 = 0xFF & (-(F_CPU/(8196L*16)));
  1284. TIFR = _BV(TOV1);
  1285. while (!(TIFR & _BV(TOV1)));
  1286. #elif defined(__AVR_ATtiny43__)
  1287. #error "LED flash for Tiny43 not yet supported"
  1288. #else
  1289. TCNT1 = -(F_CPU/(1024*16));
  1290. TIFR1 = _BV(TOV1);
  1291. while (!(TIFR1 & _BV(TOV1)));
  1292. #endif
  1293. toggle_led();
  1294. watchdogReset();
  1295. #if (SOFT_UART == 0)
  1296. /*
  1297. * While in theory, the STK500 initial commands would be buffered
  1298. * by the UART hardware, avrdude sends several attempts in rather
  1299. * quick succession, some of which will be lost and cause us to
  1300. * get out of sync. So if we see any data; stop blinking.
  1301. */
  1302. #ifndef LIN_UART
  1303. if (UART_SRA & _BV(RXC0))
  1304. #else
  1305. if (LINSIR & _BV(LRXOK))
  1306. #endif
  1307. break;
  1308. #else
  1309. // This doesn't seem to work?
  1310. // if ((UART_PIN & (1<<UART_RX_BIT)) == 0)
  1311. // break; // detect start bit on soft uart too.
  1312. #endif
  1313. } while (--count);
  1314. }
  1315. #endif
  1316. // Watchdog functions. These are only safe with interrupts turned off.
  1317. void watchdogReset() {
  1318. __asm__ __volatile__ (
  1319. " wdr\n"
  1320. );
  1321. }
  1322. void watchdogConfig(uint8_t x) {
  1323. #ifdef WDCE //does it have a Watchdog Change Enable?
  1324. #ifdef WDTCSR
  1325. WDTCSR = _BV(WDCE) | _BV(WDE);
  1326. #else
  1327. WDTCR= _BV(WDCE) | _BV(WDE);
  1328. #endif
  1329. #else //then it must be one of those newfangled ones that use CCP
  1330. CCP=0xD8; //so write this magic number to CCP
  1331. #endif
  1332. #ifdef WDTCSR
  1333. WDTCSR = x;
  1334. #else
  1335. WDTCR= x;
  1336. #endif
  1337. }
  1338. /*
  1339. * void writebuffer(memtype, buffer, address, length)
  1340. */
  1341. static inline void writebuffer(int8_t memtype, addr16_t mybuff,
  1342. addr16_t address, pagelen_t len)
  1343. {
  1344. switch (memtype) {
  1345. case 'E': // EEPROM
  1346. #if SUPPORT_EEPROM || BIGBOOT
  1347. while (len--) {
  1348. eeprom_write_byte((address.bptr++), *(mybuff.bptr++));
  1349. }
  1350. #else
  1351. /*
  1352. * On systems where EEPROM write is not supported, just busy-loop
  1353. * until the WDT expires, which will eventually cause an error on
  1354. * host system (which is what it should do.)
  1355. */
  1356. while (1)
  1357. ; // Error: wait for WDT
  1358. #endif
  1359. break;
  1360. default: // FLASH
  1361. /*
  1362. * Default to writing to Flash program memory. By making this
  1363. * the default rather than checking for the correct code, we save
  1364. * space on chips that don't support any other memory types.
  1365. */
  1366. {
  1367. // Copy buffer into programming buffer
  1368. uint16_t addrPtr = address.word;
  1369. /*
  1370. * Start the page erase and wait for it to finish. There
  1371. * used to be code to do this while receiving the data over
  1372. * the serial link, but the performance improvement was slight,
  1373. * and we needed the space back.
  1374. */
  1375. #ifdef FOURPAGEERASE
  1376. if ((address.bytes[0] & ((SPM_PAGESIZE<<2)-1))==0) {
  1377. #endif
  1378. __boot_page_erase_short(address.word);
  1379. boot_spm_busy_wait();
  1380. #ifdef FOURPAGEERASE
  1381. }
  1382. #endif
  1383. /*
  1384. * Copy data from the buffer into the flash write buffer.
  1385. */
  1386. do {
  1387. __boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
  1388. addrPtr += 2;
  1389. } while (len -= 2);
  1390. /*
  1391. * Actually Write the buffer to flash (and wait for it to finish.)
  1392. */
  1393. __boot_page_write_short(address.word);
  1394. boot_spm_busy_wait();
  1395. #if defined(RWWSRE)
  1396. // Reenable read access to flash
  1397. __boot_rww_enable_short();
  1398. #endif
  1399. } // default block
  1400. break;
  1401. } // switch
  1402. }
  1403. static inline void read_mem(uint8_t memtype, addr16_t address, pagelen_t length)
  1404. {
  1405. uint8_t ch;
  1406. switch (memtype) {
  1407. #if SUPPORT_EEPROM || BIGBOOT
  1408. case 'E': // EEPROM
  1409. do {
  1410. putch(eeprom_read_byte((address.bptr++)));
  1411. } while (--length);
  1412. break;
  1413. #endif
  1414. default:
  1415. do {
  1416. #ifdef VIRTUAL_BOOT_PARTITION
  1417. // Undo vector patch in bottom page so verify passes
  1418. if (address.word == rstVect0) ch = rstVect0_sav;
  1419. else if (address.word == rstVect1) ch = rstVect1_sav;
  1420. else if (address.word == saveVect0) ch = saveVect0_sav;
  1421. else if (address.word == saveVect1) ch = saveVect1_sav;
  1422. else ch = pgm_read_byte_near(address.bptr);
  1423. address.bptr++;
  1424. #elif defined(RAMPZ)
  1425. // Since RAMPZ should already be set, we need to use EPLM directly.
  1426. // Also, we can use the autoincrement version of lpm to update "address"
  1427. // do putch(pgm_read_byte_near(address++));
  1428. // while (--length);
  1429. // read a Flash and increment the address (may increment RAMPZ)
  1430. __asm__ (" elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
  1431. #else
  1432. // read a Flash byte and increment the address
  1433. __asm__ (" lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
  1434. #endif
  1435. putch(ch);
  1436. } while (--length);
  1437. break;
  1438. } // switch
  1439. }
  1440. #if (APP_NOSPM == 0)
  1441. /*
  1442. * Separate function for doing spm stuff
  1443. * It's needed for application to do SPM, as SPM instruction works only
  1444. * from bootloader.
  1445. *
  1446. * How it works:
  1447. * - do SPM
  1448. * - wait for SPM to complete
  1449. * - if chip have RWW/NRWW sections it does additionaly:
  1450. * - if command is WRITE or ERASE, AND data=0 then reenable RWW section
  1451. *
  1452. * In short:
  1453. * If you play erase-fill-write, just set data to 0 in ERASE and WRITE
  1454. * If you are brave, you have your code just below bootloader in NRWW section
  1455. * you could do fill-erase-write sequence with data!=0 in ERASE and
  1456. * data=0 in WRITE
  1457. */
  1458. static void do_spm(uint16_t address, uint8_t command, uint16_t data) __attribute__ ((used));
  1459. static void do_spm(uint16_t address, uint8_t command, uint16_t data) {
  1460. // Do spm stuff
  1461. asm volatile (
  1462. " movw r0, %3\n"
  1463. " __wr_spmcsr %0, %1\n"
  1464. " spm\n"
  1465. " clr r1\n"
  1466. :
  1467. : "i" (_SFR_MEM_ADDR(__SPM_REG)),
  1468. "r" ((uint8_t)command),
  1469. "z" ((uint16_t)address),
  1470. "r" ((uint16_t)data)
  1471. : "r0"
  1472. );
  1473. // wait for spm to complete
  1474. // it doesn't have much sense for __BOOT_PAGE_FILL,
  1475. // but it doesn't hurt and saves some bytes on 'if'
  1476. boot_spm_busy_wait();
  1477. #if defined(RWWSRE)
  1478. // this 'if' condition should be: (command == __BOOT_PAGE_WRITE || command == __BOOT_PAGE_ERASE)...
  1479. // but it's tweaked a little assuming that in every command we are interested in here, there
  1480. // must be also SELFPRGEN set. If we skip checking this bit, we save here 4B
  1481. if ((command & (_BV(PGWRT)|_BV(PGERS))) && (data == 0) ) {
  1482. // Reenable read access to flash
  1483. __boot_rww_enable_short();
  1484. }
  1485. #endif
  1486. }
  1487. #endif
  1488. #if BIGBOOT
  1489. /*
  1490. * Optiboot is designed to fit in 512 bytes, with a minimum feature set.
  1491. * Some chips have a minimum bootloader size of 1024 bytes, and sometimes
  1492. * it is desirable to add extra features even though 512bytes is exceedded.
  1493. * In that case, the BIGBOOT can be used.
  1494. * Our extra features so far don't come close to filling 1k, so we can
  1495. * add extra "frivolous" data to the image. In particular, we can add
  1496. * information about how Optiboot was built (which options were selected,
  1497. * what version, all in human-readable form (and extractable from the
  1498. * binary with avr-strings.)
  1499. *
  1500. * This can always be removed or trimmed if more actual program space
  1501. * is needed in the future. Currently the data occupies about 160 bytes,
  1502. */
  1503. #define xstr(s) str(s)
  1504. #define str(s) #s
  1505. __attribute__((section(".fini9"))) const char f_delimit = 0xFF;
  1506. #define OPTFLASHSECT __attribute__((section(".fini8")))
  1507. #define OPT2FLASH(o) OPTFLASHSECT const char f##o[] = #o "=" xstr(o)
  1508. #if LED_START_FLASHES
  1509. OPT2FLASH(LED_START_FLASHES);
  1510. #endif
  1511. #if LED_DATA_FLASH
  1512. OPT2FLASH(LED_DATA_FLASH);
  1513. #endif
  1514. #if LED_START_ON
  1515. OPT2FLASH(LED_START_ON);
  1516. #endif
  1517. #ifdef LED_NAME
  1518. OPTFLASHSECT const char f_LED[] = "LED=" LED_NAME;
  1519. #endif
  1520. #if SUPPORT_EEPROM
  1521. OPT2FLASH(SUPPORT_EEPROM);
  1522. #endif
  1523. #if defined(RS485)
  1524. OPTFLASHSECT const char f_rs485[] = "RS485=" RS485_NAME;
  1525. #endif
  1526. #if BAUD_RATE
  1527. OPT2FLASH(BAUD_RATE);
  1528. #endif
  1529. #if SOFT_UART
  1530. OPT2FLASH(SOFT_UART);
  1531. #endif
  1532. #if defined(UART)
  1533. OPT2FLASH(UART);
  1534. #endif
  1535. #if (!defined(NODATE)) || (NODATE == 0)
  1536. // Leave out the date, useful if we want to compare binaries
  1537. OPTFLASHSECT const char f_date[] = "Built:" __DATE__ ":" __TIME__;
  1538. #endif
  1539. #if BIGBOOT
  1540. OPT2FLASH(BIGBOOT);
  1541. #endif
  1542. #ifdef VIRTUAL_BOOT_PARTITION
  1543. OPTFLASHSECT const char f_boot[] = "Virtual_Boot_Partition";
  1544. #endif
  1545. OPT2FLASH(F_CPU);
  1546. OPTFLASHSECT const char f_device[] = "Device=" xstr(__AVR_DEVICE_NAME__);
  1547. #if OPTIBOOT_CUSTOMVER
  1548. OPT2FLASH(OPTIBOOT_CUSTOMVER);
  1549. #endif
  1550. OPTFLASHSECT const char f_version[] = "Version=" xstr(OPTIBOOT_MAJVER) "." xstr(OPTIBOOT_MINVER);
  1551. #endif