From 1c43faa1791b940d4b1f2bff3c8ce7907a5d97ad Mon Sep 17 00:00:00 2001 From: unknown <3d.gussner@gmail.com> Date: Fri, 29 Nov 2019 22:06:19 +0100 Subject: [PATCH] Prepare merge to prusa3d --- IDE_Board_Manager/Prepare-new-version.sh | 35 + IDE_Board_Manager/package_prusa3d_index.json | 68 +- IDE_Board_Manager/prusa3dboards-1.0.0.md | 24 + IDE_Board_Manager/prusa3dboards-1.0.1.md | 39 + IDE_Board_Manager/prusa3dboards-1.0.1.tar.bz2 | Bin 0 -> 32469 bytes IDE_Board_Manager/prusa3dboards-1.0.2.md | 117 ++ IDE_Board_Manager/prusa3dboards-1.0.2.tar.bz2 | Bin 0 -> 101087 bytes IDE_Board_Manager/prusa3dboards.version | 3 + IDE_Board_Manager/prusa3dboards/avrdude.conf | 424 +++++ IDE_Board_Manager/prusa3dboards/avrdude.md | 1 + IDE_Board_Manager/prusa3dboards/boards.txt | 73 + .../bootloaders/prusa_einsy_rambo/License.txt | 280 +++ .../bootloaders/prusa_einsy_rambo/Makefile | 587 +++++++ .../prusa_einsy_rambo/avr_cpunames.h | 189 ++ .../prusa_einsy_rambo/avrinterruptnames.h | 1040 +++++++++++ .../bootloaders/prusa_einsy_rambo/command.h | 118 ++ .../bootloaders/prusa_einsy_rambo/lcd.c | 718 ++++++++ .../bootloaders/prusa_einsy_rambo/lcd.h | 65 + .../bootloaders/prusa_einsy_rambo/settings.h | 83 + .../prusa_einsy_rambo/stk500boot.c | 1562 +++++++++++++++++ .../prusa_einsy_rambo/stk500boot.h | 4 + .../prusa_einsy_rambo/stk500boot.hex | 216 +++ .../stk500boot_v2_mega2560.hex | 285 +++ .../Caterina-prusa_mm_control.hex | 259 +++ .../bootloaders/prusa_mm_control/Readme.txt | 14 + .../bootloaders/prusa_mm_control/build.txt | 24 + .../bootloaders/prusa_mm_control/program.txt | 9 + .../cores/prusa_einsy_rambo}/Arduino.h | 0 .../cores/prusa_einsy_rambo}/CDC.cpp | 0 .../cores/prusa_einsy_rambo}/Client.h | 0 .../prusa_einsy_rambo}/HardwareSerial.cpp | 0 .../cores/prusa_einsy_rambo}/HardwareSerial.h | 0 .../prusa_einsy_rambo}/HardwareSerial0.cpp | 0 .../prusa_einsy_rambo}/HardwareSerial1.cpp | 0 .../prusa_einsy_rambo}/HardwareSerial2.cpp | 0 .../prusa_einsy_rambo}/HardwareSerial3.cpp | 0 .../HardwareSerial_private.h | 0 .../cores/prusa_einsy_rambo}/IPAddress.cpp | 0 .../cores/prusa_einsy_rambo}/IPAddress.h | 0 .../cores/prusa_einsy_rambo}/PluggableUSB.cpp | 0 .../cores/prusa_einsy_rambo}/PluggableUSB.h | 0 .../cores/prusa_einsy_rambo}/Print.cpp | 0 .../cores/prusa_einsy_rambo}/Print.h | 0 .../cores/prusa_einsy_rambo}/Printable.h | 0 .../cores/prusa_einsy_rambo}/Server.h | 0 .../cores/prusa_einsy_rambo}/Stream.cpp | 0 .../cores/prusa_einsy_rambo}/Stream.h | 0 .../cores/prusa_einsy_rambo}/Tone.cpp | 4 +- .../cores/prusa_einsy_rambo}/USBAPI.h | 0 .../cores/prusa_einsy_rambo}/USBCore.cpp | 0 .../cores/prusa_einsy_rambo}/USBCore.h | 0 .../cores/prusa_einsy_rambo}/USBDesc.h | 0 .../cores/prusa_einsy_rambo}/Udp.h | 0 .../cores/prusa_einsy_rambo}/WCharacter.h | 0 .../cores/prusa_einsy_rambo}/WInterrupts.c | 0 .../cores/prusa_einsy_rambo}/WMath.cpp | 0 .../cores/prusa_einsy_rambo}/WString.cpp | 0 .../cores/prusa_einsy_rambo}/WString.h | 0 .../cores/prusa_einsy_rambo}/abi.cpp | 0 .../cores/prusa_einsy_rambo}/binary.h | 0 .../cores/prusa_einsy_rambo}/hooks.c | 0 .../cores/prusa_einsy_rambo}/main.cpp | 0 .../cores/prusa_einsy_rambo}/new.cpp | 0 .../cores/prusa_einsy_rambo}/new.h | 0 .../cores/prusa_einsy_rambo}/wiring.c | 0 .../cores/prusa_einsy_rambo}/wiring_analog.c | 0 .../cores/prusa_einsy_rambo}/wiring_digital.c | 0 .../cores/prusa_einsy_rambo}/wiring_private.h | 0 .../cores/prusa_einsy_rambo}/wiring_pulse.S | 0 .../cores/prusa_einsy_rambo}/wiring_pulse.c | 0 .../cores/prusa_einsy_rambo}/wiring_shift.c | 0 .../platform.txt | 4 +- .../prusa_einsy_rambo}/pins_arduino.h | 0 .../variants/prusa_mm_control/pins_arduino.h | 380 ++++ .../prusa3drambo-1.0.1/boards.txt | 31 - README.md | 175 +- 76 files changed, 6790 insertions(+), 41 deletions(-) create mode 100644 IDE_Board_Manager/Prepare-new-version.sh create mode 100644 IDE_Board_Manager/prusa3dboards-1.0.0.md create mode 100644 IDE_Board_Manager/prusa3dboards-1.0.1.md create mode 100644 IDE_Board_Manager/prusa3dboards-1.0.1.tar.bz2 create mode 100644 IDE_Board_Manager/prusa3dboards-1.0.2.md create mode 100644 IDE_Board_Manager/prusa3dboards-1.0.2.tar.bz2 create mode 100644 IDE_Board_Manager/prusa3dboards.version create mode 100644 IDE_Board_Manager/prusa3dboards/avrdude.conf create mode 100644 IDE_Board_Manager/prusa3dboards/avrdude.md create mode 100644 IDE_Board_Manager/prusa3dboards/boards.txt create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/License.txt create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/Makefile create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/avr_cpunames.h create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/avrinterruptnames.h create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/command.h create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/lcd.c create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/lcd.h create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/settings.h create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.c create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.h create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.hex create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot_v2_mega2560.hex create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/Caterina-prusa_mm_control.hex create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/Readme.txt create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/build.txt create mode 100644 IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/program.txt rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Arduino.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/CDC.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Client.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/HardwareSerial.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/HardwareSerial.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/HardwareSerial0.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/HardwareSerial1.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/HardwareSerial2.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/HardwareSerial3.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/HardwareSerial_private.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/IPAddress.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/IPAddress.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/PluggableUSB.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/PluggableUSB.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Print.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Print.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Printable.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Server.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Stream.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Stream.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Tone.cpp (99%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/USBAPI.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/USBCore.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/USBCore.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/USBDesc.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/Udp.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/WCharacter.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/WInterrupts.c (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/WMath.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/WString.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/WString.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/abi.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/binary.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/hooks.c (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/main.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/new.cpp (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/new.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/wiring.c (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/wiring_analog.c (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/wiring_digital.c (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/wiring_private.h (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/wiring_pulse.S (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/wiring_pulse.c (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/cores/rambo => prusa3dboards/cores/prusa_einsy_rambo}/wiring_shift.c (100%) rename IDE_Board_Manager/{prusa3drambo-1.0.1 => prusa3dboards}/platform.txt (97%) rename IDE_Board_Manager/{prusa3drambo-1.0.1/variants/rambo => prusa3dboards/variants/prusa_einsy_rambo}/pins_arduino.h (100%) create mode 100644 IDE_Board_Manager/prusa3dboards/variants/prusa_mm_control/pins_arduino.h delete mode 100644 IDE_Board_Manager/prusa3drambo-1.0.1/boards.txt diff --git a/IDE_Board_Manager/Prepare-new-version.sh b/IDE_Board_Manager/Prepare-new-version.sh new file mode 100644 index 0000000..0a60dd6 --- /dev/null +++ b/IDE_Board_Manager/Prepare-new-version.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# This bash script is used to prepare the "package_prusa3d_index.json" +# +# Supported OS: Windows 10, Linux64 bit +# Beta OS: Linux32 bit +# +# 30, jul 2019, 3d-gussner, Read version from "prusa3dboards.version" file. It reads the 1st line + + +# Get version from prusa3dboards.version file +VERSION=$(head -1 prusa3dboards.version|cut -d ' ' -f1) +# rename temporaray "prusa3dboards" folder to include version number +mv prusa3dboards prusa3dboards-$VERSION +# compress prusa3dboards-$VERSION folder +tar -cjf prusa3dboards-$VERSION.tar.bz2 prusa3dboards-$VERSION +# rename prusa3dboards-$VERSION back to prusa3dboards as it makes follow changes easier in Github, cimmits/blame/history +mv prusa3dboards-$VERSION prusa3dboards +# get size of the compressed file for JSO +SIZE=$(wc -c prusa3dboards-$VERSION.tar.bz2|cut -d ' ' -f1) + +#get sha256 checksum +SHA256=$(sha256sum prusa3dboards-$VERSION.tar.bz2|cut -d ' ' -f1) + + +echo "Version : "$VERSION" to build" +echo "" +echo "Please don't forget to create new version file prusa3dboards-"$VERSION".MD" +sleep 5 +echo "Please use following values to edit JSON file" +echo "" +echo "ArchiveFileName : prusa3dboards-"$VERSION".tar.bz2" +echo "SHA256 checksum : "$SHA256 +echo "Size : "$SIZE +echo "online : prusa3dboards-"$VERSION".MD" + diff --git a/IDE_Board_Manager/package_prusa3d_index.json b/IDE_Board_Manager/package_prusa3d_index.json index 9ec47ee..1a90fdc 100644 --- a/IDE_Board_Manager/package_prusa3d_index.json +++ b/IDE_Board_Manager/package_prusa3d_index.json @@ -9,6 +9,47 @@ "online": "https://github.com/prusa3d/Arduino_Boards" }, "platforms": [ + { + "name": "Prusa Research AVR Boards", + "architecture": "avr", + "version": "1.0.2", + "category": "Contributed", + "url": "https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/prusa3dboards-1.0.2.tar.bz2", + "archiveFileName": "prusa3dboards-1.0.2.tar.bz2", + "checksum": "SHA-256:e7ff02ea51fba6a5dadfb7b14eb53f61f106f2412c0f0d95f64accc37945d82a", + "size": "101087", + "help": { + "online": "https://github.com/prusa3d/Arduino_Boards/blob/master/IDE_Board_Manager/prusa3dboards-1.0.2.md" + }, + "boards": [ + { + "name": "Original Prusa i3 MK3 Multi Material 2.0 upgrade" + }, + { + "name": "Original Prusa i3 MK3/MK3S Einsy RAMBo" + } + ], + "toolsDependencies": [] + }, + { + "name": "Prusa Research AVR MMU Boards", + "architecture": "avr", + "version": "1.0.1", + "category": "Contributed", + "url": "https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/prusa3dboards-1.0.1.tar.bz2", + "archiveFileName": "prusa3dboards-1.0.1.tar.bz2", + "checksum": "SHA-256:858cec0d14a549f637a558e51de29917796b37eaa9e1e8d6bd7449ba6bcd1ffd", + "size": "32469", + "help": { + "online": "https://github.com/prusa3d/Arduino_Boards/blob/master/IDE_Board_Manager/prusa3dboards-1.0.1.md" + }, + "boards": [ + { + "name": "Original Prusa i3 MK3 Multi Material 2.0 upgrade" + } + ], + "toolsDependencies": [] + }, { "name": "Prusa Research AVR MMU Boards", "architecture": "avr", @@ -19,7 +60,7 @@ "checksum": "SHA-256:df1061544109119ffaa2ea3fa9820aa6469f288213661e23405b7f190fd71b12", "size": "32792", "help": { - "online": "https://learn.sparkfun.com/tutorials/installing-arduino-ide/board-add-ons-with-arduino-board-manager" + "online": "https://github.com/prusa3d/Arduino_Boards/blob/master/IDE_Board_Manager/prusa3dboards-1.0.0.md" }, "boards": [ { @@ -32,7 +73,7 @@ "tools":[] }, { - "name": "PrusaResearchRambo", + "name": "PrusaResearchEinsyRAMBo", "maintainer": "Prusa Research", "websiteURL": "https://www.prusa3d.com/", "email": "info@prusa3d.com", @@ -41,7 +82,7 @@ }, "platforms": [ { - "name": "Prusa Research AVR MK3 Einsy RAMBo", + "name": "Prusa Research AVR MK3/MK3S Einsy RAMBo", "architecture": "avr", "version": "1.0.1", "category": "Contributed", @@ -50,7 +91,7 @@ "checksum": "SHA-256:68996c5de9e29603bdff3d8b7aba115f30e37383e7a3e9b89921799574d1cb31", "size": "53425", "help": { - "online": "https://learn.sparkfun.com/tutorials/installing-arduino-ide/board-add-ons-with-arduino-board-manager" + "online": "https://github.com/prusa3d/Arduino_Boards/blob/master/IDE_Board_Manager/prusa3dboards-1.0.1.md" }, "boards": [ { @@ -69,6 +110,25 @@ "version": "6.3.0-arduino9" } ] + }, + { + "name": "Prusa Research AVR MK3 RAMBo EINSy", + "architecture": "avr", + "version": "1.0.0", + "category": "Contributed", + "url": "https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/prusa3drambo-1.0.0.tar.bz2", + "archiveFileName": "prusa3drambo-1.0.0.tar.bz2", + "checksum": "SHA-256:73ec40b02ae2a13c6016057e3ba49731b8ccab71b5ed7c913f6d698819f24838", + "size": "53396", + "help": { + "online": "https://github.com/prusa3d/Arduino_Boards/blob/master/IDE_Board_Manager/prusa3dboards-1.0.1.md" + }, + "boards": [ + { + "name": "Original Prusa i3 MK3/MK3S EINSY RAMBo" + } + ], + "toolsDependencies": [] } ], "tools":[] diff --git a/IDE_Board_Manager/prusa3dboards-1.0.0.md b/IDE_Board_Manager/prusa3dboards-1.0.0.md new file mode 100644 index 0000000..88b0617 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards-1.0.0.md @@ -0,0 +1,24 @@ +# Prusa Research Boards definition version 1.0.0 + +## Boards supported +- [Prusa MM control board](https://github.com/prusa3d/MM-control-2.0) + - including bootloader + + +Folder Structure: + + . + ├── IDE_Boards_Manager + │ └── ... + └── ... + +Files: + + . + ├── IDE_Boards_Manager + │ ├── package_prusa3d_index.json + │ ├── prusa3dboards-.tar.bz2 actual used pacakges for Ardunio IDE Boards Manager + │ └── ... + ├── LICENSE + ├── README.md + └── ... diff --git a/IDE_Board_Manager/prusa3dboards-1.0.1.md b/IDE_Board_Manager/prusa3dboards-1.0.1.md new file mode 100644 index 0000000..4a33142 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards-1.0.1.md @@ -0,0 +1,39 @@ +# Prusa Research Boards definition version 1.0.1 + +## Boards supported +- [Prusa MM control board](https://github.com/prusa3d/MM-control-2.0) using prusa3dboards-1.0.0.tar.bz2 + - including bootloader +- [Einsy board](https://reprap.org/wiki/EinsyRambo) using prusa3drambo-1.0.1.tar.bz2 +- [miniRAMbo](https://reprap.org/wiki/MiniRambo) using prusa3drambo-1.0.1.tar.bz2 + +## Specials/Limits +- Restricted to use avr-gcc version `4.9.2-atmel3.5.4-arduino2` +- Restricted to use avrdude version `6.3.0-arduino9` + +Folder Structure: + + . + ├── IDE_Boards_Manager + │ ├── prusa3drambo-1.0.1 + │ ├── cores + │ └── rambo + │ ├── variants + │ └── rambo + │ └── ... + └── ... + +Files: + + . + ├── IDE_Boards_Manager + │ ├── prusa3drambo-1.0.1 Please don't change that folder name when you update your Github and post a PR. + │ ├── boards.txt contains definitions for the boards (board name, parameters for building and uploading sketches, etc.). + │ ├── platform.txt contains definitions for the CPU architecture used (compiler, build process parameters, tools used for upload, etc.). + │ ├── avrdude.conf + │ └── ... + │ ├── package_prusa3d_index.json + │ ├── prusa3dboards-.tar.bz2 actual used pacakges for Ardunio IDE Boards Manager + │ └── ... + ├── LICENSE + ├── README.md + └── ... diff --git a/IDE_Board_Manager/prusa3dboards-1.0.1.tar.bz2 b/IDE_Board_Manager/prusa3dboards-1.0.1.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..d0d72607efd6ba4c921ede13752a4fe1c952b335 GIT binary patch literal 32469 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

lPF&63X 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

9Rn7B;B#|$a~yl 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 GmJcd2GPl31Sus0?Oc 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 literal 0 HcmV?d00001 diff --git a/IDE_Board_Manager/prusa3dboards.version b/IDE_Board_Manager/prusa3dboards.version new file mode 100644 index 0000000..521fbad --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards.version @@ -0,0 +1,3 @@ +1.0.2 # With bootloader and compiler.c.elf.extra_flags for Prusa Einsy/RAMBo Prusa Frimware +1.0.1 # Added Einsy/miniRAMBo boards +1.0.0 # Original Prusa i3 MK3 Multi Material 2.0 upgrade diff --git a/IDE_Board_Manager/prusa3dboards/avrdude.conf b/IDE_Board_Manager/prusa3dboards/avrdude.conf new file mode 100644 index 0000000..861c4fb --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/avrdude.conf @@ -0,0 +1,424 @@ + +# +# This is a basic minimal config file embedded into the avrdude-slic3r binary +# so that it can work in a standalone manner. +# +# Only the bits useful for Prusa3D devices were copied over from avrdude.conf +# If needed, more configuration can still be loaded into avrdude-slic3r +# via the -C command-line option. +# + + +programmer + id = "wiring"; + desc = "Wiring"; + type = "wiring"; + connection_type = serial; +; + +programmer + id = "arduino"; + desc = "Arduino"; + type = "arduino"; + connection_type = serial; +; + +programmer + id = "avr109"; + desc = "Atmel AppNote AVR109 Boot Loader"; + type = "butterfly"; + connection_type = serial; +; + + +#------------------------------------------------------------ +# ATmega2560 +#------------------------------------------------------------ + +part + id = "m2560"; + desc = "ATmega2560"; + signature = 0x1e 0x98 0x01; + has_jtag = yes; + stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 4; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 262144; + page_size = 256; + num_pages = 1024; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + load_ext_addr = " 0 1 0 0 1 1 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 a16", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + + +#------------------------------------------------------------ +# ATmega32u4 +#------------------------------------------------------------ + +part + id = "m32u4"; + desc = "ATmega32U4"; + signature = 0x1e 0x95 0x87; + usbpid = 0x2ff4; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + diff --git a/IDE_Board_Manager/prusa3dboards/avrdude.md b/IDE_Board_Manager/prusa3dboards/avrdude.md new file mode 100644 index 0000000..d2dff75 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/avrdude.md @@ -0,0 +1 @@ +The [avrdude.conf](https://github.com/prusa3d/PrusaSlicer/tree/master/src/avrdude) is a copy of the PrusaSlicer github repository diff --git a/IDE_Board_Manager/prusa3dboards/boards.txt b/IDE_Board_Manager/prusa3dboards/boards.txt new file mode 100644 index 0000000..4c86a72 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/boards.txt @@ -0,0 +1,73 @@ +# Prusa Research Board Contribution Configuration +# +# For more information see: +# * https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification +# * https://github.com/arduino/Arduino/wiki/Arduino-Hardware-Cores-migration-guide-from-1.0-to-1.6 +# + +menu.cpu=Processor + +################################################################################ +############################### Prusa MM control ############################### +################################################################################ + +prusa_mm_control.name=Original Prusa i3 MK3 Multi Material 2.0 upgrade +prusa_mm_control.vid.0=0x2c99 +prusa_mm_control.pid.0=0x0004 +prusa_mm_control.vid.1=0x2c99 +prusa_mm_control.pid.1=0x0003 + +prusa_mm_control.upload.tool=avrdude +prusa_mm_control.upload.protocol=avr109 +prusa_mm_control.upload.maximum_size=28672 +prusa_mm_control.upload.maximum_data_size=2560 +prusa_mm_control.upload.speed=57600 +prusa_mm_control.upload.disable_flushing=true +prusa_mm_control.upload.use_1200bps_touch=true +prusa_mm_control.upload.wait_for_upload_port=true + +prusa_mm_control.bootloader.tool=avrdude +prusa_mm_control.bootloader.low_fuses=0xff +prusa_mm_control.bootloader.high_fuses=0xd8 +prusa_mm_control.bootloader.extended_fuses=0xcb +prusa_mm_control.bootloader.file=prusa_mm_control/Caterina-prusa_mm_control.hex +prusa_mm_control.bootloader.unlock_bits=0x3F +prusa_mm_control.bootloader.lock_bits=0x2F + +prusa_mm_control.build.mcu=atmega32u4 +prusa_mm_control.build.f_cpu=16000000L +prusa_mm_control.build.vid=0x2c99 +prusa_mm_control.build.pid=0x0004 +prusa_mm_control.build.usb_product="Original Prusa i3 MK3 Multi Material 2.0 upgrade" +prusa_mm_control.build.board=AVR_prusa_mm_control +prusa_mm_control.build.core=arduino:arduino +prusa_mm_control.build.variant=prusa_mm_control +prusa_mm_control.build.extra_flags={build.usb_flags} + +######################################## +########## Prusa Einsy RAMBo ########### +######################################## +prusa_einsy_rambo.name=PrusaResearch Einsy RAMBo +prusa_einsy_rambo.vid.0=0x27b1 +prusa_einsy_rambo.pid.0=0x0001 + +prusa_einsy_rambo.upload.tool=avrdude +prusa_einsy_rambo.upload.protocol=wiring +prusa_einsy_rambo.upload.maximum_size=253952 +prusa_einsy_rambo.upload.speed=115200 + +prusa_einsy_rambo.bootloader.tool=avrdude +prusa_einsy_rambo.bootloader.low_fuses=0xFF +prusa_einsy_rambo.bootloader.high_fuses=0xD8 +prusa_einsy_rambo.bootloader.extended_fuses=0xFD +prusa_einsy_rambo.bootloader.path=prusa_einsy_rambo +prusa_einsy_rambo.bootloader.file=prusa_einsy_rambo/stk500boot_v2_mega2560.hex +prusa_einsy_rambo.bootloader.unlock_bits=0x3F +prusa_einsy_rambo.bootloader.lock_bits=0x0F + +prusa_einsy_rambo.build.mcu=atmega2560 +prusa_einsy_rambo.build.f_cpu=16000000L +prusa_einsy_rambo.build.board=AVR_PRUSA_EINSY_RAMBO +prusa_einsy_rambo.build.core=prusa_einsy_rambo +prusa_einsy_rambo.build.variant=prusa_einsy_rambo +prusa_einsy_rambo.compiler.c.elf.extra_flags=-Wl,-u,vfprintf -lprintf_flt -lm \ No newline at end of file diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/License.txt b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/License.txt new file mode 100644 index 0000000..a66eb90 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/License.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/Makefile b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/Makefile new file mode 100644 index 0000000..f8e22ae --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/Makefile @@ -0,0 +1,587 @@ +# ---------------------------------------------------------------------------- +# Makefile to compile and link stk500boot bootloader +# Author: Peter Fleury +# based on WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al. +# +# Adjust F_CPU below to the clock frequency in Mhz of your AVR target +# Adjust BOOTLOADER_ADDRESS to your AVR target +# +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device, using avrdude. +# Please customize the avrdude settings below first! +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- +# = Mark Sproul msproul-at-skychariot.com + + +# MCU name +MCU = atmega2560 + + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +F_CPU = 16000000 + + +# Bootloader +# Please adjust if using a different AVR +# 0x0e00*2=0x1C00 for ATmega8 512 words Boot Size +# 0xFC00*2=0x1F800 for ATmega128 1024 words Boot Size +# 0xF800*2=0x1F000 for ATmega1280 +# 0xF000*2=0x1E000 for ATmega1280 +BOOTLOADER_ADDRESS = 3E000 + + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + + +# Target file name (without extension). +TARGET = stk500boot + + +# List C source files here. (C dependencies are automatically generated.) +SRC = stk500boot.c lcd.c + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# Debugging format. +# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. +# AVR Studio 4.10 requires dwarf-2. +# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. +DEBUG = dwarf-2 + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +EXTRAINCDIRS = + + +# Compiler flag to set the C Standard level. +# c89 = "ANSI" C +# gnu89 = c89 plus GCC extensions +# c99 = ISO C99 standard (not yet fully implemented) +# gnu99 = c99 plus GCC extensions +CSTANDARD = -std=gnu99 + + +# Place -D or -U options here +CDEFS = -DF_CPU=$(F_CPU)UL + + +# Place -I options here +CINCS = + + + +#---------------- Compiler Options ---------------- +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g$(DEBUG) +CFLAGS += $(CDEFS) $(CINCS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -fno-jump-tables +CFLAGS += -Wall -Wstrict-prototypes +CFLAGS += -Wa,-adhlns=$(<:.c=.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + + +#---------------- Assembler Options ---------------- +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + +#---------------- Library Options ---------------- +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +# If this is left blank, then it will use the Standard printf version. +PRINTF_LIB = +#PRINTF_LIB = $(PRINTF_LIB_MIN) +#PRINTF_LIB = $(PRINTF_LIB_FLOAT) + + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +# If this is left blank, then it will use the Standard scanf version. +SCANF_LIB = +#SCANF_LIB = $(SCANF_LIB_MIN) +#SCANF_LIB = $(SCANF_LIB_FLOAT) + + +MATH_LIB = -lm + + + +#---------------- External Memory Options ---------------- + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + + + + +#---------------- Linker Options ---------------- +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) + + +#--------------- bootloader linker Options ------- +# BOOTLOADER_ADDRESS (=Start of Boot Loader section +# in bytes - not words) is defined above. +#LDFLAGS += -Wl,--section-start=.text=$(BOOTLOADER_ADDRESS) -nostartfiles -nodefaultlibs +#LDFLAGS += -Wl,--section-start=.text=$(BOOTLOADER_ADDRESS) -nostartfiles +LDFLAGS += -Wl,--section-start=.text=$(BOOTLOADER_ADDRESS) + +#---------------- Programming Options (avrdude) ---------------- + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = stk500v2 + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = com1 # programmer connected to serial device + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(SRC:.c=.lst) $(ASRC:.S=.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +############################################################ +# May 25, 2010 Adding 1280 support +#mega1280: MCU = atmega1280 +#mega1280: F_CPU = 16000000 +#mega1280: BOOTLOADER_ADDRESS = 1E000 +#mega1280: CFLAGS += -D_MEGA_BOARD_ +#mega1280: begin gccversion sizebefore build sizeafter end +# mv $(TARGET).hex stk500boot_v2_mega1280.hex + + +############################################################ +# Jul 6, 2010 Adding 2560 support +mega2560: MCU = atmega2560 +mega2560: F_CPU = 16000000 +mega2560: BOOTLOADER_ADDRESS = 3E000 +mega2560: CFLAGS += -D_MEGA_BOARD_ +mega2560: begin gccversion sizebefore build sizeafter end + mv $(TARGET).hex stk500boot_v2_mega2560.hex + + +############################################################ +#Initial config on Amber128 board +# avrdude: Device signature = 0x1e9702 +# avrdude: safemode: lfuse reads as 8F +# avrdude: safemode: hfuse reads as CB +# avrdude: safemode: efuse reads as FF +# Jul 17, 2010 Adding 128 support +############################################################ +amber128: MCU = atmega128 +#amber128: F_CPU = 16000000 +amber128: F_CPU = 14745600 +amber128: BOOTLOADER_ADDRESS = 1E000 +amber128: CFLAGS += -D_BOARD_AMBER128_ +amber128: begin gccversion sizebefore build sizeafter end + mv $(TARGET).hex stk500boot_v2_amber128.hex + +############################################################ +# Aug 23, 2010 Adding atmega2561 support +m2561: MCU = atmega2561 +m2561: F_CPU = 8000000 +m2561: BOOTLOADER_ADDRESS = 3E000 +m2561: CFLAGS += -D_ANDROID_2561_ -DBAUDRATE=57600 +m2561: begin gccversion sizebefore build sizeafter end + mv $(TARGET).hex stk500boot_v2_android2561.hex + + +############################################################ +# avrdude: Device signature = 0x1e9801 +# avrdude: safemode: lfuse reads as EC +# avrdude: safemode: hfuse reads as 18 +# avrdude: safemode: efuse reads as FD +# Aug 23, 2010 Adding cerebot 2560 @ 8mhz +#avrdude -P usb -c usbtiny -p m2560 -v -U flash:w:/Arduino/WiringBootV2_upd1/stk500boot_v2_cerebotplus.hex +############################################################ +cerebot: MCU = atmega2560 +cerebot: F_CPU = 8000000 +cerebot: BOOTLOADER_ADDRESS = 3E000 +cerebot: CFLAGS += -D_CEREBOTPLUS_BOARD_ -DBAUDRATE=38400 -DUART_BAUDRATE_DOUBLE_SPEED=1 +cerebot: begin gccversion sizebefore build sizeafter end + mv $(TARGET).hex stk500boot_v2_cerebotplus.hex + + +############################################################ +# Aug 23, 2010 Adding atmega2561 support +penguino: MCU = atmega32 +penguino: F_CPU = 16000000 +penguino: BOOTLOADER_ADDRESS = 7800 +penguino: CFLAGS += -D_PENGUINO_ -DBAUDRATE=57600 +penguino: begin gccversion sizebefore build sizeafter end + mv $(TARGET).hex stk500boot_v2_penguino.hex + + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +build: elf hex eep lss sym +#build: hex eep lss sym + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --format=avr --mcu=$(MCU) $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Create preprocessed source for use in sending a bug report. +%.i : %.c + $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ + + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) *.hex + $(REMOVE) *.eep + $(REMOVE) *.cof + $(REMOVE) *.elf + $(REMOVE) *.map + $(REMOVE) *.sym + $(REMOVE) *.lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) .dep/* + + + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program debug gdb-config + diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/avr_cpunames.h b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/avr_cpunames.h new file mode 100644 index 0000000..ad0ed9c --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/avr_cpunames.h @@ -0,0 +1,189 @@ +//************************************************************************************************** +//* +//* Atmel AVR CPU name strings +//* +//************************************************************************************************** +//* Sep 19, 2010 Started on avr_cpunames.h +//************************************************************************************************** + +//#include "avr_cpunames.h" + +//************************************************************************************************** + + +#if defined (__AVR_AT94K__) + #define _AVR_CPU_NAME_ "AT94k" +#elif defined (__AVR_AT43USB320__) +#elif defined (__AVR_AT43USB355__) +#elif defined (__AVR_AT76C711__) +#elif defined (__AVR_AT86RF401__) +#elif defined (__AVR_AT90PWM1__) +#elif defined (__AVR_AT90PWM2__) +#elif defined (__AVR_AT90PWM2B__) +#elif defined (__AVR_AT90PWM3__) +#elif defined (__AVR_AT90PWM3B__) +#elif defined (__AVR_AT90PWM216__) +#elif defined (__AVR_AT90PWM316__) +#elif defined (__AVR_ATmega32C1__) +#elif defined (__AVR_ATmega32M1__) +#elif defined (__AVR_ATmega32U4__) + #define _AVR_CPU_NAME_ "ATmega32U4" +#elif defined (__AVR_ATmega32U6__) + #define _AVR_CPU_NAME_ "ATmega32U6" +#elif defined (__AVR_ATmega128__) + #define _AVR_CPU_NAME_ "Atmega128" +#elif defined (__AVR_ATmega1280__) + #define _AVR_CPU_NAME_ "ATmega1280" +#elif defined (__AVR_ATmega1281__) + #define _AVR_CPU_NAME_ "ATmega1281" +#elif defined (__AVR_ATmega1284P__) + #define _AVR_CPU_NAME_ "ATmega1284" +#elif defined (__AVR_ATmega128RFA1__) + #define _AVR_CPU_NAME_ "ATmega128RFA1" +#elif defined (__AVR_ATmega2560__) + #define _AVR_CPU_NAME_ "ATmega2560" +#elif defined (__AVR_ATmega2561__) + #define _AVR_CPU_NAME_ "ATmega2561" +#elif defined (__AVR_AT90CAN32__) + #define _AVR_CPU_NAME_ "AT90CAN32" +#elif defined (__AVR_AT90CAN64__) + #define _AVR_CPU_NAME_ "AT90CAN64" +#elif defined (__AVR_AT90CAN128__) + #define _AVR_CPU_NAME_ "AT90CAN128" +#elif defined (__AVR_AT90USB82__) + #define _AVR_CPU_NAME_ "AT90USB82" +#elif defined (__AVR_AT90USB162__) + #define _AVR_CPU_NAME_ "AT90USB162" +#elif defined (__AVR_AT90USB646__) + #define _AVR_CPU_NAME_ "AT90USB646" +#elif defined (__AVR_AT90USB647__) + #define _AVR_CPU_NAME_ "AT90USB647" +#elif defined (__AVR_AT90USB1286__) + #define _AVR_CPU_NAME_ "AT90USB1286" +#elif defined (__AVR_AT90USB1287__) + #define _AVR_CPU_NAME_ "AT90USB1287" +#elif defined (__AVR_ATmega64__) + #define _AVR_CPU_NAME_ "ATmega64" +#elif defined (__AVR_ATmega640__) + #define _AVR_CPU_NAME_ "ATmega640" +#elif defined (__AVR_ATmega644__) + #define _AVR_CPU_NAME_ "ATmega644" +#elif defined (__AVR_ATmega644P__) + #define _AVR_CPU_NAME_ "ATmega644P" +#elif defined (__AVR_ATmega645__) + #define _AVR_CPU_NAME_ "ATmega645" +#elif defined (__AVR_ATmega6450__) + #define _AVR_CPU_NAME_ "ATmega6450" +#elif defined (__AVR_ATmega649__) + #define _AVR_CPU_NAME_ "ATmega649" +#elif defined (__AVR_ATmega6490__) + #define _AVR_CPU_NAME_ "ATmega6490" +#elif defined (__AVR_ATmega103__) + #define _AVR_CPU_NAME_ "ATmega103" +#elif defined (__AVR_ATmega32__) + #define _AVR_CPU_NAME_ "Atmega32" +#elif defined (__AVR_ATmega323__) + #define _AVR_CPU_NAME_ "ATmega323" +#elif defined (__AVR_ATmega324P__) + #define _AVR_CPU_NAME_ "ATmega324P" +#elif defined (__AVR_ATmega325__) + #define _AVR_CPU_NAME_ "ATmega325" +#elif defined (__AVR_ATmega325P__) + #define _AVR_CPU_NAME_ "ATmega325P" +#elif defined (__AVR_ATmega3250__) + #define _AVR_CPU_NAME_ "ATmega3250" +#elif defined (__AVR_ATmega3250P__) + #define _AVR_CPU_NAME_ "ATmega3250P" +#elif defined (__AVR_ATmega328P__) + #define _AVR_CPU_NAME_ "ATmega328P" +#elif defined (__AVR_ATmega329__) + #define _AVR_CPU_NAME_ "ATmega329" +#elif defined (__AVR_ATmega329P__) + #define _AVR_CPU_NAME_ "ATmega329P" +#elif defined (__AVR_ATmega3290__) + #define _AVR_CPU_NAME_ "ATmega3290" +#elif defined (__AVR_ATmega3290P__) + #define _AVR_CPU_NAME_ "ATmega3290P" +#elif defined (__AVR_ATmega32HVB__) + #define _AVR_CPU_NAME_ "ATmega32HVB" +#elif defined (__AVR_ATmega406__) + #define _AVR_CPU_NAME_ "ATmega406" +#elif defined (__AVR_ATmega16__) + #define _AVR_CPU_NAME_ "Atmega16" +#elif defined (__AVR_ATmega161__) + #define _AVR_CPU_NAME_ "ATmega161" +#elif defined (__AVR_ATmega162__) + #define _AVR_CPU_NAME_ "ATmega162" +#elif defined (__AVR_ATmega163__) + #define _AVR_CPU_NAME_ "ATmega163" +#elif defined (__AVR_ATmega164P__) + #define _AVR_CPU_NAME_ "ATmega164P" +#elif defined (__AVR_ATmega165__) + #define _AVR_CPU_NAME_ "ATmega165" +#elif defined (__AVR_ATmega165P__) + #define _AVR_CPU_NAME_ "ATmega165P" +#elif defined (__AVR_ATmega168__) + #define _AVR_CPU_NAME_ "ATmega168" +#elif defined (__AVR_ATmega168P__) + #define _AVR_CPU_NAME_ "ATmega168P" +#elif defined (__AVR_ATmega169__) + #define _AVR_CPU_NAME_ "Atmega169" +#elif defined (__AVR_ATmega169P__) + #define _AVR_CPU_NAME_ "ATmega169P" +#elif defined (__AVR_ATmega8HVA__) + #define _AVR_CPU_NAME_ "ATmega8HVA" +#elif defined (__AVR_ATmega16HVA__) + #define _AVR_CPU_NAME_ "ATmega16HVA" +#elif defined (__AVR_ATmega8__) + #define _AVR_CPU_NAME_ "ATmega8" +#elif defined (__AVR_ATmega48__) + #define _AVR_CPU_NAME_ "ATmega48" +#elif defined (__AVR_ATmega48P__) + #define _AVR_CPU_NAME_ "ATmega48P" +#elif defined (__AVR_ATmega88__) + #define _AVR_CPU_NAME_ "ATmega88" +#elif defined (__AVR_ATmega88P__) + #define _AVR_CPU_NAME_ "ATmega88P" +#elif defined (__AVR_ATmega8515__) + #define _AVR_CPU_NAME_ "ATmega8515" +#elif defined (__AVR_ATmega8535__) + #define _AVR_CPU_NAME_ "ATmega8535" +#elif defined (__AVR_AT90S8535__) +#elif defined (__AVR_AT90C8534__) +#elif defined (__AVR_AT90S8515__) +#elif defined (__AVR_AT90S4434__) +#elif defined (__AVR_AT90S4433__) +#elif defined (__AVR_AT90S4414__) +#elif defined (__AVR_ATtiny22__) +#elif defined (__AVR_ATtiny26__) +#elif defined (__AVR_AT90S2343__) +#elif defined (__AVR_AT90S2333__) +#elif defined (__AVR_AT90S2323__) +#elif defined (__AVR_AT90S2313__) +#elif defined (__AVR_ATtiny2313__) + #define _AVR_CPU_NAME_ "ATtiny2313" +#elif defined (__AVR_ATtiny13__) +#elif defined (__AVR_ATtiny13A__) +#elif defined (__AVR_ATtiny25__) +#elif defined (__AVR_ATtiny45__) +#elif defined (__AVR_ATtiny85__) +#elif defined (__AVR_ATtiny24__) +#elif defined (__AVR_ATtiny44__) +#elif defined (__AVR_ATtiny84__) +#elif defined (__AVR_ATtiny261__) +#elif defined (__AVR_ATtiny461__) +#elif defined (__AVR_ATtiny861__) +#elif defined (__AVR_ATtiny43U__) +#elif defined (__AVR_ATtiny48__) +#elif defined (__AVR_ATtiny88__) +#elif defined (__AVR_ATtiny167__) +#elif defined (__AVR_ATmega8U2__) + #define _AVR_CPU_NAME_ "ATmega8U2" +#else + #error cpu not defined +#endif + + +#if !defined (_AVR_CPU_NAME_) +// #define _AVR_CPU_NAME_ "UNKNOWN" +#endif diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/avrinterruptnames.h b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/avrinterruptnames.h new file mode 100644 index 0000000..e7e3ed9 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/avrinterruptnames.h @@ -0,0 +1,1040 @@ +//************************************************************************************************** +//* +//* interrupt vector names +//* +//* It is important to note that the vector numbers listed here +//* are the ATMEL documentation numbers. The Arduino numbers are 1 less +//* This is because the Atmel docs start numbering the interrupts at 1 +//* when it is actually vector #0 in the table. +//************************************************************************************************** +//* Jun 1, 2010 Added support for ATmega1281 +//* Jun 30, 2010 Putting in more ifdefs to conserve space +//* Jul 3, 2010 More #ifdefs to conserve space and testing on most of my boards +//* Jul 4, 2010 Started using vector defs for #ifdefs as defined in +//* Jul 13, 2010 Added support for __AVR_ATmega128__ +//* Aug 26, 2010 Added support for __AVR_ATmega2561__ +//* Sep 13, 2010 Added support for __AVR_AT90CAN32__ __AVR_AT90CAN64__ __AVR_AT90CAN128__ +//************************************************************************************************** + +//#include "avrinterruptnames.h" + +//************************************************************************************************** +//* this defines the interrupt vectors and allows us to compile ONLY those strings that are actually +//* in the target CPU. This way we do not have to keep making changes based on cpu, it will be +//* automatic even if we add a new CPU +#ifndef _AVR_IO_H_ + #include +#endif +//************************************************************************************************** + +#ifdef __MWERKS__ + #define prog_char char + #define PGM_P char * +#endif + + prog_char gAvrInt_RESET[] PROGMEM = "RESET"; +#ifdef INT0_vect + prog_char gAvrInt_INT0[] PROGMEM = "INT0"; +#endif +#ifdef INT1_vect + prog_char gAvrInt_INT1[] PROGMEM = "INT1"; +#endif +#ifdef INT2_vect + prog_char gAvrInt_INT2[] PROGMEM = "INT2"; +#endif +#ifdef INT3_vect + prog_char gAvrInt_INT3[] PROGMEM = "INT3"; +#endif +#ifdef INT4_vect + prog_char gAvrInt_INT4[] PROGMEM = "INT4"; +#endif +#ifdef INT5_vect + prog_char gAvrInt_INT5[] PROGMEM = "INT5"; +#endif +#ifdef INT6_vect + prog_char gAvrInt_INT6[] PROGMEM = "INT6"; +#endif +#ifdef INT7_vect + prog_char gAvrInt_INT7[] PROGMEM = "INT7"; +#endif +#ifdef PCINT0_vect + prog_char gAvrInt_PCINT0[] PROGMEM = "PCINT0"; +#endif +#ifdef PCINT1_vect + prog_char gAvrInt_PCINT1[] PROGMEM = "PCINT1"; +#endif +#ifdef PCINT2_vect + prog_char gAvrInt_PCINT2[] PROGMEM = "PCINT2"; +#endif +#ifdef PCINT3_vect + prog_char gAvrInt_PCINT3[] PROGMEM = "PCINT3"; +#endif +#ifdef WDT_vect + prog_char gAvrInt_WDT[] PROGMEM = "WDT"; +#endif +#ifdef TIMER0_COMP_vect + prog_char gAvrInt_TIMER0_COMP[] PROGMEM = "TIMER0 COMP"; +#endif +#ifdef TIMER0_COMPA_vect + prog_char gAvrInt_TIMER0_COMPA[] PROGMEM = "TIMER0 COMPA"; +#endif +#ifdef TIMER0_COMPB_vect + prog_char gAvrInt_TIMER0_COMPB[] PROGMEM = "TIMER0 COMPB"; +#endif +#ifdef TIMER0_OVF_vect + prog_char gAvrInt_TIMER0_OVF[] PROGMEM = "TIMER0 OVF"; +#endif +#ifdef TIMER1_CAPT_vect + prog_char gAvrInt_TIMER1_CAPT[] PROGMEM = "TIMER1 CAPT"; +#endif +#ifdef TIMER1_COMPA_vect + prog_char gAvrInt_TIMER1_COMPA[] PROGMEM = "TIMER1 COMPA"; +#endif +#ifdef TIMER1_COMPB_vect + prog_char gAvrInt_TIMER1_COMPB[] PROGMEM = "TIMER1 COMPB"; +#endif +#ifdef TIMER1_COMPC_vect + prog_char gAvrInt_TIMER1_COMPC[] PROGMEM = "TIMER1 COMPC"; +#endif +#ifdef TIMER1_OVF_vect + prog_char gAvrInt_TIMER1_OVF[] PROGMEM = "TIMER1 OVF"; +#endif +#ifdef TIMER2_COMP_vect + prog_char gAvrInt_TIMER2_COMP[] PROGMEM = "TIMER2 COMP"; +#endif +#ifdef TIMER2_COMPA_vect + prog_char gAvrInt_TIMER2_COMPA[] PROGMEM = "TIMER2 COMPA"; +#endif +#ifdef TIMER2_COMPB_vect + prog_char gAvrInt_TIMER2_COMPB[] PROGMEM = "TIMER2 COMPB"; +#endif +#ifdef TIMER2_OVF_vect + prog_char gAvrInt_TIMER2_OVF[] PROGMEM = "TIMER2 OVF"; +#endif +#ifdef TIMER3_CAPT_vect + prog_char gAvrInt_TIMER3_CAPT[] PROGMEM = "TIMER3 CAPT"; +#endif +#ifdef TIMER3_COMPA_vect + prog_char gAvrInt_TIMER3_COMPA[] PROGMEM = "TIMER3 COMPA"; +#endif +#ifdef TIMER3_COMPB_vect + prog_char gAvrInt_TIMER3_COMPB[] PROGMEM = "TIMER3 COMPB"; +#endif +#ifdef TIMER3_COMPC_vect + prog_char gAvrInt_TIMER3_COMPC[] PROGMEM = "TIMER3 COMPC"; +#endif +#ifdef TIMER3_OVF_vect + prog_char gAvrInt_TIMER3_OVF[] PROGMEM = "TIMER3 OVF"; +#endif +#ifdef TIMER4_CAPT_vect + prog_char gAvrInt_TIMER4_CAPT[] PROGMEM = "TIMER4 CAPT"; +#endif +#ifdef TIMER4_COMPA_vect + prog_char gAvrInt_TIMER4_COMPA[] PROGMEM = "TIMER4 COMPA"; +#endif +#ifdef TIMER4_COMPB_vect + prog_char gAvrInt_TIMER4_COMPB[] PROGMEM = "TIMER4 COMPB"; +#endif +#ifdef TIMER4_COMPC_vect + prog_char gAvrInt_TIMER4_COMPC[] PROGMEM = "TIMER4 COMPC"; +#endif +#ifdef TIMER4_COMPD_vect + prog_char gAvrInt_TIMER4_COMPD[] PROGMEM = "TIMER4 COMPD"; +#endif +#ifdef TIMER4_OVF_vect + prog_char gAvrInt_TIMER4_OVF[] PROGMEM = "TIMER4 OVF"; +#endif +#ifdef TIMER4_FPF_vect + prog_char gAvrInt_TIMER4_FPF[] PROGMEM = "TIMER4 Fault Protection"; +#endif +#ifdef TIMER5_CAPT_vect + prog_char gAvrInt_TIMER5_CAPT[] PROGMEM = "TIMER5 CAPT"; +#endif +#ifdef TIMER5_COMPA_vect + prog_char gAvrInt_TIMER5_COMPA[] PROGMEM = "TIMER5 COMPA"; +#endif +#ifdef TIMER5_COMPB_vect + prog_char gAvrInt_TIMER5_COMPB[] PROGMEM = "TIMER5 COMPB"; +#endif +#ifdef TIMER5_COMPC_vect + prog_char gAvrInt_TIMER5_COMPC[] PROGMEM = "TIMER5 COMPC"; +#endif +#ifdef TIMER5_OVF_vect + prog_char gAvrInt_TIMER5_OVF[] PROGMEM = "TIMER5 OVF"; +#endif + +//* when there is only 1 usart +#if defined(USART_RX_vect) || defined(USART_RXC_vect) + prog_char gAvrInt_USART_RX[] PROGMEM = "USART RX"; +#endif +#if defined(USART_UDRE_vect) + prog_char gAvrInt_USART_UDRE[] PROGMEM = "USART UDRE"; +#endif +#if defined(USART_TX_vect) || defined(USART_TXC_vect) + prog_char gAvrInt_USART_TX[] PROGMEM = "USART TX"; +#endif + + +//* usart 0 +#if defined(USART0_RX_vect) + prog_char gAvrInt_USART0_RX[] PROGMEM = "USART0 RX"; +#endif +#if defined(USART0_UDRE_vect) + prog_char gAvrInt_USART0_UDRE[] PROGMEM = "USART0 UDRE"; +#endif +#if defined(USART0_TX_vect) + prog_char gAvrInt_USART0_TX[] PROGMEM = "USART0 TX"; +#endif + + +//* usart 1 +#ifdef USART1_RX_vect + prog_char gAvrInt_USART1_RX[] PROGMEM = "USART1 RX"; +#endif +#ifdef USART1_UDRE_vect + prog_char gAvrInt_USART1_UDRE[] PROGMEM = "USART1 UDRE"; +#endif +#ifdef USART1_TX_vect + prog_char gAvrInt_USART1_TX[] PROGMEM = "USART1 TX"; +#endif + +//* usart 2 +#ifdef USART2_RX_vect + prog_char gAvrInt_USART2_RX[] PROGMEM = "USART2 RX"; +#endif +#ifdef USART2_UDRE_vect + prog_char gAvrInt_USART2_UDRE[] PROGMEM = "USART2 UDRE"; +#endif +#ifdef USART2_TX_vect + prog_char gAvrInt_USART2_TX[] PROGMEM = "USART2 TX"; +#endif + +//* usart 3 +#ifdef USART3_RX_vect + prog_char gAvrInt_USART3_RX[] PROGMEM = "USART3 RX"; +#endif +#ifdef USART3_UDRE_vect + prog_char gAvrInt_USART3_UDRE[] PROGMEM = "USART3 UDRE"; +#endif +#ifdef USART3_TX_vect + prog_char gAvrInt_USART3_TX[] PROGMEM = "USART3 TX"; +#endif +#ifdef SPI_STC_vect + prog_char gAvrInt_SPI_STC[] PROGMEM = "SPI STC"; +#endif +#ifdef ADC_vect + prog_char gAvrInt_ADC[] PROGMEM = "ADC"; +#endif +#if defined(ANALOG_COMP_vect) || defined(ANA_COMP_vect) + prog_char gAvrInt_ANALOG_COMP[] PROGMEM = "ANALOG COMP"; +#endif +#if defined(EE_READY_vect) || defined(EE_RDY_vect) + prog_char gAvrInt_EE_READY[] PROGMEM = "EE READY"; +#endif +#ifdef TWI_vect + prog_char gAvrInt_TWI[] PROGMEM = "TWI"; +#endif +#if defined(SPM_READY_vect) || defined(SPM_RDY_vect) + prog_char gAvrInt_SPM_READY[] PROGMEM = "SPM READY"; +#endif +#ifdef USI_START_vect + prog_char gAvrInt_USI_START[] PROGMEM = "USI START"; +#endif +#ifdef USI_OVERFLOW_vect + prog_char gAvrInt_USI_OVERFLOW[] PROGMEM = "USI OVERFLOW"; +#endif +#ifdef USB_GEN_vect + prog_char gAvrInt_USB_General[] PROGMEM = "USB General"; +#endif +#ifdef USB_COM_vect + prog_char gAvrInt_USB_Endpoint[] PROGMEM = "USB Endpoint"; +#endif + +#ifdef LCD_vect + prog_char gAvrInt_LCD_StartFrame[] PROGMEM = "LCD Start of Frame"; +#endif + +//* these are for the chips with CAN bus support +#ifdef CANIT_vect + prog_char gAvrInt_CAN_TrafnsferCE[] PROGMEM = "CAN Transfer Complete or Error"; +#endif +#ifdef OVRIT_vect + prog_char gAvrInt_CAN_TimerOverRun[] PROGMEM = "CAN Timer Overrun"; +#endif + +//* these are for __AVR_ATmega128RFA1__ +#ifdef TRX24_PLL_LOCK_vect + prog_char gAvrInt_TRN_PLL_LOCK[] PROGMEM = "TRX24_PLL_LOCK"; +#endif +#ifdef TRX24_PLL_UNLOCK_vect + prog_char gAvrInt_TRN_PLL_UNLOCK[] PROGMEM = "TRX24_PLL_UNLOCK"; +#endif +#ifdef TRX24_RX_START_vect + prog_char gAvrInt_TRN_RX_START[] PROGMEM = "TRX24_RX_START"; +#endif +#ifdef TRX24_RX_END_vect + prog_char gAvrInt_TRN_RX_END[] PROGMEM = "TRX24_RX_END"; +#endif +#ifdef TRX24_CCA_ED_DONE_vect + prog_char gAvrInt_TRN_CAAED_DONE[] PROGMEM = "TRX24_CCA_ED_DONE"; +#endif +#ifdef TRX24_XAH_AMI_vect + prog_char gAvrInt_TRN_FRAME_MATCH[] PROGMEM = "TRX24_FRAME_ADDRESS_MATCH"; +#endif +#ifdef TRX24_TX_END_vect + prog_char gAvrInt_TRN_TX_END[] PROGMEM = "TRX24_TX_END"; +#endif +#ifdef TRX24_AWAKE_vect + prog_char gAvrInt_TRN_AWAKE[] PROGMEM = "TRX24_AWAKE"; +#endif +#ifdef SCNT_CMP1_vect + prog_char gAvrInt_SCNT_CMP1[] PROGMEM = "SCNT_CMP1"; +#endif +#ifdef SCNT_CMP2_vect + prog_char gAvrInt_SCNT_CMP2[] PROGMEM = "SCNT_CMP2"; +#endif +#ifdef SCNT_CMP3_vect + prog_char gAvrInt_SCNT_CMP3[] PROGMEM = "SCNT_CMP3"; +#endif +#ifdef SCNT_OVFL_vect + prog_char gAvrInt_SCNT_OVFL[] PROGMEM = "SCNT_OVFL"; +#endif +#ifdef SCNT_BACKOFF_vect + prog_char gAvrInt_SCNT_BACKOFF[] PROGMEM = "SCNT_BACKOFF"; +#endif +#ifdef AES_READY_vect + prog_char gAvrInt_AES_READY[] PROGMEM = "AES_READY"; +#endif +#ifdef BAT_LOW_vect + prog_char gAvrInt_BAT_LOW[] PROGMEM = "BAT_LOW"; +#endif + + + +//************************************************************************************************** +//* these do not have vector defs and have to be done by CPU type +#if defined(__AVR_ATmega645__ ) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) + prog_char gAvrInt_NOT_USED[] PROGMEM = "NOT_USED"; +#endif +#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega128RFA1__) + prog_char gAvrInt_RESERVED[] PROGMEM = "Reserved"; +#endif + + prog_char gAvrInt_END[] PROGMEM = "*"; + + + + + +//************************************************************************************************** +#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) +#pragma mark __AVR_ATmega168__ / __AVR_ATmega328P__ / __AVR_ATmega328__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_PCINT0, // 4 + gAvrInt_PCINT1, // 5 + gAvrInt_PCINT2, // 6 + gAvrInt_WDT, // 7 + gAvrInt_TIMER2_COMPA, // 8 + gAvrInt_TIMER2_COMPB, // 9 + gAvrInt_TIMER2_OVF, // 10 + gAvrInt_TIMER1_CAPT, // 11 + gAvrInt_TIMER1_COMPA, // 12 + gAvrInt_TIMER1_COMPB, // 13 + gAvrInt_TIMER1_OVF, // 14 + gAvrInt_TIMER0_COMPA, // 15 + gAvrInt_TIMER0_COMPB, // 16 + gAvrInt_TIMER0_OVF, // 17 + gAvrInt_SPI_STC, // 18 + gAvrInt_USART_RX, // 19 + gAvrInt_USART_UDRE, // 20 + gAvrInt_USART_TX, // 21 + gAvrInt_ADC, // 22 + gAvrInt_EE_READY, // 23 + gAvrInt_ANALOG_COMP, // 24 + gAvrInt_TWI, // 25 + gAvrInt_SPM_READY, // 26 +}; + +#endif + +//************************************************************************************************** +#if defined(__AVR_ATmega169__) +#pragma mark __AVR_ATmega169__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_PCINT0, // 3 + gAvrInt_PCINT1, // 4 + gAvrInt_TIMER2_COMP, // 5 + gAvrInt_TIMER2_OVF, // 6 + gAvrInt_TIMER1_CAPT, // 7 + gAvrInt_TIMER1_COMPA, // 8 + gAvrInt_TIMER1_COMPB, // 9 + gAvrInt_TIMER1_OVF, // 10 + gAvrInt_TIMER0_COMP, // 11 + gAvrInt_TIMER0_OVF, // 12 + gAvrInt_SPI_STC, // 13 + gAvrInt_USART0_RX, // 14 + gAvrInt_USART0_UDRE, // 15 + gAvrInt_USART0_TX, // 16 + gAvrInt_USI_START, // 17 + gAvrInt_USI_OVERFLOW, // 18 + gAvrInt_ANALOG_COMP, // 19 + gAvrInt_ADC, // 20 + gAvrInt_EE_READY, // 21 + gAvrInt_SPM_READY, // 22 + gAvrInt_LCD_StartFrame, // 23 + +}; + +#endif + + +//************************************************************************************************** +#if defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) +#pragma mark __AVR_ATmega640__ __AVR_ATmega1280__ __AVR_ATmega1281__ __AVR_ATmega2560__ __AVR_ATmega2561__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_INT2, // 4 + gAvrInt_INT3, // 5 + gAvrInt_INT4, // 6 + gAvrInt_INT5, // 7 + gAvrInt_INT6, // 8 + gAvrInt_INT7, // 9 + gAvrInt_PCINT0, // 10 + gAvrInt_PCINT1, // 11 +#if defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + gAvrInt_PCINT2, // 12 +#else + gAvrInt_NOT_USED, // 12 +#endif + gAvrInt_WDT, // 13 + gAvrInt_TIMER2_COMPA, // 14 + gAvrInt_TIMER2_COMPB, // 15 + gAvrInt_TIMER2_OVF, // 16 + gAvrInt_TIMER1_CAPT, // 17 + gAvrInt_TIMER1_COMPA, // 18 + gAvrInt_TIMER1_COMPB, // 19 + gAvrInt_TIMER1_COMPC, // 20 + gAvrInt_TIMER1_OVF, // 21 + gAvrInt_TIMER0_COMPA, // 22 + gAvrInt_TIMER0_COMPB, // 23 + gAvrInt_TIMER0_OVF, // 24 + gAvrInt_SPI_STC, // 25 + + gAvrInt_USART0_RX, // 26 + gAvrInt_USART0_UDRE, // 27 + gAvrInt_USART0_TX, // 28 + gAvrInt_ANALOG_COMP, // 29 + gAvrInt_ADC, // 30 + gAvrInt_EE_READY, // 31 + + gAvrInt_TIMER3_CAPT, // 32 + gAvrInt_TIMER3_COMPA, // 33 + gAvrInt_TIMER3_COMPB, // 34 + gAvrInt_TIMER3_COMPC, // 35 + gAvrInt_TIMER3_OVF, // 36 + + gAvrInt_USART1_RX, // 37 + gAvrInt_USART1_UDRE, // 38 + gAvrInt_USART1_TX, // 39 + gAvrInt_TWI, // 40 + gAvrInt_SPM_READY, // 41 +#if defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + gAvrInt_TIMER4_CAPT, // 42 +#else + gAvrInt_NOT_USED, // 42 +#endif + gAvrInt_TIMER4_COMPA, // 43 + gAvrInt_TIMER4_COMPB, // 44 + gAvrInt_TIMER4_COMPC, // 45 + gAvrInt_TIMER4_OVF, // 46 +#if defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + gAvrInt_TIMER5_CAPT, // 47 +#else + gAvrInt_NOT_USED, // 47 +#endif + gAvrInt_TIMER5_COMPA, // 48 + gAvrInt_TIMER5_COMPB, // 49 + gAvrInt_TIMER5_COMPC, // 50 + gAvrInt_TIMER5_OVF, // 51 + +#if defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + gAvrInt_USART2_RX, // 52 + gAvrInt_USART2_UDRE, // 53 + gAvrInt_USART2_TX, // 54 + + gAvrInt_USART3_RX, // 55 + gAvrInt_USART3_UDRE, // 56 + gAvrInt_USART3_TX, // 57 +#endif + +}; + +#endif + + + +//************************************************************************************************** +#if defined(__AVR_ATmega324P__ ) || defined(__AVR_ATmega644__ ) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) +#pragma mark __AVR_ATmega324P__ __AVR_ATmega644__ __AVR_ATmega644P__ __AVR_ATmega1284P__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_INT2, // 4 + gAvrInt_PCINT0, // 5 + gAvrInt_PCINT1, // 6 + gAvrInt_PCINT2, // 7 + gAvrInt_PCINT3, // 8 + gAvrInt_WDT, // 9 + gAvrInt_TIMER2_COMPA, // 10 + gAvrInt_TIMER2_COMPB, // 11 + gAvrInt_TIMER2_OVF, // 12 + gAvrInt_TIMER1_CAPT, // 13 + gAvrInt_TIMER1_COMPA, // 14 + gAvrInt_TIMER1_COMPB, // 15 + gAvrInt_TIMER1_OVF, // 16 + gAvrInt_TIMER0_COMPA, // 17 + gAvrInt_TIMER0_COMPB, // 18 + gAvrInt_TIMER0_OVF, // 19 + gAvrInt_SPI_STC, // 20 + gAvrInt_USART0_RX, // 21 + gAvrInt_USART0_UDRE, // 22 + gAvrInt_USART0_TX, // 23 + gAvrInt_ANALOG_COMP, // 24 + gAvrInt_ADC, // 25 + gAvrInt_EE_READY, // 26 + gAvrInt_TWI, // 27 + gAvrInt_SPM_READY, // 28 + +#if defined(__AVR_ATmega324P__ ) || defined(__AVR_ATmega644P__) + gAvrInt_USART1_RX, // 29 + gAvrInt_USART1_UDRE, // 30 + gAvrInt_USART1_TX, // 31 +#endif + +}; + + +#endif + +//************************************************************************************************** +#if defined(__AVR_ATmega1284P__ ) +#pragma mark __AVR_ATmega1284P__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_INT2, // 4 + gAvrInt_PCINT0, // 5 + gAvrInt_PCINT1, // 6 + gAvrInt_PCINT2, // 7 + gAvrInt_PCINT3, // 8 + gAvrInt_WDT, // 9 + gAvrInt_TIMER2_COMPA, // 10 + gAvrInt_TIMER2_COMPB, // 11 + gAvrInt_TIMER2_OVF, // 12 + gAvrInt_TIMER1_CAPT, // 13 + gAvrInt_TIMER1_COMPA, // 14 + gAvrInt_TIMER1_COMPB, // 15 + gAvrInt_TIMER1_OVF, // 16 + gAvrInt_TIMER0_COMPA, // 17 + gAvrInt_TIMER0_COMPB, // 18 + gAvrInt_TIMER0_OVF, // 19 + gAvrInt_SPI_STC, // 20 + gAvrInt_USART0_RX, // 21 + gAvrInt_USART0_UDRE, // 22 + gAvrInt_USART0_TX, // 23 + gAvrInt_ANALOG_COMP, // 24 + gAvrInt_ADC, // 25 + gAvrInt_EE_READY, // 26 + gAvrInt_TWI, // 27 + gAvrInt_SPM_READY, // 28 + + gAvrInt_USART1_RX, // 29 + gAvrInt_USART1_UDRE, // 30 + gAvrInt_USART1_TX, // 31 + //* these are NOT documented in doc8272.pdf + //* they are in iom1284p.h + gAvrInt_TIMER3_CAPT, // 32 + gAvrInt_TIMER3_COMPA, // 33 + gAvrInt_TIMER3_COMPB, // 34 + gAvrInt_TIMER3_OVF, // 35 + + +}; + + +#endif + + +//************************************************************************************************** +#if defined(__AVR_ATmega645__ ) +#pragma mark __AVR_ATmega645__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_PCINT0, // 3 + gAvrInt_PCINT1, // 4 + gAvrInt_TIMER2_COMP, // 5 + gAvrInt_TIMER2_OVF, // 6 + gAvrInt_TIMER1_CAPT, // 7 + gAvrInt_TIMER1_COMPA, // 8 + gAvrInt_TIMER1_COMPB, // 9 + gAvrInt_TIMER1_OVF, // 10 + gAvrInt_TIMER0_COMP, // 11 + gAvrInt_TIMER0_OVF, // 12 + gAvrInt_SPI_STC, // 13 + gAvrInt_USART0_RX, // 14 + gAvrInt_USART0_UDRE, // 15 + gAvrInt_USART0_TX, // 16 + gAvrInt_USI_START, // 17 + gAvrInt_USI_OVERFLOW, // 18 + gAvrInt_ANALOG_COMP, // 19 + gAvrInt_ADC, // 20 + gAvrInt_EE_READY, // 21 + gAvrInt_SPM_READY, // 22 + gAvrInt_NOT_USED, // 23 + +#if defined(__AVR_ATmega3250__) || defined(__AVR_ATmega6450__) + gAvrInt_PCINT2, // 24 + gAvrInt_PCINT3, // 25 +#endif +}; + + +#endif + +//************************************************************************************************** +#if defined(__AVR_ATmega16__ ) +#pragma mark __AVR_ATmega16__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_TIMER2_COMP, // 4 + gAvrInt_TIMER2_OVF, // 5 + gAvrInt_TIMER1_CAPT, // 6 + gAvrInt_TIMER1_COMPA, // 7 + gAvrInt_TIMER1_COMPB, // 8 + gAvrInt_TIMER1_OVF, // 9 + gAvrInt_TIMER0_OVF, // 10 + gAvrInt_SPI_STC, // 11 + gAvrInt_USART_RX, // 12 + gAvrInt_USART_UDRE, // 13 + gAvrInt_USART_TX, // 14 + gAvrInt_ADC, // 15 + gAvrInt_EE_READY, // 16 + gAvrInt_ANALOG_COMP, // 17 + gAvrInt_TWI, // 18 + gAvrInt_INT2, // 19 + gAvrInt_TIMER0_COMP, // 20 + gAvrInt_SPM_READY, // 21 + +}; + + +#endif + +//************************************************************************************************** +#if defined(__AVR_ATmega32__ ) +#pragma mark __AVR_ATmega32__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_INT2, // 4 + gAvrInt_TIMER2_COMP, // 5 + gAvrInt_TIMER2_OVF, // 6 + gAvrInt_TIMER1_CAPT, // 7 + gAvrInt_TIMER1_COMPA, // 8 + gAvrInt_TIMER1_COMPB, // 9 + gAvrInt_TIMER1_OVF, // 10 + gAvrInt_TIMER0_COMP, // 11 + gAvrInt_TIMER0_OVF, // 12 + gAvrInt_SPI_STC, // 13 + gAvrInt_USART_RX, // 14 + gAvrInt_USART_UDRE, // 15 + gAvrInt_USART_TX, // 16 + gAvrInt_ADC, // 17 + gAvrInt_EE_READY, // 18 + gAvrInt_ANALOG_COMP, // 19 + gAvrInt_TWI, // 20 + gAvrInt_SPM_READY, // 21 + +}; + + +#endif + +//************************************************************************************************** +#if defined(__AVR_ATmega32U4__) +#pragma mark __AVR_ATmega32U4__ +//* teensy 2.0 +//* http://www.pjrc.com/teensy/pinout.html +#define _INTERRUPT_NAMES_DEFINED_ + + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_INT2, // 4 + gAvrInt_INT3, // 5 + gAvrInt_RESERVED, // 6 + gAvrInt_RESERVED, // 7 + gAvrInt_INT6, // 8 + gAvrInt_RESERVED, // 9 + gAvrInt_PCINT0, // 10 + gAvrInt_USB_General, // 11 + gAvrInt_USB_Endpoint, // 12 + gAvrInt_WDT, // 13 + gAvrInt_RESERVED, // 14 + gAvrInt_RESERVED, // 15 + gAvrInt_RESERVED, // 16 + gAvrInt_TIMER1_CAPT, // 17 + gAvrInt_TIMER1_COMPA, // 18 + gAvrInt_TIMER1_COMPB, // 19 + gAvrInt_TIMER1_COMPC, // 20 + gAvrInt_TIMER1_OVF, // 21 + gAvrInt_TIMER0_COMPA, // 22 + gAvrInt_TIMER0_COMPB, // 23 + gAvrInt_TIMER0_OVF, // 24 + gAvrInt_SPI_STC, // 25 + + gAvrInt_USART1_RX, // 26 + gAvrInt_USART1_UDRE, // 27 + gAvrInt_USART1_TX, // 28 + gAvrInt_ANALOG_COMP, // 29 + + gAvrInt_ADC, // 30 + gAvrInt_EE_READY, // 31 + + gAvrInt_TIMER3_CAPT, // 32 + gAvrInt_TIMER3_COMPA, // 33 + gAvrInt_TIMER3_COMPB, // 34 + gAvrInt_TIMER3_COMPC, // 35 + gAvrInt_TIMER3_OVF, // 36 + gAvrInt_TWI, // 37 + gAvrInt_SPM_READY, // 38 + + gAvrInt_TIMER4_COMPA, // 39 + gAvrInt_TIMER4_COMPB, // 40 + gAvrInt_TIMER4_COMPD, // 41 + gAvrInt_TIMER4_OVF, // 42 + gAvrInt_TIMER4_FPF, // 43 +}; + +#endif + +//************************************************************************************************** +#if defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) +#pragma mark __AVR_AT90USB1286__ +//* teensy++ 2.0 +//* http://www.pjrc.com/teensy/pinout.html +#define _INTERRUPT_NAMES_DEFINED_ + + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_INT2, // 4 + gAvrInt_INT3, // 5 + gAvrInt_INT4, // 6 + gAvrInt_INT5, // 7 + gAvrInt_INT6, // 8 + gAvrInt_INT7, // 9 + gAvrInt_PCINT0, // 10 + gAvrInt_USB_General, // 11 + gAvrInt_USB_Endpoint, // 12 + gAvrInt_WDT, // 13 + gAvrInt_TIMER2_COMPA, // 14 + gAvrInt_TIMER2_COMPB, // 15 + gAvrInt_TIMER2_OVF, // 16 + gAvrInt_TIMER1_CAPT, // 17 + gAvrInt_TIMER1_COMPA, // 18 + gAvrInt_TIMER1_COMPB, // 19 + gAvrInt_TIMER1_COMPC, // 20 + gAvrInt_TIMER1_OVF, // 21 + gAvrInt_TIMER0_COMPA, // 22 + gAvrInt_TIMER0_COMPB, // 23 + gAvrInt_TIMER0_OVF, // 24 + gAvrInt_SPI_STC, // 25 + + gAvrInt_USART1_RX, // 26 + gAvrInt_USART1_UDRE, // 27 + gAvrInt_USART1_TX, // 28 + gAvrInt_ANALOG_COMP, // 29 + + gAvrInt_ADC, // 30 + gAvrInt_EE_READY, // 31 + + gAvrInt_TIMER3_CAPT, // 32 + gAvrInt_TIMER3_COMPA, // 33 + gAvrInt_TIMER3_COMPB, // 34 + gAvrInt_TIMER3_COMPC, // 35 + gAvrInt_TIMER3_OVF, // 36 + gAvrInt_TWI, // 37 + gAvrInt_SPM_READY, // 38 + +}; + +#endif + + + + +//************************************************************************************************** +#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega64__) +#pragma mark __AVR_ATmega64__ __AVR_ATmega128__ +#define _INTERRUPT_NAMES_DEFINED_ + + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_INT2, // 4 + gAvrInt_INT3, // 5 + gAvrInt_INT4, // 6 + gAvrInt_INT5, // 7 + gAvrInt_INT6, // 8 + gAvrInt_INT7, // 9 + gAvrInt_TIMER2_COMP, // 10 + gAvrInt_TIMER2_OVF, // 11 + gAvrInt_TIMER1_CAPT, // 12 + gAvrInt_TIMER1_COMPA, // 13 + gAvrInt_TIMER1_COMPB, // 14 + gAvrInt_TIMER1_OVF, // 15 + gAvrInt_TIMER0_COMP, // 16 + gAvrInt_TIMER0_OVF, // 17 + gAvrInt_SPI_STC, // 18 + gAvrInt_USART0_RX, // 19 + gAvrInt_USART0_UDRE, // 20 + gAvrInt_USART0_TX, // 21 + gAvrInt_ADC, // 22 + gAvrInt_EE_READY, // 23 + gAvrInt_ANALOG_COMP, // 24 + gAvrInt_TIMER1_COMPC, // 25 + gAvrInt_TIMER3_CAPT, // 26 + gAvrInt_TIMER3_COMPA, // 27 + gAvrInt_TIMER3_COMPB, // 28 + gAvrInt_TIMER3_COMPC, // 29 + gAvrInt_TIMER3_OVF, // 30 + gAvrInt_USART1_RX, // 31 + gAvrInt_USART1_UDRE, // 32 + gAvrInt_USART1_TX, // 33 + gAvrInt_TWI, // 34 + gAvrInt_SPM_READY, // 35 + +}; + +#endif + +//************************************************************************************************** +#if defined(__AVR_AT90CAN32__) || defined(__AVR_AT90CAN64__) || defined(__AVR_AT90CAN128__) +#pragma mark __AVR_AT90CAN32__ __AVR_AT90CAN64__ __AVR_AT90CAN128__ + +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + + gAvrInt_RESET, // 1 + gAvrInt_INT0, // 2 + gAvrInt_INT1, // 3 + gAvrInt_INT2, // 4 + gAvrInt_INT3, // 5 + gAvrInt_INT4, // 6 + gAvrInt_INT5, // 7 + gAvrInt_INT6, // 8 + gAvrInt_INT7, // 9 + gAvrInt_TIMER2_COMP, // 10 + gAvrInt_TIMER2_OVF, // 11 + gAvrInt_TIMER1_CAPT, // 12 + gAvrInt_TIMER1_COMPA, // 13 + gAvrInt_TIMER1_COMPB, // 14 + gAvrInt_TIMER1_COMPC, // 15 + gAvrInt_TIMER1_OVF, // 16 + gAvrInt_TIMER0_COMP, // 17 + gAvrInt_TIMER0_OVF, // 18 + gAvrInt_CAN_TrafnsferCE, // 19 + gAvrInt_CAN_TimerOverRun, // 20 + gAvrInt_SPI_STC, // 21 + gAvrInt_USART0_RX, // 22 + gAvrInt_USART0_UDRE, // 23 + gAvrInt_USART0_TX, // 24 + gAvrInt_ANALOG_COMP, // 25 + gAvrInt_ADC, // 26 + gAvrInt_EE_READY, // 27 + gAvrInt_TIMER3_CAPT, // 28 + gAvrInt_TIMER3_COMPA, // 29 + gAvrInt_TIMER3_COMPB, // 30 + gAvrInt_TIMER3_COMPC, // 31 + gAvrInt_TIMER3_OVF, // 32 + gAvrInt_USART1_RX, // 33 + gAvrInt_USART1_UDRE, // 34 + gAvrInt_USART1_TX, // 35 + gAvrInt_TWI, // 36 + gAvrInt_SPM_READY, // 37 +}; + +#endif + +//************************************************************************************************** +#if defined (__AVR_ATmega128RFA1__) +#pragma mark __AVR_ATmega128RFA1__ +#define _INTERRUPT_NAMES_DEFINED_ + +PGM_P gInterruptNameTable[] PROGMEM = +{ + //* Atmel changed the number scheme for interrupt vectors + gAvrInt_RESET, // 0 + gAvrInt_INT0, // 1 + gAvrInt_INT1, // 2 + gAvrInt_INT2, // 3 + gAvrInt_INT3, // 4 + gAvrInt_INT4, // 5 + gAvrInt_INT5, // 6 + gAvrInt_INT6, // 7 + gAvrInt_INT7, // 8 + gAvrInt_PCINT0, // 9 + gAvrInt_PCINT1, // 10 + gAvrInt_PCINT2, // 11 + gAvrInt_WDT, // 12 + gAvrInt_TIMER2_COMPA, // 13 + gAvrInt_TIMER2_COMPB, // 14 + gAvrInt_TIMER2_OVF, // 15 + gAvrInt_TIMER1_CAPT, // 16 + gAvrInt_TIMER1_COMPA, // 17 + gAvrInt_TIMER1_COMPB, // 18 + gAvrInt_TIMER1_COMPC, // 19 + gAvrInt_TIMER1_OVF, // 20 + gAvrInt_TIMER0_COMPA, // 21 + gAvrInt_TIMER0_COMPB, // 22 + gAvrInt_TIMER0_OVF, // 23 + gAvrInt_SPI_STC, // 24 + gAvrInt_USART0_RX, // 25 + gAvrInt_USART0_UDRE, // 26 + gAvrInt_USART0_TX, // 27 + gAvrInt_ANALOG_COMP, // 28 + gAvrInt_ADC, // 29 + gAvrInt_EE_READY, // 30 + gAvrInt_TIMER3_CAPT, // 31 + gAvrInt_TIMER3_COMPA, // 32 + gAvrInt_TIMER3_COMPB, // 33 + gAvrInt_TIMER3_COMPC, // 34 + gAvrInt_TIMER3_OVF, // 35 + gAvrInt_USART1_RX, // 36 + gAvrInt_USART1_UDRE, // 37 + gAvrInt_USART1_TX, // 38 + gAvrInt_TWI, // 39 + gAvrInt_SPM_READY, // 40 + gAvrInt_TIMER4_CAPT, // 41 + gAvrInt_TIMER4_COMPA, // 42 + gAvrInt_TIMER4_COMPB, // 43 + gAvrInt_TIMER4_COMPC, // 44 + gAvrInt_TIMER4_OVF, // 45 + gAvrInt_TIMER5_CAPT, // 46 + gAvrInt_TIMER5_COMPA, // 47 + gAvrInt_TIMER5_COMPB, // 48 + gAvrInt_TIMER5_COMPC, // 49 + gAvrInt_TIMER5_OVF, // 50 +#if 1 + gAvrInt_RESERVED, // 51 + gAvrInt_RESERVED, // 52 + gAvrInt_RESERVED, // 53 + + gAvrInt_RESERVED, // 54 + gAvrInt_RESERVED, // 55 + gAvrInt_RESERVED, // 56 + +#else + gAvrInt_USART2_RX, // 51 + gAvrInt_USART2_UDRE, // 52 + gAvrInt_USART2_TX, // 53 + + gAvrInt_USART3_RX, // 54 + gAvrInt_USART3_UDRE, // 55 + gAvrInt_USART3_TX, // 56 +#endif + gAvrInt_TRN_PLL_LOCK, // 57 + gAvrInt_TRN_PLL_UNLOCK, // 58 + gAvrInt_TRN_RX_START, // 59 + gAvrInt_TRN_RX_END, // 60 + gAvrInt_TRN_CAAED_DONE, // 61 + gAvrInt_TRN_FRAME_MATCH,// 62 + gAvrInt_TRN_TX_END, // 63 + gAvrInt_TRN_AWAKE, // 64 + + gAvrInt_SCNT_CMP1, // 65 + gAvrInt_SCNT_CMP2, // 66 + gAvrInt_SCNT_CMP3, // 67 + gAvrInt_SCNT_OVFL, // 68 + gAvrInt_SCNT_BACKOFF, // 69 + gAvrInt_AES_READY, // 70 + gAvrInt_BAT_LOW, // 71 + + +}; + +#endif + + +#if !defined(_INTERRUPT_NAMES_DEFINED_) + #warning No interrupt string defs for this cpu +#endif + diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/command.h b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/command.h new file mode 100644 index 0000000..8c28e26 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/command.h @@ -0,0 +1,118 @@ +//**** ATMEL AVR - A P P L I C A T I O N N O T E ************************ +//* +//* Title: AVR068 - STK500 Communication Protocol +//* Filename: command.h +//* Version: 1.0 +//* Last updated: 31.01.2005 +//* +//* Support E-mail: avr@atmel.com +//* +//************************************************************************** + +// *****************[ STK message constants ]*************************** + +#define MESSAGE_START 0x1B //= ESC = 27 decimal +#define TOKEN 0x0E + +// *****************[ STK general command constants ]************************** + +#define CMD_SIGN_ON 0x01 +#define CMD_SET_PARAMETER 0x02 +#define CMD_GET_PARAMETER 0x03 +#define CMD_SET_DEVICE_PARAMETERS 0x04 +#define CMD_OSCCAL 0x05 +#define CMD_LOAD_ADDRESS 0x06 +#define CMD_FIRMWARE_UPGRADE 0x07 + +// *****************[ STK ISP command constants ]****************************** + +#define CMD_ENTER_PROGMODE_ISP 0x10 +#define CMD_LEAVE_PROGMODE_ISP 0x11 +#define CMD_CHIP_ERASE_ISP 0x12 +#define CMD_PROGRAM_FLASH_ISP 0x13 +#define CMD_READ_FLASH_ISP 0x14 +#define CMD_PROGRAM_EEPROM_ISP 0x15 +#define CMD_READ_EEPROM_ISP 0x16 +#define CMD_PROGRAM_FUSE_ISP 0x17 +#define CMD_READ_FUSE_ISP 0x18 +#define CMD_PROGRAM_LOCK_ISP 0x19 +#define CMD_READ_LOCK_ISP 0x1A +#define CMD_READ_SIGNATURE_ISP 0x1B +#define CMD_READ_OSCCAL_ISP 0x1C +#define CMD_SPI_MULTI 0x1D + +// *****************[ STK PP command constants ]******************************* + +#define CMD_ENTER_PROGMODE_PP 0x20 +#define CMD_LEAVE_PROGMODE_PP 0x21 +#define CMD_CHIP_ERASE_PP 0x22 +#define CMD_PROGRAM_FLASH_PP 0x23 +#define CMD_READ_FLASH_PP 0x24 +#define CMD_PROGRAM_EEPROM_PP 0x25 +#define CMD_READ_EEPROM_PP 0x26 +#define CMD_PROGRAM_FUSE_PP 0x27 +#define CMD_READ_FUSE_PP 0x28 +#define CMD_PROGRAM_LOCK_PP 0x29 +#define CMD_READ_LOCK_PP 0x2A +#define CMD_READ_SIGNATURE_PP 0x2B +#define CMD_READ_OSCCAL_PP 0x2C + +#define CMD_SET_CONTROL_STACK 0x2D + +// *****************[ STK HVSP command constants ]***************************** + +#define CMD_ENTER_PROGMODE_HVSP 0x30 +#define CMD_LEAVE_PROGMODE_HVSP 0x31 +#define CMD_CHIP_ERASE_HVSP 0x32 +#define CMD_PROGRAM_FLASH_HVSP ` 0x33 +#define CMD_READ_FLASH_HVSP 0x34 +#define CMD_PROGRAM_EEPROM_HVSP 0x35 +#define CMD_READ_EEPROM_HVSP 0x36 +#define CMD_PROGRAM_FUSE_HVSP 0x37 +#define CMD_READ_FUSE_HVSP 0x38 +#define CMD_PROGRAM_LOCK_HVSP 0x39 +#define CMD_READ_LOCK_HVSP 0x3A +#define CMD_READ_SIGNATURE_HVSP 0x3B +#define CMD_READ_OSCCAL_HVSP 0x3C + +// *****************[ STK Prusa3D specific command constants ]***************** + +#define CMD_SET_UPLOAD_SIZE_PRUSA3D 0x71 + + +// *****************[ STK status constants ]*************************** + +// Success +#define STATUS_CMD_OK 0x00 + +// Warnings +#define STATUS_CMD_TOUT 0x80 +#define STATUS_RDY_BSY_TOUT 0x81 +#define STATUS_SET_PARAM_MISSING 0x82 + +// Errors +#define STATUS_CMD_FAILED 0xC0 +#define STATUS_CKSUM_ERROR 0xC1 +#define STATUS_CMD_UNKNOWN 0xC9 + +// *****************[ STK parameter constants ]*************************** +#define PARAM_BUILD_NUMBER_LOW 0x80 +#define PARAM_BUILD_NUMBER_HIGH 0x81 +#define PARAM_HW_VER 0x90 +#define PARAM_SW_MAJOR 0x91 +#define PARAM_SW_MINOR 0x92 +#define PARAM_VTARGET 0x94 +#define PARAM_VADJUST 0x95 +#define PARAM_OSC_PSCALE 0x96 +#define PARAM_OSC_CMATCH 0x97 +#define PARAM_SCK_DURATION 0x98 +#define PARAM_TOPCARD_DETECT 0x9A +#define PARAM_STATUS 0x9C +#define PARAM_DATA 0x9D +#define PARAM_RESET_POLARITY 0x9E +#define PARAM_CONTROLLER_INIT 0x9F + +// *****************[ STK answer constants ]*************************** + +#define ANSWER_CKSUM_ERROR 0xB0 + diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/lcd.c b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/lcd.c new file mode 100644 index 0000000..5e4a7d2 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/lcd.c @@ -0,0 +1,718 @@ +/***************************************************************************** +Title : HD44780 Library +Author : SA Development +Version: 1.11 +*****************************************************************************/ +#ifndef F_CPU +#define F_CPU 16000000UL +#endif +#include +#include "lcd.h" +#include +#if (USE_ADELAY_LIBRARY==1) + #include "adelay.h" +#else + #define Delay_ns(__ns) \ + if((unsigned long) (F_CPU/1000000000.0 * __ns) != F_CPU/1000000000.0 * __ns)\ + __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000000.0 * __ns)+1);\ + else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000000.0 * __ns)) + #define Delay_us(__us) \ + if((unsigned long) (F_CPU/1000000.0 * __us) != F_CPU/1000000.0 * __us)\ + __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000.0 * __us)+1);\ + else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000.0 * __us)) + #define Delay_ms(__ms) \ + if((unsigned long) (F_CPU/1000.0 * __ms) != F_CPU/1000.0 * __ms)\ + __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000.0 * __ms)+1);\ + else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000.0 * __ms)) + #define Delay_s(__s) \ + if((unsigned long) (F_CPU/1.0 * __s) != F_CPU/1.0 * __s)\ + __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1.0 * __s)+1);\ + else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1.0 * __s)) +#endif + +#if !defined(LCD_BITS) || (LCD_BITS!=4 && LCD_BITS!=8) + #error LCD_BITS is not defined or not valid. +#endif + +#if !defined(WAIT_MODE) || (WAIT_MODE!=0 && WAIT_MODE!=1) + #error WAIT_MODE is not defined or not valid. +#endif + +#if !defined(RW_LINE_IMPLEMENTED) || (RW_LINE_IMPLEMENTED!=0 && RW_LINE_IMPLEMENTED!=1) + #error RW_LINE_IMPLEMENTED is not defined or not valid. +#endif + +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED!=1) + #error WAIT_MODE=1 requires RW_LINE_IMPLEMENTED=1. +#endif + +#if !defined(LCD_DISPLAYS) || (LCD_DISPLAYS<1) || (LCD_DISPLAYS>4) + #error LCD_DISPLAYS is not defined or not valid. +#endif + +// Constants/Macros +#define PIN(x) (*(&x - 2)) // Address of Data Direction Register of Port X +#define DDR(x) (*(&x - 1)) // Address of Input Register of Port X + +//PORT defines +#define lcd_rs_port_low() LCD_RS_PORT&=~_BV(LCD_RS_PIN) +#if RW_LINE_IMPLEMENTED==1 + #define lcd_rw_port_low() LCD_RW_PORT&=~_BV(LCD_RW_PIN) +#endif +#define lcd_db0_port_low() LCD_DB0_PORT&=~_BV(LCD_DB0_PIN) +#define lcd_db1_port_low() LCD_DB1_PORT&=~_BV(LCD_DB1_PIN) +#define lcd_db2_port_low() LCD_DB2_PORT&=~_BV(LCD_DB2_PIN) +#define lcd_db3_port_low() LCD_DB3_PORT&=~_BV(LCD_DB3_PIN) +#define lcd_db4_port_low() LCD_DB4_PORT&=~_BV(LCD_DB4_PIN) +#define lcd_db5_port_low() LCD_DB5_PORT&=~_BV(LCD_DB5_PIN) +#define lcd_db6_port_low() LCD_DB6_PORT&=~_BV(LCD_DB6_PIN) +#define lcd_db7_port_low() LCD_DB7_PORT&=~_BV(LCD_DB7_PIN) + +#define lcd_rs_port_high() LCD_RS_PORT|=_BV(LCD_RS_PIN) +#if RW_LINE_IMPLEMENTED==1 + #define lcd_rw_port_high() LCD_RW_PORT|=_BV(LCD_RW_PIN) +#endif +#define lcd_db0_port_high() LCD_DB0_PORT|=_BV(LCD_DB0_PIN) +#define lcd_db1_port_high() LCD_DB1_PORT|=_BV(LCD_DB1_PIN) +#define lcd_db2_port_high() LCD_DB2_PORT|=_BV(LCD_DB2_PIN) +#define lcd_db3_port_high() LCD_DB3_PORT|=_BV(LCD_DB3_PIN) +#define lcd_db4_port_high() LCD_DB4_PORT|=_BV(LCD_DB4_PIN) +#define lcd_db5_port_high() LCD_DB5_PORT|=_BV(LCD_DB5_PIN) +#define lcd_db6_port_high() LCD_DB6_PORT|=_BV(LCD_DB6_PIN) +#define lcd_db7_port_high() LCD_DB7_PORT|=_BV(LCD_DB7_PIN) + +#define lcd_rs_port_set(value) if (value) lcd_rs_port_high(); else lcd_rs_port_low(); +#if RW_LINE_IMPLEMENTED==1 + #define lcd_rw_port_set(value) if (value) lcd_rw_port_high(); else lcd_rw_port_low(); +#endif +#define lcd_db0_port_set(value) if (value) lcd_db0_port_high(); else lcd_db0_port_low(); +#define lcd_db1_port_set(value) if (value) lcd_db1_port_high(); else lcd_db1_port_low(); +#define lcd_db2_port_set(value) if (value) lcd_db2_port_high(); else lcd_db2_port_low(); +#define lcd_db3_port_set(value) if (value) lcd_db3_port_high(); else lcd_db3_port_low(); +#define lcd_db4_port_set(value) if (value) lcd_db4_port_high(); else lcd_db4_port_low(); +#define lcd_db5_port_set(value) if (value) lcd_db5_port_high(); else lcd_db5_port_low(); +#define lcd_db6_port_set(value) if (value) lcd_db6_port_high(); else lcd_db6_port_low(); +#define lcd_db7_port_set(value) if (value) lcd_db7_port_high(); else lcd_db7_port_low(); + +//PIN defines +#define lcd_db0_pin_get() (((PIN(LCD_DB0_PORT) & _BV(LCD_DB0_PIN))==0)?0:1) +#define lcd_db1_pin_get() (((PIN(LCD_DB1_PORT) & _BV(LCD_DB1_PIN))==0)?0:1) +#define lcd_db2_pin_get() (((PIN(LCD_DB2_PORT) & _BV(LCD_DB2_PIN))==0)?0:1) +#define lcd_db3_pin_get() (((PIN(LCD_DB3_PORT) & _BV(LCD_DB3_PIN))==0)?0:1) +#define lcd_db4_pin_get() (((PIN(LCD_DB4_PORT) & _BV(LCD_DB4_PIN))==0)?0:1) +#define lcd_db5_pin_get() (((PIN(LCD_DB5_PORT) & _BV(LCD_DB5_PIN))==0)?0:1) +#define lcd_db6_pin_get() (((PIN(LCD_DB6_PORT) & _BV(LCD_DB6_PIN))==0)?0:1) +#define lcd_db7_pin_get() (((PIN(LCD_DB7_PORT) & _BV(LCD_DB7_PIN))==0)?0:1) + +//DDR defines +#define lcd_rs_ddr_low() DDR(LCD_RS_PORT)&=~_BV(LCD_RS_PIN) +#if RW_LINE_IMPLEMENTED==1 + #define lcd_rw_ddr_low() DDR(LCD_RW_PORT)&=~_BV(LCD_RW_PIN) +#endif +#define lcd_db0_ddr_low() DDR(LCD_DB0_PORT)&=~_BV(LCD_DB0_PIN) +#define lcd_db1_ddr_low() DDR(LCD_DB1_PORT)&=~_BV(LCD_DB1_PIN) +#define lcd_db2_ddr_low() DDR(LCD_DB2_PORT)&=~_BV(LCD_DB2_PIN) +#define lcd_db3_ddr_low() DDR(LCD_DB3_PORT)&=~_BV(LCD_DB3_PIN) +#define lcd_db4_ddr_low() DDR(LCD_DB4_PORT)&=~_BV(LCD_DB4_PIN) +#define lcd_db5_ddr_low() DDR(LCD_DB5_PORT)&=~_BV(LCD_DB5_PIN) +#define lcd_db6_ddr_low() DDR(LCD_DB6_PORT)&=~_BV(LCD_DB6_PIN) +#define lcd_db7_ddr_low() DDR(LCD_DB7_PORT)&=~_BV(LCD_DB7_PIN) + +#define lcd_rs_ddr_high() DDR(LCD_RS_PORT)|=_BV(LCD_RS_PIN) +#if RW_LINE_IMPLEMENTED==1 + #define lcd_rw_ddr_high() DDR(LCD_RW_PORT)|=_BV(LCD_RW_PIN) +#endif +#define lcd_db0_ddr_high() DDR(LCD_DB0_PORT)|=_BV(LCD_DB0_PIN) +#define lcd_db1_ddr_high() DDR(LCD_DB1_PORT)|=_BV(LCD_DB1_PIN) +#define lcd_db2_ddr_high() DDR(LCD_DB2_PORT)|=_BV(LCD_DB2_PIN) +#define lcd_db3_ddr_high() DDR(LCD_DB3_PORT)|=_BV(LCD_DB3_PIN) +#define lcd_db4_ddr_high() DDR(LCD_DB4_PORT)|=_BV(LCD_DB4_PIN) +#define lcd_db5_ddr_high() DDR(LCD_DB5_PORT)|=_BV(LCD_DB5_PIN) +#define lcd_db6_ddr_high() DDR(LCD_DB6_PORT)|=_BV(LCD_DB6_PIN) +#define lcd_db7_ddr_high() DDR(LCD_DB7_PORT)|=_BV(LCD_DB7_PIN) + +#define lcd_rs_ddr_set(value) if (value) lcd_rs_ddr_high(); else lcd_rs_ddr_low(); +#if RW_LINE_IMPLEMENTED==1 + #define lcd_rw_ddr_set(value) if (value) lcd_rw_ddr_high(); else lcd_rw_ddr_low(); +#endif +#define lcd_db0_ddr_set(value) if (value) lcd_db0_ddr_high(); else lcd_db0_ddr_low(); +#define lcd_db1_ddr_set(value) if (value) lcd_db1_ddr_high(); else lcd_db1_ddr_low(); +#define lcd_db2_ddr_set(value) if (value) lcd_db2_ddr_high(); else lcd_db2_ddr_low(); +#define lcd_db3_ddr_set(value) if (value) lcd_db3_ddr_high(); else lcd_db3_ddr_low(); +#define lcd_db4_ddr_set(value) if (value) lcd_db4_ddr_high(); else lcd_db4_ddr_low(); +#define lcd_db5_ddr_set(value) if (value) lcd_db5_ddr_high(); else lcd_db5_ddr_low(); +#define lcd_db6_ddr_set(value) if (value) lcd_db6_ddr_high(); else lcd_db6_ddr_low(); +#define lcd_db7_ddr_set(value) if (value) lcd_db7_ddr_high(); else lcd_db7_ddr_low(); + +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) +static unsigned char PrevCmdInvolvedAddressCounter=0; +#endif + +#if (LCD_DISPLAYS>1) +static unsigned char ActiveDisplay=1; +#endif + +static inline void lcd_e_port_low() +{ + #if (LCD_DISPLAYS>1) + switch (ActiveDisplay) + { + case 2 : LCD_E2_PORT&=~_BV(LCD_E2_PIN); + break; + #if (LCD_DISPLAYS>=3) + case 3 : LCD_E3_PORT&=~_BV(LCD_E3_PIN); + break; + #endif + #if (LCD_DISPLAYS==4) + case 4 : LCD_E4_PORT&=~_BV(LCD_E4_PIN); + break; + #endif + default : + #endif + LCD_E_PORT&=~_BV(LCD_E_PIN); + #if (LCD_DISPLAYS>1) + } + #endif +} + +static inline void lcd_e_port_high() +{ + #if (LCD_DISPLAYS>1) + switch (ActiveDisplay) + { + case 2 : LCD_E2_PORT|=_BV(LCD_E2_PIN); + break; + #if (LCD_DISPLAYS>=3) + case 3 : LCD_E3_PORT|=_BV(LCD_E3_PIN); + break; + #endif + #if (LCD_DISPLAYS==4) + case 4 : LCD_E4_PORT|=_BV(LCD_E4_PIN); + break; + #endif + default : + #endif + LCD_E_PORT|=_BV(LCD_E_PIN); + #if (LCD_DISPLAYS>1) + } + #endif +} + +static inline void lcd_e_ddr_low() +{ + #if (LCD_DISPLAYS>1) + switch (ActiveDisplay) + { + case 2 : DDR(LCD_E2_PORT)&=~_BV(LCD_E2_PIN); + break; + #if (LCD_DISPLAYS>=3) + case 3 : DDR(LCD_E3_PORT)&=~_BV(LCD_E3_PIN); + break; + #endif + #if (LCD_DISPLAYS==4) + case 4 : DDR(LCD_E4_PORT)&=~_BV(LCD_E4_PIN); + break; + #endif + default : + #endif + DDR(LCD_E_PORT)&=~_BV(LCD_E_PIN); + #if (LCD_DISPLAYS>1) + } + #endif +} + +static inline void lcd_e_ddr_high() +{ + #if (LCD_DISPLAYS>1) + switch (ActiveDisplay) + { + case 2 : DDR(LCD_E2_PORT)|=_BV(LCD_E2_PIN); + break; + #if (LCD_DISPLAYS>=3) + case 3 : DDR(LCD_E3_PORT)|=_BV(LCD_E3_PIN); + break; + #endif + #if (LCD_DISPLAYS==4) + case 4 : DDR(LCD_E4_PORT)|=_BV(LCD_E4_PIN); + break; + #endif + default : + #endif + DDR(LCD_E_PORT)|=_BV(LCD_E_PIN); + #if (LCD_DISPLAYS>1) + } + #endif +} + + +/************************************************************************* +loops while lcd is busy, returns address counter +*************************************************************************/ +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) +static uint8_t lcd_read(uint8_t rs); + +static void lcd_waitbusy(void) + { + register uint8_t c; + unsigned int ul1=0; + + while ( ((c=lcd_read(0)) & (1<=16)?F_CPU/16384:16)) // Wait Until Busy Flag is Cleared + ul1++; + } +#endif + + +/************************************************************************* +Low-level function to read byte from LCD controller +Input: rs 1: read data + 0: read busy flag / address counter +Returns: byte read from LCD controller +*************************************************************************/ +#if RW_LINE_IMPLEMENTED==1 +static uint8_t lcd_read(uint8_t rs) + { + uint8_t data; + + #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + if (rs) + lcd_waitbusy(); + if (PrevCmdInvolvedAddressCounter) + { + Delay_us(5); + PrevCmdInvolvedAddressCounter=0; + } + #endif + + if (rs) + { + lcd_rs_port_high(); // RS=1: Read Data + #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + PrevCmdInvolvedAddressCounter=1; + #endif + } + else lcd_rs_port_low(); // RS=0: Read Busy Flag + + + lcd_rw_port_high(); // RW=1: Read Mode + + #if LCD_BITS==4 + lcd_db7_ddr_low(); // Configure Data Pins as Input + lcd_db6_ddr_low(); + lcd_db5_ddr_low(); + lcd_db4_ddr_low(); + + lcd_e_port_high(); // Read High Nibble First + Delay_ns(500); + + data=lcd_db4_pin_get() << 4 | lcd_db5_pin_get() << 5 | + lcd_db6_pin_get() << 6 | lcd_db7_pin_get() << 7; + + lcd_e_port_low(); + Delay_ns(500); + + lcd_e_port_high(); // Read Low Nibble + Delay_ns(500); + + data|=lcd_db4_pin_get() << 0 | lcd_db5_pin_get() << 1 | + lcd_db6_pin_get() << 2 | lcd_db7_pin_get() << 3; + + lcd_e_port_low(); + + lcd_db7_ddr_high(); // Configure Data Pins as Output + lcd_db6_ddr_high(); + lcd_db5_ddr_high(); + lcd_db4_ddr_high(); + + lcd_db7_port_high(); // Pins High (Inactive) + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); + #else //using 8-Bit-Mode + lcd_db7_ddr_low(); // Configure Data Pins as Input + lcd_db6_ddr_low(); + lcd_db5_ddr_low(); + lcd_db4_ddr_low(); + lcd_db3_ddr_low(); + lcd_db2_ddr_low(); + lcd_db1_ddr_low(); + lcd_db0_ddr_low(); + + lcd_e_port_high(); + Delay_ns(500); + + data=lcd_db7_pin_get() << 7 | lcd_db6_pin_get() << 6 | + lcd_db5_pin_get() << 5 | lcd_db4_pin_get() << 4 | + lcd_db3_pin_get() << 3 | lcd_db2_pin_get() << 2 | + lcd_db1_pin_get() << 1 | lcd_db0_pin_get(); + + lcd_e_port_low(); + + lcd_db7_ddr_high(); // Configure Data Pins as Output + lcd_db6_ddr_high(); + lcd_db5_ddr_high(); + lcd_db4_ddr_high(); + lcd_db3_ddr_high(); + lcd_db2_ddr_high(); + lcd_db1_ddr_high(); + lcd_db0_ddr_high(); + + lcd_db7_port_high(); // Pins High (Inactive) + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); + lcd_db3_port_high(); + lcd_db2_port_high(); + lcd_db1_port_high(); + lcd_db0_port_high(); + #endif + + lcd_rw_port_low(); + + #if (WAIT_MODE==0 || RW_LINE_IMPLEMENTED==0) + if (rs) + Delay_us(40); + else Delay_us(1); + #endif + return data; + } + +uint8_t lcd_getc() + { + return lcd_read(1); + } + +#endif + +/************************************************************************* +Low-level function to write byte to LCD controller +Input: data byte to write to LCD + rs 1: write data + 0: write instruction +Returns: none +*************************************************************************/ +static void lcd_write(uint8_t data,uint8_t rs) + { + #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + lcd_waitbusy(); + if (PrevCmdInvolvedAddressCounter) + { + Delay_us(5); + PrevCmdInvolvedAddressCounter=0; + } + #endif + + if (rs) + { + lcd_rs_port_high(); // RS=1: Write Character + #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + PrevCmdInvolvedAddressCounter=1; + #endif + } + else + { + lcd_rs_port_low(); // RS=0: Write Command + #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + PrevCmdInvolvedAddressCounter=0; + #endif + } + + #if LCD_BITS==4 + lcd_db7_port_set(data&_BV(7)); //Output High Nibble + lcd_db6_port_set(data&_BV(6)); + lcd_db5_port_set(data&_BV(5)); + lcd_db4_port_set(data&_BV(4)); + + Delay_ns(100); + lcd_e_port_high(); + + Delay_ns(500); + lcd_e_port_low(); + + lcd_db7_port_set(data&_BV(3)); //Output High Nibble + lcd_db6_port_set(data&_BV(2)); + lcd_db5_port_set(data&_BV(1)); + lcd_db4_port_set(data&_BV(0)); + + Delay_ns(100); + lcd_e_port_high(); + + Delay_ns(500); + lcd_e_port_low(); + + lcd_db7_port_high(); // All Data Pins High (Inactive) + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); + + #else //using 8-Bit_Mode + lcd_db7_port_set(data&_BV(7)); //Output High Nibble + lcd_db6_port_set(data&_BV(6)); + lcd_db5_port_set(data&_BV(5)); + lcd_db4_port_set(data&_BV(4)); + lcd_db3_port_set(data&_BV(3)); //Output High Nibble + lcd_db2_port_set(data&_BV(2)); + lcd_db1_port_set(data&_BV(1)); + lcd_db0_port_set(data&_BV(0)); + + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + + lcd_db7_port_high(); // All Data Pins High (Inactive) + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); + lcd_db3_port_high(); + lcd_db2_port_high(); + lcd_db1_port_high(); + lcd_db0_port_high(); + #endif + + #if (WAIT_MODE==0 || RW_LINE_IMPLEMENTED==0) + if (!rs && data<=((1<1) + lcd_db7_port_high(); + #else + unsigned char c; + switch (ActiveDisplay) + { + case 1 : c=LCD_DISPLAY_LINES; break; + case 2 : c=LCD_DISPLAY2_LINES; break; + #if (LCD_DISPLAYS>=3) + case 3 : c=LCD_DISPLAY3_LINES; break; + #endif + #if (LCD_DISPLAYS==4) + case 4 : c=LCD_DISPLAY4_LINES; break; + #endif + } + if (c>1) + lcd_db7_port_high(); + #endif + + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_us(40); + #else + #if (LCD_DISPLAYS==1) + if (LCD_DISPLAY_LINES<2) + lcd_db3_port_low(); + #else + unsigned char c; + switch (ActiveDisplay) + { + case 1 : c=LCD_DISPLAY_LINES; break; + case 2 : c=LCD_DISPLAY2_LINES; break; + #if (LCD_DISPLAYS>=3) + case 3 : c=LCD_DISPLAY3_LINES; break; + #endif + #if (LCD_DISPLAYS==4) + case 4 : c=LCD_DISPLAY4_LINES; break; + #endif + } + if (c<2) + lcd_db3_port_low(); + #endif + + lcd_db2_port_low(); + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_us(40); + #endif + + //Display Off + lcd_command(_BV(LCD_DISPLAYMODE)); + + //Display Clear + lcd_clrscr(); + + //Entry Mode Set + lcd_command(_BV(LCD_ENTRY_MODE) | _BV(LCD_ENTRY_INC)); + + //Display On + lcd_command(_BV(LCD_DISPLAYMODE) | _BV(LCD_DISPLAYMODE_ON)); + } + +#if (LCD_DISPLAYS>1) +void lcd_use_display(int ADisplay) + { + if (ADisplay>=1 && ADisplay<=LCD_DISPLAYS) + ActiveDisplay=ADisplay; + } +#endif + diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/lcd.h b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/lcd.h new file mode 100644 index 0000000..bb9543a --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/lcd.h @@ -0,0 +1,65 @@ +/***************************************************************************** +Title : HD44780 Library +Author : SA Development +Version: 1.11 +*****************************************************************************/ + +#ifndef HD44780_H +#define HD44780_H + +#ifndef F_CPU +#define F_CPU 16000000UL +#endif + +#include "settings.h" +#include "inttypes.h" + +//LCD Constants for HD44780 +#define LCD_CLR 0 // DB0: clear display + +#define LCD_HOME 1 // DB1: return to home position + +#define LCD_ENTRY_MODE 2 // DB2: set entry mode +#define LCD_ENTRY_INC 1 // DB1: 1=increment, 0=decrement +#define LCD_ENTRY_SHIFT 0 // DB0: 1=display shift on + +#define LCD_DISPLAYMODE 3 // DB3: turn lcd/cursor on +#define LCD_DISPLAYMODE_ON 2 // DB2: turn display on +#define LCD_DISPLAYMODE_CURSOR 1 // DB1: turn cursor on +#define LCD_DISPLAYMODE_BLINK 0 // DB0: blinking cursor + +#define LCD_MOVE 4 // DB4: move cursor/display +#define LCD_MOVE_DISP 3 // DB3: move display (0-> cursor) +#define LCD_MOVE_RIGHT 2 // DB2: move right (0-> left) + +#define LCD_FUNCTION 5 // DB5: function set +#define LCD_FUNCTION_8BIT 4 // DB4: set 8BIT mode (0->4BIT mode) +#define LCD_FUNCTION_2LINES 3 // DB3: two lines (0->one line) +#define LCD_FUNCTION_10DOTS 2 // DB2: 5x10 font (0->5x7 font) + +#define LCD_CGRAM 6 // DB6: set CG RAM address +#define LCD_DDRAM 7 // DB7: set DD RAM address + +#define LCD_BUSY 7 // DB7: LCD is busy + + +void lcd_init(); +void lcd_command(uint8_t cmd); + +void lcd_clrscr(); +void lcd_home(); +void lcd_goto(uint8_t pos); + +#if RW_LINE_IMPLEMENTED==1 +uint8_t lcd_getc(); +#endif + +void lcd_putc(char c); +void lcd_puts(const char *s); +void lcd_puts_P(const char *progmem_s); + +#if (LCD_DISPLAYS>1) +void lcd_use_display(int ADisplay); +#endif + +#endif diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/settings.h b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/settings.h new file mode 100644 index 0000000..0ab697f --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/settings.h @@ -0,0 +1,83 @@ +#ifndef HD44780_SETTINGS_H +#define HD44780_SETTINGS_H + +//#define F_CPU 8000000 // Set Clock Frequency + +#define EINSYBOARD + +#define USE_ADELAY_LIBRARY 0 // Set to 1 to use my ADELAY library, 0 to use internal delay functions +#define LCD_BITS 4 // 4 for 4 Bit I/O Mode, 8 for 8 Bit I/O Mode +#define RW_LINE_IMPLEMENTED 0 // 0 for no RW line (RW on LCD tied to ground), 1 for RW line present +#define WAIT_MODE 0 // 0=Use Delay Method (Faster if running <10Mhz) +// 1=Use Check Busy Flag (Faster if running >10Mhz) ***Requires RW Line*** +#define DELAY_RESET 15 // in mS + +#if (LCD_BITS==8) // If using 8 bit mode, you must configure DB0-DB7 +#define LCD_DB0_PORT PORTC +#define LCD_DB0_PIN 0 +#define LCD_DB1_PORT PORTC +#define LCD_DB1_PIN 1 +#define LCD_DB2_PORT PORTC +#define LCD_DB2_PIN 2 +#define LCD_DB3_PORT PORTC +#define LCD_DB3_PIN 3 +#endif + + +#ifdef EINSYBOARD +#define LCD_DB4_PORT PORTF // If using 4 bit mode, yo umust configure DB4-DB7 +#define LCD_DB4_PIN PF5 +#else +#define LCD_DB4_PORT PORTD // If using 4 bit mode, yo umust configure DB4-DB7 +#define LCD_DB4_PIN PB2 +#endif + + + +#define LCD_DB5_PORT PORTG +#define LCD_DB5_PIN PG4 +#define LCD_DB6_PORT PORTH +#define LCD_DB6_PIN PK7 +#define LCD_DB7_PORT PORTG +#define LCD_DB7_PIN PA3 + +#define LCD_RS_PORT PORTD // Port for RS line +#define LCD_RS_PIN PK5 // Pin for RS line + +#define LCD_RW_PORT PORTC // Port for RW line (ONLY used if RW_LINE_IMPLEMENTED=1) +#define LCD_RW_PIN PC6 // Pin for RW line (ONLY used if RW_LINE_IMPLEMENTED=1) + + +#define LCD_DISPLAYS 1 // Up to 4 LCD displays can be used at one time +// All pins are shared between displays except for the E +// pin which each display will have its own + +// Display 1 Settings - if you only have 1 display, YOU MUST SET THESE +#define LCD_DISPLAY_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command +#ifdef EINSYBOARD +#define LCD_E_PORT PORTF // Port for E line +#define LCD_E_PIN PF7 // Pin for E line +#else +#define LCD_E_PORT PORTD // Port for E line +#define LCD_E_PIN PD3 // Pin for E line +#endif + +#if (LCD_DISPLAYS>=2) // If you have 2 displays, set these and change LCD_DISPLAYS=2 +#define LCD_DISPLAY2_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command +#define LCD_E2_PORT PORTC // Port for E line +#define LCD_E2_PIN 5 // Pin for E line +#endif + +#if (LCD_DISPLAYS>=3) // If you have 3 displays, set these and change LCD_DISPLAYS=3 +#define LCD_DISPLAY3_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command +#define LCD_E3_PORT PORTC // Port for E line +#define LCD_E3_PIN 5 // Pin for E line +#endif + +#if (LCD_DISPLAYS>=4) // If you have 4 displays, set these and change LCD_DISPLAYS=4 +#define LCD_DISPLAY4_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command +#define LCD_E4_PORT PORTC // Port for E line +#define LCD_E4_PIN 5 // Pin for E line +#endif + +#endif diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.c b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.c new file mode 100644 index 0000000..ea85564 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.c @@ -0,0 +1,1562 @@ +/***************************************************************************** +Title: STK500v2 compatible bootloader + Modified for Wiring board ATMega128-16MHz +Author: Peter Fleury http://jump.to/fleury +Compiler: avr-gcc 3.4.5 or 4.1 / avr-libc 1.4.3 +Hardware: All AVRs with bootloader support, tested with ATmega8 +License: GNU General Public License + +Modified: Worapoht Kornkaewwattanakul http://www.avride.com +Date: 17 October 2007 +Update: 1st, 29 Dec 2007 : Enable CMD_SPI_MULTI but ignore unused command by return 0x00 byte response.. +Compiler: WINAVR20060421 +Description: add timeout feature like previous Wiring bootloader + +DESCRIPTION: + This program allows an AVR with bootloader capabilities to + read/write its own Flash/EEprom. To enter Programming mode + an input pin is checked. If this pin is pulled low, programming mode + is entered. If not, normal execution is done from $0000 + "reset" vector in Application area. + Size fits into a 1024 word bootloader section + when compiled with avr-gcc 4.1 + (direct replace on Wiring Board without fuse setting changed) + +USAGE: + - Set AVR MCU type and clock-frequency (F_CPU) in the Makefile. + - Set baud rate below (AVRISP only works with 115200 bps) + - compile/link the bootloader with the supplied Makefile + - program the "Boot Flash section size" (BOOTSZ fuses), + for boot-size 1024 words: program BOOTSZ01 + - enable the BOOT Reset Vector (program BOOTRST) + - Upload the hex file to the AVR using any ISP programmer + - Program Boot Lock Mode 3 (program BootLock 11 and BootLock 12 lock bits) // (leave them) + - Reset your AVR while keeping PROG_PIN pulled low // (for enter bootloader by switch) + - Start AVRISP Programmer (AVRStudio/Tools/Program AVR) + - AVRISP will detect the bootloader + - Program your application FLASH file and optional EEPROM file using AVRISP + +Note: + Erasing the device without flashing, through AVRISP GUI button "Erase Device" + is not implemented, due to AVRStudio limitations. + Flash is always erased before programming. + + AVRdude: + Please uncomment #define REMOVE_CMD_SPI_MULTI when using AVRdude. + Comment #define REMOVE_PROGRAM_LOCK_BIT_SUPPORT to reduce code size + Read Fuse Bits and Read/Write Lock Bits is not supported + +NOTES: + Based on Atmel Application Note AVR109 - Self-programming + Based on Atmel Application Note AVR068 - STK500v2 Protocol + +LICENSE: + Copyright (C) 2006 Peter Fleury + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*****************************************************************************/ + +//************************************************************************ +//* Edit History +//************************************************************************ +//* Jul 7, 2010 = Mark Sproul msproul@skycharoit.com +//* Jul 7, 2010 Working on mega2560. No Auto-restart +//* Jul 7, 2010 Switched to 8K bytes (4K words) so that we have room for the monitor +//* Jul 8, 2010 Found older version of source that had auto restart, put that code back in +//* Jul 8, 2010 Adding monitor code +//* Jul 11, 2010 Added blinking LED while waiting for download to start +//* Jul 11, 2010 Added EEPROM test +//* Jul 29, 2010 Added recchar_timeout for timing out on bootloading +//* Aug 23, 2010 Added support for atmega2561 +//* Aug 26, 2010 Removed support for BOOT_BY_SWITCH +//* Sep 8, 2010 Added support for atmega16 +//* Nov 9, 2010 Issue 392:Fixed bug that 3 !!! in code would cause it to jump to monitor +//* Jun 24, 2011 Removed analogRead (was not used) +//* Dec 29, 2011 Issue 181: added watch dog timmer support +//* Dec 29, 2011 Issue 505: bootloader is comparing the seqNum to 1 or the current sequence +//* Jan 1, 2012 Issue 543: CMD_CHIP_ERASE_ISP now returns STATUS_CMD_FAILED instead of STATUS_CMD_OK +//* Jan 1, 2012 Issue 543: Write EEPROM now does something (NOT TESTED) +//* Jan 1, 2012 Issue 544: stk500v2 bootloader doesn't support reading fuses +//************************************************************************ + +//************************************************************************ +//* these are used to test issues +//* http://code.google.com/p/arduino/issues/detail?id=505 +//* Reported by mark.stubbs, Mar 14, 2011 +//* The STK500V2 bootloader is comparing the seqNum to 1 or the current sequence +//* (IE: Requiring the sequence to be 1 or match seqNum before continuing). +//* The correct behavior is for the STK500V2 to accept the PC's sequence number, and echo it back for the reply message. +#define _FIX_ISSUE_505_ +//************************************************************************ +//* Issue 181: added watch dog timmer support +#define _FIX_ISSUE_181_ +// LCD startup screen and boot animation +#define LCD_HD44780 +#define LCD_HD44780_ANIMATION +#define LCD_HD44780_COUNTER +// Dual serial support +#define DUALSERIAL +// EINSY board +#define EINSYBOARD + + +#include +#include +#include +#include +#include +#include +#include +#include +#include "command.h" + +#ifdef LCD_HD44780 +#include "lcd.h" +#endif + + +#ifndef EEWE + #define EEWE 1 +#endif +#ifndef EEMWE + #define EEMWE 2 +#endif + + + +/* + * Uncomment the following lines to save code space + */ +//#define REMOVE_PROGRAM_LOCK_BIT_SUPPORT // disable program lock bits +//#define REMOVE_BOOTLOADER_LED // no LED to show active bootloader +//#define REMOVE_CMD_SPI_MULTI // disable processing of SPI_MULTI commands, Remark this line for AVRDUDE +// + + + +//************************************************************************ +//* LED on pin "PROGLED_PIN" on port "PROGLED_PORT" +//* indicates that bootloader is active +//* PG2 -> LED on Wiring board +//************************************************************************ +#define BLINK_LED_WHILE_WAITING + +#ifdef _MEGA_BOARD_ + #define PROGLED_PORT PORTB + #define PROGLED_DDR DDRB + #define PROGLED_PIN PINB7 +#elif defined( _BOARD_AMBER128_ ) + //* this is for the amber 128 http://www.soc-robotics.com/ + //* onbarod led is PORTE4 + #define PROGLED_PORT PORTD + #define PROGLED_DDR DDRD + #define PROGLED_PIN PINE7 +#elif defined( _CEREBOTPLUS_BOARD_ ) || defined(_CEREBOT_II_BOARD_) + //* this is for the Cerebot 2560 board and the Cerebot-ii + //* onbarod leds are on PORTE4-7 + #define PROGLED_PORT PORTE + #define PROGLED_DDR DDRE + #define PROGLED_PIN PINE7 +#elif defined( _PENGUINO_ ) + //* this is for the Penguino + //* onbarod led is PORTE4 + #define PROGLED_PORT PORTC + #define PROGLED_DDR DDRC + #define PROGLED_PIN PINC6 +#elif defined( _ANDROID_2561_ ) || defined( __AVR_ATmega2561__ ) + //* this is for the Boston Android 2561 + //* onbarod led is PORTE4 + #define PROGLED_PORT PORTA + #define PROGLED_DDR DDRA + #define PROGLED_PIN PINA3 +#elif defined( _BOARD_MEGA16 ) + //* onbarod led is PORTA7 + #define PROGLED_PORT PORTA + #define PROGLED_DDR DDRA + #define PROGLED_PIN PINA7 + #define UART_BAUDRATE_DOUBLE_SPEED 0 + +#elif defined( _BOARD_BAHBOT_ ) + //* dosent have an onboard LED but this is what will probably be added to this port + #define PROGLED_PORT PORTB + #define PROGLED_DDR DDRB + #define PROGLED_PIN PINB0 + +#elif defined( _BOARD_ROBOTX_ ) + #define PROGLED_PORT PORTB + #define PROGLED_DDR DDRB + #define PROGLED_PIN PINB6 +#elif defined( _BOARD_CUSTOM1284_BLINK_B0_ ) + #define PROGLED_PORT PORTB + #define PROGLED_DDR DDRB + #define PROGLED_PIN PINB0 +#elif defined( _BOARD_CUSTOM1284_ ) + #define PROGLED_PORT PORTD + #define PROGLED_DDR DDRD + #define PROGLED_PIN PIND5 +#elif defined( _AVRLIP_ ) + #define PROGLED_PORT PORTB + #define PROGLED_DDR DDRB + #define PROGLED_PIN PINB5 +#elif defined( _BOARD_STK500_ ) + #define PROGLED_PORT PORTA + #define PROGLED_DDR DDRA + #define PROGLED_PIN PINA7 +#elif defined( _BOARD_STK502_ ) + #define PROGLED_PORT PORTB + #define PROGLED_DDR DDRB + #define PROGLED_PIN PINB5 +#elif defined( _BOARD_STK525_ ) + #define PROGLED_PORT PORTB + #define PROGLED_DDR DDRB + #define PROGLED_PIN PINB7 +#else + #define PROGLED_PORT PORTG + #define PROGLED_DDR DDRG + #define PROGLED_PIN PING2 +#endif + + + +/* + * define CPU frequency in Mhz here if not defined in Makefile + */ +#ifndef F_CPU + #define F_CPU 16000000UL +#endif + +#define _BLINK_LOOP_COUNT_ (F_CPU / 2250) +/* + * UART Baudrate, AVRStudio AVRISP only accepts 115200 bps + */ + +#ifndef BAUDRATE + #define BAUDRATE 115200 +#endif + +/* + * Enable (1) or disable (0) USART double speed operation + */ +#ifndef UART_BAUDRATE_DOUBLE_SPEED + #if defined (__AVR_ATmega32__) + #define UART_BAUDRATE_DOUBLE_SPEED 0 + #else + #define UART_BAUDRATE_DOUBLE_SPEED 1 + #endif +#endif + +/* + * HW and SW version, reported to AVRISP, must match version of AVRStudio + */ +#define CONFIG_PARAM_BUILD_NUMBER_LOW 0 +#define CONFIG_PARAM_BUILD_NUMBER_HIGH 0 +#define CONFIG_PARAM_HW_VER 0x0F +#define CONFIG_PARAM_SW_MAJOR 2 +#define CONFIG_PARAM_SW_MINOR 0x0A + +/* + * Calculate the address where the bootloader starts from FLASHEND and BOOTSIZE + * (adjust BOOTSIZE below and BOOTLOADER_ADDRESS in Makefile if you want to change the size of the bootloader) + */ +//#define BOOTSIZE 1024 +#if FLASHEND > 0x0F000 + #define BOOTSIZE 8192 +#else + #define BOOTSIZE 2048 +#endif + +//#define APP_END (FLASHEND -(2*BOOTSIZE) + 1) +#define APP_END (FLASHEND -(BOOTSIZE) + 1) + +/* + * Signature bytes are not available in avr-gcc io_xxx.h + */ +#if defined (__AVR_ATmega8__) + #define SIGNATURE_BYTES 0x1E9307 +#elif defined (__AVR_ATmega16__) + #define SIGNATURE_BYTES 0x1E9403 +#elif defined (__AVR_ATmega32__) + #define SIGNATURE_BYTES 0x1E9502 +#elif defined (__AVR_ATmega8515__) + #define SIGNATURE_BYTES 0x1E9306 +#elif defined (__AVR_ATmega8535__) + #define SIGNATURE_BYTES 0x1E9308 +#elif defined (__AVR_ATmega162__) + #define SIGNATURE_BYTES 0x1E9404 +#elif defined (__AVR_ATmega128__) + #define SIGNATURE_BYTES 0x1E9702 +#elif defined (__AVR_ATmega1280__) + #define SIGNATURE_BYTES 0x1E9703 +#elif defined (__AVR_ATmega2560__) + #define SIGNATURE_BYTES 0x1E9801 +#elif defined (__AVR_ATmega2561__) + #define SIGNATURE_BYTES 0x1e9802 +#elif defined (__AVR_ATmega1284P__) + #define SIGNATURE_BYTES 0x1e9705 +#elif defined (__AVR_ATmega640__) + #define SIGNATURE_BYTES 0x1e9608 +#elif defined (__AVR_ATmega64__) + #define SIGNATURE_BYTES 0x1E9602 +#elif defined (__AVR_ATmega169__) + #define SIGNATURE_BYTES 0x1e9405 +#elif defined (__AVR_AT90USB1287__) + #define SIGNATURE_BYTES 0x1e9782 +#else + #error "no signature definition for MCU available" +#endif + + +#if defined(_BOARD_ROBOTX_) || defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) + #define UART_BAUD_RATE_LOW UBRR1L + #define UART_STATUS_REG UCSR1A + #define UART_CONTROL_REG UCSR1B + #define UART_ENABLE_TRANSMITTER TXEN1 + #define UART_ENABLE_RECEIVER RXEN1 + #define UART_TRANSMIT_COMPLETE TXC1 + #define UART_RECEIVE_COMPLETE RXC1 + #define UART_DATA_REG UDR1 + #define UART_DOUBLE_SPEED U2X1 + +#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ + || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) + /* ATMega8 with one USART */ + #define UART_BAUD_RATE_LOW UBRRL + #define UART_STATUS_REG UCSRA + #define UART_CONTROL_REG UCSRB + #define UART_ENABLE_TRANSMITTER TXEN + #define UART_ENABLE_RECEIVER RXEN + #define UART_TRANSMIT_COMPLETE TXC + #define UART_RECEIVE_COMPLETE RXC + #define UART_DATA_REG UDR + #define UART_DOUBLE_SPEED U2X + +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega162__) \ + || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) + /* ATMega with two USART, use UART0 */ + #define UART_BAUD_RATE_LOW UBRR0L + #define UART_STATUS_REG UCSR0A + #define UART_CONTROL_REG UCSR0B + #define UART_ENABLE_TRANSMITTER TXEN0 + #define UART_ENABLE_RECEIVER RXEN0 + #define UART_TRANSMIT_COMPLETE TXC0 + #define UART_RECEIVE_COMPLETE RXC0 + #define UART_DATA_REG UDR0 + #define UART_DOUBLE_SPEED U2X0 +#elif defined(UBRR0L) && defined(UCSR0A) && defined(TXEN0) + /* ATMega with two USART, use UART0 */ + #define UART_BAUD_RATE_LOW UBRR0L + #define UART_STATUS_REG UCSR0A + #define UART_CONTROL_REG UCSR0B + #define UART_ENABLE_TRANSMITTER TXEN0 + #define UART_ENABLE_RECEIVER RXEN0 + #define UART_TRANSMIT_COMPLETE TXC0 + #define UART_RECEIVE_COMPLETE RXC0 + #define UART_DATA_REG UDR0 + #define UART_DOUBLE_SPEED U2X0 +#elif defined(UBRRL) && defined(UCSRA) && defined(UCSRB) && defined(TXEN) && defined(RXEN) + //* catch all + #define UART_BAUD_RATE_LOW UBRRL + #define UART_STATUS_REG UCSRA + #define UART_CONTROL_REG UCSRB + #define UART_ENABLE_TRANSMITTER TXEN + #define UART_ENABLE_RECEIVER RXEN + #define UART_TRANSMIT_COMPLETE TXC + #define UART_RECEIVE_COMPLETE RXC + #define UART_DATA_REG UDR + #define UART_DOUBLE_SPEED U2X +#else + #error "no UART definition for MCU available" +#endif + + +/* + * Macro to calculate UBBR from XTAL and baudrate + */ +#if defined(__AVR_ATmega32__) && UART_BAUDRATE_DOUBLE_SPEED + #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu / 4 / baudRate - 1) / 2) +#elif defined(__AVR_ATmega32__) + #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu / 8 / baudRate - 1) / 2) +#elif UART_BAUDRATE_DOUBLE_SPEED + #define UART_BAUD_SELECT(baudRate,xtalCpu) (((float)(xtalCpu))/(((float)(baudRate))*8.0)-1.0+0.5) +#else + #define UART_BAUD_SELECT(baudRate,xtalCpu) (((float)(xtalCpu))/(((float)(baudRate))*16.0)-1.0+0.5) +#endif + +#ifdef DUALSERIAL + +// UART defines +#define UART_BAUD_RATE_LOW0 UBRR0L +#define UART_STATUS_REG0 UCSR0A +#define UART_CONTROL_REG0 UCSR0B +#define UART_ENABLE_TRANSMITTER0 TXEN0 +#define UART_ENABLE_RECEIVER0 RXEN0 +#define UART_TRANSMIT_COMPLETE0 TXC0 +#define UART_RECEIVE_COMPLETE0 RXC0 +#define UART_DATA_REG0 UDR0 +#define UART_DOUBLE_SPEED0 U2X0 + +#define UART_BAUD_RATE_LOW2 UBRR2L +#define UART_STATUS_REG2 UCSR2A +#define UART_CONTROL_REG2 UCSR2B +#define UART_ENABLE_TRANSMITTER2 TXEN2 +#define UART_ENABLE_RECEIVER2 RXEN2 +#define UART_TRANSMIT_COMPLETE2 TXC2 +#define UART_RECEIVE_COMPLETE2 RXC2 +#define UART_DATA_REG2 UDR2 +#define UART_DOUBLE_SPEED2 U2X2 + +#endif //DUALSERIAL + + +#define UART_BAUD_SELECT(baudRate,xtalCpu) (((float)(xtalCpu))/(((float)(baudRate))*8.0)-1.0+0.5) + +/* + * States used in the receive state machine + */ +#define ST_START 0 +#define ST_GET_SEQ_NUM 1 +#define ST_MSG_SIZE_1 2 +#define ST_MSG_SIZE_2 3 +#define ST_GET_TOKEN 4 +#define ST_GET_DATA 5 +#define ST_GET_CHECK 6 +#define ST_PROCESS 7 + +/* + * use 16bit address variable for ATmegas with <= 64K flash + */ +#if defined(RAMPZ) + typedef uint32_t address_t; +#else + typedef uint16_t address_t; +#endif + +/* + * function prototypes + */ +static void sendchar(char c); +//static unsigned char recchar(void); + +#ifdef DUALSERIAL +int selectedSerial; +#endif //DUALSERIAL + +/* + * since this bootloader is not linked against the avr-gcc crt1 functions, + * to reduce the code size, we need to provide our own initialization + */ +void __jumpMain (void) __attribute__ ((naked)) __attribute__ ((section (".init9"))); +#include + +//#define SPH_REG 0x3E +//#define SPL_REG 0x3D + +#define STACK_TOP (RAMEND - 16) + +//***************************************************************************** +void __jumpMain(void) +{ +//* July 17, 2010 Added stack pointer initialzation +//* the first line did not do the job on the ATmega128 + + asm volatile ( ".set __stack, %0" :: "i" (STACK_TOP) ); + +//* set stack pointer to top of RAM + + asm volatile ( "ldi 16, %0" :: "i" (STACK_TOP >> 8) ); + asm volatile ( "out %0,16" :: "i" (AVR_STACK_POINTER_HI_ADDR) ); + + asm volatile ( "ldi 16, %0" :: "i" (STACK_TOP & 0x0ff) ); + asm volatile ( "out %0,16" :: "i" (AVR_STACK_POINTER_LO_ADDR) ); + + asm volatile ( "clr __zero_reg__" ); // GCC depends on register r1 set to 0 + asm volatile ( "out %0, __zero_reg__" :: "I" (_SFR_IO_ADDR(SREG)) ); // set SREG to 0 + asm volatile ( "jmp main"); // jump to main() +} + + +//***************************************************************************** +void delay_ms(unsigned int timedelay) +{ + unsigned int i; + for (i=0;i 9)?('A' + val - 10):('0' + val)); +} + +void lcd_print_hex_byte(uint8_t val) +{ + lcd_print_hex_nibble(val >> 4); + lcd_print_hex_nibble(val & 0xf); +} + +void lcd_print_hex_word(uint16_t val) +{ + lcd_print_hex_byte(val >> 8); + lcd_print_hex_byte(val & 0xff); +} + +void lcd_print_hex_dword(uint32_t val) +{ + lcd_print_hex_word(val >> 16); + lcd_print_hex_word(val & 0xffff); +} +/**/ +/* +const unsigned long ulFlashEnd = FLASHEND; +const unsigned long ulRamEnd = RAMEND; +const unsigned long ulBootSize = BOOTSIZE; +const unsigned long ulAppEnd = APP_END; +*/ +//***************************************************************************** +/* + * send single byte to USART, wait until transmission is completed + */ +static void sendchar(char c) +{ +#ifdef DUALSERIAL + if (selectedSerial == 0) + { + UART_DATA_REG0 = c; // prepare transmission + while (!(UART_STATUS_REG0 & (1 << UART_TRANSMIT_COMPLETE0))); // wait until byte sent + UART_STATUS_REG0 |= (1 << UART_TRANSMIT_COMPLETE0); // delete TXCflag + } + else if (selectedSerial == 2) + { + UART_DATA_REG2 = c; // prepare transmission + while (!(UART_STATUS_REG2 & (1 << UART_TRANSMIT_COMPLETE2))); // wait until byte sent + UART_STATUS_REG2 |= (1 << UART_TRANSMIT_COMPLETE2); // delete TXCflag + } +#else //DUALSERIAL + UART_DATA_REG = c; // prepare transmission + while (!(UART_STATUS_REG & (1 << UART_TRANSMIT_COMPLETE))); // wait until byte sent + UART_STATUS_REG |= (1 << UART_TRANSMIT_COMPLETE); // delete TXCflag +#endif //DUALSERIAL +} + + +//************************************************************************ +#ifdef DUALSERIAL +static int Serial_Available(int serial) +{ + if (serial == 0) + return (UART_STATUS_REG0 & (1 << UART_RECEIVE_COMPLETE0)); // wait for data + else if (serial == 2) + return (UART_STATUS_REG2 & (1 << UART_RECEIVE_COMPLETE2)); // wait for data + return 0; +} +#else //DUALSERIAL +static int Serial_Available(void) +{ + return (UART_STATUS_REG & (1 << UART_RECEIVE_COMPLETE)); // wait for data +} +#endif //DUALSERIAL + + +//***************************************************************************** +/* + * Read single byte from USART, block if no data available + */ +/*static unsigned char recchar(void) +{ +#ifdef DUALSERIAL + if (selectedSerial == 0) + { + while (!(UART_STATUS_REG0 & (1 << UART_RECEIVE_COMPLETE0))) { } // wait for data + return UART_DATA_REG0; + } + else if (selectedSerial == 2) + { + while (!(UART_STATUS_REG2 & (1 << UART_RECEIVE_COMPLETE2))) { } // wait for data + return UART_DATA_REG2; + } + return 0; +#else //DUALSERIAL + while (!(UART_STATUS_REG & (1 << UART_RECEIVE_COMPLETE))) { } // wait for data + return UART_DATA_REG; +#endif //DUALSERIAL +}*/ + +#define MAX_TIME_COUNT (F_CPU >> 1) +//***************************************************************************** +static unsigned char recchar_timeout(void) +{ + uint32_t count = 0; +#ifdef DUALSERIAL + while (1) + { + if ((selectedSerial == 0) && (UART_STATUS_REG0 & (1 << UART_RECEIVE_COMPLETE0))) break; + else if ((selectedSerial == 2) && (UART_STATUS_REG2 & (1 << UART_RECEIVE_COMPLETE2))) break; + count++; + if (count > MAX_TIME_COUNT) + { + unsigned int data; + #if (FLASHEND > 0x10000) + data = pgm_read_word_far(0); //* get the first word of the user program + #else + data = pgm_read_word_near(0); //* get the first word of the user program + #endif + if (data != 0xffff) //* make sure its valid before jumping to it. + { + asm volatile( + "clr r30 \n\t" + "clr r31 \n\t" + "ijmp \n\t" + ); + } + count = 0; + } + } + if (selectedSerial == 0) return UART_DATA_REG0; + else if (selectedSerial == 2) return UART_DATA_REG2; + return 0; +#else //DUALSERIAL + while (!(UART_STATUS_REG & (1 << UART_RECEIVE_COMPLETE))) + { + // wait for data + count++; + if (count > MAX_TIME_COUNT) + { + unsigned int data; + #if (FLASHEND > 0x10000) + data = pgm_read_word_far(0); //* get the first word of the user program + #else + data = pgm_read_word_near(0); //* get the first word of the user program + #endif + if (data != 0xffff) //* make sure its valid before jumping to it. + { + asm volatile( + "clr r30 \n\t" + "clr r31 \n\t" + "ijmp \n\t" + ); + } + count = 0; + } + } + return UART_DATA_REG; +#endif //DUALSERIAL +} + +#ifdef DUALSERIAL +void initUart() +{ + // init uart0 + UART_STATUS_REG0 |= (1 <> 8) ); + asm volatile ( "out %0,16" :: "i" (AVR_STACK_POINTER_HI_ADDR) ); + asm volatile ( "ldi 16, %0" :: "i" (RAMEND & 0x0ff) ); + asm volatile ( "out %0,16" :: "i" (AVR_STACK_POINTER_LO_ADDR) );*/ + +#ifdef _FIX_ISSUE_181_ + //************************************************************************ + //* Dec 29, 2011 Issue #181, added watch dog timmer support + //* handle the watch dog timer + uint8_t mcuStatusReg; + mcuStatusReg = MCUSR; + + __asm__ __volatile__ ("cli"); + __asm__ __volatile__ ("wdr"); + MCUSR = 0; + WDTCSR |= _BV(WDCE) | _BV(WDE); + WDTCSR = 0; + __asm__ __volatile__ ("sei"); + // check if WDT generated the reset, if so, go straight to app + if (mcuStatusReg & _BV(WDRF)) + { + if (boot_app_magic == 0x55aa55aa) + { +/// uint16_t tmp_boot_copy_size = boot_copy_size; +/// uint32_t tmp_boot_src_addr = boot_src_addr; + + address = boot_dst_addr; + address_t pageAddress = address; + while (boot_copy_size) + { + if (boot_app_flags & BOOT_APP_FLG_ERASE) + { + boot_page_erase(pageAddress); + boot_spm_busy_wait(); + } + pageAddress += SPM_PAGESIZE; + if ((boot_app_flags & BOOT_APP_FLG_COPY)) + { + while (boot_copy_size && (address < pageAddress)) + { + uint16_t word = 0x0000; + if (boot_app_flags & BOOT_APP_FLG_FLASH) + word = pgm_read_word_far(boot_src_addr); //from FLASH + else + word = *((uint16_t*)boot_src_addr); //from RAM + boot_page_fill(address, word); + address += 2; + boot_src_addr += 2; + if (boot_copy_size > 2) + boot_copy_size -= 2; + else + boot_copy_size = 0; + } + boot_page_write(pageAddress - SPM_PAGESIZE); + boot_spm_busy_wait(); + boot_rww_enable(); + } + else + { + address += SPM_PAGESIZE; + if (boot_copy_size > SPM_PAGESIZE) + boot_copy_size -= SPM_PAGESIZE; + else + boot_copy_size = 0; + } + } +/// boot_copy_size = tmp_boot_copy_size; +/// boot_src_addr = tmp_boot_src_addr; + + } + goto exit; +// original implementation app_start() does not work +// app_start(); + } + //************************************************************************ +#endif + + + boot_timer = 0; + boot_state = 0; + +#ifdef BLINK_LED_WHILE_WAITING +// boot_timeout = 90000; //* should be about 4 seconds +// boot_timeout = 170000; + boot_timeout = 20000; //* should be about 1 second +#else + boot_timeout = 3500000; // 7 seconds , approx 2us per step when optimize "s" +#endif + /* + * Branch to bootloader or application code ? + */ + +#ifdef DUALSERIAL + selectedSerial = 0; +#endif //DUALSERIAL + + +#ifndef REMOVE_BOOTLOADER_LED + /* PROG_PIN pulled low, indicate with LED that bootloader is active */ + PROGLED_DDR |= (1< boot_timeout) + { + boot_state = 1; // (after ++ -> boot_state=2 bootloader timeout, jump to main 0x00000 ) + } + #ifdef BLINK_LED_WHILE_WAITING + if ((boot_timer % _BLINK_LOOP_COUNT_) == 0) + { + //* toggle the LED + PROGLED_PORT ^= (1< boot_timeout) + { + boot_state = 1; // (after ++ -> boot_state=2 bootloader timeout, jump to main 0x00000 ) + } + #ifdef BLINK_LED_WHILE_WAITING + if ((boot_timer % _BLINK_LOOP_COUNT_) == 0) + { + //* toggle the LED + PROGLED_PORT ^= (1< 10) + { + animationTimer = 0; + animationFrame++; + if (animationFrame > 5) animationFrame = 0; + lcd_goto(91); + lcd_puts("| |"); + lcd_goto((animationFrame <= 3)?(92 + animationFrame):(98 - animationFrame)); + lcd_putc('*'); + } + } +#endif //LCD_HD44780_ANIMATION + +#ifdef LCD_HD44780_COUNTER + if ((flashSize != 0) && flashOperation) + { + if (flashOperation == 1) //write + { + lcd_goto(88); + lcd_puts("write "); + } + if (flashOperation == 2) //verify + { + lcd_goto(87); + lcd_puts("verify "); + } + int progress = 100 * flashCounter / flashSize; + char text[4] = " "; + for (int i = 2; i >= 0; i--) + if (progress > 0) + { + text[i] = '0' + (progress % 10); + progress /= 10; + } + else + text[i] = ' '; + lcd_puts(text); + lcd_putc('%'); + } +#endif //LCD_HD44780_COUNTER + + /* + * Now process the STK500 commands, see Atmel Appnote AVR068 + */ + + switch (msgBuffer[0]) + { + #ifndef REMOVE_CMD_SPI_MULTI + case CMD_SPI_MULTI: + { + unsigned char answerByte; + unsigned char flag=0; + + if ( msgBuffer[4]== 0x30 ) + { + unsigned char signatureIndex = msgBuffer[6]; + + if ( signatureIndex == 0 ) + { + answerByte = (SIGNATURE_BYTES >> 16) & 0x000000FF; + } + else if ( signatureIndex == 1 ) + { + answerByte = (SIGNATURE_BYTES >> 8) & 0x000000FF; + } + else + { + answerByte = SIGNATURE_BYTES & 0x000000FF; + } + } + else if ( msgBuffer[4] & 0x50 ) + { + //* Issue 544: stk500v2 bootloader doesn't support reading fuses + //* I cant find the docs that say what these are supposed to be but this was figured out by trial and error + // answerByte = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); + // answerByte = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); + // answerByte = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS); + if (msgBuffer[4] == 0x50) + { + answerByte = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); + } + else if (msgBuffer[4] == 0x58) + { + answerByte = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); + } + else + { + answerByte = 0; + } + } + else + { + answerByte = 0; // for all others command are not implemented, return dummy value for AVRDUDE happy + } + if ( !flag ) + { + msgLength = 7; + msgBuffer[1] = STATUS_CMD_OK; + msgBuffer[2] = 0; + msgBuffer[3] = msgBuffer[4]; + msgBuffer[4] = 0; + msgBuffer[5] = answerByte; + msgBuffer[6] = STATUS_CMD_OK; + } + } + break; + #endif + case CMD_SIGN_ON: + msgLength = 11; + msgBuffer[1] = STATUS_CMD_OK; + msgBuffer[2] = 8; + msgBuffer[3] = 'A'; + msgBuffer[4] = 'V'; + msgBuffer[5] = 'R'; + msgBuffer[6] = 'I'; + msgBuffer[7] = 'S'; + msgBuffer[8] = 'P'; + msgBuffer[9] = '_'; + msgBuffer[10] = '2'; + break; + + case CMD_GET_PARAMETER: + { + unsigned char value; + + switch(msgBuffer[1]) + { + case PARAM_BUILD_NUMBER_LOW: + value = CONFIG_PARAM_BUILD_NUMBER_LOW; + break; + case PARAM_BUILD_NUMBER_HIGH: + value = CONFIG_PARAM_BUILD_NUMBER_HIGH; + break; + case PARAM_HW_VER: + value = CONFIG_PARAM_HW_VER; + break; + case PARAM_SW_MAJOR: + value = CONFIG_PARAM_SW_MAJOR; + break; + case PARAM_SW_MINOR: + value = CONFIG_PARAM_SW_MINOR; + break; + default: + value = 0; + break; + } + msgLength = 3; + msgBuffer[1] = STATUS_CMD_OK; + msgBuffer[2] = value; + } + break; + + case CMD_LEAVE_PROGMODE_ISP: + isLeave = 1; + //* fall thru + + case CMD_SET_PARAMETER: + case CMD_ENTER_PROGMODE_ISP: + msgLength = 2; + msgBuffer[1] = STATUS_CMD_OK; + break; + + case CMD_READ_SIGNATURE_ISP: + { + unsigned char signatureIndex = msgBuffer[4]; + unsigned char signature; + + if ( signatureIndex == 0 ) + signature = (SIGNATURE_BYTES >>16) & 0x000000FF; + else if ( signatureIndex == 1 ) + signature = (SIGNATURE_BYTES >> 8) & 0x000000FF; + else + signature = SIGNATURE_BYTES & 0x000000FF; + + msgLength = 4; + msgBuffer[1] = STATUS_CMD_OK; + msgBuffer[2] = signature; + msgBuffer[3] = STATUS_CMD_OK; + } + break; + + case CMD_READ_LOCK_ISP: + msgLength = 4; + msgBuffer[1] = STATUS_CMD_OK; + msgBuffer[2] = boot_lock_fuse_bits_get( GET_LOCK_BITS ); + msgBuffer[3] = STATUS_CMD_OK; + break; + + case CMD_READ_FUSE_ISP: + { + unsigned char fuseBits; + + if ( msgBuffer[2] == 0x50 ) + { + if ( msgBuffer[3] == 0x08 ) + fuseBits = boot_lock_fuse_bits_get( GET_EXTENDED_FUSE_BITS ); + else + fuseBits = boot_lock_fuse_bits_get( GET_LOW_FUSE_BITS ); + } + else + { + fuseBits = boot_lock_fuse_bits_get( GET_HIGH_FUSE_BITS ); + } + msgLength = 4; + msgBuffer[1] = STATUS_CMD_OK; + msgBuffer[2] = fuseBits; + msgBuffer[3] = STATUS_CMD_OK; + } + break; + + #ifndef REMOVE_PROGRAM_LOCK_BIT_SUPPORT + case CMD_PROGRAM_LOCK_ISP: + { + unsigned char lockBits = msgBuffer[4]; + + lockBits = (~lockBits) & 0x3C; // mask BLBxx bits + boot_lock_bits_set(lockBits); // and program it + boot_spm_busy_wait(); + + msgLength = 3; + msgBuffer[1] = STATUS_CMD_OK; + msgBuffer[2] = STATUS_CMD_OK; + } + break; + #endif + case CMD_CHIP_ERASE_ISP: + eraseAddress = 0; + msgLength = 2; + // msgBuffer[1] = STATUS_CMD_OK; + msgBuffer[1] = STATUS_CMD_FAILED; //* isue 543, return FAILED instead of OK + break; + + case CMD_LOAD_ADDRESS: + #if defined(RAMPZ) + address = ( ((address_t)(msgBuffer[1])<<24)|((address_t)(msgBuffer[2])<<16)|((address_t)(msgBuffer[3])<<8)|(msgBuffer[4]) )<<1; + #else + address = ( ((msgBuffer[3])<<8)|(msgBuffer[4]) )<<1; //convert word to byte address + #endif + msgLength = 2; + msgBuffer[1] = STATUS_CMD_OK; + break; + + case CMD_SET_UPLOAD_SIZE_PRUSA3D: + ((unsigned char*)&flashSize)[0] = msgBuffer[1]; + ((unsigned char*)&flashSize)[1] = msgBuffer[2]; + ((unsigned char*)&flashSize)[2] = msgBuffer[3]; + ((unsigned char*)&flashSize)[3] = 0; + msgLength = 2; + msgBuffer[1] = STATUS_CMD_OK; + break; + + case CMD_PROGRAM_FLASH_ISP: + case CMD_PROGRAM_EEPROM_ISP: + { + unsigned int size = ((msgBuffer[1])<<8) | msgBuffer[2]; + unsigned char *p = msgBuffer+10; + unsigned int data; + unsigned char highByte, lowByte; + address_t tempaddress = address; + + + if ( msgBuffer[0] == CMD_PROGRAM_FLASH_ISP ) + { + if (flashSize != 0) + { + if (address == 0) //first page + { + flashCounter = size; //initial value = size + flashAddressLast = 0; //last + flashOperation = 1; //write + } + else if (address != flashAddressLast) + flashCounter += size; //add size to counter + flashAddressLast = address; + } + + // erase only main section (bootloader protection) + if (eraseAddress < APP_END ) //erase and write only blocks with address less 0x3e000 + { //because prevent "brick" + boot_page_erase(eraseAddress); // Perform page erase + boot_spm_busy_wait(); // Wait until the memory is erased. + eraseAddress += SPM_PAGESIZE; // point to next page to be erase + } + if (address < APP_END) + { + /* Write FLASH */ + do { + lowByte = *p++; + highByte = *p++; + + data = (highByte << 8) | lowByte; + boot_page_fill(address,data); + + address = address + 2; // Select next word in memory + size -= 2; // Reduce number of bytes to write by two + } while (size); // Loop until all bytes written + + boot_page_write(tempaddress); + boot_spm_busy_wait(); + boot_rww_enable(); // Re-enable the RWW section + } + } + else + { + //* issue 543, this should work, It has not been tested. + uint16_t ii = address >> 1; + /* write EEPROM */ + while (size) { + eeprom_write_byte((uint8_t*)ii, *p++); + address+=2; // Select next EEPROM byte + ii++; + size--; + } + } + msgLength = 2; + msgBuffer[1] = STATUS_CMD_OK; + + } + break; + + case CMD_READ_FLASH_ISP: + case CMD_READ_EEPROM_ISP: + { + unsigned int size = ((msgBuffer[1])<<8) | msgBuffer[2]; + unsigned char *p = msgBuffer+1; + msgLength = size+3; + + *p++ = STATUS_CMD_OK; + if (msgBuffer[0] == CMD_READ_FLASH_ISP ) + { + if (flashSize != 0) + { + if ((address == 0x00000) && (flashOperation == 1)) + { + flashOperation = 2; //verify + flashCounter = size; //initial value = size + } + else + flashCounter += size; //add size to counter + } + + unsigned int data; + + // Read FLASH + do { + //#if defined(RAMPZ) + #if (FLASHEND > 0x10000) + data = pgm_read_word_far(address); + #else + data = pgm_read_word_near(address); + #endif + *p++ = (unsigned char)data; //LSB + *p++ = (unsigned char)(data >> 8); //MSB + address += 2; // Select next word in memory + size -= 2; + }while (size); + } + else + { + /* Read EEPROM */ + do { + EEARL = address; // Setup EEPROM address + EEARH = ((address >> 8)); + address++; // Select next EEPROM byte + EECR |= (1<>8)&0xFF); + sendchar(c); + checksum ^= c; + + c = msgLength&0x00FF; + sendchar(c); + checksum ^= c; + + sendchar(TOKEN); + checksum ^= TOKEN; + + p = msgBuffer; + while ( msgLength ) + { + c = *p++; + sendchar(c); + checksum ^=c; + msgLength--; + } + sendchar(checksum); + seqNum++; + + #ifndef REMOVE_BOOTLOADER_LED + //* toggle the LED + PROGLED_PORT ^= (1< + + +base address = f000 +avrdude: Device signature = 0x1e9703 +avrdude: safemode: lfuse reads as FF +avrdude: safemode: hfuse reads as D8 +avrdude: safemode: efuse reads as F5 +avrdude> +*/ + +//************************************************************************ diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.h b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.h new file mode 100644 index 0000000..0ddb1fa --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.h @@ -0,0 +1,4 @@ +#ifndef STK500BOOT_H +#define STK500BOOT_H +extern void sendchar(char c); +#endif // STK500BOOT_H diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.hex b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.hex new file mode 100644 index 0000000..93fa242 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot.hex @@ -0,0 +1,216 @@ +:020000023000CC +:10E000000D9472F00D949BF00D949BF00D949BF089 +:10E010000D949BF00D949BF00D949BF00D949BF050 +:10E020000D949BF00D949BF00D949BF00D949BF040 +:10E030000D949BF00D949BF00D949BF00D949BF030 +:10E040000D949BF00D949BF00D949BF00D949BF020 +:10E050000D949BF00D949BF00D949BF00D949BF010 +:10E060000D949BF00D949BF00D949BF00D949BF000 +:10E070000D949BF00D949BF00D949BF00D949BF0F0 +:10E080000D949BF00D949BF00D949BF00D949BF0E0 +:10E090000D949BF00D949BF00D949BF00D949BF0D0 +:10E0A0000D949BF00D949BF00D949BF00D949BF0C0 +:10E0B0000D949BF00D949BF00D949BF00D949BF0B0 +:10E0C0000D949BF00D949BF00D949BF00D949BF0A0 +:10E0D0000D949BF00D949BF00D949BF00D949BF090 +:10E0E0000D949BF011241FBECFEFD1E2DEBFCDBF58 +:10E0F00001E00CBF12E0A0E0B2E0EAEEFCEE03E0CB +:10E100000BBF02C007900D92A235B107D9F712E0FC +:10E11000A2E5B2E001C01D92A435B107E1F70F946A +:10E12000C0F00D9473F601E20EBF0FEF0DBF112486 +:10E130001FBE0D94C0F00D9400F020E030E040EDE3 +:10E1400057E005C0FA013197F1F72F5F3F4F2817CD +:10E150003907C0F30895E0ECF0E0808182608083AD +:10E1600020E12093C40098E19093C100E0EDF0E03D +:10E170008081826080832093D4009093D1000895A1 +:10E180002F923F924F925F926F927F928F929F92C7 +:10E19000AF92BF92CF92DF92EF92FF920F931F93B5 +:10E1A000DF93CF93CDB7DEB7C053D1400FB6F8940D +:10E1B000DEBF0FBECDBF01E20EBF0FEF0DBF94B7A4 +:10E1C000F894A89514BE80916000886180936000E7 +:10E1D00010926000789493FF05C0E0915202F09194 +:10E1E00053021995279A2F9A8091C00082608093DC +:10E1F000C00080E18093C40088E18093C1000000EA +:10E200000F94ABF00F94D2F50F94CAF587E10F94F9 +:10E21000CEF580E092E00F94B6F58DE20F94CEF546 +:10E220008EE092E00F94B6F5EE24FF248701F4E02F +:10E23000AF2EB12CCC24DD2424C0C5010197F1F709 +:10E240000894E11CF11C011D111D21E2E2162EE4CF +:10E25000F20620E0020720E0120718F0E1E0CE2EDF +:10E26000D12CC801B70127EC3BE140E050E00F940E +:10E2700043F6611571058105910519F485B1805842 +:10E2800085B98091C00087FD03C0C114D104A9F2F3 +:10E29000A6014F5F5F4FC25EDE4F59834883CE5168 +:10E2A000D140C25EDE4F88819981CE51D140019725 +:10E2B00009F0CDC3CD5DDE4F19821882C352D14023 +:10E2C000A0E0CE5DDE4F1882C252D14044245524D6 +:10E2D00022243324C05EDE4F19821882C052D140FE +:10E2E000882499245401CB5DDE4F188219821A824A +:10E2F0001B82C552D140ABBEF40127913691C15D5E +:10E30000DE4F39832883CF52D1409DC3C25EDE4F9A +:10E3100048815981CE51D1404130510509F52091B4 +:10E32000C600C25EDE4F19821882CE51D14022C093 +:10E330002F5F3F4F4F4F5F4F213082E138078AE711 +:10E34000480780E0580780F0C15DDE4FE881F98121 +:10E35000CF52D140EF5FFF4F19F0EE27FF2709940E +:10E3600020E030E040E050E08091C00087FFE0CF47 +:10E370002091C600933011F1943028F4913089F047 +:10E380009230B8F408C0953061F19530F0F09630D5 +:10E3900009F048C043C02B3109F0B8CF91E0ABE1A0 +:10E3A000B5CFA227CE5DDE4F2883C252D14092E086 +:10E3B000ADCF722F60E0A22793E0A8CF822F90E02C +:10E3C000682B792BA22794E0A1CF2E3009F05AC3F5 +:10E3D000A22795E0CD5DDE4F19821882C352D1404D +:10E3E00095CFE1E0F0E0EC0FFD1FCD5DDE4F488101 +:10E3F0005981C352D140E40FF51F20834F5F5F4F17 +:10E40000CD5DDE4F59834883C352D140A2274617C2 +:10E41000570709F07BCFBA0196E078CF2A1709F0A9 +:10E4200031C303C0973009F071CF0894411C511CCF +:10E430005BE04516510408F45DC00894211C311CB2 +:10E4400086E02816310410F02224332480E00F9453 +:10E45000CEF5C05EDE4FA881B981C052D140AB2B52 +:10E46000B1F484E10F94CEF580E292E00F94B6F51A +:10E470008DE20F94CEF584E392E00F94B6F5E1E0DF +:10E48000F0E0C05EDE4FF983E883C052D1408BE5F7 +:10E490000F94CEF588E492E00F94B6F5F2E02F16D3 +:10E4A0003104E9F023E02216310440F42114310450 +:10E4B00091F031E023163104D9F413C044E024165E +:10E4C000310469F054E02516310438F085E028164F +:10E4D000310471F406C08CE505C08FE503C08EE5FC +:10E4E00001C08DE50F94CEF58FE492E00F94B6F560 +:10E4F000442455249981933109F40EC19431C0F418 +:10E50000963009F4DCC0973048F4923069F19330CA +:10E5100009F470C0913009F017C256C0913109F466 +:10E520007AC0923108F0C0C0903109F00DC21CC011 +:10E53000983109F488C0993150F4953109F4ECC050 +:10E54000953108F49AC1963109F0FEC196C19A310D +:10E5500009F471C09A3108F496C09B3109F460C087 +:10E560009D3109F0F1C102C090E056C09D81903309 +:10E5700059F48F81882311F49EE11CC0813011F081 +:10E5800091E018C098E916C0892F807591F09035F8 +:10E5900039F489E0E0E0F0E08093570094910AC0FC +:10E5A000983539F4E3E0F0E089E0809357009491E6 +:10E5B00001C090E01A821B828D818C831D829E8314 +:10E5C0001F8227E030E0C4C11A8288E08B8381E497 +:10E5D0008C8386E58D8382E58E8389E48F8383E552 +:10E5E000888780E589878FE58A8782E38B872BE0A0 +:10E5F00030E0AEC18A81813941F0823941F0803901 +:10E6000011F48FE005C080E003C082E001C08AE021 +:10E610001A828B8346C091E01A8222E030E099C1D1 +:10E620008D81882311F48EE128C0813011F081E0C2 +:10E6300024C088E922C01A8289E0E1E0F0E08093FA +:10E64000570084911BC08B81803589F48C81883080 +:10E6500039F4E2E0F0E089E08093570084910DC046 +:10E6600089E0E0E0F0E080935700849106C0E3E0A9 +:10E67000F0E089E08093570084911A828B831C829A +:10E6800024E030E065C18D81836C99E0E1E0F0E049 +:10E69000082E90935700E89507B600FCFDCF1A822C +:10E6A0001B8223E030E054C180EC8A83CB5DDE4FD7 +:10E6B000188219821A821B82C552D14047C18A81B1 +:10E6C00090E0A0E0B0E0B82EAA24992488248B81A1 +:10E6D00090E0A0E0B0E0DC0199278827882A992AF9 +:10E6E000AA2ABB2A8D8190E0A0E0B0E0882A992A6E +:10E6F000AA2ABB2A8C8190E0A0E0B0E0BA2FA92F13 +:10E70000982F8827882A992AAA2ABB2A880C991C1C +:10E71000AA1CBB1C1A821AC1FA81C65DDE4FF8839F +:10E72000CA52D140C75DDE4F1882C952D1408B8199 +:10E73000C82EDD24C75DDE4F28813981C952D14002 +:10E74000C22AD32A933109F06DC0CB5DDE4F888198 +:10E750009981AA81BB81C552D1408030E0EC9E07EF +:10E76000E3E0AE07E0E0BE07F0F423E0FC01A09395 +:10E770005B0020935700E89507B600FCFDCFCB5D0A +:10E78000DE4F88819981AA81BB81C552D1408050DA +:10E790009F4FAF4FBF4FCB5DDE4F88839983AA83D6 +:10E7A000BB83C552D140B501A401DE011B968C91FB +:10E7B00011962C9111971296C45DDE4F2883CC528E +:10E7C000D140C55DDE4F1882CB52D14090E0C55D8F +:10E7D000DE4FE881F981CB52D1408E2B9F2B21E077 +:10E7E0000C01FA0160935B0020935700E895112417 +:10E7F0004E5F5F4F6F4F7F4F8EEF9FEFC80ED91E5A +:10E80000C114D104A1F695E0F401A0925B009093AD +:10E810005700E89507B600FCFDCF81E180935700D3 +:10E82000E89527C0D501C401B695A795979587951A +:10E830007C0186012BE0622E712C6C0E7D1E0BC0BC +:10E84000D3016D913D01C7010F9465F60894E11C59 +:10E85000F11C015010400115110591F7A60160E06F +:10E8600070E0440F551F661F771F480D591D6A1D24 +:10E870007B1D1A824A015B0169C0BA81C25DDE4F0D +:10E88000B883CE52D140C35DDE4F1882CD52D14005 +:10E890008B81C82EDD24C35DDE4FE881F981CD5226 +:10E8A000D140CE2ADF2A1A8289818431D1F496019F +:10E8B000BE016D5F7F4FABBEF40187919691DB0186 +:10E8C0008C9311969C936E5F7F4F82E090E0A0E066 +:10E8D000B0E0880E991EAA1EBB1E2250304059F788 +:10E8E0002DC0A5019401BE016D5F7F4F0894C10842 +:10E8F000D108760100E010E00894C11CD11C0894F6 +:10E90000E11CF11C011D111DE80CF91C0A1D1B1D49 +:10E9100021BDBB27A52F942F832F82BD2F5F3F4F93 +:10E920004F4F5F4FF89A80B5DB018D93BD012E15D7 +:10E930003F054007510761F749015A0196012D5FD4 +:10E940003F4FFB01108204C080EC8A8322E030E05C +:10E9500090E0FBE1F093C6008091C00086FFFCCF01 +:10E960008091C00080648093C000CE5DDE4F4881FE +:10E97000C252D1404093C6008091C00086FFFCCFB8 +:10E980008091C00080648093C000532F3093C600F4 +:10E990008091C00086FFFCCF8091C000806480938E +:10E9A000C000422F2093C6008091C00086FFFCCF9C +:10E9B0008091C00080648093C0008EE08093C60088 +:10E9C0008091C00086FFFCCF8091C000806480935E +:10E9D000C000A5E1CE5DDE4F8881C252D140A8279C +:10E9E000A427A527FE01319610C040814093C600A0 +:10E9F0008091C00086FFFCCF31968091C00080647A +:10EA00008093C000A427215030402115310569F7BB +:10EA1000A093C6008091C00086FFFCCF8091C0000B +:10EA200080648093C00085B1805885B9992379F4BA +:10EA3000CE5DDE4F9881C252D1409F5FCE5DDE4FEA +:10EA40009883C252D14090E060E070E05FCC27989C +:10EA50002F9880E090E020ED37E0F9013197F1F751 +:10EA6000019684369105C9F700008091C0008D7F22 +:10EA70008093C00081E180935700E895EE27FF273F +:10EA80000994FFCF90E042CC282F662311F05D9AC5 +:10EA900001C05D9827FF02C0A39A01C0A398922FDE +:10EAA00026FF04C080910201806803C080910201AA +:10EAB0008F778093020195FF02C0A49A01C0A498A9 +:10EAC00094FF02C05A9A01C05A9800C05B9A82E033 +:10EAD0008A95F1F700C05B9893FF02C0A39A01C02A +:10EAE000A39892FF04C080910201806803C08091C6 +:10EAF00002018F778093020191FF02C0A49A01C0A6 +:10EB0000A49890FF02C05A9A01C05A9800C05B9A1C +:10EB100092E09A95F1F700C05B98A39A8091020168 +:10EB2000806880930201A49A5A9A662341F42430A3 +:10EB300030F48FE999E10197F1F700C003C095ED3A +:10EB40009A95F1F70000089561E00F9444F5089557 +:10EB5000CF93DF93EC0102C00F94A4F5FE01219640 +:10EB600084918823C9F7DF91CF910895CF93DF93E4 +:10EB7000EC0102C00F94A4F589918823D9F7DF91A5 +:10EB8000CF91089560E00F9444F5089582E00F94CA +:10EB9000C2F5089581E00F94C2F5089580580F944E +:10EBA000C2F50895539A559A9B9AE1E0F1E080816D +:10EBB000806880839C9A529A5B985D98A39AE2E061 +:10EBC000F1E0808180688083A49A5A9A8FE59AEE5A +:10EBD0000197F1F700C00000A39880818F778083B0 +:10EBE00000C05B9A92E09A95F1F700C05B988FE0C5 +:10EBF00090E40197F1F700C000005B9A92E09A95CB +:10EC0000F1F700C05B988FE891E00197F1F700C041 +:10EC100000005B9A92E09A95F1F700C05B9885ED51 +:10EC20008A95F1F700005A9800C05B9A92E09A9595 +:10EC3000F1F700C05B9885ED8A95F1F700005A98CE +:10EC400000C05B9A92E09A95F1F700C05B9882E071 +:10EC50008A95F1F700C0A39A00C05B9A92E09A955A +:10EC6000F1F700C05B9885ED8A95F1F7000088E028 +:10EC70000F94C2F50F94CAF586E00F94C2F58CE0AC +:10EC80000F94C2F50895A1E21A2EAA1BBB1BFD0129 +:10EC90000DC0AA1FBB1FEE1FFF1FA217B307E4077B +:10ECA000F50720F0A21BB30BE40BF50B661F771FD3 +:10ECB000881F991F1A9469F76095709580959095B3 +:10ECC0009B01AC01BD01CF010895262FF999FECF1C +:10ECD0001FBA92BD81BD20BD0FB6F894FA9AF99A79 +:0AECE0000FBE01960895F894FFCFCF +:10ECEA0020334420205072696E74657273002020AC +:10ECFA00204F726967696E616C205072757361008A +:10ED0A0020446F206E6F7420646973636F6E6E6542 +:10ED1A006374210020557067726164696E672066AA +:10ED2A0069726D77617265007C202020207C002A40 +:02ED3A000000D7 +:040000033000E000E9 +:00000001FF diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot_v2_mega2560.hex b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot_v2_mega2560.hex new file mode 100644 index 0000000..fa36efc --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_einsy_rambo/stk500boot_v2_mega2560.hex @@ -0,0 +1,285 @@ +:020000023000CC +:10E000000D9472F00D949BF00D949BF00D949BF089 +:10E010000D949BF00D949BF00D949BF00D949BF050 +:10E020000D949BF00D949BF00D949BF00D949BF040 +:10E030000D949BF00D949BF00D949BF00D949BF030 +:10E040000D949BF00D949BF00D949BF00D949BF020 +:10E050000D949BF00D949BF00D949BF00D949BF010 +:10E060000D949BF00D949BF00D949BF00D949BF000 +:10E070000D949BF00D949BF00D949BF00D949BF0F0 +:10E080000D949BF00D949BF00D949BF00D949BF0E0 +:10E090000D949BF00D949BF00D949BF00D949BF0D0 +:10E0A0000D949BF00D949BF00D949BF00D949BF0C0 +:10E0B0000D949BF00D949BF00D949BF00D949BF0B0 +:10E0C0000D949BF00D949BF00D949BF00D949BF0A0 +:10E0D0000D949BF00D949BF00D949BF00D949BF090 +:10E0E0000D949BF011241FBECFEFD1E2DEBFCDBF58 +:10E0F00001E00CBF12E0A0E0B2E0E4E2F1EF03E0E7 +:10E100000BBF02C007900D92A836B107D9F712E0F5 +:10E11000A8E6B2E001C01D92A837B107E1F70F945D +:10E12000FEF00D9490F801E20EBF0FEE0DBF11242A +:10E130001FBE0D94FEF00D9400F020E030E040EDA5 +:10E1400057E005C0FA013197F1F72F5F3F4F2817CD +:10E150003907C0F308952091760230917702211596 +:10E16000310561F48093C6008091C00086FFFCCF2A +:10E170008091C00080648093C000089522303105F2 +:10E1800059F48093D6008091D00086FFFCCF809117 +:10E19000D00080648093D0000895E0ECF0E08081AE +:10E1A0008260808320E12093C40098E19093C100B5 +:10E1B000E0EDF0E08081826080832093D400909332 +:10E1C000D1000895019719F480E885B9089515B82C +:10E1D000089581B1806F81B982B1806F82B96D9AE3 +:10E1E00075989D9AA598E1E0F1E08081886280832E +:10E1F000E2E0F1E080818862808308952F923F926F +:10E200004F925F926F927F928F929F92AF92BF9246 +:10E21000CF92DF92EF92FF920F931F93DF93CF93F2 +:10E22000CDB7DEB7C053D1400FB6F894DEBF0FBEF6 +:10E23000CDBF94B7F894A89514BE80916000886112 +:10E240008093600010926000789493FFC0C080912A +:10E25000FC1F9091FD1FA091FE1FB091FF1F8A5AD5 +:10E260009545AA4AB54509F0D6C52091F41F3091CD +:10E27000F51F4091F61F5091F71F79018A01F3E0D5 +:10E280008F2E9924939475E061E199C08091FB1FD2 +:10E2900080FF09C0F70100935B0080925700E8956A +:10E2A00007B600FCFDCFA12CE1E0BE2EC12CD12C85 +:10E2B000AE0CBF1CC01ED11E8091FB1F81FD4DC046 +:10E2C00065C08091FB1F82FF0DC08091F01F90916F +:10E2D000F11FA091F21FB091F31FABBFFC0187911A +:10E2E00096910BC08091F01F9091F11FA091F21FA9 +:10E2F000B091F31FFC01808191810C01F9014093E1 +:10E300005B0090925700E89511242E5F3F4F4F4FCE +:10E310005F4F8091F01F9091F11FA091F21FB0917B +:10E32000F31F0296A11DB11D8093F01F9093F11F62 +:10E33000A093F21FB093F31F8091F81F9091F91FE3 +:10E340008330910530F002979093F91F8093F81F66 +:10E3500004C01092F91F1092F81F8091F81F90913D +:10E36000F91F892B31F02A153B054C055D0508F492 +:10E37000A8CFF70100935B0070935700E89507B6AC +:10E3800000FCFDCF60935700E89517C020503F4F29 +:10E390004F4F5F4F8091F81F9091F91FF1E081304E +:10E3A0009F0738F0805091409093F91F8093F81F99 +:10E3B00004C01092F91F1092F81F86017501809118 +:10E3C000F81F9091F91F892B09F060CF24C5109296 +:10E3D000770210927602279A2F9A8091C00082606D +:10E3E0008093C00080E18093C40088E18093C100E5 +:10E3F00000000F94E9F080E885B90F94CDF00F94F8 +:10E40000A9F70F94A1F780E00F94A5F781E40F948A +:10E41000A5F780E092E00F948DF787E10F94A5F7C0 +:10E4200082E192E00F948DF785E60F94A5F781E2E3 +:10E4300092E00F948DF715B8A0907602B090770215 +:10E44000EE24FF24870134E0832E912CCC24DD249C +:10E4500024C0C4010197F1F70894E11CF11C011DCF +:10E46000111D21E2E2162EE4F20620E0020720E070 +:10E47000120718F021E0C22ED12CC801B70127ECF9 +:10E480003BE140E050E00F944CF8611571058105C7 +:10E49000910519F485B1805885B98091C00087FD38 +:10E4A00007C08091D00087FD03C0C114D10489F258 +:10E4B0008091D00087FF03C092E0A92EB12C960175 +:10E4C0002F5F3F4FB0927702A09276022130310544 +:10E4D00009F094C422243324CC24CC5DDE4F18826E +:10E4E000C452D140882499245401CB5DDE4F188258 +:10E4F00019821A821B82C552D140CE5DDE4F19822D +:10E500001882C252D1404424552400E010E0ABBE32 +:10E51000F40187919691C15DDE4F99838883CF5234 +:10E52000D14064C420E030E02130310551F120E0D9 +:10E5300030E040E050E0109721F48091C00087FD6A +:10E5400020C0A230B10521F48091D00087FD1CC00D +:10E550002F5F3F4F4F4F5F4F2130E2E13E07EAE729 +:10E560004E07E0E05E0738F3C15DDE4F2881398158 +:10E57000CF52D1402F5F3F4FD1F2EE27FF270994B2 +:10E58000D6CF2091C60002C02091D600933011F161 +:10E59000943028F4913089F09230B8F407C0953067 +:10E5A00041F19530F0F09630D1F535C02B3109F0BE +:10E5B000B9CF91E08BE1C82EB5CFC226CC5DDE4F3E +:10E5C0002883C452D14092E0ADCF722F60E0C226C2 +:10E5D00093E0A8CF822F90E0682B792BC22694E09D +:10E5E000A1CF2E3009F025C4C22695E02224332481 +:10E5F00099CFE5E0F0E0EC0FFD1FE20DF31D208365 +:10E600000894211C311CC2262616370609F08ACF31 +:10E61000B10196E087CF2C1509F00BC403C09730E9 +:10E6200009F080CF012B81F40F94A1F784E10F94BE +:10E63000A5F785E292E00F948DF78DE20F94A5F790 +:10E6400089E392E00F948DF78091680290916902BE +:10E65000A0916A02B0916B020097A105B10599F5EE +:10E66000CE5DDE4FA881B981C252D1401196CE5DF8 +:10E67000DE4FB983A883C252D1401B9720F1089482 +:10E68000411C511CB6E04B16510410F04424552493 +:10E690008BE50F94A5F78DE492E00F948DF7E4E0FD +:10E6A0004E16510418F4842D845A02C082E684194F +:10E6B0000F94A5F78AE20F947BF7CE5DDE4F1982A7 +:10E6C0001882C252D1408091680290916902A09153 +:10E6D0006A02B0916B020097A105B10509F461C00F +:10E6E0008091740290917502009709F45AC00197C5 +:10E6F00039F488E50F94A5F784E592E00F948DF73F +:10E700008091740290917502029739F487E50F9415 +:10E71000A5F78BE592E00F948DF760916C027091F4 +:10E720006D0280916E0290916F0224E630E040E02D +:10E7300050E00F941AF820916802309169024091DC +:10E740006A0250916B020F944CF880916302909191 +:10E750006402A0916502B091660289839A83AB83BB +:10E76000BC83FE0133961216130674F4C9016AE0E5 +:10E7700070E00F9439F8805D8083C9016AE070E031 +:10E780000F9439F89B0102C080E280833197EC1727 +:10E79000FD0749F7CE0101960F948DF785E20F949E +:10E7A0007BF76D81643109F432C26531F0F4663073 +:10E7B00009F4E7C0673048F4623091F1633009F43E +:10E7C00077C0613009F0C5C25CC0613109F481C015 +:10E7D000623120F4603109F0BCC222C0623109F418 +:10E7E000C5C0633109F0B5C205C1693109F4ACC0D7 +:10E7F0006A3150F4663109F40AC2663108F4FAC08D +:10E80000683109F0A6C27FC06B3109F469C06B3171 +:10E8100008F471C06D3131F0613709F09AC2DDC082 +:10E82000DD2459C09985903359F48B85882311F4E0 +:10E830009EE11CC0813011F091E018C098E916C02B +:10E84000892F807591F0903539F489E0E0E0F0E0AF +:10E850008093570094910AC0983539F4E3E0F0E0D2 +:10E8600089E080935700949101C090E01E821F823E +:10E870008985888719869A871B86F7E0EF2EF12C09 +:10E880006DC21E8288E08F8381E4888786E5898750 +:10E8900082E58A8789E48B8783E58C8780E58D878D +:10E8A0008FE58E8782E38F87EBE0EE2EF12C56C248 +:10E8B0008E81813941F0823941F0803911F48FE045 +:10E8C00005C080E003C082E001C08AE01E828F8321 +:10E8D00049C0DD24D3941E8272E0E72EF12C3FC2A2 +:10E8E0008985882311F48EE128C0813011F081E000 +:10E8F00024C088E922C01E82E1E0F0E089E0809334 +:10E90000570084911BC08F81803589F488858830B9 +:10E9100039F4E2E0F0E089E08093570084910DC083 +:10E9200089E0E0E0F0E080935700849106C0E3E0E6 +:10E93000F0E089E08093570084911E828F831886CF +:10E9400064E0E62EF12C0AC28985836C99E0E1E04F +:10E95000F0E0082E90935700E89507B600FCFDCF35 +:10E960001E821F8253E0E52EF12CF8C180EC8E83CD +:10E97000CB5DDE4F188219821A821B82C552D140AC +:10E98000EAC18E8190E0A0E0B0E0B82EAA249924DC +:10E9900088248F8190E0A0E0B0E0DC0199278827EF +:10E9A000882A992AAA2ABB2A898590E0A0E0B0E0AB +:10E9B000882A992AAA2ABB2A888590E0A0E0B0E09C +:10E9C000BA2FA92F982F8827882A992AAA2ABB2AE2 +:10E9D000880C991CAA1CBB1C0BC08E8180936802FA +:10E9E0008F8180936902888580936A0210926B02FE +:10E9F0001E82B1C1FE81C65DDE4FF883CA52D1408E +:10EA0000C75DDE4F1882C952D1408F81C82EDD24E8 +:10EA1000C75DDE4F28813981C952D140C22AD32A2D +:10EA2000633109F0C9C08091680290916902A09198 +:10EA30006A02B0916B020097A105B10509F443C0C9 +:10EA400081149104A104B10491F4C601A0E0B0E0E6 +:10EA500080936C0290936D02A0936E02B0936F024C +:10EA600081E090E0909375028093740224C08091BD +:10EA7000700290917102A0917202B0917302881697 +:10EA80009906AA06BB06B9F0960140E050E08091D5 +:10EA90006C0290916D02A0916E02B0916F02820F94 +:10EAA000931FA41FB51F80936C0290936D02A093D7 +:10EAB0006E02B0936F028092700290927102A092E7 +:10EAC0007202B0927302CB5DDE4F88819981AA8178 +:10EAD000BB81C552D1408030E0EE9E07E3E0AE0737 +:10EAE000E0E0BE07F0F423E0FC01A0935B0020937C +:10EAF0005700E89507B600FCFDCFCB5DDE4F88815F +:10EB00009981AA81BB81C552D14080509F4FAF4FA0 +:10EB1000BF4FCB5DDE4F88839983AA83BB83C552E9 +:10EB2000D14090E0891690EE990693E0A90690E016 +:10EB3000B90618F0B501A40166C0B501A401DE0153 +:10EB40001F968C9111962C9111971296C45DDE4FF1 +:10EB50002883CC52D140C55DDE4F1882CB52D140C4 +:10EB600090E0C55DDE4FE881F981CB52D1408E2B1C +:10EB70009F2B21E00C01FA0160935B00209357006A +:10EB8000E89511244E5F5F4F6F4F7F4F8EEF9FEFE1 +:10EB9000C80ED91EC114D104A1F695E0F401A092CB +:10EBA0005B0090935700E89507B600FCFDCF81E12C +:10EBB00080935700E89527C0D501C401B695A79565 +:10EBC000979587957C018601AFE06A2E712C6C0EBB +:10EBD0007D1E0BC0D3016D913D01C7010F9482F8DA +:10EBE0000894E11CF11C015010400115110591F72A +:10EBF000A60160E070E0440F551F661F771F480DA7 +:10EC0000591D6A1D7B1D1E824A015B01A4C0BE8185 +:10EC1000C25DDE4FB883CE52D140C35DDE4F188255 +:10EC2000CD52D1408F81C82EDD24C35DDE4FE881F7 +:10EC3000F981CD52D140CE2ADF2A1E828D818431C6 +:10EC400009F052C08091680290916902A0916A0215 +:10EC5000B0916B020097A105B10561F18114910497 +:10EC6000A104B10481F4809174029091750201971E +:10EC700051F482E090E09093750280937402C60193 +:10EC8000A0E0B0E00FC0960140E050E080916C023F +:10EC900090916D02A0916E02B0916F02820F931F4E +:10ECA000A41FB51F80936C0290936D02A0936E0217 +:10ECB000B0936F029601BE01695F7F4FABBEF40156 +:10ECC00087919691DB018C9311969C936E5F7F4F99 +:10ECD00082E090E0A0E0B0E0880E991EAA1EBB1E64 +:10ECE0002250304059F72DC0A5019401BE01695F43 +:10ECF0007F4F0894C108D108760100E010E0089425 +:10ED0000C11CD11C0894E11CF11C011D111DE80C53 +:10ED1000F91C0A1D1B1D21BDBB27A52F942F832F76 +:10ED200082BD2F5F3F4F4F4F5F4FF89A80B5DB0199 +:10ED30008D93BD012E153F054007510761F749012D +:10ED40005A0133E0E32EF12CEC0CFD1CFB01108288 +:10ED500005C080EC8E8322E0E22EF12CDD248BE1D5 +:10ED60000F94ABF0CC5DDE4F8881C452D1400F943C +:10ED7000ABF08F2D0F94ABF08E2D0F94ABF08EE097 +:10ED80000F94ABF095E1C92ECC5DDE4FF881C452F3 +:10ED9000D140CF26CE24CF2485E0682E712C6C0E76 +:10EDA0007D1E0AC0D3011D913D01812F0F94ABF050 +:10EDB000C1260894E108F108E114F10499F78C2DBB +:10EDC0000F94ABF085B1805885B9DD20B9F4CC5DE6 +:10EDD000DE4FB881C452D140BF5FCC5DDE4FB883F7 +:10EDE000C452D14001E010E020E030E0A091760272 +:10EDF000B091770290E060E070E096CB27982F9872 +:10EE000080E090E020ED37E0F9013197F1F70196CD +:10EE100084369105C9F700008091C0008D7F8093F2 +:10EE2000C00081E180935700E895EE27FF27099401 +:10EE3000FFCF90E077CB282F662311F05D9A01C0B9 +:10EE40005D9827FF02C0A39A01C0A398922F26FFC6 +:10EE500004C080910201806803C0809102018F7715 +:10EE60008093020195FF02C0A49A01C0A49894FF68 +:10EE700002C08D9A01C08D9800C08F9A82E08A9559 +:10EE8000F1F700C08F9893FF02C0A39A01C0A39826 +:10EE900092FF04C080910201806803C0809102014A +:10EEA0008F778093020191FF02C0A49A01C0A498B9 +:10EEB00090FF02C08D9A01C08D9800C08F9A92E099 +:10EEC0009A95F1F700C08F98A39A8091020180680B +:10EED00080930201A49A8D9A662341F4243030F481 +:10EEE0008FE999E10197F1F700C003C095ED9A957C +:10EEF000F1F70000089561E00F941BF70895CF9398 +:10EF0000DF93EC0102C00F947BF7FE012196849100 +:10EF10008823C9F7DF91CF910895CF93DF93EC0158 +:10EF200002C00F947BF789918823D9F7DF91CF91A5 +:10EF3000089560E00F941BF7089582E00F9499F70D +:10EF4000089581E00F9499F7089580580F9499F7E8 +:10EF50000895879A559A9B9AE1E0F1E08081806854 +:10EF600080839C9A859A8F985D98A39AE2E0F1E05D +:10EF7000808180688083A49A8D9A8FE59AEE0197AC +:10EF8000F1F700C00000A39880818F77808300C0D4 +:10EF90008F9A92E09A95F1F700C08F988FE090E4F5 +:10EFA0000197F1F700C000008F9A92E09A95F1F76F +:10EFB00000C08F988FE891E00197F1F700C0000042 +:10EFC0008F9A92E09A95F1F700C08F9885ED8A9517 +:10EFD000F1F700008D9800C08F9A92E09A95F1F7B2 +:10EFE00000C08F9885ED8A95F1F700008D9800C0DC +:10EFF0008F9A92E09A95F1F700C08F9882E08A95F7 +:10F00000F1F700C0A39A00C08F9A92E09A95F1F7A9 +:10F0100000C08F9885ED8A95F1F7000088E00F9485 +:10F0200099F70F94A1F786E00F9499F78CE00F946D +:10F0300099F70895629FD001739FF001829FE00DC0 +:10F04000F11D649FE00DF11D929FF00D839FF00D67 +:10F05000749FF00D659FF00D9927729FB00DE11D13 +:10F06000F91F639FB00DE11DF91FBD01CF011124F0 +:10F07000089597FB092E07260AD077FD04D02ED0DD +:10F0800006D000201AF4709561957F4F0895F6F729 +:10F09000909581959F4F0895A1E21A2EAA1BBB1B44 +:10F0A000FD010DC0AA1FBB1FEE1FFF1FA217B30754 +:10F0B000E407F50720F0A21BB30BE40BF50B661F6A +:10F0C000771F881F991F1A9469F76095709580952E +:10F0D00090959B01AC01BD01CF010895AA1BBB1BFC +:10F0E00051E107C0AA1FBB1FA617B70710F0A61B48 +:10F0F000B70B881F991F5A95A9F780959095BC0169 +:10F10000CD010895262FF999FECF1FBA92BD81BD7A +:10F1100020BD0FB6F894FA9AF99A0FBE0196089599 +:04F12000F894FFCF91 +:10F124004F726967696E616C2050727573612069F2 +:10F134003300507275736120526573656172636840 +:10F14400002E2E2E0020446F206E6F74206469738D +:10F15400636F6E6E6563742100205570677261641D +:10F16400696E67206669726D77617265007C202024 +:10F1740020207C0077726974652000766572696668 +:08F1840079200020202000008A +:040000033000E000E9 +:00000001FF diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/Caterina-prusa_mm_control.hex b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/Caterina-prusa_mm_control.hex new file mode 100644 index 0000000..ff8a9f5 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/Caterina-prusa_mm_control.hex @@ -0,0 +1,259 @@ +:107000005FC0000080C000007EC000007CC00000A7 +:107010007AC0000078C0000076C0000074C0000094 +:1070200072C0000070C00000C0C400006CC000004E +:107030006AC0000068C0000066C0000064C00000B4 +:1070400062C00000CDC000005EC000005CC0000057 +:107050005AC0000058C0000056C0000054C00000D4 +:1070600052C0000050C000004EC000004CC00000E4 +:107070004AC0000048C0000046C0000044C00000F4 +:1070800042C0000040C000003EC000003CC0000004 +:107090003AC0000038C0000036C0000034C0000014 +:1070A00032C0000030C000002EC00000443E5D3EF3 +:1070B000043F5D3E043F953EB73E043FD73EE93E68 +:1070C00011241FBECFEFDAE0DEBFCDBF8091FE0AF4 +:1070D0009091FF0A90935D0280935C0212E0A0E021 +:1070E000B1E0EAEAFEE702C005900D92A032B107D6 +:1070F000D9F722E0A0E2B2E001C01D92AC35B207A0 +:10710000E1F718D3C4C67CCF84E08093E900809176 +:10711000E80085FD0DC08091E8008B778093E80042 +:107120008091E80082FDF3CF8EB38111F9CF02C0C8 +:107130008091F100089593E09093E9009091E80028 +:1071400095FF03C08093F10008959091E8009E7729 +:107150009093E8009091E80090FDF4CF9EB39111D8 +:10716000F9CF0895F89481E085BF15BE0C94000016 +:10717000089520912602309127022F5F3F4F3093D0 +:10718000270220932602832F37FF02C08EEF831B36 +:10719000880F821710F45D9808955D9A089584B75A +:1071A000877F84BF90E880E00FB6F89490936100E9 +:1071B000809361000FBE81E085BF82E085BF559A54 +:1071C000E1E6F0E0908310825D98109289009AEFDA +:1071D0009093880080936F0083E080938100CDC3FB +:1071E0001F920F920FB60F9211242F938F939F939C +:1071F000EF93FF931092850010928400E0E0F0E09E +:1072000085919491019649F08091200290912102FC +:1072100001969093210280932002FF91EF919F911C +:107220008F912F910F900FBE0F901F90189542E0F5 +:1072300061EC82E037D342E161E883E033D342E19D +:1072400060E884E02FC380915402982F9F77913299 +:1072500039F590915502903291F0913209F5813AC9 +:10726000F9F48091E800877F8093E80067E070E0A0 +:1072700082E091E04BD48091E8008B770FC081329F +:1072800079F48091E800877F8093E80067E070E000 +:1072900082E091E098D48091E8008E778093E800B6 +:1072A00008954F925F926F927F92AF92BF92CF926A +:1072B000DF92EF92FF920F931F93CF93DF9384E0BF +:1072C0008093E9008091E80082FF25C21DDFC82F6E +:1072D000853481F48CE49DE1909321028093200217 +:1072E00007B600FCFDCFF999FECF81E180935700EE +:1072F000E89503C0843521F407DF8DE01CDFE2C18F +:107300008C34D9F38035C9F3843721F484E413DF56 +:1073100080E0F4CF813611F489E5F0CF813491F427 +:10732000F3DEC82FF1DE90E0880F991F2C2F30E09C +:10733000322F2227330F822B932B092E000CAA0BFE +:10734000BB0B94C1803711F483E5D8CF833549F462 +:10735000C7E1D2E01C2F195F8991EDDE1C13FCCF31 +:10736000B1C1863521F481E3E6DE80E3C7CF833700 +:1073700031F487E8E0DE85E9DEDE8EE1BFCF8536D9 +:10738000F1F4E0E0F0E083E095E007B600FCFDCF2B +:10739000F999FECF80935700E89507B600FCFDCF22 +:1073A000F999FECF90935700E89507B600FCFDCF02 +:1073B000E058FF4FE11540E7F40739F79ECF8237D9 +:1073C00019F4E1E0F0E00EC0863419F4E0E0F0E0FA +:1073D00009C08E3419F4E3E0F0E004C0813539F4DB +:1073E000E2E0F0E089E080935700849187CF823615 +:1073F00031F489E5A0DE80E09EDE80E87FCF823434 +:1074000019F0873609F016C110922102109220025D +:107410007BDE082F79DED82F77DE182F8BEB810FDC +:10742000823010F08FE36ACF2D2F30E0302B109296 +:107430006F00C73609F048C007B600FCFDCFF999C8 +:10744000FECF81E180935700E895E90100E0BB247D +:10745000B394209709F4EAC0C0902202D09023028E +:10746000E0902402F09025021634B9F4E02FF0E009 +:10747000EC29FD2984915FDE002369F052E0C50EFE +:10748000D11CE11CF11CC0922202D0922302E09296 +:107490002402F09225020B2515C0D701C601B6952E +:1074A000A79597958795DDD446DE82E0C80ED11C5E +:1074B000E11CF11CC0922202D0922302E09224022D +:1074C000F09225022197C5CFC0902202D0902302CE +:1074D000E0902402F0902502163421F5D701C60170 +:1074E0008F779927AA27BB27C114E0E7DE06E104BE +:1074F000F104C0F4892B8A2B8B2BA1F48FB7F8945D +:1075000007B600FCFDCFF999FECF93E0F60190930A +:107510005700E89507B600FCFDCF91E19093570026 +:10752000E8958FBFE901B12C00E0AA24A39420972D +:1075300009F454C0163469F5002339F107B600FC8C +:10754000FDCFF999FECF4090220250902302609027 +:10755000240270902502D8DD2B2D30E0A901582B94 +:10756000F2010A01A0925700E8951124B301A2018B +:107570004E5F5F4F6F4F7F4F409322025093230225 +:10758000609324027093250202C0BEDDB82E0A2546 +:1075900023C0BADD682F8091220290912302A0912E +:1075A0002402B0912502B695A7959795879561D449 +:1075B0004091220250912302609124027091250291 +:1075C0004E5F5F4F6F4F7F4F4093220250932302D5 +:1075D00060932402709325022197A9CF163421F5D8 +:1075E000D701C6018F779927AA27BB27C114F0E7D7 +:1075F000DF06E104F104C0F4892B8A2B8B2BA1F464 +:107600008FB7F89407B600FCFDCFF999FECF95E04F +:10761000F60190935700E89507B600FCFDCF91E185 +:1076200090935700E8958FBF8DE085DD82E08093D1 +:107630006F0048C0843419F567DD682F80912202FD +:1076400090912302A0912402B0912502B695A795AE +:10765000979587950ED48091220290912302A09154 +:107660002402B09125020296A11DB11D8093220231 +:1076700090932302A0932402B09325023ECE843639 +:10768000F1F4C0902202D0902302E0902402F09006 +:107690002502D701C601B695A79597958795E1D3A1 +:1076A0004ADDF2E0CF0ED11CE11CF11CC092220297 +:1076B000D0922302E0922402F092250203C08B3183 +:1076C00009F0B0CE83E08093E9009091E8008091CA +:1076D000E8008E778093E80095FD11C08091E80066 +:1076E00080FD04C08EB38111F9CF15C08091E800F0 +:1076F0008E778093E80003C08EB3882361F0809179 +:10770000E80080FFF9CF84E08093E9008091E800F1 +:107710008B778093E800DF91CF911F910F91FF90BD +:10772000EF90DF90CF90BF90AF907F906F905F9081 +:107730004F9008951092FF0A1092FE0A84B714BE6B +:107740000FB6F894A89590916000986190936000AE +:10775000109260000FBE81FD1DC080FF07C0E0E0F9 +:10776000F0E0259134912F3F3F4F99F483FF12C0F1 +:1077700020915C0230915D028091000190910101A5 +:107780002817390739F0E0E0F0E0859194910196EF +:1077900009F0E8DC04DD78941092210210922002B6 +:1077A00080DD48D3809120029091210281349F4155 +:1077B00010F4DFDCF5CF8091E00081608093E00081 +:1077C0009BE088E10FB6F894A895809360000FBE07 +:1077D00090936000FFCFCF93292F30E02230310506 +:1077E00061F02330310571F02130310509F051C0CD +:1077F00082E190E025E032E050C08EE390E027EC9B +:1078000031E04BC0882309F435C0813009F437C01A +:10781000823009F439C0833009F03BC09AE290937A +:10782000280280932902AAE2B2E090E0C1E22FB7D9 +:10783000F894E92FE695F0E03E968C2F87BF84916F +:107840002FBF90FF82958F70682F70E08A3018F0FC +:1078500027E330E002C020E330E0260F371F2D93EE +:107860003D939F5F943119F78091280290E028E2C0 +:1078700032E013C084E090E023EC31E00EC08CE7EE +:1078800090E025E431E009C08AE390E029E031E0AE +:1078900004C080E090E020E030E0FA0131832083F2 +:1078A000CF9108958093E900EBEEF0E08081816054 +:1078B0008083EDEEF0E010826093EC0040838091D5 +:1078C000EE00881F8827881F08958091540287FF43 +:1078D0000FC08091E80082FD04C08EB38111F9CF02 +:1078E00010C08091E8008B770AC08EB3882349F0DE +:1078F0008091E80080FFF9CF8091E8008E77809337 +:10790000E80008950F931F93CF93DF9341D048D0A1 +:10791000C8EDD0E088818F778883888180688883EC +:1079200088818F7D888319BC1EBA1092520200EEA6 +:1079300010E0F80180818B7F80838881816088835B +:1079400042E060E080E0AEDFE1EEF0E080818E7F3B +:107950008083E2EEF0E080818160808380818860B6 +:107960008083F80180818E7F808388818061888315 +:10797000DF91CF911F910F910895E7EDF0E08081A5 +:10798000816080838AE482BF81E080935302BACF12 +:10799000E8EDF0E080818E7F80831092E200089510 +:1079A0001092DA001092E10008951F920F920FB624 +:1079B0000F9211242F933F934F935F936F937F9375 +:1079C0008F939F93AF93BF93EF93FF938091DA00D0 +:1079D00080FF1BC08091D80080FF17C08091DA0023 +:1079E0008E7F8093DA008091D90080FF0BC080E108 +:1079F00089BD82E189BD09B400FEFDCF81E08EBB67 +:107A000018D203C019BC1EBA14D28091E10080FFC5 +:107A100017C08091E20080FF13C08091E2008E7F4A +:107A20008093E2008091E20080618093E200809187 +:107A3000D80080628093D80019BC85E08EBBF9D154 +:107A40008091E10084FF2CC08091E20084FF28C077 +:107A500080E189BD82E189BD09B400FEFDCF80913E +:107A6000D8008F7D8093D8008091E1008F7E809335 +:107A7000E1008091E2008F7E8093E2008091E2003D +:107A800081608093E20080915202811106C0809152 +:107A9000E30087FD02C081E001C084E08EBBC9D154 +:107AA0008091E10083FF21C08091E20083FF1DC02F +:107AB0008091E100877F8093E10082E08EBB10928D +:107AC00052028091E1008E7F8093E1008091E2007C +:107AD0008E7F8093E2008091E20080618093E200DB +:107AE00042E060E080E0DEDEA4D1FF91EF91BF9143 +:107AF000AF919F918F917F916F915F914F913F9146 +:107B00002F910F900FBE0F901F90189520915A0241 +:107B100030915B022617370748F06115710539F47B +:107B20002091E8002E772093E80001C0B90140E0E1 +:107B300061157105A1F12EB3222309F440C025304F +:107B400009F43FC02091E80023FD37C02091E800F0 +:107B500022FD2DC02091E80020FFEACF4091F300E4 +:107B60002091F20030E0342BFC01CF01611571054A +:107B700059F02830310540F481918093F100615033 +:107B800071092F5F3F4FF1CF41E02830310509F0F7 +:107B900040E02091E8002E772093E800C9CF411102 +:107BA000CACF05C08EB3882351F0853051F0809143 +:107BB000E80082FFF7CF80E0089581E0089582E039 +:107BC000089583E008956115710529F42091E80076 +:107BD0002B772093E800FC016115710531F18EB31C +:107BE000882359F1853059F18091E80083FD23C045 +:107BF0008091E80082FFF0CF2091F3008091F200A5 +:107C000090E0922B892B31F08091F10081936150AB +:107C1000710991F78091E8008B778093E800DCCFC1 +:107C20008EB3882351F0853051F08091E80080FFB9 +:107C3000F7CF80E0089581E0089582E0089583E021 +:107C400008950F931F93CF93DF9300D0CDB7DEB786 +:107C5000E4E5F2E088E08E0F9091F10091938E13AD +:107C6000FBCFF1DA8091E80083FFCEC0809154020F +:107C700090915502492F50E04A30510508F0C4C098 +:107C8000FA01EA5AF74CE7C0823809F0BDC080918A +:107C9000580287708093E9008091EB001092E90010 +:107CA0009091E800977F9093E80085FB882780F902 +:107CB0008093F1001092F10085C0282F2D7F09F0EC +:107CC000A3C0823009F0A0C080915602811127C064 +:107CD00080915802877009F497C08093E900209141 +:107CE000EB0020FF1CC0933021F48091EB008062F8 +:107CF00014C09091EB0090619093EB0021E030E094 +:107D0000A90102C0440F551F8A95E2F74093EA008B +:107D10001092EA008091EB0088608093EB00109253 +:107D2000E9008091E800877F50C081116DC01091FB +:107D300056021F770FB7F8948091E800877F8093F1 +:107D4000E800C3DD8091E80080FFFCCF8091E30074 +:107D50008078812B8093E30080688093E300111189 +:107D600002C082E001C083E08EBB0FBF4DC08058CF +:107D7000823008F049C0AE014F5F5F4F60915802FA +:107D8000809156029091570226DDBC01892B09F49F +:107D90003BC09091E800977F9093E80089819A8199 +:107DA000B5DE8091E8008B778093E8002DC08038A5 +:107DB00059F58091E800877F8093E8008091520216 +:107DC0008093F1008091E8008E778093E8007DDD5C +:107DD0001BC0811119C0909156029230A8F4809175 +:107DE000E800877F8093E800909352026EDD8091D7 +:107DF0005202811106C08091E30087FD02C081E03C +:107E000001C084E08EBB13DA8091E80083FF0AC0D2 +:107E10008091EB0080628093EB008091E800877F87 +:107E20008093E8000F900F90DF91CF911F910F91F9 +:107E300008950895CF938EB3882359F0C091E90037 +:107E4000C7701092E9008091E80083FDFADEC093CC +:107E5000E900CF910895EE0FFF1F0590F491E02DFA +:107E60000994F999FECF92BD81BDF89A992780B502 +:107E70000895262FF999FECF1FBA92BD81BD20BD6E +:107E80000FB6F894FA9AF99A0FBE01960895F894ED +:027E9000FFCF22 +:107E920008950895089508950895089508950895F8 +:087EA200089508950895089564 +:107EAA007777000000000000083A0350007200755E +:107EBA0000730061002000520065007300650061D4 +:107ECA0000720063006800200028007000720075CC +:107EDA000073006100330064002E0063006F006DC0 +:107EEA0000290000007C034F0072006900670069E6 +:107EFA00006E0061006C0020005000720075007373 +:107F0A0000610020006900330020004D004B00335F +:107F1A000020004D0075006C007400690020004DBF +:107F2A00006100740065007200690061006C002045 +:107F3A000032002E003000200075007000670072C9 +:107F4A00006100640065002000280062006F006F75 +:107F5A000074006C006F0061006400650072002903 +:107F6A000000000403090409023E000201008032F5 +:107F7A000904000001020201000524001001042482 +:107F8A0002040524060001070582030800FF09040C +:107F9A000100020A0000000705040210000107059B +:107FAA0083021000011201100102000008992C033B +:107FBA00000100020103014341544552494E410068 +:107FE00058CF58CF58CF58CF58CF58CF58CF58CF59 +:087FF00058CF58CF58CF58CFED +:087FF8000070000000DFFBDC5B +:040000030000700089 +:00000001FF diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/Readme.txt b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/Readme.txt new file mode 100644 index 0000000..f9707e9 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/Readme.txt @@ -0,0 +1,14 @@ +Notes on building the improved 32u4 Caterina bootloader: + +1. Must download LUFA-111009 and extract to this directory. + + This should be in a folder named LUFA-111009/ + +2. Make sure avr-gcc is installed. It make come with tools, but + if not maybe wingnu32 make, and core tools can be downloaded and used. + +3. Try using powershell if you get "...died before initialization" errors. + +4. The "build.txt" file and "program.txt" files can be renamed + to .bat files and run to build and program the boards listed + herein (Windows only, unfortunately). \ No newline at end of file diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/build.txt b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/build.txt new file mode 100644 index 0000000..8aae266 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/build.txt @@ -0,0 +1,24 @@ +make clean +make PID=0x9209 F_CPU=16000000 +copy Caterina.hex Caterina-wiflyin.hex +make clean +make PID=0x9207 F_CPU=8000000 +copy Caterina.hex Caterina-lilypadusb.hex +make clean +make PID=0x9205 F_CPU=16000000 +copy Caterina.hex Caterina-promicro16.hex +make clean +make PID=0x9203 F_CPU=8000000 +copy Caterina.hex Caterina-promicro8.hex +make clean +make PID=0x2B74 F_CPU=16000000 +copy Caterina.hex Caterina-makey.hex +make clean +make PID=0xF100 F_CPU=8000000 +copy Caterina.hex Caterina-fio.hex +make clean +make PID=0x920B F_CPU=16000000 +copy Caterina.hex Caterina-minibench.hex +make clean +make PID=0x0110 F_CPU=8000000 +copy Caterina.hex Caterina-lilypadusbplus.hex \ No newline at end of file diff --git a/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/program.txt b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/program.txt new file mode 100644 index 0000000..e1819de --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/bootloaders/prusa_mm_control/program.txt @@ -0,0 +1,9 @@ +@ECHO OFF +IF "%1"=="" avrdude -p m32u4 -P usb -c avrispmkii -U flash:w:Caterina.hex -U efuse:w:0xcb:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m +IF "%1"=="lilypadusb" avrdude -p m32u4 -P usb -c avrispmkii -U flash:w:Caterina-lilypadusb.hex -U efuse:w:0xfe:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m +IF "%1"=="fio" avrdude -p m32u4 -P usb -c avrispmkii -U flash:w:Caterina-fio.hex -U efuse:w:0xfe:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m +IF "%1"=="promicro8" avrdude -p m32u4 -P usb -c avrispmkii -U flash:w:Caterina-promicro8.hex -U efuse:w:0xfe:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m +IF "%1"=="promicro16" avrdude -p m32u4 -P usb -c avrispmkii -U flash:w:Caterina-promicro16.hex -U efuse:w:0xcb:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m +IF "%1"=="makey" avrdude -p m32u4 -P usb -c avrispmkii -U flash:w:Caterina-makey.hex -U efuse:w:0xcb:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m +IF "%1"=="wiflyin" avrdude -p m32u4 -P usb -c avrispmkii -U flash:w:Caterina-wiflyin.hex -U efuse:w:0xcb:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m +IF "%1"=="minibench" avrdude -p m32u4 -P usb -c avrispmkii -U flash:w:Caterina-minibench.hex -U efuse:w:0xcb:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m \ No newline at end of file diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Arduino.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Arduino.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Arduino.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Arduino.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/CDC.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/CDC.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/CDC.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/CDC.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Client.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Client.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Client.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Client.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial0.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial0.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial0.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial0.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial1.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial1.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial1.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial1.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial2.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial2.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial2.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial2.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial3.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial3.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial3.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial3.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial_private.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial_private.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/HardwareSerial_private.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/HardwareSerial_private.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/IPAddress.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/IPAddress.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/IPAddress.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/IPAddress.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/IPAddress.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/IPAddress.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/IPAddress.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/IPAddress.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/PluggableUSB.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/PluggableUSB.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/PluggableUSB.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/PluggableUSB.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/PluggableUSB.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/PluggableUSB.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/PluggableUSB.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/PluggableUSB.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Print.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Print.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Print.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Print.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Print.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Print.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Print.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Print.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Printable.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Printable.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Printable.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Printable.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Server.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Server.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Server.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Server.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Stream.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Stream.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Stream.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Stream.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Stream.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Stream.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Stream.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Stream.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Tone.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Tone.cpp similarity index 99% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Tone.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Tone.cpp index 1bfb3e3..fed4ae3 100644 --- a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Tone.cpp +++ b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Tone.cpp @@ -91,9 +91,9 @@ volatile uint8_t timer5_pin_mask; #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define AVAILABLE_TONE_PINS 1 -#define USE_TIMER2 +#define USE_TIMER4 -const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ }; +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 4 /*, 3, 5 */ }; static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ }; #elif defined(__AVR_ATmega8__) diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/USBAPI.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/USBAPI.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/USBAPI.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/USBAPI.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/USBCore.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/USBCore.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/USBCore.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/USBCore.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/USBCore.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/USBCore.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/USBCore.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/USBCore.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/USBDesc.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/USBDesc.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/USBDesc.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/USBDesc.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Udp.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Udp.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/Udp.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/Udp.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WCharacter.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WCharacter.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WCharacter.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WCharacter.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WInterrupts.c b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WInterrupts.c similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WInterrupts.c rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WInterrupts.c diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WMath.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WMath.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WMath.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WMath.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WString.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WString.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WString.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WString.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WString.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WString.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/WString.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/WString.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/abi.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/abi.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/abi.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/abi.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/binary.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/binary.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/binary.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/binary.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/hooks.c b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/hooks.c similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/hooks.c rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/hooks.c diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/main.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/main.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/main.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/main.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/new.cpp b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/new.cpp similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/new.cpp rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/new.cpp diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/new.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/new.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/new.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/new.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring.c b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring.c similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring.c rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring.c diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_analog.c b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_analog.c similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_analog.c rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_analog.c diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_digital.c b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_digital.c similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_digital.c rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_digital.c diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_private.h b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_private.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_private.h rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_private.h diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_pulse.S b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_pulse.S similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_pulse.S rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_pulse.S diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_pulse.c b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_pulse.c similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_pulse.c rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_pulse.c diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_shift.c b/IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_shift.c similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/cores/rambo/wiring_shift.c rename to IDE_Board_Manager/prusa3dboards/cores/prusa_einsy_rambo/wiring_shift.c diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/platform.txt b/IDE_Board_Manager/prusa3dboards/platform.txt similarity index 97% rename from IDE_Board_Manager/prusa3drambo-1.0.1/platform.txt rename to IDE_Board_Manager/prusa3dboards/platform.txt index 63d0b93..7f552a4 100644 --- a/IDE_Board_Manager/prusa3drambo-1.0.1/platform.txt +++ b/IDE_Board_Manager/prusa3dboards/platform.txt @@ -5,7 +5,7 @@ # For more info: # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification -name=Arduino AVR Boards +name=Prusa Research AVR Boards version=1.6.20 # AVR compile variables @@ -21,7 +21,7 @@ compiler.warning_flags.all=-Wall -Wextra compiler.path={runtime.tools.avr-gcc.path}/bin/ compiler.c.cmd=avr-gcc compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -compiler.c.elf.flags={compiler.warning_flags} -Os -Wl,-u,vfprintf -lprintf_flt -lm -g -flto -fuse-linker-plugin -Wl,--gc-sections +compiler.c.elf.flags={compiler.warning_flags} -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections compiler.c.elf.cmd=avr-gcc compiler.S.flags=-c -g -x assembler-with-cpp -flto -MMD compiler.cpp.cmd=avr-g++ diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/variants/rambo/pins_arduino.h b/IDE_Board_Manager/prusa3dboards/variants/prusa_einsy_rambo/pins_arduino.h similarity index 100% rename from IDE_Board_Manager/prusa3drambo-1.0.1/variants/rambo/pins_arduino.h rename to IDE_Board_Manager/prusa3dboards/variants/prusa_einsy_rambo/pins_arduino.h diff --git a/IDE_Board_Manager/prusa3dboards/variants/prusa_mm_control/pins_arduino.h b/IDE_Board_Manager/prusa3dboards/variants/prusa_mm_control/pins_arduino.h new file mode 100644 index 0000000..809e323 --- /dev/null +++ b/IDE_Board_Manager/prusa3dboards/variants/prusa_mm_control/pins_arduino.h @@ -0,0 +1,380 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +// Workaround for wrong definitions in "iom32u4.h". +// This should be fixed in the AVR toolchain. +#undef UHCON +#undef UHINT +#undef UHIEN +#undef UHADDR +#undef UHFNUM +#undef UHFNUML +#undef UHFNUMH +#undef UHFLEN +#undef UPINRQX +#undef UPINTX +#undef UPNUM +#undef UPRST +#undef UPCONX +#undef UPCFG0X +#undef UPCFG1X +#undef UPSTAX +#undef UPCFG2X +#undef UPIENX +#undef UPDATX +#undef TCCR2A +#undef WGM20 +#undef WGM21 +#undef COM2B0 +#undef COM2B1 +#undef COM2A0 +#undef COM2A1 +#undef TCCR2B +#undef CS20 +#undef CS21 +#undef CS22 +#undef WGM22 +#undef FOC2B +#undef FOC2A +#undef TCNT2 +#undef TCNT2_0 +#undef TCNT2_1 +#undef TCNT2_2 +#undef TCNT2_3 +#undef TCNT2_4 +#undef TCNT2_5 +#undef TCNT2_6 +#undef TCNT2_7 +#undef OCR2A +#undef OCR2_0 +#undef OCR2_1 +#undef OCR2_2 +#undef OCR2_3 +#undef OCR2_4 +#undef OCR2_5 +#undef OCR2_6 +#undef OCR2_7 +#undef OCR2B +#undef OCR2_0 +#undef OCR2_1 +#undef OCR2_2 +#undef OCR2_3 +#undef OCR2_4 +#undef OCR2_5 +#undef OCR2_6 +#undef OCR2_7 + +#define NUM_DIGITAL_PINS 31 +#define NUM_ANALOG_INPUTS 12 + +#define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0) +#define TXLED0 PORTD |= (1<<5) +#define TXLED1 PORTD &= ~(1<<5) +#define RXLED0 PORTB |= (1<<0) +#define RXLED1 PORTB &= ~(1<<0) + +static const uint8_t SDA = 2; +static const uint8_t SCL = 3; +#define LED_BUILTIN 13 +#define LED_BUILTIN_RX 17 +#define LED_BUILTIN_TX 30 + +// Map SPI port to 'new' pins D14..D17 +static const uint8_t SS = 17; +static const uint8_t MOSI = 16; +static const uint8_t MISO = 14; +static const uint8_t SCK = 15; + +// Mapping of analog pins as digital I/O +// A6-A11 share with digital pins +static const uint8_t A0 = 18; +static const uint8_t A1 = 19; +static const uint8_t A2 = 20; +static const uint8_t A3 = 21; +static const uint8_t A4 = 22; +static const uint8_t A5 = 23; +static const uint8_t A6 = 24; // D4 +static const uint8_t A7 = 25; // D6 +static const uint8_t A8 = 26; // D8 +static const uint8_t A9 = 27; // D9 +static const uint8_t A10 = 28; // D10 +static const uint8_t A11 = 29; // D12 + +#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0)) +#define digitalPinToPCICRbit(p) 0 +#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0)) +#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4)))))) + +// __AVR_ATmega32U4__ has an unusual mapping of pins to channels +extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; +#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) ) + +#define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT))))) + +#ifdef ARDUINO_MAIN + +// On the Arduino board, digital pins are also used +// for the analog output (software PWM). Analog input +// pins are a separate set. + +// ATMEL ATMEGA32U4 / ARDUINO LEONARDO +// +// D0 PD2 RXD1/INT2 +// D1 PD3 TXD1/INT3 +// D2 PD1 SDA SDA/INT1 +// D3# PD0 PWM8/SCL OC0B/SCL/INT0 +// D4 A6 PD4 ADC8 +// D5# PC6 ??? OC3A/#OC4A +// D6# A7 PD7 FastPWM #OC4D/ADC10 +// D7 PE6 INT6/AIN0 +// +// D8 A8 PB4 ADC11/PCINT4 +// D9# A9 PB5 PWM16 OC1A/#OC4B/ADC12/PCINT5 +// D10# A10 PB6 PWM16 OC1B/0c4B/ADC13/PCINT6 +// D11# PB7 PWM8/16 0C0A/OC1C/#RTS/PCINT7 +// D12 A11 PD6 T1/#OC4D/ADC9 +// D13# PC7 PWM10 CLK0/OC4A +// +// A0 D18 PF7 ADC7 +// A1 D19 PF6 ADC6 +// A2 D20 PF5 ADC5 +// A3 D21 PF4 ADC4 +// A4 D22 PF1 ADC1 +// A5 D23 PF0 ADC0 +// +// New pins D14..D17 to map SPI port to digital pins +// +// MISO D14 PB3 MISO,PCINT3 +// SCK D15 PB1 SCK,PCINT1 +// MOSI D16 PB2 MOSI,PCINT2 +// SS D17 PB0 RXLED,SS/PCINT0 +// +// Connected LEDs on board for TX and RX +// TXLED D30 PD5 XCK1 +// RXLED D17 PB0 +// HWB PE2 HWB + +// these arrays map port names (e.g. port B) to the +// appropriate addresses for various functions (e.g. reading +// and writing) +const uint16_t PROGMEM port_to_mode_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) &DDRB, + (uint16_t) &DDRC, + (uint16_t) &DDRD, + (uint16_t) &DDRE, + (uint16_t) &DDRF, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) &PORTB, + (uint16_t) &PORTC, + (uint16_t) &PORTD, + (uint16_t) &PORTE, + (uint16_t) &PORTF, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) &PINB, + (uint16_t) &PINC, + (uint16_t) &PIND, + (uint16_t) &PINE, + (uint16_t) &PINF, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { + PD, // D0 - PD2 + PD, // D1 - PD3 + PD, // D2 - PD1 + PD, // D3 - PD0 + PD, // D4 - PD4 + PC, // D5 - PC6 + PD, // D6 - PD7 + PE, // D7 - PE6 + + PB, // D8 - PB4 + PB, // D9 - PB5 + PB, // D10 - PB6 + PB, // D11 - PB7 + PD, // D12 - PD6 + PC, // D13 - PC7 + + PB, // D14 - MISO - PB3 + PB, // D15 - SCK - PB1 + PB, // D16 - MOSI - PB2 + PB, // D17 - SS - PB0 + + PF, // D18 - A0 - PF7 + PF, // D19 - A1 - PF6 + PF, // D20 - A2 - PF5 + PF, // D21 - A3 - PF4 + PF, // D22 - A4 - PF1 + PF, // D23 - A5 - PF0 + + PD, // D24 / PD5 + PD, // D25 / D6 - A7 - PD7 + PB, // D26 / D8 - A8 - PB4 + PB, // D27 / D9 - A9 - PB5 + PB, // D28 / D10 - A10 - PB6 + PD, // D29 / D12 - A11 - PD6 + PD, // D30 / TX Led - PD5 +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { + _BV(2), // D0 - PD2 + _BV(3), // D1 - PD3 + _BV(1), // D2 - PD1 + _BV(0), // D3 - PD0 + _BV(4), // D4 - PD4 + _BV(6), // D5 - PC6 + _BV(7), // D6 - PD7 + _BV(6), // D7 - PE6 + + _BV(4), // D8 - PB4 + _BV(5), // D9 - PB5 + _BV(6), // D10 - PB6 + _BV(7), // D11 - PB7 + _BV(6), // D12 - PD6 + _BV(7), // D13 - PC7 + + _BV(3), // D14 - MISO - PB3 + _BV(1), // D15 - SCK - PB1 + _BV(2), // D16 - MOSI - PB2 + _BV(0), // D17 - SS - PB0 + + _BV(7), // D18 - A0 - PF7 + _BV(6), // D19 - A1 - PF6 + _BV(5), // D20 - A2 - PF5 + _BV(4), // D21 - A3 - PF4 + _BV(1), // D22 - A4 - PF1 + _BV(0), // D23 - A5 - PF0 + + _BV(4), // D24 / D4 - A6 - PD4 + _BV(7), // D25 / D6 - A7 - PD7 + _BV(4), // D26 / D8 - A8 - PB4 + _BV(5), // D27 / D9 - A9 - PB5 + _BV(6), // D28 / D10 - A10 - PB6 + _BV(6), // D29 / D12 - A11 - PD6 + _BV(5), // D30 / TX Led - PD5 +}; + +const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + TIMER0B, /* 3 */ + NOT_ON_TIMER, + TIMER3A, /* 5 */ + TIMER4D, /* 6 */ + NOT_ON_TIMER, + + NOT_ON_TIMER, + TIMER1A, /* 9 */ + TIMER1B, /* 10 */ + TIMER0A, /* 11 */ + + NOT_ON_TIMER, + TIMER4A, /* 13 */ + + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, +}; + +const uint8_t PROGMEM analog_pin_to_channel_PGM[] = { + 7, // A0 PF7 ADC7 + 6, // A1 PF6 ADC6 + 5, // A2 PF5 ADC5 + 4, // A3 PF4 ADC4 + 1, // A4 PF1 ADC1 + 0, // A5 PF0 ADC0 + 8, // A6 D4 PD4 ADC8 + 10, // A7 D6 PD7 ADC10 + 11, // A8 D8 PB4 ADC11 + 12, // A9 D9 PB5 ADC12 + 13, // A10 D10 PB6 ADC13 + 9 // A11 D12 PD6 ADC9 +}; + +#endif /* ARDUINO_MAIN */ + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +// Alias SerialUSB to Serial +#define SerialUSB SERIAL_PORT_USBVIRTUAL + +#ifndef MAGIC_KEY +#define MAGIC_KEY 0x7777 +#endif + +#ifndef MAGIC_KEY_POS +#define MAGIC_KEY_POS 0x0800 +#endif +#ifndef NEW_LUFA_SIGNATURE +#define NEW_LUFA_SIGNATURE 0xDCFB +#endif + +#endif /* Pins_Arduino_h */ diff --git a/IDE_Board_Manager/prusa3drambo-1.0.1/boards.txt b/IDE_Board_Manager/prusa3drambo-1.0.1/boards.txt deleted file mode 100644 index 61f1787..0000000 --- a/IDE_Board_Manager/prusa3drambo-1.0.1/boards.txt +++ /dev/null @@ -1,31 +0,0 @@ -# See: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification - -############################################################## - -menu.cpu=Processor - -######################################## -## RAMBo -######################################## -rambo.name=PrusaResearch EINSY RAMBo -rambo.vid.0=0x27b1 -rambo.pid.0=0x0001 - -rambo.upload.tool=arduino:avrdude -rambo.upload.protocol=wiring -rambo.upload.maximum_size=253952 -rambo.upload.speed=115200 - -rambo.bootloader.low_fuses=0xFF -rambo.bootloader.high_fuses=0xD8 -rambo.bootloader.extended_fuses=0xFD -rambo.bootloader.path=stk500v2 -#rambo.bootloader.file=stk500boot_v2_mega2560.hex -rambo.bootloader.unlock_bits=0x3F -rambo.bootloader.lock_bits=0x0F - -rambo.build.mcu=atmega2560 -rambo.build.f_cpu=16000000L -rambo.build.board=AVR_RAMBO -rambo.build.core=rambo -rambo.build.variant=rambo diff --git a/README.md b/README.md index b52b7f8..3bd03cf 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,173 @@ -# Arduino_Boards -Board definitions for Arduino compatible boards manufactured by Prusa Research +# Prusa Research AVR Boards +Prusa Research AVR Boards definitions for Arduino compatible boards manufactured/used by Prusa Research +- [Prusa MM Control board](https://github.com/prusa3d/MM-control-2.0) +- Prusa Einsy and miniRAMBo boards by Ultimachine [Einsy](https://github.com/ultimachine/Einsy-Rambo) and [miniRAMBo](https://github.com/ultimachine/Mini-Rambo) + +# Table of contents + + + * [Linux build](#linux) + * Windows build + * [Using Linux subsystem](#using-linux-subsystem-under-windows-10-64-bit) + * [Using Git-bash](#using-git-bash-under-windows-10-64-bit) + * [How-to change code and dependencies](#2-How-to-modify) + * [Prepare new version](#3-Prepare-new-version) + + + +# 1-Build environment +## Linux + +## Windows +Please make sure if you modify code, files, etc. that the line endings are UNIX conform (LF and not CRLF). +### Using Linux subsystem under Windows 10 64-bit +_notes: Script and instructions contributed by 3d-gussner. Use at your own risk. Script downloads Arduino executables outside of Prusa control. Report problems [there.](https://github.com/3d-gussner/Arduino_Boards/issues)._ +- follow the [Microsoft guide](https://docs.microsoft.com/en-us/windows/wsl/install-win10) +- Tested versions are at this moment + - Ubuntu other may different + - After the installation and reboot please open your Ubuntu bash and do following steps + - run command `apt-get update` + - run command `apt-get upgrade` to update your OS. + +#### Some Tips for Ubuntu +- Linux is case sensetive so please don't forget to use capital letters where needed, like changing to a directory +- To change the path to your Prusa-Firmware location you downloaded and unzipped + - Example: You files are under `C:\Users\\Downloads\Arduino_Boards` + - use under Ubuntu the following command `cd /mnt/c/Users//Downloads/Arduino_Boards` + to change to the right folder +- Unix and windows have different line endings (LF vs CRLF), try dos2unix to convert + - This should fix the `"$'\r': command not found"` error + - to install run `apt-get install dos2unix` + +#### Modify Arduino_Boards with Ubuntu Linux subsystem installed +- open Ubuntu bash +- change to your source code folder (case sensitive) +- Read How-to-modify below +- run `./Prepare-new-version.sh` +- Read How-to-modify part `package_prusa3d_index.json` below + +### Using Git-bash under Windows 10 64-bit +_notes: Script and instructions contributed by 3d-gussner. Use at your own risk. Script downloads Arduino executables outside of Prusa control. Report problems [there.](https://github.com/3d-gussner/Prusa-Firmware/issues) Multi language build is supported._ +- Download and install the [64bit Git version](https://git-scm.com/download/win) +- Also follow these [instructions](https://gist.github.com/evanwill/0207876c3243bbb6863e65ec5dc3f058) + +#### Compile Prusa-firmware with Git-bash installed +- open Git-bash +- Read How-to-modify below +- change to your source code folder +- run `bash Prepare-new-version.sh` +- Read How-to-modify `package_prusa3d_index.json` below + +# 2-How-to-modify +Folder Structure: + + . + +-- IDE_Boards_Manager + ¦ +-- prusa3dboards Please don't change that folder name when you update your Github and post a PR. + ¦ +-- bootloaders + ¦ +-- prusa_einsy_rambo Which is a clone of https://github.com/prusa3d/stk500v2-prusa + ¦ +-- prusa_mm_control + ¦ +-- cores + ¦ +-- prusa_einsy_rambo + ¦ +-- variants + ¦ +-- prusa_einsy_rambo + ¦ +-- prusa_mm_control + ¦ +-- ... + +-- ... + +Files: + + . + +-- IDE_Boards_Manager + ¦ +-- prusa3dboards Please don't change that folder name when you update your Github and post a PR. + ¦ +-- boards.txt contains definitions for the boards (board name, parameters for building and uploading sketches, etc.). + ¦ +-- platform.txt contains definitions for the CPU architecture used (compiler, build process parameters, tools used for upload, etc.). + ¦ +-- avrdude.conf + ¦ +-- ... + ¦ +-- package_prusa3d_index.json + ¦ +-- prusa3dboards.version contains the release version numbers and is used in `Prepare-new-version.sh`. The first line is used. + ¦ +-- prusa3dboards-.tar.bz2 actual used pacakges for Ardunio IDE Boards Manager + ¦ +-- prusa3dboards-.md Info about the version + ¦ +-- ... + +-- LICENSE + +-- README.md + +-- ... + +More information about [boards.txt](https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#boardstxt) +More information about [platforms.txt](https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification#platformtxt) +More information about [package_prusa3d_index.json](https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.6.x-package_index.json-format-specification) + +Naming convention for version: +- <`major:#1`.`minor:#2`.`maintenance:#2`"-`devel status:0-4`-`devel build:#6`" where `-devel status` and `devel build` are optional + - `#1` = numbers 0-9 + - `#2` = numbers 0-99 + - `0-4`= only numbers between 0 and 4. 0=devel, 1=alpha, 2=beta, 3=pre-release, 4=release candidate + - `#6` = numbers 0-999999 + +Few examples: + +- 1.0.0-0-235 Is a version in development and devel build 235. +- 1.0.0 Is the frist stable version +- 1.0.1 Is a stable version that was maintaind...like adding a bootloader or changing tools to existing boards +- 1.1.0-3 Is a pre-release version including new boards +- 1.1.0 Is the first stable version including new boards + +After modifying the source code please follow these steps: +- add the new version (following the naming conention) in the first line of `prusa3dboards.version` +- run `Prepare-new-version.sh` to generate `prusa3dboards-tar.bz2` and to show `sha256checksum` and `size` needed in the `package_prusa3d_index.json` +- open `package_prusa3d_index.json`in your prefered editor (like notepad++) + - Directly under + + ``` + { + "packages": [ + { + "name": "PrusaResearch", + "maintainer": "Prusa Research", + "websiteURL": "https://www.prusa3d.com/", + "email": "info@prusa3d.com", + "help": { + "online": "https://github.com/3d-gussner/Arduino_Boards" + }, + "platforms": [ + ``` + you will find the latest Prusa Research AVR Boards definition ... something like this + ``` + { + "name": "Prusa Research AVR Boards", + "architecture": "avr", + "version": "1.0.2", + "category": "Contributed", + "url": "https://raw.githubusercontent.com/3d-gussner/Arduino_Boards/V1.0.2/IDE_Board_Manager/prusa3dboards-1.0.2.tar.bz2", + "archiveFileName": "prusa3dboards-1.0.2.tar.bz2", + "checksum": "SHA-256:7d49c48d86644513bd2f2222024934e827783f9f5be160c8a1ae14e177d0393a", + "size": "120855", + "help": { + "online": "https://learn.sparkfun.com/tutorials/installing-arduino-ide/board-add-ons-with-arduino-board-manager" + }, + "boards": [ + { + "name": "Original Prusa i3 MK3 Multi Material 2.0 upgrade" + }, + { + "name": "Original Prusa i3 MK3/MK3S Einsy RAMBo" + } + ], + "toolsDependencies": [] + }, + ``` + + +- Copy and paste this section twice +- Modify the top one with new values + - change `"version": "1.0.2",` `"version": "", + - change in `"url":` and `"archiveFileName":` the "ArchiveFileName" parts you got from `Prepare-new-version.sh` + - if you have your own github for of this repository and you made a new worktree/branch to test your code you should not forget to modify the `"url":` to your `branch` + - change in `"checksum": ` the "SHA256 checksum" you got from `Prepare-new-version.sh` + - change in `"size":` the "Size" you got from `Prepare-new-version.sh` +- double check the syntax/format of the JSON file. In Notepad++ makes it is quite easy by using the [+] and [-] to see if your changes are correct. + +When you have an own github and work localy use `git status` to verify your status. +- You may need to use `git add IDE_Board_Manager/prusa3dboards-.tar.bz2` +- You need to commit your changes with `git commit -a`. Please try to document your changes as detailed as possible. +