aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid A. Mellis <d.mellis@arduino.cc>2009-06-01 08:32:11 +0000
committerDavid A. Mellis <d.mellis@arduino.cc>2009-06-01 08:32:11 +0000
commitdb605dd18b11ecfb5cd9f92c721c52cb70543384 (patch)
tree8a9029ffc560970ce1204ba86785ad44ef044906
First integration of the Arduino code in Processing 5503: PreProcessor and Compiler have been integrated with changes to the Sketch.
Compilation still has problems (Thread error on success, and can't handle non-pde files in a sketch). Modified the Mac OS X make.sh to copy the hardware, avr tools, and example over. Removing some of the antlr stuff. Disabling the Commander (command-line execution) for now. Added Library, LibraryManager, and Target. Added support for prefixed preferences (e.g. for boards and programmers).
-rw-r--r--boards.txt240
-rwxr-xr-xbootloaders/atmega/ATmegaBOOT_168.c1054
-rw-r--r--bootloaders/atmega/ATmegaBOOT_168_atmega1280.hex245
-rw-r--r--bootloaders/atmega/ATmegaBOOT_168_atmega328.hex125
-rw-r--r--bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex124
-rw-r--r--bootloaders/atmega/ATmegaBOOT_168_diecimila.hex126
-rw-r--r--bootloaders/atmega/ATmegaBOOT_168_ng.hex110
-rw-r--r--bootloaders/atmega/ATmegaBOOT_168_pro_8MHz.hex126
-rwxr-xr-xbootloaders/atmega/Makefile224
-rwxr-xr-xbootloaders/atmega8/ATmegaBOOT.c507
-rw-r--r--bootloaders/atmega8/ATmegaBOOT.hex66
-rw-r--r--bootloaders/atmega8/Makefile88
-rw-r--r--bootloaders/bt/ATmegaBOOT_168.c1032
-rw-r--r--bootloaders/bt/ATmegaBOOT_168.hex121
-rw-r--r--bootloaders/lilypad/LilyPadBOOT_168.hex117
-rw-r--r--bootloaders/lilypad/src/ATmegaBOOT.c979
-rw-r--r--bootloaders/lilypad/src/Makefile84
-rwxr-xr-xcores/arduino/HardwareSerial.cpp191
-rwxr-xr-xcores/arduino/HardwareSerial.h65
-rwxr-xr-xcores/arduino/Makefile243
-rwxr-xr-xcores/arduino/Print.cpp215
-rwxr-xr-xcores/arduino/Print.h62
-rw-r--r--cores/arduino/WConstants.h1
-rwxr-xr-xcores/arduino/WInterrupts.c215
-rw-r--r--cores/arduino/WMath.cpp60
-rwxr-xr-xcores/arduino/WProgram.h29
-rw-r--r--cores/arduino/binary.h515
-rwxr-xr-xcores/arduino/main.cxx12
-rwxr-xr-xcores/arduino/pins_arduino.c469
-rw-r--r--cores/arduino/pins_arduino.h76
-rwxr-xr-xcores/arduino/wiring.c250
-rwxr-xr-xcores/arduino/wiring.h137
-rwxr-xr-xcores/arduino/wiring_analog.c179
-rwxr-xr-xcores/arduino/wiring_digital.c111
-rwxr-xr-xcores/arduino/wiring_private.h68
-rwxr-xr-xcores/arduino/wiring_pulse.c66
-rwxr-xr-xcores/arduino/wiring_shift.c40
-rwxr-xr-xcores/atmega8/pins_atmega8.c119
-rwxr-xr-xcores/blank/WProgram.h0
-rw-r--r--cores/blank/main.cxx0
-rwxr-xr-xlibraries/EEPROM/EEPROM.cpp50
-rwxr-xr-xlibraries/EEPROM/EEPROM.h35
-rw-r--r--libraries/EEPROM/examples/eeprom_clear/eeprom_clear.pde21
-rw-r--r--libraries/EEPROM/examples/eeprom_read/eeprom_read.pde38
-rw-r--r--libraries/EEPROM/examples/eeprom_write/eeprom_write.pde38
-rw-r--r--libraries/EEPROM/keywords.txt18
-rw-r--r--libraries/Ethernet/Client.cpp140
-rw-r--r--libraries/Ethernet/Client.h31
-rw-r--r--libraries/Ethernet/Ethernet.cpp38
-rw-r--r--libraries/Ethernet/Ethernet.h22
-rw-r--r--libraries/Ethernet/Server.cpp91
-rw-r--r--libraries/Ethernet/Server.h25
-rw-r--r--libraries/Ethernet/examples/ChatServer/ChatServer.pde34
-rw-r--r--libraries/Ethernet/examples/WebClient/WebClient.pde41
-rw-r--r--libraries/Ethernet/examples/WebServer/WebServer.pde61
-rwxr-xr-xlibraries/Ethernet/utility/socket.c558
-rwxr-xr-xlibraries/Ethernet/utility/socket.h23
-rwxr-xr-xlibraries/Ethernet/utility/spi.h58
-rwxr-xr-xlibraries/Ethernet/utility/types.h165
-rwxr-xr-xlibraries/Ethernet/utility/w5100.c1302
-rwxr-xr-xlibraries/Ethernet/utility/w5100.h299
-rw-r--r--libraries/Firmata/Firmata.cpp445
-rw-r--r--libraries/Firmata/Firmata.h169
-rw-r--r--libraries/Firmata/LICENSE.txt458
-rw-r--r--libraries/Firmata/TODO.txt14
-rw-r--r--libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.pde83
-rw-r--r--libraries/Firmata/examples/AnalogFirmata/Makefile263
-rw-r--r--libraries/Firmata/examples/EchoString/EchoString.pde40
-rw-r--r--libraries/Firmata/examples/EchoString/Makefile263
-rw-r--r--libraries/Firmata/examples/ServoFirmata/Makefile263
-rw-r--r--libraries/Firmata/examples/ServoFirmata/ServoFirmata.pde39
-rw-r--r--libraries/Firmata/examples/SimpleAnalogFirmata/Makefile263
-rw-r--r--libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.pde32
-rw-r--r--libraries/Firmata/examples/SimpleDigitalFirmata/Makefile263
-rw-r--r--libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.pde58
-rw-r--r--libraries/Firmata/examples/StandardFirmata/LICENSE.txt458
-rw-r--r--libraries/Firmata/examples/StandardFirmata/Makefile261
-rw-r--r--libraries/Firmata/examples/StandardFirmata/StandardFirmata.pde226
-rw-r--r--libraries/Firmata/keywords.txt62
-rwxr-xr-xlibraries/LiquidCrystal/LiquidCrystal.cpp128
-rwxr-xr-xlibraries/LiquidCrystal/LiquidCrystal.h31
-rw-r--r--libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.pde18
-rw-r--r--libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.pde34
-rwxr-xr-xlibraries/LiquidCrystal/keywords.txt23
-rwxr-xr-xlibraries/Matrix/Matrix.cpp229
-rwxr-xr-xlibraries/Matrix/Matrix.h54
-rw-r--r--libraries/Matrix/examples/hello_matrix/hello_matrix.pde42
-rw-r--r--libraries/Matrix/examples/sprite_animation/sprite_animation.pde48
-rw-r--r--libraries/Matrix/keywords.txt22
-rwxr-xr-xlibraries/Servo/Servo.cpp133
-rwxr-xr-xlibraries/Servo/Servo.h52
-rw-r--r--libraries/Servo/examples/Knob/Knob.pde22
-rw-r--r--libraries/Servo/examples/Sweep/Sweep.pde29
-rwxr-xr-xlibraries/Servo/keywords.txt22
-rwxr-xr-xlibraries/SoftwareSerial/SoftwareSerial.cpp227
-rwxr-xr-xlibraries/SoftwareSerial/SoftwareSerial.h56
-rw-r--r--libraries/SoftwareSerial/keywords.txt18
-rw-r--r--libraries/Sprite/Sprite.cpp95
-rw-r--r--libraries/Sprite/Sprite.h48
-rw-r--r--libraries/Sprite/binary.h515
-rw-r--r--libraries/Sprite/keywords.txt534
-rw-r--r--libraries/Stepper/Stepper.cpp220
-rw-r--r--libraries/Stepper/Stepper.h83
-rw-r--r--libraries/Stepper/examples/MotorKnob/MotorKnob.pde40
-rw-r--r--libraries/Stepper/keywords.txt28
-rwxr-xr-xlibraries/Wire/Wire.cpp265
-rwxr-xr-xlibraries/Wire/Wire.h67
-rwxr-xr-xlibraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.pde84
-rw-r--r--libraries/Wire/examples/digital_potentiometer/digital_potentiometer.pde34
-rw-r--r--libraries/Wire/examples/master_reader/master_reader.pde29
-rw-r--r--libraries/Wire/examples/master_writer/master_writer.pde28
-rw-r--r--libraries/Wire/examples/slave_receiver/slave_receiver.pde35
-rw-r--r--libraries/Wire/examples/slave_sender/slave_sender.pde29
-rw-r--r--libraries/Wire/keywords.txt31
-rw-r--r--libraries/Wire/utility/twi.c474
-rwxr-xr-xlibraries/Wire/utility/twi.h57
-rw-r--r--programmers.txt15
117 files changed, 19138 insertions, 0 deletions
diff --git a/boards.txt b/boards.txt
new file mode 100644
index 0000000..24ddfc0
--- /dev/null
+++ b/boards.txt
@@ -0,0 +1,240 @@
+##############################################################
+
+atmega328.name=Arduino Duemilanove w/ ATmega328
+
+atmega328.upload.protocol=stk500
+atmega328.upload.maximum_size=30720
+atmega328.upload.speed=57600
+
+atmega328.bootloader.low_fuses=0xFF
+atmega328.bootloader.high_fuses=0xDA
+atmega328.bootloader.extended_fuses=0x05
+atmega328.bootloader.path=atmega
+atmega328.bootloader.file=ATmegaBOOT_168_atmega328.hex
+atmega328.bootloader.unlock_bits=0x3F
+atmega328.bootloader.lock_bits=0x0F
+
+atmega328.build.mcu=atmega328p
+atmega328.build.f_cpu=16000000L
+atmega328.build.core=arduino
+
+##############################################################
+
+diecimila.name=Arduino Diecimila or Duemilanove w/ ATmega168
+
+diecimila.upload.protocol=stk500
+diecimila.upload.maximum_size=14336
+diecimila.upload.speed=19200
+
+diecimila.bootloader.low_fuses=0xff
+diecimila.bootloader.high_fuses=0xdd
+diecimila.bootloader.extended_fuses=0x00
+diecimila.bootloader.path=atmega
+diecimila.bootloader.file=ATmegaBOOT_168_diecimila.hex
+diecimila.bootloader.unlock_bits=0x3F
+diecimila.bootloader.lock_bits=0x0F
+
+diecimila.build.mcu=atmega168
+diecimila.build.f_cpu=16000000L
+diecimila.build.core=arduino
+
+##############################################################
+
+mega.name=Arduino Mega
+
+mega.upload.protocol=stk500
+mega.upload.maximum_size=126976
+mega.upload.speed=57600
+
+mega.bootloader.low_fuses=0xFF
+mega.bootloader.high_fuses=0xDA
+mega.bootloader.extended_fuses=0xF5
+mega.bootloader.path=atmega
+mega.bootloader.file=ATmegaBOOT_168_atmega1280.hex
+mega.bootloader.unlock_bits=0x3F
+mega.bootloader.lock_bits=0x0F
+
+mega.build.mcu=atmega1280
+mega.build.f_cpu=16000000L
+mega.build.core=arduino
+
+##############################################################
+
+mini.name=Arduino Mini
+
+mini.upload.protocol=stk500
+mini.upload.maximum_size=14336
+mini.upload.speed=19200
+
+mini.bootloader.low_fuses=0xff
+mini.bootloader.high_fuses=0xdd
+mini.bootloader.extended_fuses=0x00
+mini.bootloader.path=atmega
+mini.bootloader.file=ATmegaBOOT_168_ng.hex
+mini.bootloader.unlock_bits=0x3F
+mini.bootloader.lock_bits=0x0F
+
+mini.build.mcu=atmega168
+mini.build.f_cpu=16000000L
+mini.build.core=arduino
+
+##############################################################
+
+nano.name=Arduino Nano
+
+nano.upload.protocol=stk500
+nano.upload.maximum_size=14336
+nano.upload.speed=19200
+
+nano.bootloader.low_fuses=0xff
+nano.bootloader.high_fuses=0xdd
+nano.bootloader.extended_fuses=0x00
+nano.bootloader.path=atmega
+nano.bootloader.file=ATmegaBOOT_168_diecimila.hex
+nano.bootloader.unlock_bits=0x3F
+nano.bootloader.lock_bits=0x0F
+
+nano.build.mcu=atmega168
+nano.build.f_cpu=16000000L
+nano.build.core=arduino
+
+##############################################################
+
+bt.name=Arduino BT
+
+bt.upload.protocol=stk500
+bt.upload.maximum_size=14336
+bt.upload.speed=19200
+bt.upload.disable_flushing=true
+
+bt.bootloader.low_fuses=0xff
+bt.bootloader.high_fuses=0xdd
+bt.bootloader.extended_fuses=0x00
+bt.bootloader.path=bt
+bt.bootloader.file=ATmegaBOOT_168.hex
+bt.bootloader.unlock_bits=0x3F
+bt.bootloader.lock_bits=0x0F
+
+bt.build.mcu=atmega168
+bt.build.f_cpu=16000000L
+bt.build.core=arduino
+
+##############################################################
+
+lilypad328.name=LilyPad Arduino w/ ATmega328
+
+lilypad328.upload.protocol=stk500
+lilypad328.upload.maximum_size=30720
+lilypad328.upload.speed=57600
+
+lilypad328.bootloader.low_fuses=0xFF
+lilypad328.bootloader.high_fuses=0xDA
+lilypad328.bootloader.extended_fuses=0x05
+lilypad328.bootloader.path=atmega
+lilypad328.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
+lilypad328.bootloader.unlock_bits=0x3F
+lilypad328.bootloader.lock_bits=0x0F
+
+lilypad328.build.mcu=atmega328p
+lilypad328.build.f_cpu=8000000L
+lilypad328.build.core=arduino
+
+##############################################################
+
+lilypad.name=LilyPad Arduino w/ ATmega168
+
+lilypad.upload.protocol=stk500
+lilypad.upload.maximum_size=14336
+lilypad.upload.speed=19200
+
+lilypad.bootloader.low_fuses=0xe2
+lilypad.bootloader.high_fuses=0xdd
+lilypad.bootloader.extended_fuses=0x00
+lilypad.bootloader.path=lilypad
+lilypad.bootloader.file=LilyPadBOOT_168.hex
+lilypad.bootloader.unlock_bits=0x3F
+lilypad.bootloader.lock_bits=0x0F
+
+lilypad.build.mcu=atmega168
+lilypad.build.f_cpu=8000000L
+lilypad.build.core=arduino
+
+##############################################################
+
+pro328.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
+
+pro328.upload.protocol=stk500
+pro328.upload.maximum_size=30720
+pro328.upload.speed=57600
+
+pro328.bootloader.low_fuses=0xFF
+pro328.bootloader.high_fuses=0xDA
+pro328.bootloader.extended_fuses=0x05
+pro328.bootloader.path=atmega
+pro328.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
+pro328.bootloader.unlock_bits=0x3F
+pro328.bootloader.lock_bits=0x0F
+
+pro328.build.mcu=atmega328p
+pro328.build.f_cpu=8000000L
+pro328.build.core=arduino
+
+##############################################################
+
+pro.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168
+
+pro.upload.protocol=stk500
+pro.upload.maximum_size=14336
+pro.upload.speed=19200
+
+pro.bootloader.low_fuses=0xc6
+pro.bootloader.high_fuses=0xdd
+pro.bootloader.extended_fuses=0x00
+pro.bootloader.path=atmega
+pro.bootloader.file=ATmegaBOOT_168_pro_8MHz.hex
+pro.bootloader.unlock_bits=0x3F
+pro.bootloader.lock_bits=0x0F
+
+pro.build.mcu=atmega168
+pro.build.f_cpu=8000000L
+pro.build.core=arduino
+
+##############################################################
+
+atmega168.name=Arduino NG or older w/ ATmega168
+
+atmega168.upload.protocol=stk500
+atmega168.upload.maximum_size=14336
+atmega168.upload.speed=19200
+
+atmega168.bootloader.low_fuses=0xff
+atmega168.bootloader.high_fuses=0xdd
+atmega168.bootloader.extended_fuses=0x00
+atmega168.bootloader.path=atmega
+atmega168.bootloader.file=ATmegaBOOT_168_ng.hex
+atmega168.bootloader.unlock_bits=0x3F
+atmega168.bootloader.lock_bits=0x0F
+
+atmega168.build.mcu=atmega168
+atmega168.build.f_cpu=16000000L
+atmega168.build.core=arduino
+
+##############################################################
+
+atmega8.name=Arduino NG or older w/ ATmega8
+
+atmega8.upload.protocol=stk500
+atmega8.upload.maximum_size=7168
+atmega8.upload.speed=19200
+
+atmega8.bootloader.low_fuses=0xdf
+atmega8.bootloader.high_fuses=0xca
+atmega8.bootloader.path=atmega8
+atmega8.bootloader.file=ATmegaBOOT.hex
+atmega8.bootloader.unlock_bits=0x3F
+atmega8.bootloader.lock_bits=0x0F
+
+atmega8.build.mcu=atmega8
+atmega8.build.f_cpu=16000000L
+atmega8.build.core=arduino
+
diff --git a/bootloaders/atmega/ATmegaBOOT_168.c b/bootloaders/atmega/ATmegaBOOT_168.c
new file mode 100755
index 0000000..2b9fefa
--- /dev/null
+++ b/bootloaders/atmega/ATmegaBOOT_168.c
@@ -0,0 +1,1054 @@
+/**********************************************************/
+/* Serial Bootloader for Atmel megaAVR Controllers */
+/* */
+/* tested with ATmega8, ATmega128 and ATmega168 */
+/* should work with other mega's, see code for details */
+/* */
+/* ATmegaBOOT.c */
+/* */
+/* */
+/* 20090308: integrated Mega changes into main bootloader */
+/* source by D. Mellis */
+/* 20080930: hacked for Arduino Mega (with the 1280 */
+/* processor, backwards compatible) */
+/* by D. Cuartielles */
+/* 20070626: hacked for Arduino Diecimila (which auto- */
+/* resets when a USB connection is made to it) */
+/* by D. Mellis */
+/* 20060802: hacked for Arduino by D. Cuartielles */
+/* based on a previous hack by D. Mellis */
+/* and D. Cuartielles */
+/* */
+/* Monitor and debug functions were added to the original */
+/* code by Dr. Erik Lins, chip45.com. (See below) */
+/* */
+/* Thanks to Karl Pitrich for fixing a bootloader pin */
+/* problem and more informative LED blinking! */
+/* */
+/* For the latest version see: */
+/* http://www.chip45.com/ */
+/* */
+/* ------------------------------------------------------ */
+/* */
+/* based on stk500boot.c */
+/* Copyright (c) 2003, Jason P. Kyle */
+/* All rights reserved. */
+/* see avr1.org for original file and information */
+/* */
+/* 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 */
+/* (at your option) 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. */
+/* */
+/* You should have received a copy of the GNU General */
+/* Public License along with this program; if not, write */
+/* to the Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/* */
+/* Licence can be viewed at */
+/* http://www.fsf.org/licenses/gpl.txt */
+/* */
+/* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */
+/* m8515,m8535. ATmega161 has a very small boot block so */
+/* isn't supported. */
+/* */
+/* Tested with m168 */
+/**********************************************************/
+
+/* $Id$ */
+
+
+/* some includes */
+#include <inttypes.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <util/delay.h>
+
+/* the current avr-libc eeprom functions do not support the ATmega168 */
+/* own eeprom write/read functions are used instead */
+#if !defined(__AVR_ATmega168__) || !defined(__AVR_ATmega328P__)
+#include <avr/eeprom.h>
+#endif
+
+/* Use the F_CPU defined in Makefile */
+
+/* 20060803: hacked by DojoCorp */
+/* 20070626: hacked by David A. Mellis to decrease waiting time for auto-reset */
+/* set the waiting time for the bootloader */
+/* get this from the Makefile instead */
+/* #define MAX_TIME_COUNT (F_CPU>>4) */
+
+/* 20070707: hacked by David A. Mellis - after this many errors give up and launch application */
+#define MAX_ERROR_COUNT 5
+
+/* set the UART baud rate */
+/* 20060803: hacked by DojoCorp */
+//#define BAUD_RATE 115200
+#ifndef BAUD_RATE
+#define BAUD_RATE 19200
+#endif
+
+
+/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */
+/* never allow AVR Studio to do an update !!!! */
+#define HW_VER 0x02
+#define SW_MAJOR 0x01
+#define SW_MINOR 0x10
+
+
+/* Adjust to suit whatever pin your hardware uses to enter the bootloader */
+/* ATmega128 has two UARTS so two pins are used to enter bootloader and select UART */
+/* ATmega1280 has four UARTS, but for Arduino Mega, we will only use RXD0 to get code */
+/* BL0... means UART0, BL1... means UART1 */
+#ifdef __AVR_ATmega128__
+#define BL_DDR DDRF
+#define BL_PORT PORTF
+#define BL_PIN PINF
+#define BL0 PINF7
+#define BL1 PINF6
+#elif defined __AVR_ATmega1280__
+/* we just don't do anything for the MEGA and enter bootloader on reset anyway*/
+#else
+/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */
+#define BL_DDR DDRD
+#define BL_PORT PORTD
+#define BL_PIN PIND
+#define BL PIND6
+#endif
+
+
+/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */
+/* if monitor functions are included, LED goes on after monitor was entered */
+#if defined __AVR_ATmega128__ || defined __AVR_ATmega1280__
+/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128, Arduino Mega) */
+#define LED_DDR DDRB
+#define LED_PORT PORTB
+#define LED_PIN PINB
+#define LED PINB7
+#else
+/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duomilanuove */
+/* other boards like e.g. Crumb8, Crumb168 are using PB2 */
+#define LED_DDR DDRB
+#define LED_PORT PORTB
+#define LED_PIN PINB
+#define LED PINB5
+#endif
+
+
+/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+#define MONITOR 1
+#endif
+
+
+/* define various device id's */
+/* manufacturer byte is always the same */
+#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :(
+
+#if defined __AVR_ATmega1280__
+#define SIG2 0x97
+#define SIG3 0x03
+#define PAGE_SIZE 0x80U //128 words
+
+#elif defined __AVR_ATmega1281__
+#define SIG2 0x97
+#define SIG3 0x04
+#define PAGE_SIZE 0x80U //128 words
+
+#elif defined __AVR_ATmega128__
+#define SIG2 0x97
+#define SIG3 0x02
+#define PAGE_SIZE 0x80U //128 words
+
+#elif defined __AVR_ATmega64__
+#define SIG2 0x96
+#define SIG3 0x02
+#define PAGE_SIZE 0x80U //128 words
+
+#elif defined __AVR_ATmega32__
+#define SIG2 0x95
+#define SIG3 0x02
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega16__
+#define SIG2 0x94
+#define SIG3 0x03
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega8__
+#define SIG2 0x93
+#define SIG3 0x07
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega88__
+#define SIG2 0x93
+#define SIG3 0x0a
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega168__
+#define SIG2 0x94
+#define SIG3 0x06
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega328P__
+#define SIG2 0x95
+#define SIG3 0x0F
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega162__
+#define SIG2 0x94
+#define SIG3 0x04
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega163__
+#define SIG2 0x94
+#define SIG3 0x02
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega169__
+#define SIG2 0x94
+#define SIG3 0x05
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega8515__
+#define SIG2 0x93
+#define SIG3 0x06
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega8535__
+#define SIG2 0x93
+#define SIG3 0x08
+#define PAGE_SIZE 0x20U //32 words
+#endif
+
+
+/* function prototypes */
+void putch(char);
+char getch(void);
+void getNch(uint8_t);
+void byte_response(uint8_t);
+void nothing_response(void);
+char gethex(void);
+void puthex(char);
+void flash_led(uint8_t);
+
+/* some variables */
+union address_union {
+ uint16_t word;
+ uint8_t byte[2];
+} address;
+
+union length_union {
+ uint16_t word;
+ uint8_t byte[2];
+} length;
+
+struct flags_struct {
+ unsigned eeprom : 1;
+ unsigned rampz : 1;
+} flags;
+
+uint8_t buff[256];
+uint8_t address_high;
+
+uint8_t pagesz=0x80;
+
+uint8_t i;
+uint8_t bootuart = 0;
+
+uint8_t error_count = 0;
+
+void (*app_start)(void) = 0x0000;
+
+
+/* main program starts here */
+int main(void)
+{
+ uint8_t ch,ch2;
+ uint16_t w;
+
+#ifdef WATCHDOG_MODS
+ ch = MCUSR;
+ MCUSR = 0;
+
+ WDTCSR |= _BV(WDCE) | _BV(WDE);
+ WDTCSR = 0;
+
+ // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot.
+ if (! (ch & _BV(EXTRF))) // if its a not an external reset...
+ app_start(); // skip bootloader
+#else
+ asm volatile("nop\n\t");
+#endif
+
+ /* set pin direction for bootloader pin and enable pullup */
+ /* for ATmega128, two pins need to be initialized */
+#ifdef __AVR_ATmega128__
+ BL_DDR &= ~_BV(BL0);
+ BL_DDR &= ~_BV(BL1);
+ BL_PORT |= _BV(BL0);
+ BL_PORT |= _BV(BL1);
+#else
+ /* We run the bootloader regardless of the state of this pin. Thus, don't
+ put it in a different state than the other pins. --DAM, 070709
+ This also applies to Arduino Mega -- DC, 080930
+ BL_DDR &= ~_BV(BL);
+ BL_PORT |= _BV(BL);
+ */
+#endif
+
+
+#ifdef __AVR_ATmega128__
+ /* check which UART should be used for booting */
+ if(bit_is_clear(BL_PIN, BL0)) {
+ bootuart = 1;
+ }
+ else if(bit_is_clear(BL_PIN, BL1)) {
+ bootuart = 2;
+ }
+#endif
+
+#if defined __AVR_ATmega1280__
+ /* the mega1280 chip has four serial ports ... we could eventually use any of them, or not? */
+ /* however, we don't wanna confuse people, to avoid making a mess, we will stick to RXD0, TXD0 */
+ bootuart = 1;
+#endif
+
+ /* check if flash is programmed already, if not start bootloader anyway */
+ if(pgm_read_byte_near(0x0000) != 0xFF) {
+
+#ifdef __AVR_ATmega128__
+ /* no UART was selected, start application */
+ if(!bootuart) {
+ app_start();
+ }
+#else
+ /* check if bootloader pin is set low */
+ /* we don't start this part neither for the m8, nor m168 */
+ //if(bit_is_set(BL_PIN, BL)) {
+ // app_start();
+ // }
+#endif
+ }
+
+#ifdef __AVR_ATmega128__
+ /* no bootuart was selected, default to uart 0 */
+ if(!bootuart) {
+ bootuart = 1;
+ }
+#endif
+
+
+ /* initialize UART(s) depending on CPU defined */
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ if(bootuart == 1) {
+ UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSR0A = 0x00;
+ UCSR0C = 0x06;
+ UCSR0B = _BV(TXEN0)|_BV(RXEN0);
+ }
+ if(bootuart == 2) {
+ UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSR1A = 0x00;
+ UCSR1C = 0x06;
+ UCSR1B = _BV(TXEN1)|_BV(RXEN1);
+ }
+#elif defined __AVR_ATmega163__
+ UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSRA = 0x00;
+ UCSRB = _BV(TXEN)|_BV(RXEN);
+#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
+
+#ifdef DOUBLE_SPEED
+ UCSR0A = (1<<U2X0); //Double speed mode USART0
+ UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*8L)-1);
+ UBRR0H = (F_CPU/(BAUD_RATE*8L)-1) >> 8;
+#else
+ UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+#endif
+
+ UCSR0B = (1<<RXEN0) | (1<<TXEN0);
+ UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);
+
+ /* Enable internal pull-up resistor on pin D0 (RX), in order
+ to supress line noise that prevents the bootloader from
+ timing out (DAM: 20070509) */
+ DDRD &= ~_BV(PIND0);
+ PORTD |= _BV(PIND0);
+#elif defined __AVR_ATmega8__
+ /* m8 */
+ UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate
+ UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
+ UCSRB = (1<<RXEN)|(1<<TXEN); // enable Rx & Tx
+ UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // config USART; 8N1
+#else
+ /* m16,m32,m169,m8515,m8535 */
+ UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSRA = 0x00;
+ UCSRC = 0x06;
+ UCSRB = _BV(TXEN)|_BV(RXEN);
+#endif
+
+#if defined __AVR_ATmega1280__
+ /* Enable internal pull-up resistor on pin D0 (RX), in order
+ to supress line noise that prevents the bootloader from
+ timing out (DAM: 20070509) */
+ /* feature added to the Arduino Mega --DC: 080930 */
+ DDRE &= ~_BV(PINE0);
+ PORTE |= _BV(PINE0);
+#endif
+
+
+ /* set LED pin as output */
+ LED_DDR |= _BV(LED);
+
+
+ /* flash onboard LED to signal entering of bootloader */
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ // 4x for UART0, 5x for UART1
+ flash_led(NUM_LED_FLASHES + bootuart);
+#else
+ flash_led(NUM_LED_FLASHES);
+#endif
+
+ /* 20050803: by DojoCorp, this is one of the parts provoking the
+ system to stop listening, cancelled from the original */
+ //putch('\0');
+
+ /* forever loop */
+ for (;;) {
+
+ /* get character from UART */
+ ch = getch();
+
+ /* A bunch of if...else if... gives smaller code than switch...case ! */
+
+ /* Hello is anyone home ? */
+ if(ch=='0') {
+ nothing_response();
+ }
+
+
+ /* Request programmer ID */
+ /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry */
+ /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares. */
+ else if(ch=='1') {
+ if (getch() == ' ') {
+ putch(0x14);
+ putch('A');
+ putch('V');
+ putch('R');
+ putch(' ');
+ putch('I');
+ putch('S');
+ putch('P');
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+ }
+
+
+ /* AVR ISP/STK500 board commands DON'T CARE so default nothing_response */
+ else if(ch=='@') {
+ ch2 = getch();
+ if (ch2>0x85) getch();
+ nothing_response();
+ }
+
+
+ /* AVR ISP/STK500 board requests */
+ else if(ch=='A') {
+ ch2 = getch();
+ if(ch2==0x80) byte_response(HW_VER); // Hardware version
+ else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version
+ else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version
+ else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56
+ else byte_response(0x00); // Covers various unnecessary responses we don't care about
+ }
+
+
+ /* Device Parameters DON'T CARE, DEVICE IS FIXED */
+ else if(ch=='B') {
+ getNch(20);
+ nothing_response();
+ }
+
+
+ /* Parallel programming stuff DON'T CARE */
+ else if(ch=='E') {
+ getNch(5);
+ nothing_response();
+ }
+
+
+ /* P: Enter programming mode */
+ /* R: Erase device, don't care as we will erase one page at a time anyway. */
+ else if(ch=='P' || ch=='R') {
+ nothing_response();
+ }
+
+
+ /* Leave programming mode */
+ else if(ch=='Q') {
+ nothing_response();
+#ifdef WATCHDOG_MODS
+ // autoreset via watchdog (sneaky!)
+ WDTCSR = _BV(WDE);
+ while (1); // 16 ms
+#endif
+ }
+
+
+ /* Set address, little endian. EEPROM in bytes, FLASH in words */
+ /* Perhaps extra address bytes may be added in future to support > 128kB FLASH. */
+ /* This might explain why little endian was used here, big endian used everywhere else. */
+ else if(ch=='U') {
+ address.byte[0] = getch();
+ address.byte[1] = getch();
+ nothing_response();
+ }
+
+
+ /* Universal SPI programming command, disabled. Would be used for fuses and lock bits. */
+ else if(ch=='V') {
+ if (getch() == 0x30) {
+ getch();
+ ch = getch();
+ getch();
+ if (ch == 0) {
+ byte_response(SIG1);
+ } else if (ch == 1) {
+ byte_response(SIG2);
+ } else {
+ byte_response(SIG3);
+ }
+ } else {
+ getNch(3);
+ byte_response(0x00);
+ }
+ }
+
+
+ /* Write memory, length is big endian and is in bytes */
+ else if(ch=='d') {
+ length.byte[1] = getch();
+ length.byte[0] = getch();
+ flags.eeprom = 0;
+ if (getch() == 'E') flags.eeprom = 1;
+ for (w=0;w<length.word;w++) {
+ buff[w] = getch(); // Store data in buffer, can't keep up with serial data stream whilst programming pages
+ }
+ if (getch() == ' ') {
+ if (flags.eeprom) { //Write to EEPROM one byte at a time
+ address.word <<= 1;
+ for(w=0;w<length.word;w++) {
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
+ while(EECR & (1<<EEPE));
+ EEAR = (uint16_t)(void *)address.word;
+ EEDR = buff[w];
+ EECR |= (1<<EEMPE);
+ EECR |= (1<<EEPE);
+#else
+ eeprom_write_byte((void *)address.word,buff[w]);
+#endif
+ address.word++;
+ }
+ }
+ else { //Write to FLASH one page at a time
+ if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME
+ else address_high = 0x00;
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
+ RAMPZ = address_high;
+#endif
+ address.word = address.word << 1; //address * 2 -> byte location
+ /* if ((length.byte[0] & 0x01) == 0x01) length.word++; //Even up an odd number of bytes */
+ if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes
+ cli(); //Disable interrupts, just to be sure
+#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
+ while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete
+#else
+ while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete
+#endif
+ asm volatile(
+ "clr r17 \n\t" //page_word_count
+ "lds r30,address \n\t" //Address of FLASH location (in bytes)
+ "lds r31,address+1 \n\t"
+ "ldi r28,lo8(buff) \n\t" //Start of buffer array in RAM
+ "ldi r29,hi8(buff) \n\t"
+ "lds r24,length \n\t" //Length of data to be written (in bytes)
+ "lds r25,length+1 \n\t"
+ "length_loop: \n\t" //Main loop, repeat for number of words in block
+ "cpi r17,0x00 \n\t" //If page_word_count=0 then erase page
+ "brne no_page_erase \n\t"
+ "wait_spm1: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm1 \n\t"
+ "ldi r16,0x03 \n\t" //Erase page pointed to by Z
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "wait_spm2: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm2 \n\t"
+
+ "ldi r16,0x11 \n\t" //Re-enable RWW section
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "no_page_erase: \n\t"
+ "ld r0,Y+ \n\t" //Write 2 bytes into page buffer
+ "ld r1,Y+ \n\t"
+
+ "wait_spm3: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm3 \n\t"
+ "ldi r16,0x01 \n\t" //Load r0,r1 into FLASH page buffer
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+
+ "inc r17 \n\t" //page_word_count++
+ "cpi r17,%1 \n\t"
+ "brlo same_page \n\t" //Still same page in FLASH
+ "write_page: \n\t"
+ "clr r17 \n\t" //New page, write current one first
+ "wait_spm4: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm4 \n\t"
+#ifdef __AVR_ATmega163__
+ "andi r30,0x80 \n\t" // m163 requires Z6:Z1 to be zero during page write
+#endif
+ "ldi r16,0x05 \n\t" //Write page pointed to by Z
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+ "ori r30,0x7E \n\t" // recover Z6:Z1 state after page write (had to be zero during write)
+#endif
+ "wait_spm5: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm5 \n\t"
+ "ldi r16,0x11 \n\t" //Re-enable RWW section
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "same_page: \n\t"
+ "adiw r30,2 \n\t" //Next word in FLASH
+ "sbiw r24,2 \n\t" //length-2
+ "breq final_write \n\t" //Finished
+ "rjmp length_loop \n\t"
+ "final_write: \n\t"
+ "cpi r17,0 \n\t"
+ "breq block_done \n\t"
+ "adiw r24,2 \n\t" //length+2, fool above check on length after short page write
+ "rjmp write_page \n\t"
+ "block_done: \n\t"
+ "clr __zero_reg__ \n\t" //restore zero register
+#if defined __AVR_ATmega168__ || __AVR_ATmega328P__ || __AVR_ATmega128__ || __AVR_ATmega1280__ || __AVR_ATmega1281__
+ : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
+#else
+ : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
+#endif
+ );
+ /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */
+ /* exit the bootloader without a power cycle anyhow */
+ }
+ putch(0x14);
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+ }
+
+
+ /* Read memory block mode, length is big endian. */
+ else if(ch=='t') {
+ length.byte[1] = getch();
+ length.byte[0] = getch();
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ if (address.word>0x7FFF) flags.rampz = 1; // No go with m256, FIXME
+ else flags.rampz = 0;
+#endif
+ address.word = address.word << 1; // address * 2 -> byte location
+ if (getch() == 'E') flags.eeprom = 1;
+ else flags.eeprom = 0;
+ if (getch() == ' ') { // Command terminator
+ putch(0x14);
+ for (w=0;w < length.word;w++) { // Can handle odd and even lengths okay
+ if (flags.eeprom) { // Byte access EEPROM read
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
+ while(EECR & (1<<EEPE));
+ EEAR = (uint16_t)(void *)address.word;
+ EECR |= (1<<EERE);
+ putch(EEDR);
+#else
+ putch(eeprom_read_byte((void *)address.word));
+#endif
+ address.word++;
+ }
+ else {
+
+ if (!flags.rampz) putch(pgm_read_byte_near(address.word));
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ else putch(pgm_read_byte_far(address.word + 0x10000));
+ // Hmmmm, yuck FIXME when m256 arrvies
+#endif
+ address.word++;
+ }
+ }
+ putch(0x10);
+ }
+ }
+
+
+ /* Get device signature bytes */
+ else if(ch=='u') {
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(SIG1);
+ putch(SIG2);
+ putch(SIG3);
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+ }
+
+
+ /* Read oscillator calibration byte */
+ else if(ch=='v') {
+ byte_response(0x00);
+ }
+
+
+#if defined MONITOR
+
+ /* here come the extended monitor commands by Erik Lins */
+
+ /* check for three times exclamation mark pressed */
+ else if(ch=='!') {
+ ch = getch();
+ if(ch=='!') {
+ ch = getch();
+ if(ch=='!') {
+ PGM_P welcome = "";
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ uint16_t extaddr;
+#endif
+ uint8_t addrl, addrh;
+
+#ifdef CRUMB128
+ welcome = "ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
+#elif defined PROBOMEGA128
+ welcome = "ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
+#elif defined SAVVY128
+ welcome = "ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
+#elif defined __AVR_ATmega1280__
+ welcome = "ATmegaBOOT / Arduino Mega - (C) Arduino LLC - 090930\n\r";
+#endif
+
+ /* turn on LED */
+ LED_DDR |= _BV(LED);
+ LED_PORT &= ~_BV(LED);
+
+ /* print a welcome message and command overview */
+ for(i=0; welcome[i] != '\0'; ++i) {
+ putch(welcome[i]);
+ }
+
+ /* test for valid commands */
+ for(;;) {
+ putch('\n');
+ putch('\r');
+ putch(':');
+ putch(' ');
+
+ ch = getch();
+ putch(ch);
+
+ /* toggle LED */
+ if(ch == 't') {
+ if(bit_is_set(LED_PIN,LED)) {
+ LED_PORT &= ~_BV(LED);
+ putch('1');
+ } else {
+ LED_PORT |= _BV(LED);
+ putch('0');
+ }
+ }
+
+ /* read byte from address */
+ else if(ch == 'r') {
+ ch = getch(); putch(ch);
+ addrh = gethex();
+ addrl = gethex();
+ putch('=');
+ ch = *(uint8_t *)((addrh << 8) + addrl);
+ puthex(ch);
+ }
+
+ /* write a byte to address */
+ else if(ch == 'w') {
+ ch = getch(); putch(ch);
+ addrh = gethex();
+ addrl = gethex();
+ ch = getch(); putch(ch);
+ ch = gethex();
+ *(uint8_t *)((addrh << 8) + addrl) = ch;
+ }
+
+ /* read from uart and echo back */
+ else if(ch == 'u') {
+ for(;;) {
+ putch(getch());
+ }
+ }
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ /* external bus loop */
+ else if(ch == 'b') {
+ putch('b');
+ putch('u');
+ putch('s');
+ MCUCR = 0x80;
+ XMCRA = 0;
+ XMCRB = 0;
+ extaddr = 0x1100;
+ for(;;) {
+ ch = *(volatile uint8_t *)extaddr;
+ if(++extaddr == 0) {
+ extaddr = 0x1100;
+ }
+ }
+ }
+#endif
+
+ else if(ch == 'j') {
+ app_start();
+ }
+
+ } /* end of monitor functions */
+
+ }
+ }
+ }
+ /* end of monitor */
+#endif
+ else if (++error_count == MAX_ERROR_COUNT) {
+ app_start();
+ }
+ } /* end of forever loop */
+
+}
+
+
+char gethexnib(void) {
+ char a;
+ a = getch(); putch(a);
+ if(a >= 'a') {
+ return (a - 'a' + 0x0a);
+ } else if(a >= '0') {
+ return(a - '0');
+ }
+ return a;
+}
+
+
+char gethex(void) {
+ return (gethexnib() << 4) + gethexnib();
+}
+
+
+void puthex(char ch) {
+ char ah;
+
+ ah = ch >> 4;
+ if(ah >= 0x0a) {
+ ah = ah - 0x0a + 'a';
+ } else {
+ ah += '0';
+ }
+
+ ch &= 0x0f;
+ if(ch >= 0x0a) {
+ ch = ch - 0x0a + 'a';
+ } else {
+ ch += '0';
+ }
+
+ putch(ah);
+ putch(ch);
+}
+
+
+void putch(char ch)
+{
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ if(bootuart == 1) {
+ while (!(UCSR0A & _BV(UDRE0)));
+ UDR0 = ch;
+ }
+ else if (bootuart == 2) {
+ while (!(UCSR1A & _BV(UDRE1)));
+ UDR1 = ch;
+ }
+#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
+ while (!(UCSR0A & _BV(UDRE0)));
+ UDR0 = ch;
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ while (!(UCSRA & _BV(UDRE)));
+ UDR = ch;
+#endif
+}
+
+
+char getch(void)
+{
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ uint32_t count = 0;
+ if(bootuart == 1) {
+ while(!(UCSR0A & _BV(RXC0))) {
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+
+ return UDR0;
+ }
+ else if(bootuart == 2) {
+ while(!(UCSR1A & _BV(RXC1))) {
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+
+ return UDR1;
+ }
+ return 0;
+#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
+ uint32_t count = 0;
+ while(!(UCSR0A & _BV(RXC0))){
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+ return UDR0;
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ uint32_t count = 0;
+ while(!(UCSRA & _BV(RXC))){
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+ return UDR;
+#endif
+}
+
+
+void getNch(uint8_t count)
+{
+ while(count--) {
+#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
+ if(bootuart == 1) {
+ while(!(UCSR0A & _BV(RXC0)));
+ UDR0;
+ }
+ else if(bootuart == 2) {
+ while(!(UCSR1A & _BV(RXC1)));
+ UDR1;
+ }
+#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
+ getch();
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ //while(!(UCSRA & _BV(RXC)));
+ //UDR;
+ getch(); // need to handle time out
+#endif
+ }
+}
+
+
+void byte_response(uint8_t val)
+{
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(val);
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+}
+
+
+void nothing_response(void)
+{
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+}
+
+void flash_led(uint8_t count)
+{
+ while (count--) {
+ LED_PORT |= _BV(LED);
+ _delay_ms(100);
+ LED_PORT &= ~_BV(LED);
+ _delay_ms(100);
+ }
+}
+
+
+/* end of file ATmegaBOOT.c */
diff --git a/bootloaders/atmega/ATmegaBOOT_168_atmega1280.hex b/bootloaders/atmega/ATmegaBOOT_168_atmega1280.hex
new file mode 100644
index 0000000..f16e877
--- /dev/null
+++ b/bootloaders/atmega/ATmegaBOOT_168_atmega1280.hex
@@ -0,0 +1,245 @@
+:020000021000EC
+:10F000000C9472F80C9492F80C9492F80C9492F878
+:10F010000C9492F80C9492F80C9492F80C9492F848
+:10F020000C9492F80C9492F80C9492F80C9492F838
+:10F030000C9492F80C9492F80C9492F80C9492F828
+:10F040000C9492F80C9492F80C9492F80C9492F818
+:10F050000C9492F80C9492F80C9492F80C9492F808
+:10F060000C9492F80C9492F80C9492F80C9492F8F8
+:10F070000C9492F80C9492F80C9492F80C9492F8E8
+:10F080000C9492F80C9492F80C9492F80C9492F8D8
+:10F090000C9492F80C9492F80C9492F80C9492F8C8
+:10F0A0000C9492F80C9492F80C9492F80C9492F8B8
+:10F0B0000C9492F80C9492F80C9492F80C9492F8A8
+:10F0C0000C9492F80C9492F80C9492F80C9492F898
+:10F0D0000C9492F80C9492F80C9492F80C9492F888
+:10F0E0000C9492F811241FBECFEFD1E2DEBFCDBF4A
+:10F0F00012E0A0E0B2E0EEEDFEEF01E00BBF02C0D7
+:10F1000007900D92A833B107D9F71BBE13E0A8E30F
+:10F11000B2E001C01D92A334B107E1F70E9412FAD8
+:10F120000C946DFF0C9400F8982F959595959595F6
+:10F130009595905D8F708A301CF1282F295A809107
+:10F140003802813019F0823071F008958091C0004A
+:10F1500085FFFCCF9093C6008091C00085FFFCCF57
+:10F160002093C60008958091C80085FFFCCF90933E
+:10F17000CE008091C80085FFFCCF2093CE0008957B
+:10F18000282F205DDCCF982F80913802813019F034
+:10F19000823041F008958091C00085FFFCCF9093AC
+:10F1A000C60008958091C80085FFFCCF9093CE00E3
+:10F1B0000895EF92FF920F931F9380913802813050
+:10F1C00069F1823031F080E01F910F91FF90EF9054
+:10F1D0000895EE24FF2487018091C80087FD17C0A1
+:10F1E0000894E11CF11C011D111D81E4E81682E464
+:10F1F000F8068FE0080780E0180770F3E0913A0204
+:10F20000F0913B0209958091C80087FFE9CF80917A
+:10F21000CE001F910F91FF90EF900895EE24FF24F0
+:10F2200087018091C00087FD17C00894E11CF11C84
+:10F23000011D111D81E4E81682E4F8068FE008073D
+:10F2400080E0180770F3E0913A02F0913B020995D3
+:10F250008091C00087FFE9CF8091C6001F910F9178
+:10F26000FF90EF9008950E94D9F8982F809138026E
+:10F27000813049F0823091F091366CF490330CF08B
+:10F280009053892F08958091C00085FFFCCF909303
+:10F29000C60091369CF39755892F08958091C80038
+:10F2A00085FFFCCF9093CE00E7CF1F930E9433F9E8
+:10F2B000182F0E9433F91295107F810F1F91089526
+:10F2C000982F20913802992339F0213031F02230E3
+:10F2D00061F091509923C9F708958091C00087FF8C
+:10F2E000FCCF8091C6009150F5CF8091C80087FF78
+:10F2F000FCCF8091CE009150EDCF1F93182F0E942C
+:10F30000D9F8803249F0809139028F5F80933902B9
+:10F31000853091F11F910895809138028130B9F0C4
+:10F320008230C1F78091C80085FFFCCF84E18093D3
+:10F33000CE008091C80085FFFCCF1093CE00809155
+:10F34000C80085FFFCCF80E18093CE00E3CF8091A1
+:10F35000C00085FFFCCF84E18093C6008091C0008F
+:10F3600085FFFCCF1093C6008091C00085FFFCCFC5
+:10F3700080E18093C600CECFE0913A02F0913B024B
+:10F3800009951F9108950E94D9F8803241F080912B
+:10F3900039028F5F80933902853029F10895809179
+:10F3A0003802813089F08230C9F78091C80085FF2A
+:10F3B000FCCF84E18093CE008091C80085FFFCCF14
+:10F3C00080E18093CE0008958091C00085FFFCCF3E
+:10F3D00084E18093C6008091C00085FFFCCF80E16E
+:10F3E0008093C6000895E0913A02F0913B0209959E
+:10F3F000089540E951E08823A1F02F9A28EE33E0E8
+:10F40000FA013197F1F721503040D1F72F9828EECB
+:10F4100033E0FA013197F1F721503040D1F78150B4
+:10F4200061F708952F923F924F925F926F927F9271
+:10F430008F929F92AF92BF92CF92DF92EF92FF9204
+:10F440000F931F93CF93DF93000081E080933802E6
+:10F4500080E18093C4001092C5001092C00086E045
+:10F460008093C20088E18093C1006898709A279ABF
+:10F4700081E00E94F9F9E4E1EE2E7EE1D72E67E902
+:10F48000C62E53E0B52E40E1A42E9924939431E486
+:10F49000832E26E5722E92E5692E80E2582E09E42D
+:10F4A000402E13E5312EB0E52B2E0E94D9F8803383
+:10F4B000C9F1813309F452C0803409F4C8C08134E1
+:10F4C00009F4EAC0823489F1853409F4CAC0803570
+:10F4D00049F1823539F1813529F1853509F4ECC0DE
+:10F4E000863509F409C1843609F428C1843709F442
+:10F4F000ABC1853709F473C2863709F4D9C08132AC
+:10F5000009F4B7C2809139028F5F80933902853048
+:10F5100061F6E0913A02F0913B0209950E94D9F818
+:10F52000803339F60E94C3F9C0CF2091380293E1AD
+:10F5300005C0223061F09923A9F391502130C9F719
+:10F540008091C00087FFFCCF8091C600F4CF8091EE
+:10F55000C80087FFFCCF8091CE00EDCF0E94D9F884
+:10F56000803281F6809138028130D1F1823009F009
+:10F570009CCF8091C80085FFFCCFE092CE008091A7
+:10F58000C80085FFFCCF8092CE008091C80085FF27
+:10F59000FCCF7092CE008091C80085FFFCCF6092B6
+:10F5A000CE008091C80085FFFCCF5092CE008091A4
+:10F5B000C80085FFFCCF4092CE008091C80085FF37
+:10F5C000FCCF3092CE008091C80085FFFCCF209206
+:10F5D000CE008091C80085FFFCCFA092CE0065CF01
+:10F5E0008091C00085FFFCCFE092C6008091C000F2
+:10F5F00085FFFCCF8092C6008091C00085FFFCCFC4
+:10F600007092C6008091C00085FFFCCF6092C6005A
+:10F610008091C00085FFFCCF5092C6008091C00051
+:10F6200085FFFCCF4092C6008091C00085FFFCCFD3
+:10F630003092C6008091C00085FFFCCF2092C600AA
+:10F640008091C00085FFFCCFA092C6002ECF0E9403
+:10F65000D9F8863808F466CF0E94D9F80E94C3F919
+:10F6600024CF2091380294E0213041F0223069F01B
+:10F67000992309F457CF91502130C1F78091C000F0
+:10F6800087FFFCCF8091C600F3CF8091C80087FF31
+:10F69000FCCF8091CE00ECCF0E94D9F8803841F1A8
+:10F6A000813809F447C0823809F4CAC08839E1F0CA
+:10F6B00080E00E947DF9F9CE0E94D9F880933C0247
+:10F6C0000E94D9F880933D020E94C3F9EECE0E94B9
+:10F6D000D9F80E94D9F8182F0E94D9F8112309F4FB
+:10F6E0007EC2113009F40AC283E00E947DF9DDCEAA
+:10F6F00082E00E947DF9D9CE0E94D9F8803339F397
+:10F700002091380292E0213039F0223061F09923C3
+:10F7100079F291502130C9F78091C00087FFFCCF6A
+:10F720008091C600F4CF8091C80087FFFCCF809104
+:10F73000CE00EDCF81E00E947DF9B7CE0E94D9F8CE
+:10F7400080933F030E94D9F880933E038091420347
+:10F750008E7F809342030E94D9F8853409F4B3C1A7
+:10F7600080913E0390913F03892B89F000E010E0E7
+:10F770000E94D9F8F801E25CFD4F80830F5F1F4FB4
+:10F7800080913E0390913F030817190788F30E9468
+:10F79000D9F8803209F0B6CE8091420380FFB2C121
+:10F7A00040913C0250913D02440F551F50933D0241
+:10F7B00040933C0260913E0370913F0361157105D7
+:10F7C000F1F080E090E09A01280F391FFC01E25C23
+:10F7D000FD4FE081F999FECF1FBA32BD21BDE0BDDA
+:10F7E0000FB6F894FA9AF99A0FBE01968617970702
+:10F7F00050F3460F571F50933D0240933C028091B7
+:10F800003802813081F0823009F04FCE8091C800FB
+:10F8100085FFFCCFE092CE008091C80085FFFCCF31
+:10F82000A092CE0042CE8091C00085FFFCCFE09236
+:10F83000C6008091C00085FFFCCFA092C60035CEE7
+:10F8400080E10E947DF931CE0E94D9F880933F0378
+:10F850000E94D9F880933E0320913C0230913D02F2
+:10F8600037FD46C1809142038D7F80934203220F72
+:10F87000331F30933D0220933C020E94D9F8853417
+:10F8800009F430C1809142038E7F809342030E942D
+:10F89000D9F8803209F009CE60913802613009F45C
+:10F8A0006FC0623009F473C000913E0310913F03B2
+:10F8B0000115110509F440C080914203782F717041
+:10F8C000F82EF69481E0F82240913C0250913D02DE
+:10F8D00020E030E013C0FF2009F060C0FA019491ED
+:10F8E000613009F43BC0623009F441C0CA0101969D
+:10F8F0002F5F3F4FAC0120173107D0F4772359F326
+:10F90000F999FECF52BD41BDF89A90B56130F9F03A
+:10F91000623061F78091C80085FFFCCF9093CE00E4
+:10F92000CA0101962F5F3F4FAC012017310730F31A
+:10F9300090933D0280933C02613009F4CAC062306A
+:10F9400009F0B3CD8091C80085FFFCCF46CE8091F1
+:10F95000C00085FFFCCF9093C600C8CF8091C00047
+:10F9600085FDF9CF8091C00085FFF8CFF4CF80915D
+:10F97000C80085FDD3CF8091C80085FFF8CFCECFDA
+:10F980008091C00085FFFCCFE092C6008DCF8091B2
+:10F99000C80085FFFCCFE092CE0086CFCA01A0E070
+:10F9A000B0E080509040AF4FBF4FABBFFC0197918C
+:10F9B000613061F0623009F099CF8091C80085FD17
+:10F9C000ADCF8091C80085FFF8CFA8CF8091C0004F
+:10F9D00085FDC1CF8091C00085FFF8CFBCCF0E94CC
+:10F9E000D9F8803209F08ECD80913802813011F142
+:10F9F000823009F05ACD8091C80085FFFCCFE0929B
+:10FA0000CE008091C80085FFFCCFD092CE008091BF
+:10FA1000C80085FFFCCFC092CE008091C80085FF52
+:10FA2000FCCFB092CE008091C80085FFFCCFA092A1
+:10FA3000CE003BCD8091C00085FFFCCFE092C60098
+:10FA40008091C00085FFFCCFD092C6008091C0009D
+:10FA500085FFFCCFC092C6008091C00085FFFCCF1F
+:10FA6000B092C6008091C00085FFFCCFA092C60076
+:10FA70001CCD0E94D9F8813209F017CD0E94D9F827
+:10FA8000813209F012CD279A2F98109240032091CD
+:10FA90003802E1E491E00EC0223009F4A4C0909352
+:10FAA0004003E92FF0E0E050FE4FE0819F5FEE233E
+:10FAB00009F4A0C0213081F78091C00085FFFCCF00
+:10FAC000E093C600ECCF80914203816080934203B3
+:10FAD00047CE8091C00085FDB7CD8091C00085FFE5
+:10FAE000F8CFB2CD80914203816080934203CFCEA4
+:10FAF00080914203826080934203B9CE87E90E94DD
+:10FB00007DF9D3CC80913D028823880F880B892111
+:10FB1000809341038BBF80913C0290913D02880FFE
+:10FB2000991F90933D0280933C0280913E0380FF99
+:10FB300009C080913E0390913F03019690933F034B
+:10FB400080933E03F894F999FECF1127E0913C028F
+:10FB5000F0913D02CEE3D2E080913E0390913F03CD
+:10FB6000103091F40091570001700130D9F303E097
+:10FB700000935700E8950091570001700130D9F3C8
+:10FB800001E100935700E895099019900091570002
+:10FB900001700130D9F301E000935700E895139507
+:10FBA000103898F011270091570001700130D9F3F7
+:10FBB00005E000935700E89500915700017001306F
+:10FBC000D9F301E100935700E8953296029709F0C6
+:10FBD000C7CF103011F00296E5CF112410CE8EE180
+:10FBE0000E947DF962CC8091C80085FFFCCFE09334
+:10FBF000CE0055CF7AE0B72E6DE0A62E5AE3952EB3
+:10FC000040E2842E3DE3732E90E3692E81E3582E6B
+:10FC1000213009F442C0223009F45FC00E94D9F8B3
+:10FC2000982F20913802213089F1223009F44EC0FA
+:10FC3000943709F46BC0923709F405C1973709F47A
+:10FC40007BC0953799F0923609F4BDC09A3601F71A
+:10FC5000E0913A02F0913B02099520913802D8CF09
+:10FC60008091C00085FFFCCF9093C6000E94D9F818
+:10FC7000982F80913802813099F38230B9F78091C2
+:10FC8000C80085FFFCCF9093CE00F0CF8091C000DC
+:10FC900085FFFCCF9093C600CBCF8091C00085FF3D
+:10FCA000FCCFB092C6008091C00085FFFCCFA0922F
+:10FCB000C6008091C00085FFFCCF9092C600809165
+:10FCC000C00085FFFCCF8092C600A8CF8091C800FD
+:10FCD00085FFFCCF9093CE00ABCF8091C80085FF0D
+:10FCE000FCCFB092CE008091C80085FFFCCFA092DF
+:10FCF000CE008091C80085FFFCCF9092CE0080910D
+:10FD0000C80085FFFCCF8092CE0088CF1F9947C0E6
+:10FD10002F9A213051F0223009F07ACF8091C8001B
+:10FD200085FFFCCF6092CE0073CF8091C00085FF2D
+:10FD3000FCCF6092C6006CCF0E94D9F8982F8091BA
+:10FD400038028130F1F0823009F4ABC00E9455F9DD
+:10FD5000082F0E9455F9182F0E94D9F8982F8091EA
+:10FD600038028130A9F0823009F4A2C00E9455F90E
+:10FD7000D02ECC24F601E10FF11D808320913802B2
+:10FD800047CF8091C00085FFFCCF9093C600DECFA7
+:10FD90008091C00085FFFCCF9093C600E7CF2F98DD
+:10FDA000213051F0223009F033CF8091C80085FF17
+:10FDB000FCCF5092CE002CCF8091C00085FFFCCFAD
+:10FDC0005092C60025CF213041F1223081F080E8E9
+:10FDD00085BF109274001092750080E091E1FC01E3
+:10FDE000819180E091E13097D1F3CF01F8CF8091FC
+:10FDF000C80085FFFCCF82E68093CE008091C800CA
+:10FE000085FFFCCF85E78093CE008091C80085FFF9
+:10FE1000FCCF83E78093CE00DACF8091C00085FFCE
+:10FE2000FCCF82E68093C6008091C00085FFFCCFA6
+:10FE300085E78093C6008091C00085FFFCCF83E7F3
+:10FE40008093C600C4CF0E94D9F8982F80913802C1
+:10FE50008130C9F08230D1F10E9455F9182F0E94EB
+:10FE600055F9982F809138028130A1F0823039F114
+:10FE7000F12EEE24F701E90FF11D80810E9494F824
+:10FE800020913802C5CE8091C00085FFFCCF9093B1
+:10FE9000C600E2CF8091C00085FFFCCF7092C60003
+:10FEA000E7CF8091C80085FFFCCF9093CE004ECF66
+:10FEB0008091C80085FFFCCF9093CE0057CF8091F2
+:10FEC000C80085FFFCCF7092CE00D2CF8091C800D1
+:0EFED00085FFFCCF9093CE00BFCFF894FFCFFC
+:10FEDE0041546D656761424F4F54202F204172642B
+:10FEEE0075696E6F204D656761202D20284329208E
+:10FEFE0041726475696E6F204C4C43202D20303951
+:08FF0E00303933300A0D008088
+:040000031000F000F9
+:00000001FF
diff --git a/bootloaders/atmega/ATmegaBOOT_168_atmega328.hex b/bootloaders/atmega/ATmegaBOOT_168_atmega328.hex
new file mode 100644
index 0000000..43a8b30
--- /dev/null
+++ b/bootloaders/atmega/ATmegaBOOT_168_atmega328.hex
@@ -0,0 +1,125 @@
+:107800000C94343C0C94513C0C94513C0C94513CE1
+:107810000C94513C0C94513C0C94513C0C94513CB4
+:107820000C94513C0C94513C0C94513C0C94513CA4
+:107830000C94513C0C94513C0C94513C0C94513C94
+:107840000C94513C0C94513C0C94513C0C94513C84
+:107850000C94513C0C94513C0C94513C0C94513C74
+:107860000C94513C0C94513C11241FBECFEFD8E036
+:10787000DEBFCDBF11E0A0E0B1E0ECE9FFE702C060
+:1078800005900D92A230B107D9F712E0A2E0B1E065
+:1078900001C01D92AD30B107E1F70E942D3D0C945F
+:1078A000CC3F0C94003C982F959595959595959582
+:1078B000905D8F708A307CF0282F295A8091C0000B
+:1078C00085FFFCCF9093C6008091C00085FFFCCF60
+:1078D0002093C6000895282F205DF0CF982F809127
+:1078E000C00085FFFCCF9093C6000895EF92FF92F1
+:1078F0000F931F93EE24FF2487018091C00087FD22
+:1079000017C00894E11CF11C011D111D81E4E8164B
+:1079100082E4F8068FE0080780E0180770F3E09132
+:107920000401F091050109958091C00087FFE9CF1E
+:107930008091C6001F910F91FF90EF9008950E94D3
+:10794000763C982F8091C00085FFFCCF9093C600B5
+:1079500091362CF490330CF09053892F089597555D
+:10796000892F08951F930E949F3C182F0E949F3CCF
+:107970001295107F810F1F9108951F93182F882350
+:1079800021F00E94763C1150E1F71F9108951F935A
+:10799000182F0E94763C803249F0809103018F5F5E
+:1079A000809303018530C1F01F9108958091C0003C
+:1079B00085FFFCCF84E18093C6008091C00085FFE5
+:1079C000FCCF1093C6008091C00085FFFCCF80E102
+:1079D0008093C6001F910895E0910401F091050184
+:1079E00009951F9108950E94763C803241F0809164
+:1079F00003018F5F80930301853081F008958091AA
+:107A0000C00085FFFCCF84E18093C6008091C00058
+:107A100085FFFCCF80E18093C6000895E0910401CA
+:107A2000F09105010995089540E951E08823A1F0FE
+:107A30002D9A28EE33E0FA013197F1F721503040CA
+:107A4000D1F72D9828EE33E0FA013197F1F7215064
+:107A50003040D1F7815061F708953F924F925F9285
+:107A60006F927F928F929F92AF92BF92CF92DF924E
+:107A7000EF92FF920F931F93CF93DF93000080E16B
+:107A80008093C4001092C50088E18093C10086E015
+:107A90008093C2005098589A259A81E00E94143D24
+:107AA00024E1F22E9EE1E92E85E9D82E0FE0C02ECA
+:107AB00010E1B12EAA24A394B1E49B2EA6E58A2E50
+:107AC000F2E57F2EE0E26E2E79E4572E63E5462E36
+:107AD00050E5352E0E94763C8033B1F18133B9F107
+:107AE000803409F46FC0813409F476C0823409F41B
+:107AF00085C0853409F488C0803531F1823521F1A3
+:107B0000813511F1853509F485C0863509F48DC0BC
+:107B1000843609F496C0843709F403C1853709F423
+:107B200072C1863709F466C0809103018F5F80932C
+:107B30000301853079F6E0910401F0910501099582
+:107B40000E94763C803351F60E94F33CC3CF0E94E2
+:107B5000763C803249F78091C00085FFFCCFF092DF
+:107B6000C6008091C00085FFFCCF9092C600809136
+:107B7000C00085FFFCCF8092C6008091C00085FFC9
+:107B8000FCCF7092C6008091C00085FFFCCF609250
+:107B9000C6008091C00085FFFCCF5092C600809146
+:107BA000C00085FFFCCF4092C6008091C00085FFD9
+:107BB000FCCF3092C6008091C00085FFFCCFB09210
+:107BC000C60088CF0E94763C863808F4BDCF0E945C
+:107BD000763C0E94F33C7ECF0E94763C803809F4CC
+:107BE0009CC0813809F40BC1823809F43CC1883942
+:107BF00009F48FC080E00E94C73C6CCF84E10E94F2
+:107C0000BD3C0E94F33C66CF85E00E94BD3C0E94D3
+:107C1000F33C60CF0E94763C809306010E94763C44
+:107C2000809307010E94F33C55CF0E94763C80333D
+:107C300009F41DC183E00E94BD3C80E00E94C73C66
+:107C400049CF0E94763C809309020E94763C809343
+:107C5000080280910C028E7F80930C020E94763C79
+:107C6000853409F415C18091080290910902892B8D
+:107C700089F000E010E00E94763CF801E85FFE4FDA
+:107C800080830F5F1F4F80910802909109020817AF
+:107C9000190788F30E94763C803209F045CF809125
+:107CA0000C0280FF01C16091060170910701660F0F
+:107CB000771F7093070160930601A0910802B091AD
+:107CC00009021097C9F0E8E0F1E09B01AD014E0F09
+:107CD0005F1FF999FECF32BD21BD819180BDFA9A17
+:107CE000F99A2F5F3F4FE417F50799F76A0F7B1F4B
+:107CF00070930701609306018091C00085FFFCCF5F
+:107D0000F092C6008091C00085FFFCCFB092C60003
+:107D1000E1CE83E00E94C73CDDCE82E00E94C73CFA
+:107D2000D9CE0E94763C809309020E94763C8093D3
+:107D300008028091060190910701880F991F909386
+:107D40000701809306010E94763C853409F4A6C0A1
+:107D500080910C028E7F80930C020E94763C8032D0
+:107D600009F0B8CE8091C00085FFFCCFF092C6002C
+:107D7000609108027091090261157105B9F140E046
+:107D800050E080910C02A82FA170B82FB27011C0E2
+:107D9000BB2309F45CC0E0910601F0910701319624
+:107DA000F0930701E09306014F5F5F4F46175707B7
+:107DB000E8F4AA2369F3F999FECF209106013091E6
+:107DC000070132BD21BDF89A90B58091C00085FFB2
+:107DD000FCCF9093C6002F5F3F4F30930701209355
+:107DE00006014F5F5F4F4617570718F38091C00099
+:107DF00085FDE5CE8091C00085FFF8CFE0CE81E023
+:107E00000E94C73C67CE0E94763C803209F08CCE3F
+:107E10008091C00085FFFCCFF092C6008091C00029
+:107E200085FFFCCFE092C6008091C00085FFFCCFAB
+:107E3000D092C6008091C00085FFFCCFC092C600E2
+:107E40008091C00085FFFCCFB092C60043CEE09188
+:107E50000601F091070194918091C00085FFFCCF4D
+:107E60009093C6009CCF80E10E94C73C33CE0E9415
+:107E7000763C0E94763C182F0E94763C112309F430
+:107E800083C0113009F484C08FE00E94C73C22CE29
+:107E900080910C02816080930C02E5CE80910C02EF
+:107EA000816080930C0259CF809107018823880F4D
+:107EB000880B8A2180930B02809106019091070123
+:107EC000880F991F90930701809306018091080203
+:107ED00080FF09C080910802909109020196909359
+:107EE000090280930802F894F999FECF1127E091D6
+:107EF0000601F0910701C8E0D1E08091080290915D
+:107F00000902103091F40091570001700130D9F34B
+:107F100003E000935700E89500915700017001308D
+:107F2000D9F301E100935700E89509901990009169
+:107F3000570001700130D9F301E000935700E89534
+:107F40001395103498F011270091570001700130FB
+:107F5000D9F305E000935700E895009157000170B0
+:107F60000130D9F301E100935700E895329602976A
+:107F700009F0C7CF103011F00296E5CF112480919F
+:107F8000C00085FFB9CEBCCE8EE10E94C73CA2CD19
+:0C7F900085E90E94C73C9ECDF894FFCF0D
+:027F9C00800063
+:040000030000780081
+:00000001FF
diff --git a/bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex b/bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
new file mode 100644
index 0000000..9753e2e
--- /dev/null
+++ b/bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
@@ -0,0 +1,124 @@
+:107800000C94343C0C94513C0C94513C0C94513CE1
+:107810000C94513C0C94513C0C94513C0C94513CB4
+:107820000C94513C0C94513C0C94513C0C94513CA4
+:107830000C94513C0C94513C0C94513C0C94513C94
+:107840000C94513C0C94513C0C94513C0C94513C84
+:107850000C94513C0C94513C0C94513C0C94513C74
+:107860000C94513C0C94513C11241FBECFEFD8E036
+:10787000DEBFCDBF11E0A0E0B1E0EAE8FFE702C063
+:1078800005900D92A230B107D9F712E0A2E0B1E065
+:1078900001C01D92AD30B107E1F70E942D3D0C945F
+:1078A000C33F0C94003C982F95959595959595958B
+:1078B000905D8F708A307CF0282F295A8091C0000B
+:1078C00085FFFCCF9093C6008091C00085FFFCCF60
+:1078D0002093C6000895282F205DF0CF982F809127
+:1078E000C00085FFFCCF9093C6000895EF92FF92F1
+:1078F0000F931F93EE24FF2487018091C00087FD22
+:1079000017C00894E11CF11C011D111D81E2E8164D
+:1079100081EAF80687E0080780E0180770F3E09135
+:107920000401F091050109958091C00087FFE9CF1E
+:107930008091C6001F910F91FF90EF9008950E94D3
+:10794000763C982F8091C00085FFFCCF9093C600B5
+:1079500091362CF490330CF09053892F089597555D
+:10796000892F08951F930E949F3C182F0E949F3CCF
+:107970001295107F810F1F9108951F93182F882350
+:1079800021F00E94763C1150E1F71F9108951F935A
+:10799000182F0E94763C803249F0809103018F5F5E
+:1079A000809303018530C1F01F9108958091C0003C
+:1079B00085FFFCCF84E18093C6008091C00085FFE5
+:1079C000FCCF1093C6008091C00085FFFCCF80E102
+:1079D0008093C6001F910895E0910401F091050184
+:1079E00009951F9108950E94763C803241F0809164
+:1079F00003018F5F80930301853081F008958091AA
+:107A0000C00085FFFCCF84E18093C6008091C00058
+:107A100085FFFCCF80E18093C6000895E0910401CA
+:107A2000F09105010995089548EC50E08823A1F0F4
+:107A30002D9A28EE33E0FA013197F1F721503040CA
+:107A4000D1F72D9828EE33E0FA013197F1F7215064
+:107A50003040D1F7815061F708953F924F925F9285
+:107A60006F927F928F929F92AF92BF92CF92DF924E
+:107A7000EF92FF920F931F93CF93DF93000082E06A
+:107A80008093C00080E18093C4001092C50088E11B
+:107A90008093C10086E08093C2005098589A259A3E
+:107AA00081E00E94143D24E1F22E9EE1E92E85E959
+:107AB000D82E0FE0C02E10E1B12EAA24A394B1E479
+:107AC0009B2EA6E58A2EF2E57F2EE0E26E2E79E46B
+:107AD000572E63E5462E50E5352E0E94763C8033C6
+:107AE000B1F18133B9F1803409F46FC0813409F404
+:107AF00076C0823409F485C0853409F488C08035A5
+:107B000031F1823521F1813511F1853509F485C0D6
+:107B1000863509F48DC0843609F496C0843709F49B
+:107B200003C1853709F472C1863709F466C08091B4
+:107B300003018F5F80930301853079F6E0910401A2
+:107B4000F091050109950E94763C803351F60E9420
+:107B5000F33CC3CF0E94763C803249F78091C0004D
+:107B600085FFFCCFF092C6008091C00085FFFCCF5E
+:107B70009092C6008091C00085FFFCCF8092C60025
+:107B80008091C00085FFFCCF7092C6008091C0003C
+:107B900085FFFCCF6092C6008091C00085FFFCCFBE
+:107BA0005092C6008091C00085FFFCCF4092C60075
+:107BB0008091C00085FFFCCF3092C6008091C0004C
+:107BC00085FFFCCFB092C60088CF0E94763C8638F5
+:107BD00008F4BDCF0E94763C0E94F33C7ECF0E9409
+:107BE000763C803809F49CC0813809F40BC1823896
+:107BF00009F430C1883909F48FC080E00E94C73C85
+:107C00006CCF84E10E94BD3C0E94F33C66CF85E0CE
+:107C10000E94BD3C0E94F33C60CF0E94763C809362
+:107C200006010E94763C809307010E94F33C55CFE9
+:107C30000E94763C803309F411C183E00E94BD3C70
+:107C400080E00E94C73C49CF0E94763C80930902A5
+:107C50000E94763C8093080280910C028E7F809374
+:107C60000C020E94763C853409F409C18091080217
+:107C700090910902892B89F000E010E00E94763C87
+:107C8000F801E85FFE4F80830F5F1F4F809108026D
+:107C9000909109020817190788F30E94763C8032F8
+:107CA00009F045CF80910C0280FFF5C0609106017C
+:107CB00070910701660F771F7093070160930601AB
+:107CC000A0910802B09109021097C9F0E8E0F1E034
+:107CD0009B01AD014E0F5F1FF999FECF32BD21BD53
+:107CE000819180BDFA9AF99A2F5F3F4FE417F5070B
+:107CF00099F76A0F7B1F70930701609306018091CB
+:107D0000C00085FFFCCFF092C6008091C00085FFC7
+:107D1000FCCFB092C600E1CE83E00E94C73CDDCE2E
+:107D200082E00E94C73CD9CE0E94763C8093090233
+:107D30000E94763C80930802809106019091070191
+:107D4000880F991F90930701809306010E94763C4B
+:107D5000853409F49AC080910C028E7F80930C02C6
+:107D60000E94763C803209F0B8CE8091C00085FF39
+:107D7000FCCFF092C600A0910802B09109021097C2
+:107D8000C1F180910C02082F0170182F1695117007
+:107D9000E0910601F0910701AF014F5F5F4FBA011B
+:107DA00020E030E00023B1F4112339F49491809164
+:107DB000C00085FFFCCF9093C6002F5F3F4FCB01E3
+:107DC0000196FA012A173B0780F4BC014F5F5F4F11
+:107DD000002351F3F999FECFF2BDE1BDF89A90B5B9
+:107DE0008091C00085FFFCCFE6CF709307016093C0
+:107DF00006018091C00085FDE5CE8091C00085FF21
+:107E0000F8CFE0CE81E00E94C73C67CE0E94763C6E
+:107E1000803209F08CCE8091C00085FFFCCFF092BB
+:107E2000C6008091C00085FFFCCFE092C600809123
+:107E3000C00085FFFCCFD092C6008091C00085FFB6
+:107E4000FCCFC092C6008091C00085FFFCCFB092ED
+:107E5000C60043CE80E10E94C73C3FCE0E94763CE4
+:107E60000E94763C182F0E94763C112309F483C0AF
+:107E7000113009F484C08FE00E94C73C2ECE80915F
+:107E80000C02816080930C02F1CE80910C02816023
+:107E900080930C0265CF809107018823880F880B9F
+:107EA0008A2180930B028091060190910701880F2F
+:107EB000991F90930701809306018091080280FF2B
+:107EC00009C08091080290910902019690930902DD
+:107ED00080930802F894F999FECF1127E0910601EA
+:107EE000F0910701C8E0D1E0809108029091090269
+:107EF000103091F40091570001700130D9F303E084
+:107F000000935700E8950091570001700130D9F3B4
+:107F100001E100935700E8950990199000915700EE
+:107F200001700130D9F301E000935700E8951395F3
+:107F3000103498F011270091570001700130D9F3E7
+:107F400005E000935700E89500915700017001305B
+:107F5000D9F301E100935700E8953296029709F0B2
+:107F6000C7CF103011F00296E5CF11248091C000E8
+:107F700085FFC5CEC8CE8EE10E94C73CAECD85E957
+:0A7F80000E94C73CAACDF894FFCF81
+:027F8A00800075
+:040000030000780081
+:00000001FF
diff --git a/bootloaders/atmega/ATmegaBOOT_168_diecimila.hex b/bootloaders/atmega/ATmegaBOOT_168_diecimila.hex
new file mode 100644
index 0000000..feac9d2
--- /dev/null
+++ b/bootloaders/atmega/ATmegaBOOT_168_diecimila.hex
@@ -0,0 +1,126 @@
+:103800000C94341C0C94511C0C94511C0C94511CA1
+:103810000C94511C0C94511C0C94511C0C94511C74
+:103820000C94511C0C94511C0C94511C0C94511C64
+:103830000C94511C0C94511C0C94511C0C94511C54
+:103840000C94511C0C94511C0C94511C0C94511C44
+:103850000C94511C0C94511C0C94511C0C94511C34
+:103860000C94511C0C94511C11241FBECFEFD4E0BA
+:10387000DEBFCDBF11E0A0E0B1E0E4EAFFE302C0AB
+:1038800005900D92A230B107D9F712E0A2E0B1E0A5
+:1038900001C01D92AD30B107E1F70E94361D0C94B6
+:1038A000D01F0C94001C982F9595959595959595FE
+:1038B000905D8F708A307CF0282F295A8091C0004B
+:1038C00085FFFCCF9093C6008091C00085FFFCCFA0
+:1038D0002093C6000895282F205DF0CF982F809167
+:1038E000C00085FFFCCF9093C6000895EF92FF9231
+:1038F0000F931F93EE24FF2487018091C00087FD62
+:1039000017C00894E11CF11C011D111D81E4E8168B
+:1039100082E4F8068FE0080780E0180770F3E09172
+:103920000401F091050109958091C00087FFE9CF5E
+:103930008091C6001F910F91FF90EF9008950E9413
+:10394000761C982F8091C00085FFFCCF9093C60015
+:1039500091362CF490330CF09053892F089597559D
+:10396000892F08951F930E949F1C182F0E949F1C4F
+:103970001295107F810F1F910895882351F0982F81
+:1039800091508091C00087FFFCCF8091C6009923A1
+:10399000B9F708951F93182F0E94761C803249F0C2
+:1039A000809103018F5F809303018530C1F01F91E7
+:1039B00008958091C00085FFFCCF84E18093C6000C
+:1039C0008091C00085FFFCCF1093C6008091C0009D
+:1039D00085FFFCCF80E18093C6001F910895E091A0
+:1039E0000401F091050109951F9108950E94761C2C
+:1039F000803241F0809103018F5F80930301853015
+:103A000081F008958091C00085FFFCCF84E1809310
+:103A1000C6008091C00085FFFCCF80E18093C60086
+:103A20000895E0910401F09105010995089510921F
+:103A30000A028823D1F090E040E951E02D9A28EE67
+:103A400033E0FA013197F1F721503040D1F72D984A
+:103A500028EE33E0FA013197F1F721503040D1F7E9
+:103A60009F5F981758F380930A0208953F924F92F0
+:103A70005F926F927F928F929F92AF92BF92CF92FE
+:103A8000DF92EF92FF920F931F93CF93DF9300008B
+:103A900083E38093C4001092C50088E18093C10045
+:103AA00086E08093C2005098589A259A81E00E943F
+:103AB000171D44E1F42E3EE1E32E24E9D22E96E0D8
+:103AC000C92E80E1B82EAA24A39401E4902E16E515
+:103AD000812EB2E57B2EA0E26A2EF9E45F2EE3E5AB
+:103AE0004E2E70E5372E0E94761C8033B1F1813363
+:103AF00009F441C0803409F479C0813409F48CC0E0
+:103B0000823471F1853409F47BC0803531F182351E
+:103B100021F1813511F1853509F48DC0863509F41F
+:103B20009DC0843609F4AEC0843709F41BC18537C3
+:103B300009F485C1863709F47AC0809103018F5F4B
+:103B400080930301853079F6E0910401F09105013D
+:103B500009950E94761C803351F60E94F61CC3CF53
+:103B600093E18091C00087FFFCCF8091C60099232C
+:103B7000A1F39150F6CF0E94761C8032F1F680912D
+:103B8000C00085FFFCCFF092C6008091C00085FF89
+:103B9000FCCF9092C6008091C00085FFFCCF809240
+:103BA000C6008091C00085FFFCCF7092C600809156
+:103BB000C00085FFFCCF6092C6008091C00085FFE9
+:103BC000FCCF5092C6008091C00085FFFCCF409290
+:103BD000C6008091C00085FFFCCF3092C600809166
+:103BE000C00085FFFCCFB092C6007DCF0E94761C3E
+:103BF000863808F4B2CF0E94761C0E94F61C73CF60
+:103C000094E08091C00087FFFCCF8091C60099238B
+:103C100009F4A3CF9150F5CF0E94761C8038D1F0E3
+:103C2000813861F1823809F499C0883979F080E0EF
+:103C30000E94CA1C58CF0E94761C809306010E94E5
+:103C4000761C809307010E94F61C4DCF83E00E94F2
+:103C5000CA1C49CF82E00E94CA1C45CF0E94761C34
+:103C6000803309F486C192E08091C00087FFFCCFC9
+:103C70008091C6009923D9F29150F6CF81E00E943D
+:103C8000CA1C31CF0E94761C809309020E94761CC8
+:103C90008093080280910C028E7F80930C020E9418
+:103CA000761C853429F480910C02816080930C028B
+:103CB0008091080290910902892B89F000E010E0C0
+:103CC0000E94761CF801E85FFE4F80830F5F1F4F54
+:103CD00080910802909109020817190788F30E9441
+:103CE000761C803209F029CF80910C0280FFD1C070
+:103CF0004091060150910701440F551F5093070151
+:103D000040930601A0910802B09109021097C9F0F2
+:103D1000E8E0F1E09A01BD016E0F7F1FF999FECF37
+:103D200032BD21BD819180BDFA9AF99A2F5F3F4F34
+:103D3000E617F70799F74A0F5B1F50930701409367
+:103D400006018091C00085FFFCCFF092C6008091F3
+:103D5000C00085FFFCCFB092C600C5CE80E10E94B6
+:103D6000CA1CC1CE0E94761C809309020E94761C58
+:103D7000809308028091060190910701880F991F96
+:103D800090930701809306010E94761C853409F404
+:103D90007AC080910C028E7F80930C020E94761C68
+:103DA000803209F0A0CE8091C00085FFFCCFF09258
+:103DB000C600A0910802B09109021097B9F1809154
+:103DC0000C02182F1170082F0270E0910601F0917B
+:103DD00007019F012F5F3F4FB90140E050E01123E1
+:103DE000B1F4002339F494918091C00085FFFCCF99
+:103DF0009093C6004F5F5F4FCB010196F9014A17C0
+:103E00005B0780F4BC012F5F3F4F112351F3F999F9
+:103E1000FECFF2BDE1BDF89A90B58091C00085FF5C
+:103E2000FCCFE6CF70930701609306018091C0003C
+:103E300085FDD9CE8091C00085FFF8CFD4CE0E94F9
+:103E4000761C803209F079CE8091C00085FFFCCFCE
+:103E5000F092C6008091C00085FFFCCFE092C600C2
+:103E60008091C00085FFFCCFD092C6008091C00039
+:103E700085FFFCCFC092C6008091C00085FFFCCFBB
+:103E8000B092C60030CE80910C02816080930C020B
+:103E900085CF809107018823880F880B8A21809322
+:103EA0000B028091060190910701880F991F909352
+:103EB0000701809306018091080280FF09C080916C
+:103EC00008029091090201969093090280930802DA
+:103ED000F894F999FECF1127E0910601F0910701BE
+:103EE000C8E0D1E08091080290910902103091F46D
+:103EF0000091570001700130D9F303E0009357009F
+:103F0000E8950091570001700130D9F301E1009369
+:103F10005700E89509901990009157000170013001
+:103F2000D9F301E000935700E8951395103498F009
+:103F300011270091570001700130D9F305E000937B
+:103F40005700E8950091570001700130D9F301E165
+:103F500000935700E8953296029709F0C7CF1030CA
+:103F600011F00296E5CF11248091C00085FFE9CEC3
+:103F7000ECCE0E94761C0E94761C182F0E94761CA4
+:103F8000112351F0113021F086E00E94CA1CABCD04
+:103F900084E90E94CA1CA7CD8EE10E94CA1CA3CD51
+:043FA000F894FFCFC3
+:023FA40080009B
+:0400000300003800C1
+:00000001FF
diff --git a/bootloaders/atmega/ATmegaBOOT_168_ng.hex b/bootloaders/atmega/ATmegaBOOT_168_ng.hex
new file mode 100644
index 0000000..387091e
--- /dev/null
+++ b/bootloaders/atmega/ATmegaBOOT_168_ng.hex
@@ -0,0 +1,110 @@
+:103800000C94341C0C94511C0C94511C0C94511CA1
+:103810000C94511C0C94511C0C94511C0C94511C74
+:103820000C94511C0C94511C0C94511C0C94511C64
+:103830000C94511C0C94511C0C94511C0C94511C54
+:103840000C94511C0C94511C0C94511C0C94511C44
+:103850000C94511C0C94511C0C94511C0C94511C34
+:103860000C94511C0C94511C11241FBECFEFD4E0BA
+:10387000DEBFCDBF11E0A0E0B1E0E4EAFEE302C0AC
+:1038800005900D92A230B107D9F712E0A2E0B1E0A5
+:1038900001C01D92AD30B107E1F70E94ED1C0C9400
+:1038A000511F0C94001C482F10920A0280E08417CC
+:1038B000E0F4582F2D9A28EE33E080E991E001974B
+:1038C000F1F721503040C9F72D9828EE33E080E918
+:1038D00091E00197F1F721503040C9F7852F8F5FB4
+:1038E000582F841738F380930A020895EF92FF92BD
+:1038F0000F931F93EE24FF2487018091C00087FD62
+:1039000017C00894E11CF11C011D111D81E0E8168F
+:1039100082E1F8068AE7080780E0180770F3E09173
+:103920000201F091030109958091C00087FFE9CF62
+:103930008091C600992787FD90951F910F91FF9068
+:10394000EF900895982F8091C00085FFFCCF909351
+:10395000C60008950E94761C803271F080910401A7
+:103960008F5F80930401853009F00895E091020192
+:10397000F09103010995089584E10E94A21C80E161
+:103980000E94A21C0895CF93C82F0E94761C8032FB
+:1039900041F0809104018F5F80930401853081F4B0
+:1039A0000AC084E10E94A21C8C2F0E94A21C80E10C
+:1039B0000E94A21C05C0E0910201F091030109954B
+:1039C000CF910895CF93C82FC150CF3F21F00E94CF
+:1039D000761CC150E0F7CF910895CFEFD4E0DEBF61
+:1039E000CDBF000083E38093C4001092C50088E13E
+:1039F0008093C10086E08093C2005098589A259A1F
+:103A000083E00E94531C0E94761C8033B1F1813305
+:103A1000B9F1803409F455C0813409F45BC08234B3
+:103A200009F46DC0853409F470C0803531F18235F8
+:103A300021F1813511F1853509F46BC0863509F422
+:103A400073C0843609F47AC0843709F4CEC0853750
+:103A500009F429C1863709F44AC0809104018F5FB7
+:103A600080930401853079F6E0910201F091030121
+:103A700009950E94761C803351F60E94AA1CC3CF80
+:103A80000E94761CC82F803241F784E10E94A21C5C
+:103A900081E40E94A21C86E50E94A21C82E50E948D
+:103AA000A21C8C2F0E94A21C89E40E94A21C83E508
+:103AB0000E94A21C80E50E94A21C80E10E94A21C20
+:103AC000A2CF0E94761C8638C0F20E94761C0E940B
+:103AD000AA1C99CF0E94761C803809F486C18138CF
+:103AE00009F487C1823809F488C1883921F080E05F
+:103AF0000E94C31C88CF83E00E94C31C84CF84E152
+:103B00000E94E21C0E94AA1C7ECF85E00E94E21C5B
+:103B1000F9CF0E94761C809306010E94761C809348
+:103B200007010E94AA1C6FCF0E94761C803309F403
+:103B3000CAC083E00E94E21C80E0DACF0E94761CBB
+:103B4000809309020E94761C8093080280910C02E7
+:103B50008E7F80930C020E94761C853409F4C4C0C9
+:103B600000E010E0809108029091090218161906F1
+:103B700070F4C8E0D1E00E94761C89930F5F1F4F5C
+:103B8000809108029091090208171907A0F30E947A
+:103B9000761C803209F061CF80910C0280FFAEC0AC
+:103BA000E0910601F0910701EE0FFF1F00E010E029
+:103BB00020910802309109021216130680F4A8E041
+:103BC000B1E0F999FECFF2BDE1BD8D9180BDFA9AC9
+:103BD000F99A31960F5F1F4F0217130790F3F09376
+:103BE0000701E093060184E166CF0E94761C809372
+:103BF00009020E94761C8093080280910601909130
+:103C00000701880F991F90930701809306010E9476
+:103C1000761C853409F46EC080910C028E7F8093EF
+:103C20000C020E94761C803209F0EDCE84E10E94E5
+:103C3000A21C00E010E02091080230910902121647
+:103C4000130608F03ACFE0910601F0910701809148
+:103C50000C0280FF1FC0F999FECFF2BDE1BDF89ABA
+:103C600080B50E94A21CE0910601F09107013196F7
+:103C7000F0930701E09306012091080230910902B8
+:103C80000F5F1F4F0217130708F017CF80910C0228
+:103C900080FDE1CF869580FFB4C03196F093070197
+:103CA000E0930601EDCF0E94761C803209F0D5CE5C
+:103CB00084E10E94A21C8EE10E94A21C84E90E9461
+:103CC000A21C86E0F8CE0E94761C0E94761CC82FAB
+:103CD0000E94761CCC2309F47CC0C13009F47DC05D
+:103CE00086E00E94C31C8FCE80910C02816080937D
+:103CF0000C0236CF80910C02816091CF8091070138
+:103D000087FD6FC010920B02809106019091070110
+:103D1000880F991F909307018093060180910802F4
+:103D200080FF09C08091080290910902019690934A
+:103D3000090280930802F894F999FECF1127E091C7
+:103D40000601F0910701C8E0D1E08091080290914E
+:103D50000902103091F40091570001700130D9F33D
+:103D600003E000935700E89500915700017001307F
+:103D7000D9F301E100935700E8950990199000915B
+:103D8000570001700130D9F301E000935700E89526
+:103D90001395103498F011270091570001700130ED
+:103DA000D9F305E000935700E895009157000170A2
+:103DB0000130D9F301E100935700E895329602975C
+:103DC00009F0C7CF103011F00296E5CF112484E13D
+:103DD00072CE8EE10E94C31C16CE84E90E94C31CE1
+:103DE00012CE81E080930B028FCF82E00E94C31C31
+:103DF0000ACE81E00E94C31C06CE80E10E94C31C53
+:103E000002CE84910E94A21C2091080230910902E6
+:103E1000E0910601F091070140CFCF930E94761CFC
+:103E2000C82F0E94A21CC13614F0C75503C0C0336E
+:103E30000CF0C0538C2F992787FD9095CF91089552
+:103E40000F931F930E940D1F082F112707FD109538
+:103E500002951295107F1027007F10270E940D1FDA
+:103E6000800F992787FD90951F910F910895CF930B
+:103E7000C82F85958595859585958A3034F0895A22
+:103E8000CF70CA3034F0C95A05C0805DCF70CA30D7
+:103E9000D4F7C05D0E94A21C8C2F0E94A21CCF915F
+:043EA0000895FFCFB3
+:023EA40080009C
+:0400000300003800C1
+:00000001FF
diff --git a/bootloaders/atmega/ATmegaBOOT_168_pro_8MHz.hex b/bootloaders/atmega/ATmegaBOOT_168_pro_8MHz.hex
new file mode 100644
index 0000000..994e478
--- /dev/null
+++ b/bootloaders/atmega/ATmegaBOOT_168_pro_8MHz.hex
@@ -0,0 +1,126 @@
+:103800000C94341C0C94511C0C94511C0C94511CA1
+:103810000C94511C0C94511C0C94511C0C94511C74
+:103820000C94511C0C94511C0C94511C0C94511C64
+:103830000C94511C0C94511C0C94511C0C94511C54
+:103840000C94511C0C94511C0C94511C0C94511C44
+:103850000C94511C0C94511C0C94511C0C94511C34
+:103860000C94511C0C94511C11241FBECFEFD4E0BA
+:10387000DEBFCDBF11E0A0E0B1E0EEEAFFE302C0A1
+:1038800005900D92A230B107D9F712E0A2E0B1E0A5
+:1038900001C01D92AD30B107E1F70E94331D0C94B9
+:1038A000D51F0C94001C982F9595959595959595F9
+:1038B000905D8F708A307CF0282F295A8091C0004B
+:1038C00085FFFCCF9093C6008091C00085FFFCCFA0
+:1038D0002093C6000895282F205DF0CF982F809167
+:1038E000C00085FFFCCF9093C6000895EF92FF9231
+:1038F0000F931F93EE24FF2487018091C00087FD62
+:1039000017C00894E11CF11C011D111D81E2E8168D
+:1039100081EAF80687E0080780E0180770F3E09175
+:103920000401F091050109958091C00087FFE9CF5E
+:103930008091C6001F910F91FF90EF9008950E9413
+:10394000761C982F8091C00085FFFCCF9093C60015
+:1039500091362CF490330CF09053892F089597559D
+:10396000892F08951F930E949F1C182F0E949F1C4F
+:103970001295107F810F1F9108951F93182F882390
+:1039800021F00E94761C1150E1F71F9108951F93BA
+:10399000182F0E94761C803249F0809103018F5FBE
+:1039A000809303018530C1F01F9108958091C0007C
+:1039B00085FFFCCF84E18093C6008091C00085FF25
+:1039C000FCCF1093C6008091C00085FFFCCF80E142
+:1039D0008093C6001F910895E0910401F0910501C4
+:1039E00009951F9108950E94761C803241F08091C4
+:1039F00003018F5F80930301853081F008958091EA
+:103A0000C00085FFFCCF84E18093C6008091C00098
+:103A100085FFFCCF80E18093C6000895E09104010A
+:103A2000F09105010995089510920A028823D1F0BA
+:103A300090E048EC50E02D9A28EE33E0FA013197FF
+:103A4000F1F721503040D1F72D9828EE33E0FA01FC
+:103A50003197F1F721503040D1F79F5F981758F315
+:103A600080930A0208953F924F925F926F927F92E5
+:103A70008F929F92AF92BF92CF92DF92EF92FF927E
+:103A80000F931F93CF93DF9394B714BE8091600080
+:103A90008861809360001092600091FF0CC289E100
+:103AA0008093C4001092C50088E18093C10086E035
+:103AB0008093C2005098589A259A81E00E94141D64
+:103AC00044E1F42E3EE1E32E24E9D22E96E0C92E05
+:103AD00080E1B82EAA24A39401E4902E16E5812E4D
+:103AE000B2E57B2EA0E26A2EF9E45F2EE3E54E2ECE
+:103AF00070E5372E0E94761C8033B9F18133C1F115
+:103B0000803409F470C0813409F477C0823409F438
+:103B100086C0853409F489C0803539F1823529F1B0
+:103B2000813509F4AFC1853509F485C0863509F4BE
+:103B30008DC0843609F435C1843709F4C1C0853796
+:103B400009F490C0863709F466C0809103018F5F45
+:103B500080930301853071F6E0910401F091050135
+:103B600009950E94761C803349F60E94F31CC2CF4F
+:103B70000E94761C803249F78091C00085FFFCCFFF
+:103B8000F092C6008091C00085FFFCCF9092C600E5
+:103B90008091C00085FFFCCF8092C6008091C0005C
+:103BA00085FFFCCF7092C6008091C00085FFFCCFDE
+:103BB0006092C6008091C00085FFFCCF5092C60085
+:103BC0008091C00085FFFCCF4092C6008091C0006C
+:103BD00085FFFCCF3092C6008091C00085FFFCCFEE
+:103BE000B092C60087CF0E94761C863808F4BDCFFD
+:103BF0000E94761C0E94F31C7DCF0E94761C8038A8
+:103C000009F45AC0813809F453C0823809F440C11C
+:103C1000883909F449C080E00E94C71C6BCF84E159
+:103C20000E94BD1C0E94F31C65CF85E00E94BD1C54
+:103C30000E94F31C5FCF0E94761C809306010E94B5
+:103C4000761C809307010E94F31C54CF0E94761CBF
+:103C5000803309F421C183E00E94BD1C80E00E94F2
+:103C6000C71C48CF0E94761C803209F06ECF80912D
+:103C7000C00085FFFCCFF092C6008091C00085FF98
+:103C8000FCCFE092C6008091C00085FFFCCFD092AF
+:103C9000C6008091C00085FFFCCFC092C600809115
+:103CA000C00085FFFCCF9CCF83E00E94C71C22CFC1
+:103CB00081E00E94C71C1ECF82E00E94C71C1ACF61
+:103CC0000E94761C809309020E94761C8093080251
+:103CD0008091060190910701880F991F9093070129
+:103CE000809306010E94761C853409F4C5C080913A
+:103CF0000C028E7F80930C020E94761C803209F0A9
+:103D0000F9CE8091C00085FFFCCFF092C600609193
+:103D10000802709109026115710591F140E050E0CF
+:103D200080910C02A82FA170B82FB27010C0BB23D5
+:103D300061F1E0910601F09107013196F0930701DE
+:103D4000E09306014F5F5F4F46175707C8F4AA2359
+:103D500071F3F999FECF209106013091070132BD30
+:103D600021BDF89A90B58091C00085FFFCCF90935B
+:103D7000C6002F5F3F4F3093070120930601E2CF2B
+:103D80008091C00085FFFCCF2BCFE0910601F09120
+:103D9000070194918091C00085FFFCCF9093C600ED
+:103DA000CCCF0E94761C809309020E94761C8093DF
+:103DB000080280910C028E7F80930C020E94761C78
+:103DC000853429F480910C02816080930C028091EB
+:103DD000080290910902892B89F000E010E00E940E
+:103DE000761CF801E85FFE4F80830F5F1F4F8091C4
+:103DF0000802909109020817190788F30E94761C9F
+:103E0000803209F0A2CE80910C0280FF62C0409106
+:103E1000060150910701440F551F5093070140932D
+:103E20000601609108027091090261157105C9F0DF
+:103E3000E8E0F1E09A01DB01AE0FBF1FF999FECF78
+:103E400032BD21BD819180BDFA9AF99A2F5F3F4F13
+:103E5000EA17FB0799F7460F571F50930701409346
+:103E600006018091C00085FFFCCFF092C6008091D2
+:103E7000C00085FFFCCFB4CE80910C02816080939E
+:103E80000C023ACF0E94F31C88E080936000FFCFC1
+:103E900080E10E94C71C2ECE0E94761C0E94761CD8
+:103EA000182F0E94761C112381F0113051F086E00A
+:103EB0000E94C71C1FCEE0910401F09105010995F5
+:103EC000EECD84E90E94C71C15CE8EE10E94C71C6E
+:103ED00011CE809107018823880F880B8A21809357
+:103EE0000B028091060190910701880F991F909312
+:103EF0000701809306018091080280FF09C080912C
+:103F00000802909109020196909309028093080299
+:103F1000F894F999FECF1127E0910601F09107017D
+:103F2000C8E0D1E08091080290910902103091F42C
+:103F30000091570001700130D9F303E0009357005E
+:103F4000E8950091570001700130D9F301E1009329
+:103F50005700E895099019900091570001700130C1
+:103F6000D9F301E000935700E8951395103498F0C9
+:103F700011270091570001700130D9F305E000933B
+:103F80005700E8950091570001700130D9F301E125
+:103F900000935700E8953296029709F0C7CF10308A
+:0E3FA00011F00296E5CF11245CCFF894FFCF0C
+:023FAE00800091
+:0400000300003800C1
+:00000001FF
diff --git a/bootloaders/atmega/Makefile b/bootloaders/atmega/Makefile
new file mode 100755
index 0000000..0fd54db
--- /dev/null
+++ b/bootloaders/atmega/Makefile
@@ -0,0 +1,224 @@
+# Makefile for ATmegaBOOT
+# E.Lins, 18.7.2005
+# $Id$
+#
+# Instructions
+#
+# To make bootloader .hex file:
+# make diecimila
+# make lilypad
+# make ng
+# etc...
+#
+# To burn bootloader .hex file:
+# make diecimila_isp
+# make lilypad_isp
+# make ng_isp
+# etc...
+
+# program name should not be changed...
+PROGRAM = ATmegaBOOT_168
+
+# enter the parameters for the avrdude isp tool
+ISPTOOL = stk500v2
+ISPPORT = usb
+ISPSPEED = -b 115200
+
+MCU_TARGET = atmega168
+LDSECTION = --section-start=.text=0x3800
+
+# the efuse should really be 0xf8; since, however, only the lower
+# three bits of that byte are used on the atmega168, avrdude gets
+# confused if you specify 1's for the higher bits, see:
+# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
+#
+# similarly, the lock bits should be 0xff instead of 0x3f (to
+# unlock the bootloader section) and 0xcf instead of 0x0f (to
+# lock it), but since the high two bits of the lock byte are
+# unused, avrdude would get confused.
+
+ISPFUSES = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
+-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
+ISPFLASH = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
+-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f:m
+
+STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
+STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
+-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt
+STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt
+
+
+OBJ = $(PROGRAM).o
+OPTIMIZE = -O2
+
+DEFS =
+LIBS =
+
+CC = avr-gcc
+
+# Override is only needed by avr-lib build system.
+
+override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
+override LDFLAGS = -Wl,$(LDSECTION)
+#override LDFLAGS = -Wl,-Map,$(PROGRAM).map,$(LDSECTION)
+
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+
+all:
+
+lilypad: TARGET = lilypad
+lilypad: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>1' '-DNUM_LED_FLASHES=3'
+lilypad: AVR_FREQ = 8000000L
+lilypad: $(PROGRAM)_lilypad.hex
+
+lilypad_isp: lilypad
+lilypad_isp: TARGET = lilypad
+lilypad_isp: HFUSE = DD
+lilypad_isp: LFUSE = E2
+lilypad_isp: EFUSE = 00
+lilypad_isp: isp
+
+lilypad_resonator: TARGET = lilypad_resonator
+lilypad_resonator: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=3'
+lilypad_resonator: AVR_FREQ = 8000000L
+lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
+
+lilypad_resonator_isp: lilypad_resonator
+lilypad_resonator_isp: TARGET = lilypad_resonator
+lilypad_resonator_isp: HFUSE = DD
+lilypad_resonator_isp: LFUSE = C6
+lilypad_resonator_isp: EFUSE = 00
+lilypad_resonator_isp: isp
+
+pro8: TARGET = pro_8MHz
+pro8: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS'
+pro8: AVR_FREQ = 8000000L
+pro8: $(PROGRAM)_pro_8MHz.hex
+
+pro8_isp: pro8
+pro8_isp: TARGET = pro_8MHz
+pro8_isp: HFUSE = DD
+pro8_isp: LFUSE = C6
+pro8_isp: EFUSE = 00
+pro8_isp: isp
+
+pro16: TARGET = pro_16MHz
+pro16: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS'
+pro16: AVR_FREQ = 16000000L
+pro16: $(PROGRAM)_pro_16MHz.hex
+
+pro16_isp: pro16
+pro16_isp: TARGET = pro_16MHz
+pro16_isp: HFUSE = DD
+pro16_isp: LFUSE = C6
+pro16_isp: EFUSE = 00
+pro16_isp: isp
+
+pro20: TARGET = pro_20mhz
+pro20: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS'
+pro20: AVR_FREQ = 20000000L
+pro20: $(PROGRAM)_pro_20mhz.hex
+
+pro20_isp: pro20
+pro20_isp: TARGET = pro_20mhz
+pro20_isp: HFUSE = DD
+pro20_isp: LFUSE = C6
+pro20_isp: EFUSE = 00
+pro20_isp: isp
+
+diecimila: TARGET = diecimila
+diecimila: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1'
+diecimila: AVR_FREQ = 16000000L
+diecimila: $(PROGRAM)_diecimila.hex
+
+diecimila_isp: diecimila
+diecimila_isp: TARGET = diecimila
+diecimila_isp: HFUSE = DD
+diecimila_isp: LFUSE = FF
+diecimila_isp: EFUSE = 00
+diecimila_isp: isp
+
+ng: TARGET = ng
+ng: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>1' '-DNUM_LED_FLASHES=3'
+ng: AVR_FREQ = 16000000L
+ng: $(PROGRAM)_ng.hex
+
+ng_isp: ng
+ng_isp: TARGET = ng
+ng_isp: HFUSE = DD
+ng_isp: LFUSE = FF
+ng_isp: EFUSE = 00
+ng_isp: isp
+
+atmega328: TARGET = atmega328
+atmega328: MCU_TARGET = atmega328p
+atmega328: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600
+atmega328: AVR_FREQ = 16000000L
+atmega328: LDSECTION = --section-start=.text=0x7800
+atmega328: $(PROGRAM)_atmega328.hex
+
+atmega328_isp: atmega328
+atmega328_isp: TARGET = atmega328
+atmega328_isp: MCU_TARGET = atmega328p
+atmega328_isp: HFUSE = DA
+atmega328_isp: LFUSE = FF
+atmega328_isp: EFUSE = 05
+atmega328_isp: isp
+
+atmega328_pro8: TARGET = atmega328_pro_8MHz
+atmega328_pro8: MCU_TARGET = atmega328p
+atmega328_pro8: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -DDOUBLE_SPEED
+atmega328_pro8: AVR_FREQ = 8000000L
+atmega328_pro8: LDSECTION = --section-start=.text=0x7800
+atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
+
+atmega328_pro8_isp: atmega328_pro8
+atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
+atmega328_pro8_isp: MCU_TARGET = atmega328p
+atmega328_pro8_isp: HFUSE = DA
+atmega328_pro8_isp: LFUSE = FF
+atmega328_pro8_isp: EFUSE = 05
+atmega328_pro8_isp: isp
+
+mega: TARGET = atmega1280
+mega: MCU_TARGET = atmega1280
+mega: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=0' -DBAUD_RATE=57600
+mega: AVR_FREQ = 16000000L
+mega: LDSECTION = --section-start=.text=0x1F000
+mega: $(PROGRAM)_atmega1280.hex
+
+mega_isp: mega
+mega_isp: TARGET = atmega1280
+mega_isp: MCU_TARGET = atmega1280
+mega_isp: HFUSE = DA
+mega_isp: LFUSE = FF
+mega_isp: EFUSE = F5
+mega_isp: isp
+
+isp: $(TARGET)
+ $(ISPFUSES)
+ $(ISPFLASH)
+
+isp-stk500: $(PROGRAM)_$(TARGET).hex
+ $(STK500-1)
+ $(STK500-2)
+
+%.elf: $(OBJ)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+clean:
+ rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
+
+%.lst: %.elf
+ $(OBJDUMP) -h -S $< > $@
+
+%.hex: %.elf
+ $(OBJCOPY) -j .text -j .data -O ihex $< $@
+
+%.srec: %.elf
+ $(OBJCOPY) -j .text -j .data -O srec $< $@
+
+%.bin: %.elf
+ $(OBJCOPY) -j .text -j .data -O binary $< $@
+
diff --git a/bootloaders/atmega8/ATmegaBOOT.c b/bootloaders/atmega8/ATmegaBOOT.c
new file mode 100755
index 0000000..17977e6
--- /dev/null
+++ b/bootloaders/atmega8/ATmegaBOOT.c
@@ -0,0 +1,507 @@
+/**********************************************************/
+/* Serial Bootloader for Atmel mega8 AVR Controller */
+/* */
+/* ATmegaBOOT.c */
+/* */
+/* Copyright (c) 2003, Jason P. Kyle */
+/* */
+/* Hacked by DojoCorp - ZGZ - MMX - IVR */
+/* Hacked by David A. Mellis */
+/* */
+/* 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 */
+/* (at your option) 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. */
+/* */
+/* You should have received a copy of the GNU General */
+/* Public License along with this program; if not, write */
+/* to the Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/* */
+/* Licence can be viewed at */
+/* http://www.fsf.org/licenses/gpl.txt */
+/* */
+/* Target = Atmel AVR m8 */
+/**********************************************************/
+
+#include <inttypes.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/eeprom.h>
+#include <avr/interrupt.h>
+#include <avr/delay.h>
+
+//#define F_CPU 16000000
+
+/* We, Malmoitians, like slow interaction
+ * therefore the slow baud rate ;-)
+ */
+//#define BAUD_RATE 9600
+
+/* 6.000.000 is more or less 8 seconds at the
+ * speed configured here
+ */
+//#define MAX_TIME_COUNT 6000000
+#define MAX_TIME_COUNT (F_CPU>>1)
+///#define MAX_TIME_COUNT_MORATORY 1600000
+
+/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */
+#define HW_VER 0x02
+#define SW_MAJOR 0x01
+#define SW_MINOR 0x12
+
+// AVR-GCC compiler compatibility
+// avr-gcc compiler v3.1.x and older doesn't support outb() and inb()
+// if necessary, convert outb and inb to outp and inp
+#ifndef outb
+ #define outb(sfr,val) (_SFR_BYTE(sfr) = (val))
+#endif
+#ifndef inb
+ #define inb(sfr) _SFR_BYTE(sfr)
+#endif
+
+/* defines for future compatibility */
+#ifndef cbi
+ #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+#endif
+#ifndef sbi
+ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#endif
+
+/* Adjust to suit whatever pin your hardware uses to enter the bootloader */
+#define eeprom_rb(addr) eeprom_read_byte ((uint8_t *)(addr))
+#define eeprom_rw(addr) eeprom_read_word ((uint16_t *)(addr))
+#define eeprom_wb(addr, val) eeprom_write_byte ((uint8_t *)(addr), (uint8_t)(val))
+
+/* Onboard LED is connected to pin PB5 */
+#define LED_DDR DDRB
+#define LED_PORT PORTB
+#define LED_PIN PINB
+#define LED PINB5
+
+
+#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :(
+#define SIG2 0x93
+#define SIG3 0x07
+#define PAGE_SIZE 0x20U //32 words
+
+
+void putch(char);
+char getch(void);
+void getNch(uint8_t);
+void byte_response(uint8_t);
+void nothing_response(void);
+
+union address_union {
+ uint16_t word;
+ uint8_t byte[2];
+} address;
+
+union length_union {
+ uint16_t word;
+ uint8_t byte[2];
+} length;
+
+struct flags_struct {
+ unsigned eeprom : 1;
+ unsigned rampz : 1;
+} flags;
+
+uint8_t buff[256];
+//uint8_t address_high;
+
+uint8_t pagesz=0x80;
+
+uint8_t i;
+//uint8_t bootuart0=0,bootuart1=0;
+
+
+void (*app_start)(void) = 0x0000;
+
+int main(void)
+{
+ uint8_t ch,ch2;
+ uint16_t w;
+
+ //cbi(BL_DDR,BL);
+ //sbi(BL_PORT,BL);
+
+ asm volatile("nop\n\t");
+
+ /* check if flash is programmed already, if not start bootloader anyway */
+ //if(pgm_read_byte_near(0x0000) != 0xFF) {
+
+ /* check if bootloader pin is set low */
+ //if(bit_is_set(BL_PIN,BL)) app_start();
+ //}
+
+ /* initialize UART(s) depending on CPU defined */
+ /* m8 */
+ UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate
+ UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
+ UCSRB = (1<<RXEN)|(1<<TXEN); // enable Rx & Tx
+ UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // config USART; 8N1
+
+ //UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ //UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ //UCSRA = 0x00;
+ //UCSRC = 0x86;
+ //UCSRB = _BV(TXEN)|_BV(RXEN);
+
+
+ /* this was giving uisp problems, so I removed it; without it, the boot
+ works on with uisp and avrdude on the mac (at least). */
+ //putch('\0');
+
+ //uint32_t l;
+ //uint32_t time_count;
+ //time_count=0;
+
+ /* set LED pin as output */
+ sbi(LED_DDR,LED);
+ for (i = 0; i < 16; i++) {
+ outb(LED_PORT, inb(LED_PORT) ^ _BV(LED));
+ _delay_loop_2(0);
+ }
+
+ //for (l=0; l<40000000; l++)
+ //outb(LED_PORT, inb(LED_PORT) ^= _BV(LED));
+
+ /* flash onboard LED three times to signal entering of bootloader */
+ //for(i=0; i<3; ++i) {
+ //for(l=0; l<40000000; ++l);
+ //sbi(LED_PORT,LED);
+ //for(l=0; l<40000000; ++l);
+ //cbi(LED_PORT,LED);
+ //}
+
+ /* see comment at previous call to putch() */
+ //putch('\0'); // this line is needed for the synchronization of the programmer
+
+ /* forever */
+ for (;;) {
+ //if((inb(UCSRA) & _BV(RXC))){
+ /* get character from UART */
+ ch = getch();
+
+ /* A bunch of if...else if... gives smaller code than switch...case ! */
+
+ /* Hello is anyone home ? */
+ if(ch=='0') {
+ nothing_response();
+ }
+
+ /* Request programmer ID */
+ /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry */
+ /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares. */
+ else if(ch=='1') {
+ if (getch() == ' ') {
+ putch(0x14);
+ putch('A');
+ putch('V');
+ putch('R');
+ putch(' ');
+ putch('I');
+ putch('S');
+ putch('P');
+ putch(0x10);
+ }
+ }
+
+ /* AVR ISP/STK500 board commands DON'T CARE so default nothing_response */
+ else if(ch=='@') {
+ ch2 = getch();
+ if (ch2>0x85) getch();
+ nothing_response();
+ }
+
+ /* AVR ISP/STK500 board requests */
+ else if(ch=='A') {
+ ch2 = getch();
+ if(ch2==0x80) byte_response(HW_VER); // Hardware version
+ else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version
+ else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version
+ //else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56
+ else byte_response(0x00); // Covers various unnecessary responses we don't care about
+ }
+
+ /* Device Parameters DON'T CARE, DEVICE IS FIXED */
+ else if(ch=='B') {
+ getNch(20);
+ nothing_response();
+ }
+
+ /* Parallel programming stuff DON'T CARE */
+ else if(ch=='E') {
+ getNch(5);
+ nothing_response();
+ }
+
+ /* Enter programming mode */
+ else if(ch=='P') {
+ nothing_response();
+ // FIXME: modified only here by DojoCorp, Mumbai, India, 20050626
+ //time_count=0; // exted the delay once entered prog.mode
+ }
+
+ /* Leave programming mode */
+ else if(ch=='Q') {
+ nothing_response();
+ //time_count=MAX_TIME_COUNT_MORATORY; // once the programming is done,
+ // we should start the application
+ // but uisp has problems with this,
+ // therefore we just change the times
+ // and give the programmer 1 sec to react
+ }
+
+ /* Erase device, don't care as we will erase one page at a time anyway. */
+ else if(ch=='R') {
+ nothing_response();
+ }
+
+ /* Set address, little endian. EEPROM in bytes, FLASH in words */
+ /* Perhaps extra address bytes may be added in future to support > 128kB FLASH. */
+ /* This might explain why little endian was used here, big endian used everywhere else. */
+ else if(ch=='U') {
+ address.byte[0] = getch();
+ address.byte[1] = getch();
+ nothing_response();
+ }
+
+ /* Universal SPI programming command, disabled. Would be used for fuses and lock bits. */
+ else if(ch=='V') {
+ getNch(4);
+ byte_response(0x00);
+ }
+
+ /* Write memory, length is big endian and is in bytes */
+ else if(ch=='d') {
+ length.byte[1] = getch();
+ length.byte[0] = getch();
+ flags.eeprom = 0;
+ if (getch() == 'E') flags.eeprom = 1;
+ for (w=0;w<length.word;w++) {
+ buff[w] = getch(); // Store data in buffer, can't keep up with serial data stream whilst programming pages
+ }
+ if (getch() == ' ') {
+ if (flags.eeprom) { //Write to EEPROM one byte at a time
+ for(w=0;w<length.word;w++) {
+ eeprom_wb(address.word,buff[w]);
+ address.word++;
+ }
+ } else { //Write to FLASH one page at a time
+ //if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME
+ //else address_high = 0x00;
+
+ //address.word = address.word << 1; //address * 2 -> byte location
+ //if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes
+ cli(); //Disable interrupts, just to be sure
+ while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete
+ asm volatile(
+ "clr r17 \n\t" //page_word_count
+ "lds r30,address \n\t" //Address of FLASH location (in words)
+ "lds r31,address+1 \n\t"
+ "lsl r30 \n\t" //address * 2 -> byte location
+ "rol r31 \n\t"
+ "ldi r28,lo8(buff) \n\t" //Start of buffer array in RAM
+ "ldi r29,hi8(buff) \n\t"
+ "lds r24,length \n\t" //Length of data to be written (in bytes)
+ "lds r25,length+1 \n\t"
+ "sbrs r24,0 \n\t" //Even up an odd number of bytes
+ "rjmp length_loop \n\t"
+ "adiw r24,1 \n\t"
+ "length_loop: \n\t" //Main loop, repeat for number of words in block
+ "cpi r17,0x00 \n\t" //If page_word_count=0 then erase page
+ "brne no_page_erase \n\t"
+ "rcall wait_spm \n\t"
+// "wait_spm1: \n\t"
+// "lds r16,%0 \n\t" //Wait for previous spm to complete
+// "andi r16,1 \n\t"
+// "cpi r16,1 \n\t"
+// "breq wait_spm1 \n\t"
+ "ldi r16,0x03 \n\t" //Erase page pointed to by Z
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+ "rcall wait_spm \n\t"
+// "wait_spm2: \n\t"
+// "lds r16,%0 \n\t" //Wait for previous spm to complete
+// "andi r16,1 \n\t"
+// "cpi r16,1 \n\t"
+// "breq wait_spm2 \n\t"
+ "ldi r16,0x11 \n\t" //Re-enable RWW section
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+ "no_page_erase: \n\t"
+ "ld r0,Y+ \n\t" //Write 2 bytes into page buffer
+ "ld r1,Y+ \n\t"
+
+ "rcall wait_spm \n\t"
+// "wait_spm3: \n\t"
+// "lds r16,%0 \n\t" //Wait for previous spm to complete
+// "andi r16,1 \n\t"
+// "cpi r16,1 \n\t"
+// "breq wait_spm3 \n\t"
+ "ldi r16,0x01 \n\t" //Load r0,r1 into FLASH page buffer
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+
+ "inc r17 \n\t" //page_word_count++
+ "cpi r17,%1 \n\t"
+ "brlo same_page \n\t" //Still same page in FLASH
+ "write_page: \n\t"
+ "clr r17 \n\t" //New page, write current one first
+ "rcall wait_spm \n\t"
+// "wait_spm4: \n\t"
+// "lds r16,%0 \n\t" //Wait for previous spm to complete
+// "andi r16,1 \n\t"
+// "cpi r16,1 \n\t"
+// "breq wait_spm4 \n\t"
+ "ldi r16,0x05 \n\t" //Write page pointed to by Z
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+ "rcall wait_spm \n\t"
+// "wait_spm5: \n\t"
+// "lds r16,%0 \n\t" //Wait for previous spm to complete
+// "andi r16,1 \n\t"
+// "cpi r16,1 \n\t"
+// "breq wait_spm5 \n\t"
+ "ldi r16,0x11 \n\t" //Re-enable RWW section
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+ "same_page: \n\t"
+ "adiw r30,2 \n\t" //Next word in FLASH
+ "sbiw r24,2 \n\t" //length-2
+ "breq final_write \n\t" //Finished
+ "rjmp length_loop \n\t"
+
+ "wait_spm: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm \n\t"
+ "ret \n\t"
+
+ "final_write: \n\t"
+ "cpi r17,0 \n\t"
+ "breq block_done \n\t"
+ "adiw r24,2 \n\t" //length+2, fool above check on length after short page write
+ "rjmp write_page \n\t"
+ "block_done: \n\t"
+ "clr __zero_reg__ \n\t" //restore zero register
+ : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31");
+
+ /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */
+ /* exit the bootloader without a power cycle anyhow */
+ }
+ putch(0x14);
+ putch(0x10);
+ }
+ }
+
+ /* Read memory block mode, length is big endian. */
+ else if(ch=='t') {
+ length.byte[1] = getch();
+ length.byte[0] = getch();
+ if (getch() == 'E') flags.eeprom = 1;
+ else {
+ flags.eeprom = 0;
+ address.word = address.word << 1; // address * 2 -> byte location
+ }
+ if (getch() == ' ') { // Command terminator
+ putch(0x14);
+ for (w=0;w < length.word;w++) { // Can handle odd and even lengths okay
+ if (flags.eeprom) { // Byte access EEPROM read
+ putch(eeprom_rb(address.word));
+ address.word++;
+ } else {
+ if (!flags.rampz) putch(pgm_read_byte_near(address.word));
+ address.word++;
+ }
+ }
+ putch(0x10);
+ }
+ }
+
+ /* Get device signature bytes */
+ else if(ch=='u') {
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(SIG1);
+ putch(SIG2);
+ putch(SIG3);
+ putch(0x10);
+ }
+ }
+
+ /* Read oscillator calibration byte */
+ else if(ch=='v') {
+ byte_response(0x00);
+ }
+// } else {
+// time_count++;
+// if (time_count>=MAX_TIME_COUNT) {
+// app_start();
+// }
+// }
+ } /* end of forever loop */
+}
+
+void putch(char ch)
+{
+ /* m8 */
+ while (!(inb(UCSRA) & _BV(UDRE)));
+ outb(UDR,ch);
+}
+
+char getch(void)
+{
+ /* m8 */
+ uint32_t count = 0;
+ while(!(inb(UCSRA) & _BV(RXC))) {
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+ return (inb(UDR));
+}
+
+void getNch(uint8_t count)
+{
+ uint8_t i;
+ for(i=0;i<count;i++) {
+ /* m8 */
+ //while(!(inb(UCSRA) & _BV(RXC)));
+ //inb(UDR);
+ getch(); // need to handle time out
+ }
+}
+
+void byte_response(uint8_t val)
+{
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(val);
+ putch(0x10);
+ }
+}
+
+void nothing_response(void)
+{
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(0x10);
+ }
+}
+
+/* end of file ATmegaBOOT.c */
+
+
+
diff --git a/bootloaders/atmega8/ATmegaBOOT.hex b/bootloaders/atmega8/ATmegaBOOT.hex
new file mode 100644
index 0000000..6190d48
--- /dev/null
+++ b/bootloaders/atmega8/ATmegaBOOT.hex
@@ -0,0 +1,66 @@
+:101C000012C02BC02AC029C028C027C026C025C0AA
+:101C100024C023C022C021C020C01FC01EC01DC0C0
+:101C20001CC01BC01AC011241FBECFE5D4E0DEBF0C
+:101C3000CDBF10E0A0E6B0E0E8EEFFE102C0059005
+:101C40000D92A236B107D9F711E0A2E6B0E001C0CB
+:101C50001D92AA36B107E1F74FC0D2CFEF92FF92A3
+:101C60000F931F93EE24FF24870113C00894E11CF7
+:101C7000F11C011D111D81E0E81682E1F8068AE7DA
+:101C8000080780E0180728F0E0916200F0916300F7
+:101C900009955F9BEBCF8CB1992787FD90951F919C
+:101CA0000F91FF90EF9008955D9BFECF8CB9089542
+:101CB000D5DF803221F484E1F7DF80E1F5DF08959C
+:101CC0001F93182FCBDF803231F484E1EDDF812FB9
+:101CD000EBDF80E1E9DF1F9108951F93CF93DF933E
+:101CE000182FC0E0D0E002C0B9DF2196C117E0F3A1
+:101CF000DF91CF911F910895CFE5D4E0DEBFCDBF36
+:101D0000000010BC83E389B988E18AB986E880BD08
+:101D1000BD9A1092680130E2E0E0F0E02FE088B375
+:101D2000832788BBCF010197F1F7215027FFF7CF19
+:101D300020E12093680192DF803381F1813399F4AF
+:101D40008DDF8032C1F784E1AFDF81E4ADDF86E56E
+:101D5000ABDF82E5A9DF80E2A7DF89E4A5DF83E5C9
+:101D6000A3DF80E5C7C0803429F478DF8638B0F07F
+:101D700075DF14C0813471F471DF803811F482E0B2
+:101D80001DC1813811F481E019C1823809F015C1F3
+:101D900082E114C1823421F484E19FDF89DFCBCF5B
+:101DA000853411F485E0F9CF8035C1F38135B1F385
+:101DB0008235A1F3853539F451DF809364004EDF1D
+:101DC00080936500EBCF863519F484E086DFF5C09B
+:101DD000843609F093C042DF809367013FDF809330
+:101DE0006601809169018E7F8093690137DF8534B8
+:101DF00029F480916901816080936901C0E0D0E09D
+:101E000006E610E005C02ADFF80181938F012196D4
+:101E10008091660190916701C817D907A0F31EDF72
+:101E2000803209F088CF8091690180FF1FC020E0D7
+:101E300030E0E6E6F0E012C0A0916400B0916500E9
+:101E40008191082EC5D08091640090916500019623
+:101E500090936500809364002F5F3F4F80916601EF
+:101E6000909167012817390738F343C0F894E19936
+:101E7000FECF1127E0916400F0916500EE0FFF1F87
+:101E8000C6E6D0E0809166019091670180FF01C0B5
+:101E90000196103051F422D003E000935700E895EA
+:101EA0001DD001E100935700E8950990199016D0D4
+:101EB00001E000935700E8951395103258F0112770
+:101EC0000DD005E000935700E89508D001E100939C
+:101ED0005700E8953296029739F0DBCF0091570012
+:101EE00001700130D9F30895103011F00296E7CF58
+:101EF000112484E1D9DE80E1D7DE1DCF843709F0DB
+:101F00004BC0ACDE80936701A9DE80936601A6DE3C
+:101F100090916901853421F49160909369010DC01D
+:101F20009E7F909369018091640090916500880F75
+:101F3000991F909365008093640090DE803209F0D1
+:101F4000FACE84E1B1DEC0E0D0E01EC0809169012C
+:101F500080FF07C0A0916400B091650031D0802D52
+:101F600008C081FD07C0E0916400F0916500E49134
+:101F70008E2F9ADE80916400909165000196909377
+:101F800065008093640021968091660190916701BD
+:101F9000C817D907D8F2AFCF853761F45FDE80323A
+:101FA00009F0C9CE84E180DE8EE17EDE83E97CDE4D
+:101FB00087E0A0CF863709F0BECE80E081DEBBCEC1
+:101FC000E199FECFBFBBAEBBE09A11960DB208956A
+:101FD000E199FECFBFBBAEBB0DBA11960FB6F89418
+:081FE000E29AE19A0FBE089598
+:021FE800800077
+:0400000300001C00DD
+:00000001FF
diff --git a/bootloaders/atmega8/Makefile b/bootloaders/atmega8/Makefile
new file mode 100644
index 0000000..8c0edd3
--- /dev/null
+++ b/bootloaders/atmega8/Makefile
@@ -0,0 +1,88 @@
+# Makefile for ATmegaBOOT
+# E.Lins, 2004-10-14
+
+# program name should not be changed...
+PROGRAM = ATmegaBOOT
+
+PRODUCT=atmega8
+
+# enter the parameters for the UISP isp tool
+ISPPARAMS = -dprog=stk500 -dserial=$(SERIAL) -dspeed=115200
+
+
+#DIRAVR = /usr/local/avr
+DIRAVRBIN = $(DIRAVR)/bin
+DIRAVRUTILS = $(DIRAVR)/utils/bin
+DIRINC = $(DIRAVR)/include
+DIRLIB = $(DIRAVR)/avr/lib
+
+
+MCU_TARGET = atmega8
+LDSECTION = --section-start=.text=0x1c00
+FUSE_L = 0xdf
+FUSE_H = 0xca
+ISPFUSES = $(DIRAVRBIN)/uisp -dpart=ATmega8 $(ISPPARAMS) --wr_fuse_l=$(FUSE_L) --wr_fuse_h=$(FUSE_H)
+ISPFLASH = $(DIRAVRBIN)/uisp -dpart=ATmega8 $(ISPPARAMS) --erase --upload if=$(PROGRAM).hex -v
+
+
+OBJ = $(PROGRAM).o
+OPTIMIZE = -Os
+
+DEFS = -DF_CPU=16000000 -DBAUD_RATE=19200
+LIBS =
+
+CC = $(DIRAVRBIN)/avr-gcc
+
+
+# Override is only needed by avr-lib build system.
+
+override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -D$(PRODUCT) $(DEFS) -I$(DIRINC)
+override LDFLAGS = -Wl,-Map,$(PROGRAM).map,$(LDSECTION)
+
+OBJCOPY = $(DIRAVRBIN)/avr-objcopy
+OBJDUMP = $(DIRAVRBIN)/avr-objdump
+SIZE = $(DIRAVRBIN)/avr-size
+
+all: $(PROGRAM).elf lst text asm size
+
+isp: $(PROGRAM).hex
+ $(ISPFUSES)
+ $(ISPFLASH)
+
+$(PROGRAM).elf: $(OBJ)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+clean:
+ rm -rf *.s
+ rm -rf *.o *.elf
+ rm -rf *.lst *.map
+
+asm: $(PROGRAM).s
+
+%.s: %.c
+ $(CC) -S $(CFLAGS) -g1 $^
+
+lst: $(PROGRAM).lst
+
+%.lst: %.elf
+ $(OBJDUMP) -h -S $< > $@
+
+size: $(PROGRAM).hex
+ $(SIZE) $^
+
+# Rules for building the .text rom images
+
+text: hex bin srec
+
+hex: $(PROGRAM).hex
+bin: $(PROGRAM).bin
+srec: $(PROGRAM).srec
+
+%.hex: %.elf
+ $(OBJCOPY) -j .text -j .data -O ihex $< $@
+
+%.srec: %.elf
+ $(OBJCOPY) -j .text -j .data -O srec $< $@
+
+%.bin: %.elf
+ $(OBJCOPY) -j .text -j .data -O binary $< $@
diff --git a/bootloaders/bt/ATmegaBOOT_168.c b/bootloaders/bt/ATmegaBOOT_168.c
new file mode 100644
index 0000000..a85dc9a
--- /dev/null
+++ b/bootloaders/bt/ATmegaBOOT_168.c
@@ -0,0 +1,1032 @@
+/**********************************************************/
+/* Serial Bootloader for Atmel megaAVR Controllers */
+/* */
+/* tested with ATmega8, ATmega128 and ATmega168 */
+/* should work with other mega's, see code for details */
+/* */
+/* ATmegaBOOT.c */
+/* */
+/* build: 050815 */
+/* date : 15.08.2005 */
+/* */
+/* 20060802: hacked for Arduino by D. Cuartielles */
+/* based on a previous hack by D. Mellis */
+/* and D. Cuartielles */
+/* */
+/* Monitor and debug functions were added to the original */
+/* code by Dr. Erik Lins, chip45.com. (See below) */
+/* */
+/* Thanks to Karl Pitrich for fixing a bootloader pin */
+/* problem and more informative LED blinking! */
+/* */
+/* For the latest version see: */
+/* http://www.chip45.com/ */
+/* */
+/* ------------------------------------------------------ */
+/* */
+/* based on stk500boot.c */
+/* Copyright (c) 2003, Jason P. Kyle */
+/* All rights reserved. */
+/* see avr1.org for original file and information */
+/* */
+/* 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 */
+/* (at your option) 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. */
+/* */
+/* You should have received a copy of the GNU General */
+/* Public License along with this program; if not, write */
+/* to the Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/* */
+/* Licence can be viewed at */
+/* http://www.fsf.org/licenses/gpl.txt */
+/* */
+/* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */
+/* m8515,m8535. ATmega161 has a very small boot block so */
+/* isn't supported. */
+/* */
+/* Tested with m128,m8,m163 - feel free to let me know */
+/* how/if it works for you. */
+/* */
+/**********************************************************/
+
+
+/* some includes */
+#include <inttypes.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+
+
+#define set_output(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#define set_input(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+
+
+#define high(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#define low(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+
+
+
+
+/* the current avr-libc eeprom functions do not support the ATmega168 */
+/* own eeprom write/read functions are used instead */
+#ifndef __AVR_ATmega168__
+#include <avr/eeprom.h>
+#endif
+
+/* define F_CPU according to AVR_FREQ set in Makefile */
+/* Is there a better way to pass such a parameter from Makefile to source code ? */
+
+#define F_CPU 16000000L
+
+#include <util/delay.h>
+
+
+/* 20060803: hacked by DojoCorp */
+/* set the waiting time for the bootloader */
+#define MAX_TIME_COUNT (F_CPU>>1)
+
+/* set the UART baud rate */
+/* 20060803: hacked by DojoCorp */
+#define BAUD_RATE 115200
+
+
+/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */
+/* never allow AVR Studio to do an update !!!! */
+#define HW_VER 0x02
+#define SW_MAJOR 0x01
+#define SW_MINOR 0x0f
+
+
+/* Adjust to suit whatever pin your hardware uses to enter the bootloader */
+/* ATmega128 has two UARTS so two pins are used to enter bootloader and select UART */
+/* BL0... means UART0, BL1... means UART1 */
+#ifdef __AVR_ATmega128__
+#define BL_DDR DDRF
+#define BL_PORT PORTF
+#define BL_PIN PINF
+#define BL0 PINF7
+#define BL1 PINF6
+#else
+/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */
+#define BL_DDR DDRD
+#define BL_PORT PORTD
+#define BL_PIN PIND
+#define BL PIND6
+#endif
+
+
+/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */
+/* if monitor functions are included, LED goes on after monitor was entered */
+#ifdef __AVR_ATmega128__
+/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128) */
+#define LED_DDR DDRB
+#define LED_PORT PORTB
+#define LED_PIN PINB
+#define LED PINB7
+#else
+/* Onboard LED is connected to pin PB2 (e.g. Crumb8, Crumb168) */
+#define LED_DDR DDRB
+#define LED_PORT PORTB
+#define LED_PIN PINB
+/* 20060803: hacked by DojoCorp, LED pin is B5 in Arduino */
+/* #define LED PINB2 */
+#define LED PINB5
+#endif
+
+
+/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */
+#ifdef __AVR_ATmega128__
+#define MONITOR
+#endif
+
+
+/* define various device id's */
+/* manufacturer byte is always the same */
+#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :(
+
+#if defined __AVR_ATmega128__
+#define SIG2 0x97
+#define SIG3 0x02
+#define PAGE_SIZE 0x80U //128 words
+
+#elif defined __AVR_ATmega64__
+#define SIG2 0x96
+#define SIG3 0x02
+#define PAGE_SIZE 0x80U //128 words
+
+#elif defined __AVR_ATmega32__
+#define SIG2 0x95
+#define SIG3 0x02
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega16__
+#define SIG2 0x94
+#define SIG3 0x03
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega8__
+#define SIG2 0x93
+#define SIG3 0x07
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega88__
+#define SIG2 0x93
+#define SIG3 0x0a
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega168__
+#define SIG2 0x94
+#define SIG3 0x06
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega162__
+#define SIG2 0x94
+#define SIG3 0x04
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega163__
+#define SIG2 0x94
+#define SIG3 0x02
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega169__
+#define SIG2 0x94
+#define SIG3 0x05
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega8515__
+#define SIG2 0x93
+#define SIG3 0x06
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega8535__
+#define SIG2 0x93
+#define SIG3 0x08
+#define PAGE_SIZE 0x20U //32 words
+#endif
+
+
+/* function prototypes */
+void putch(char);
+char getch(void);
+void getNch(uint8_t);
+void byte_response(uint8_t);
+void nothing_response(void);
+char gethex(void);
+void puthex(char);
+void flash_led(uint8_t);
+
+/* some variables */
+union address_union {
+ uint16_t word;
+ uint8_t byte[2];
+} address;
+
+union length_union {
+ uint16_t word;
+ uint8_t byte[2];
+} length;
+
+struct flags_struct {
+ unsigned eeprom : 1;
+ unsigned rampz : 1;
+} flags;
+
+uint8_t buff[256];
+uint8_t address_high;
+
+uint8_t pagesz=0x80;
+
+uint8_t i;
+uint8_t bootuart = 0;
+
+void (*app_start)(void) = 0x0000;
+
+
+/* main program starts here */
+int main(void)
+{
+ uint8_t ch,ch2;
+ uint16_t w;
+
+ asm volatile("nop\n\t");
+
+ /* set pin direction for bootloader pin and enable pullup */
+ /* for ATmega128, two pins need to be initialized */
+#ifdef __AVR_ATmega128__
+ BL_DDR &= ~_BV(BL0);
+ BL_DDR &= ~_BV(BL1);
+ BL_PORT |= _BV(BL0);
+ BL_PORT |= _BV(BL1);
+#else
+ BL_DDR &= ~_BV(BL);
+ BL_PORT |= _BV(BL);
+#endif
+
+
+#ifdef __AVR_ATmega128__
+ /* check which UART should be used for booting */
+ if(bit_is_clear(BL_PIN, BL0)) {
+ bootuart = 1;
+ }
+ else if(bit_is_clear(BL_PIN, BL1)) {
+ bootuart = 2;
+ }
+#endif
+
+ /* check if flash is programmed already, if not start bootloader anyway */
+ if(pgm_read_byte_near(0x0000) != 0xFF) {
+
+#ifdef __AVR_ATmega128__
+ /* no UART was selected, start application */
+ if(!bootuart) {
+ app_start();
+ }
+#else
+ /* check if bootloader pin is set low */
+ /* we don't start this part neither for the m8, nor m168 */
+ //if(bit_is_set(BL_PIN, BL)) {
+ // app_start();
+ // }
+#endif
+ }
+
+#ifdef __AVR_ATmega128__
+ /* no bootuart was selected, default to uart 0 */
+ if(!bootuart) {
+ bootuart = 1;
+ }
+#endif
+
+
+ /* initialize UART(s) depending on CPU defined */
+#ifdef __AVR_ATmega128__
+ if(bootuart == 1) {
+ UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSR0A = 0x00;
+ UCSR0C = 0x06;
+ UCSR0B = _BV(TXEN0)|_BV(RXEN0);
+ }
+ if(bootuart == 2) {
+ UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSR1A = 0x00;
+ UCSR1C = 0x06;
+ UCSR1B = _BV(TXEN1)|_BV(RXEN1);
+ }
+#elif defined __AVR_ATmega163__
+ UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSRA = 0x00;
+ UCSRB = _BV(TXEN)|_BV(RXEN);
+#elif defined __AVR_ATmega168__
+ UBRR0H = ((F_CPU / 16 + BAUD_RATE / 2) / BAUD_RATE - 1) >> 8;
+ UBRR0L = ((F_CPU / 16 + BAUD_RATE / 2) / BAUD_RATE - 1);
+
+
+ //UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ //UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSR0B = (1<<RXEN0) | (1<<TXEN0);
+ UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);
+#elif defined __AVR_ATmega8__
+ /* m8 */
+ UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate
+ UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
+ UCSRB = (1<<RXEN)|(1<<TXEN); // enable Rx & Tx
+ UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // config USART; 8N1
+#else
+ /* m16,m32,m169,m8515,m8535 */
+ UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSRA = 0x00;
+ UCSRC = 0x06;
+ UCSRB = _BV(TXEN)|_BV(RXEN);
+#endif
+
+ /* set LED pin as output */
+ LED_DDR |= _BV(LED);
+
+
+
+ set_output(DDRD,PIND7);
+ high(PORTD,PD7);
+ for (i = 0; i < 16; i++) {
+
+ _delay_loop_2(0);
+ }
+
+
+ low(PORTD,PD7);
+
+
+ /* flash onboard LED to signal entering of bootloader */
+#ifdef __AVR_ATmega128__
+ // 4x for UART0, 5x for UART1
+ flash_led(3 + bootuart);
+#else
+ flash_led(3);
+#endif
+
+ /* 20050803: by DojoCorp, this is one of the parts provoking the
+ system to stop listening, cancelled from the original */
+ //putch('\0');
+
+
+ //message("SET BT PAGEMODE 3 2000 1");
+putch('S');
+putch('E');
+putch('T');
+putch(' ');
+putch('B');
+putch('T');
+putch(' ');
+putch('P');
+putch('A');
+putch('G');
+putch('E');
+putch('M');
+putch('O');
+putch('D');
+putch('E');
+putch(' ');
+putch('3');
+putch(' ');
+putch('2');
+putch('0');
+putch('0');
+putch('0');
+putch(' ');
+putch('1');
+putch(0x0D);
+
+
+ //put_s("SET BT ROLE 0 f 7d00");
+ putch('S');
+ putch('E');
+ putch('T');
+ putch(' ');
+ putch('B');
+ putch('T');
+ putch(' ');
+ putch('R');
+ putch('O');
+ putch('L');
+ putch('E');
+ putch(' ');
+ putch('0');
+ putch(' ');
+ putch('f');
+ putch(' ');
+ putch('7');
+ putch('d');
+ putch('0');
+ putch('0');
+ putch(0x0D);
+
+
+
+
+
+
+ /* forever loop */
+ for (;;) {
+
+ /* get character from UART */
+ ch = getch();
+
+ /* A bunch of if...else if... gives smaller code than switch...case ! */
+
+ /* Hello is anyone home ? */
+ if(ch=='0') {
+ nothing_response();
+ }
+
+
+ /* Request programmer ID */
+ /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry */
+ /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares. */
+ else if(ch=='1') {
+ if (getch() == ' ') {
+ putch(0x14);
+ putch('A');
+ putch('V');
+ putch('R');
+ putch(' ');
+ putch('I');
+ putch('S');
+ putch('P');
+ putch(0x10);
+ }
+ }
+
+
+ /* AVR ISP/STK500 board commands DON'T CARE so default nothing_response */
+ else if(ch=='@') {
+ ch2 = getch();
+ if (ch2>0x85) getch();
+ nothing_response();
+ }
+
+
+ /* AVR ISP/STK500 board requests */
+ else if(ch=='A') {
+ ch2 = getch();
+ if(ch2==0x80) byte_response(HW_VER); // Hardware version
+ else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version
+ else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version
+ else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56
+ else byte_response(0x00); // Covers various unnecessary responses we don't care about
+ }
+
+
+ /* Device Parameters DON'T CARE, DEVICE IS FIXED */
+ else if(ch=='B') {
+ getNch(20);
+ nothing_response();
+ }
+
+
+ /* Parallel programming stuff DON'T CARE */
+ else if(ch=='E') {
+ getNch(5);
+ nothing_response();
+ }
+
+
+ /* Enter programming mode */
+ else if(ch=='P') {
+ nothing_response();
+ }
+
+
+ /* Leave programming mode */
+ else if(ch=='Q') {
+ nothing_response();
+ }
+
+
+ /* Erase device, don't care as we will erase one page at a time anyway. */
+ else if(ch=='R') {
+ nothing_response();
+ }
+
+
+ /* Set address, little endian. EEPROM in bytes, FLASH in words */
+ /* Perhaps extra address bytes may be added in future to support > 128kB FLASH. */
+ /* This might explain why little endian was used here, big endian used everywhere else. */
+ else if(ch=='U') {
+ address.byte[0] = getch();
+ address.byte[1] = getch();
+ nothing_response();
+ }
+
+
+ /* Universal SPI programming command, disabled. Would be used for fuses and lock bits. */
+ else if(ch=='V') {
+ getNch(4);
+ byte_response(0x00);
+ }
+
+
+ /* Write memory, length is big endian and is in bytes */
+ else if(ch=='d') {
+ length.byte[1] = getch();
+ length.byte[0] = getch();
+ flags.eeprom = 0;
+ if (getch() == 'E') flags.eeprom = 1;
+ for (w=0;w<length.word;w++) {
+ buff[w] = getch(); // Store data in buffer, can't keep up with serial data stream whilst programming pages
+ }
+ if (getch() == ' ') {
+ if (flags.eeprom) { //Write to EEPROM one byte at a time
+ for(w=0;w<length.word;w++) {
+#ifdef __AVR_ATmega168__
+ while(EECR & (1<<EEPE));
+ EEAR = (uint16_t)(void *)address.word;
+ EEDR = buff[w];
+ EECR |= (1<<EEMPE);
+ EECR |= (1<<EEPE);
+#else
+ eeprom_write_byte((void *)address.word,buff[w]);
+#endif
+ address.word++;
+ }
+ }
+ else { //Write to FLASH one page at a time
+ if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME
+ else address_high = 0x00;
+#ifdef __AVR_ATmega128__
+ RAMPZ = address_high;
+#endif
+ address.word = address.word << 1; //address * 2 -> byte location
+ /* if ((length.byte[0] & 0x01) == 0x01) length.word++; //Even up an odd number of bytes */
+ if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes
+ cli(); //Disable interrupts, just to be sure
+ // HACKME: EEPE used to be EEWE
+ while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete
+ asm volatile(
+ "clr r17 \n\t" //page_word_count
+ "lds r30,address \n\t" //Address of FLASH location (in bytes)
+ "lds r31,address+1 \n\t"
+ "ldi r28,lo8(buff) \n\t" //Start of buffer array in RAM
+ "ldi r29,hi8(buff) \n\t"
+ "lds r24,length \n\t" //Length of data to be written (in bytes)
+ "lds r25,length+1 \n\t"
+ "length_loop: \n\t" //Main loop, repeat for number of words in block
+ "cpi r17,0x00 \n\t" //If page_word_count=0 then erase page
+ "brne no_page_erase \n\t"
+ "wait_spm1: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm1 \n\t"
+ "ldi r16,0x03 \n\t" //Erase page pointed to by Z
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "wait_spm2: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm2 \n\t"
+
+ "ldi r16,0x11 \n\t" //Re-enable RWW section
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "no_page_erase: \n\t"
+ "ld r0,Y+ \n\t" //Write 2 bytes into page buffer
+ "ld r1,Y+ \n\t"
+
+ "wait_spm3: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm3 \n\t"
+ "ldi r16,0x01 \n\t" //Load r0,r1 into FLASH page buffer
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+
+ "inc r17 \n\t" //page_word_count++
+ "cpi r17,%1 \n\t"
+ "brlo same_page \n\t" //Still same page in FLASH
+ "write_page: \n\t"
+ "clr r17 \n\t" //New page, write current one first
+ "wait_spm4: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm4 \n\t"
+#ifdef __AVR_ATmega163__
+ "andi r30,0x80 \n\t" // m163 requires Z6:Z1 to be zero during page write
+#endif
+ "ldi r16,0x05 \n\t" //Write page pointed to by Z
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+ "ori r30,0x7E \n\t" // recover Z6:Z1 state after page write (had to be zero during write)
+#endif
+ "wait_spm5: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm5 \n\t"
+ "ldi r16,0x11 \n\t" //Re-enable RWW section
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "same_page: \n\t"
+ "adiw r30,2 \n\t" //Next word in FLASH
+ "sbiw r24,2 \n\t" //length-2
+ "breq final_write \n\t" //Finished
+ "rjmp length_loop \n\t"
+ "final_write: \n\t"
+ "cpi r17,0 \n\t"
+ "breq block_done \n\t"
+ "adiw r24,2 \n\t" //length+2, fool above check on length after short page write
+ "rjmp write_page \n\t"
+ "block_done: \n\t"
+ "clr __zero_reg__ \n\t" //restore zero register
+#if defined __AVR_ATmega168__
+ : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
+#else
+ : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
+#endif
+ );
+ /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */
+ /* exit the bootloader without a power cycle anyhow */
+ }
+ putch(0x14);
+ putch(0x10);
+ }
+ }
+
+
+ /* Read memory block mode, length is big endian. */
+ else if(ch=='t') {
+ length.byte[1] = getch();
+ length.byte[0] = getch();
+#if defined __AVR_ATmega128__
+ if (address.word>0x7FFF) flags.rampz = 1; // No go with m256, FIXME
+ else flags.rampz = 0;
+#endif
+ if (getch() == 'E') flags.eeprom = 1;
+ else {
+ flags.eeprom = 0;
+ address.word = address.word << 1; // address * 2 -> byte location
+ }
+ if (getch() == ' ') { // Command terminator
+ putch(0x14);
+ for (w=0;w < length.word;w++) { // Can handle odd and even lengths okay
+ if (flags.eeprom) { // Byte access EEPROM read
+#ifdef __AVR_ATmega168__
+ while(EECR & (1<<EEPE));
+ EEAR = (uint16_t)(void *)address.word;
+ EECR |= (1<<EERE);
+ putch(EEDR);
+#else
+ putch(eeprom_read_byte((void *)address.word));
+#endif
+ address.word++;
+ }
+ else {
+
+ if (!flags.rampz) putch(pgm_read_byte_near(address.word));
+#if defined __AVR_ATmega128__
+ else putch(pgm_read_byte_far(address.word + 0x10000));
+ // Hmmmm, yuck FIXME when m256 arrvies
+#endif
+ address.word++;
+ }
+ }
+ putch(0x10);
+ }
+ }
+
+
+ /* Get device signature bytes */
+ else if(ch=='u') {
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(SIG1);
+ putch(SIG2);
+ putch(SIG3);
+ putch(0x10);
+ }
+ }
+
+
+ /* Read oscillator calibration byte */
+ else if(ch=='v') {
+ byte_response(0x00);
+ }
+
+
+#ifdef MONITOR
+
+ /* here come the extended monitor commands by Erik Lins */
+
+ /* check for three times exclamation mark pressed */
+ else if(ch=='!') {
+ ch = getch();
+ if(ch=='!') {
+ ch = getch();
+ if(ch=='!') {
+
+#ifdef __AVR_ATmega128__
+ uint16_t extaddr;
+#endif
+ uint8_t addrl, addrh;
+
+#ifdef CRUMB128
+ PGM_P welcome = {"ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
+#elif defined PROBOMEGA128
+ PGM_P welcome = {"ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
+#elif defined SAVVY128
+ PGM_P welcome = {"ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
+#endif
+
+ /* turn on LED */
+ LED_DDR |= _BV(LED);
+ LED_PORT &= ~_BV(LED);
+
+ /* print a welcome message and command overview */
+ for(i=0; welcome[i] != '\0'; ++i) {
+ putch(welcome[i]);
+ }
+
+ /* test for valid commands */
+ for(;;) {
+ putch('\n');
+ putch('\r');
+ putch(':');
+ putch(' ');
+
+ ch = getch();
+ putch(ch);
+
+ /* toggle LED */
+ if(ch == 't') {
+ if(bit_is_set(LED_PIN,LED)) {
+ LED_PORT &= ~_BV(LED);
+ putch('1');
+ } else {
+ LED_PORT |= _BV(LED);
+ putch('0');
+ }
+
+ }
+
+ /* read byte from address */
+ else if(ch == 'r') {
+ ch = getch(); putch(ch);
+ addrh = gethex();
+ addrl = gethex();
+ putch('=');
+ ch = *(uint8_t *)((addrh << 8) + addrl);
+ puthex(ch);
+ }
+
+ /* write a byte to address */
+ else if(ch == 'w') {
+ ch = getch(); putch(ch);
+ addrh = gethex();
+ addrl = gethex();
+ ch = getch(); putch(ch);
+ ch = gethex();
+ *(uint8_t *)((addrh << 8) + addrl) = ch;
+
+ }
+
+ /* read from uart and echo back */
+ else if(ch == 'u') {
+ for(;;) {
+ putch(getch());
+ }
+ }
+#ifdef __AVR_ATmega128__
+ /* external bus loop */
+ else if(ch == 'b') {
+ putch('b');
+ putch('u');
+ putch('s');
+ MCUCR = 0x80;
+ XMCRA = 0;
+ XMCRB = 0;
+ extaddr = 0x1100;
+ for(;;) {
+ ch = *(volatile uint8_t *)extaddr;
+ if(++extaddr == 0) {
+ extaddr = 0x1100;
+ }
+ }
+ }
+#endif
+
+ else if(ch == 'j') {
+ app_start();
+ }
+
+ }
+ /* end of monitor functions */
+
+ }
+ }
+ }
+ /* end of monitor */
+#endif
+
+
+ }
+ /* end of forever loop */
+
+}
+
+
+char gethex(void) {
+ char ah,al;
+
+ ah = getch(); putch(ah);
+ al = getch(); putch(al);
+ if(ah >= 'a') {
+ ah = ah - 'a' + 0x0a;
+ } else if(ah >= '0') {
+ ah -= '0';
+ }
+ if(al >= 'a') {
+ al = al - 'a' + 0x0a;
+ } else if(al >= '0') {
+ al -= '0';
+ }
+ return (ah << 4) + al;
+}
+
+
+void puthex(char ch) {
+ char ah,al;
+
+ ah = (ch & 0xf0) >> 4;
+ if(ah >= 0x0a) {
+ ah = ah - 0x0a + 'a';
+ } else {
+ ah += '0';
+ }
+ al = (ch & 0x0f);
+ if(al >= 0x0a) {
+ al = al - 0x0a + 'a';
+ } else {
+ al += '0';
+ }
+ putch(ah);
+ putch(al);
+}
+
+
+void putch(char ch)
+{
+#ifdef __AVR_ATmega128__
+ if(bootuart == 1) {
+ while (!(UCSR0A & _BV(UDRE0)));
+ UDR0 = ch;
+ }
+ else if (bootuart == 2) {
+ while (!(UCSR1A & _BV(UDRE1)));
+ UDR1 = ch;
+ }
+#elif defined __AVR_ATmega168__
+ while (!(UCSR0A & _BV(UDRE0)));
+ UDR0 = ch;
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ while (!(UCSRA & _BV(UDRE)));
+ UDR = ch;
+#endif
+}
+
+
+char getch(void)
+{
+#ifdef __AVR_ATmega128__
+ if(bootuart == 1) {
+ while(!(UCSR0A & _BV(RXC0)));
+ return UDR0;
+ }
+ else if(bootuart == 2) {
+ while(!(UCSR1A & _BV(RXC1)));
+ return UDR1;
+ }
+ return 0;
+#elif defined __AVR_ATmega168__
+ uint32_t count = 0;
+ while(!(UCSR0A & _BV(RXC0))){
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+ return UDR0;
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ uint32_t count = 0;
+ while(!(UCSRA & _BV(RXC))){
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+ return UDR;
+#endif
+}
+
+
+void getNch(uint8_t count)
+{
+ uint8_t i;
+ for(i=0;i<count;i++) {
+#ifdef __AVR_ATmega128__
+ if(bootuart == 1) {
+ while(!(UCSR0A & _BV(RXC0)));
+ UDR0;
+ }
+ else if(bootuart == 2) {
+ while(!(UCSR1A & _BV(RXC1)));
+ UDR1;
+ }
+#elif defined __AVR_ATmega168__
+ while(!(UCSR0A & _BV(RXC0)));
+ UDR0;
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ //while(!(UCSRA & _BV(RXC)));
+ //UDR;
+ uint8_t i;
+ for(i=0;i<count;i++) {
+ getch(); // need to handle time out
+ }
+#endif
+ }
+}
+
+
+void byte_response(uint8_t val)
+{
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(val);
+ putch(0x10);
+ }
+}
+
+
+void nothing_response(void)
+{
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(0x10);
+ }
+}
+
+void flash_led(uint8_t count)
+{
+ /* flash onboard LED three times to signal entering of bootloader */
+ uint32_t l;
+
+ if (count == 0) {
+ count = 3;
+ }
+
+ for (i = 0; i < count; ++i) {
+ LED_PORT |= _BV(LED);
+ for(l = 0; l < (2 * F_CPU); ++l);
+ LED_PORT &= ~_BV(LED);
+ for(l = 0; l < (F_CPU / 5); ++l);
+ }
+}
+
+
+/* end of file ATmegaBOOT.c */
diff --git a/bootloaders/bt/ATmegaBOOT_168.hex b/bootloaders/bt/ATmegaBOOT_168.hex
new file mode 100644
index 0000000..036ae54
--- /dev/null
+++ b/bootloaders/bt/ATmegaBOOT_168.hex
@@ -0,0 +1,121 @@
+:103800000C94341C0C944F1C0C944F1C0C944F1CA7
+:103810000C944F1C0C944F1C0C944F1C0C944F1C7C
+:103820000C944F1C0C944F1C0C944F1C0C944F1C6C
+:103830000C944F1C0C944F1C0C944F1C0C944F1C5C
+:103840000C944F1C0C944F1C0C944F1C0C944F1C4C
+:103850000C944F1C0C944F1C0C944F1C0C944F1C3C
+:103860000C944F1C0C944F1C11241FBECFEFD4E0BE
+:10387000DEBFCDBF11E0A0E0B1E0E0E6FFE302C0B3
+:1038800005900D92A230B107D9F712E0A2E0B1E0A5
+:1038900001C01D92AC30B107E1F70C94D61C0C941A
+:1038A000001C882309F483E01092090290E0981725
+:1038B000F0F4692F2D9A2FEF37E448EE51E02253B0
+:1038C00030404040504057FFFACF2D982FEF33ED56
+:1038D00040E350E0225330404040504057FFFACF81
+:1038E000962F9F5F692F981728F3909309020895E8
+:1038F000982F8091C00085FFFCCF9093C60008955B
+:10390000EF92FF920F931F93EE24FF248701809183
+:10391000C00087FD17C00894E11CF11C011D111D9A
+:1039200081E0E81682E1F8068AE7080780E01807D8
+:1039300070F3E0910201F091030109958091C000BC
+:1039400087FFE9CF8091C600992787FD90951F9149
+:103950000F91FF90EF9008950E94801C803209F033
+:10396000089584E10E94781C80E10E94781C0895EB
+:10397000CF93C82F0E94801C803249F484E10E94BA
+:10398000781C8C2F0E94781C80E10E94781CCF91BB
+:103990000895282F90E007C08091C0008823E4F7A5
+:1039A0008091C6009F5F9217B8F30895CFEFD4E0DF
+:1039B000DEBFCDBF000056985E9A1092C50088E029
+:1039C0008093C40088E18093C10086E08093C200A8
+:1039D000259A579A5F9A109209022FE080E090E0B2
+:1039E0000197F1F7215027FFF9CF20E12093090239
+:1039F0005F9883E00E94511C83E50E94781C85E457
+:103A00000E94781C84E50E94781C80E20E94781C49
+:103A100082E40E94781C84E50E94781C80E20E9467
+:103A2000781C80E50E94781C81E40E94781C87E461
+:103A30000E94781C85E40E94781C8DE40E94781C0A
+:103A40008FE40E94781C84E40E94781C85E40E9424
+:103A5000781C80E20E94781C83E30E94781C80E23C
+:103A60000E94781C82E30E94781C80E30E94781CEC
+:103A700080E30E94781C80E30E94781C80E20E9410
+:103A8000781C81E30E94781C8DE00E94781C83E5FD
+:103A90000E94781C85E40E94781C84E50E94781CB2
+:103AA00080E20E94781C82E40E94781C84E50E94D7
+:103AB000781C80E20E94781C82E50E94781C8FE4CA
+:103AC0000E94781C8CE40E94781C85E40E94781C7B
+:103AD00080E20E94781C80E30E94781C80E20E94B1
+:103AE000781C86E60E94781C80E20E94781C87E39E
+:103AF0000E94781C84E60E94781C80E30E94781C57
+:103B000080E30E94781C8DE00E94781C0E94801C3B
+:103B1000803361F1813369F1803409F449C0813423
+:103B200009F44FC0823409F45DC0853409F460C0E3
+:103B30008035E1F08135D1F08235C1F0853509F469
+:103B40005BC0863509F463C0843609F465C08437E8
+:103B500009F4B9C0853709F414C18637B9F680E095
+:103B60000E94B81C0E94801C8033A1F60E94AC1CED
+:103B7000CDCF0E94801CC82F803241F684E10E9484
+:103B8000781C81E40E94781C86E50E94781C82E5FE
+:103B90000E94781C8C2F0E94781C89E40E94781C5B
+:103BA00083E50E94781C80E50E94781C80E1ACCF00
+:103BB0000E94801C8638D0F20E94801C0E94AC1C9F
+:103BC000A5CF0E94801C803809F4EDC0813809F42B
+:103BD000EEC0823809F4EFC0883909F683E00E940C
+:103BE000B81CC0CF84E10E94C91C0E94AC1C8ECFBF
+:103BF00085E00E94C91CF9CF0E94801C80930501BA
+:103C00000E94801C809306010E94AC1C7FCF84E040
+:103C10000E94C91C80E0A4CF0E94801C80930802EF
+:103C20000E94801C8093070280910B028E7F8093FC
+:103C30000B020E94801C853409F4C1C000E010E032
+:103C400080910702909108021816190670F4C7E0D7
+:103C5000D1E00E94801C89930F5F1F4F8091070263
+:103C60009091080208171907A0F30E94801C803267
+:103C700009F04CCF80910B0280FFADC000E010E056
+:103C8000209107023091080212161306C0F4E09149
+:103C90000501F0910601A7E0B1E0F999FECFF2BD70
+:103CA000E1BD8D9180BDFA9AF99A31960F5F1F4F51
+:103CB0000217130790F3F0930601E093050184E1E6
+:103CC0000E94781C73CF0E94801C809308020E947F
+:103CD000801C809307020E94801C853409F475C003
+:103CE00080910B028E7F80930B0280910501909151
+:103CF0000601880F991F90930601809305010E9489
+:103D0000801C803209F002CF84E10E94781C00E020
+:103D100010E020910702309108021216130608F0F5
+:103D200045CFE0910501F091060180910B0280FFE3
+:103D30001FC0F999FECFF2BDE1BDF89A80B50E948F
+:103D4000781CE0910501F09106013196F09306018F
+:103D5000E093050120910702309108020F5F1F4F89
+:103D60000217130708F022CF80910B0280FDE1CFEC
+:103D7000869580FF9BC03196F0930601E093050184
+:103D8000EDCF0E94801C803209F0C0CE84E10E94F9
+:103D9000781C8EE10E94781C84E90E94781C86E0E1
+:103DA0000E94781C03CF82E00E94B81CDBCE81E029
+:103DB0000E94B81CD7CE8FE00E94B81CD3CE809151
+:103DC0000B02816080930B0239CF80910B028160DE
+:103DD00080930B0294CF8091060187FD73C01092EF
+:103DE0000A028091050190910601880F991F909316
+:103DF0000601809305018091070280FF09C0809130
+:103E0000070290910802019690930802809307029E
+:103E1000F894F999FECF1127E0910501F091060180
+:103E2000C7E0D1E08091070290910802103091F430
+:103E30000091570001700130D9F303E0009357005F
+:103E4000E8950091570001700130D9F301E100932A
+:103E50005700E895099019900091570001700130C2
+:103E6000D9F301E000935700E8951395103498F0CA
+:103E700011270091570001700130D9F305E000933C
+:103E80005700E8950091570001700130D9F301E126
+:103E900000935700E8953296029709F0C7CF10308B
+:103EA00011F00296E5CF112484E10ACF84910E949B
+:103EB000781C2091070230910802E0910501F091F1
+:103EC000060159CF81E080930A028BCF1F93CF93D5
+:103ED0000E94801CC82F0E94781C0E94801C182FF2
+:103EE0000E94781CC1362CF0C75511363CF017558E
+:103EF00008C0C033D4F3C0531136CCF710330CF0E4
+:103F00001053C295C07FC10F8C2F992787FD9095C4
+:103F1000CF911F910895CF93282F992787FD9095D2
+:103F2000807F9070959587959595879595958795C0
+:103F3000959587958A303CF0895AC22FCF70CA3048
+:103F40003CF0C95A06C0805DC22FCF70CA30CCF792
+:103F5000C05D0E94781C8C2F0E94781CCF91089520
+:023F60008000DF
+:0400000300003800C1
+:00000001FF
diff --git a/bootloaders/lilypad/LilyPadBOOT_168.hex b/bootloaders/lilypad/LilyPadBOOT_168.hex
new file mode 100644
index 0000000..aea378e
--- /dev/null
+++ b/bootloaders/lilypad/LilyPadBOOT_168.hex
@@ -0,0 +1,117 @@
+:103800000C94341C0C944F1C0C944F1C0C944F1CA7
+:103810000C944F1C0C944F1C0C944F1C0C944F1C7C
+:103820000C944F1C0C944F1C0C944F1C0C944F1C6C
+:103830000C944F1C0C944F1C0C944F1C0C944F1C5C
+:103840000C944F1C0C944F1C0C944F1C0C944F1C4C
+:103850000C944F1C0C944F1C0C944F1C0C944F1C3C
+:103860000C944F1C0C944F1C11241FBECFEFD4E0BE
+:10387000DEBFCDBF11E0A0E0B1E0E8E1FFE302C0B0
+:1038800005900D92A230B107D9F712E0A2E0B1E0A5
+:1038900001C01D92AD30B107E1F70C94311D0C94BD
+:1038A000001CCF93DF93CDB7DEB724970FB6F89403
+:1038B000DEBF0FBECDBF382F882309F433E010924E
+:1038C0000A02332309F44BC020E02D9A19821A8290
+:1038D0001B821C8289819A81AB81BC8180549F416B
+:1038E000A040B040A0F489819A81AB81BC8101964F
+:1038F000A11DB11D89839A83AB83BC8389819A8181
+:10390000AB81BC8180549F41A040B04060F32D98B2
+:1039100019821A821B821C8289819A81AB81BC81A7
+:1039200080549F41A040B040A0F489819A81AB812E
+:10393000BC810196A11DB11D89839A83AB83BC8391
+:1039400089819A81AB81BC8180549F41A040B04065
+:1039500060F32F5F231708F4B8CF20930A02249650
+:103960000FB6F894DEBF0FBECDBFDF91CF910895A3
+:10397000EF92FF920F931F93EE24FF248701809113
+:10398000C00087FD17C00894E11CF11C011D111D2A
+:1039900081E0E81689E0F8068DE3080780E0180763
+:1039A00070F3E0910201F091030109958091C0004C
+:1039B00087FFE9CF8091C600992787FD90951F91D9
+:1039C0000F91FF90EF900895982F8091C00085FF90
+:1039D000FCCF9093C60008950E94B81C803271F00D
+:1039E000809104018F5F80930401853009F0089570
+:1039F000E0910201F09103010995089584E10E948C
+:103A0000E41C80E10E94E41C08951F93182F0E947B
+:103A1000B81C803269F0809104018F5F80930401AB
+:103A2000853079F4E0910201F0910301099509C014
+:103A300084E10E94E41C812F0E94E41C80E10E942A
+:103A4000E41C1F910895282F882351F090E0809165
+:103A5000C00087FFFCCF8091C6009F5F2917B9F790
+:103A60000895CFEFD4E0DEBFCDBF000089E18093A1
+:103A7000C4001092C50088E18093C10086E0809365
+:103A8000C2005098589A259A83E00E94511C0E94C7
+:103A9000B81C8033B1F18133B9F1803409F454C0DA
+:103AA000813409F45AC0823409F469C0853409F4B8
+:103AB0006CC0803531F1813521F1823511F18535C8
+:103AC00009F4B2C0863509F4BAC0843609F463C07B
+:103AD000843709F4BBC0853709F40EC1863709F471
+:103AE0004AC0809104018F5F80930401853079F68C
+:103AF000E0910201F091030109950E94B81C803306
+:103B000051F60E94EC1CC3CF0E94B81C803249F7CA
+:103B100084E10E94E41C81E40E94E41C86E50E948A
+:103B2000E41C82E50E94E41C80E20E94E41C89E41B
+:103B30000E94E41C83E50E94E41C80E50E94E41CD2
+:103B400080E10E94E41CA3CF0E94B81C8638C8F212
+:103B50000E94B81C0E94EC1C9ACF0E94B81C8038AE
+:103B600009F4F7C0813809F4F8C0823809F4F9C0C3
+:103B7000883909F4BDC080E00E94051D88CF84E12A
+:103B80000E94231D0E94EC1C82CF85E00E94231D11
+:103B90000E94EC1C7CCF0E94B81C809309020E94FA
+:103BA000B81C8093080280910C028E7F80930C02D7
+:103BB0000E94B81C853409F4C6C080910802909117
+:103BC0000902892B09F0ADC00E94B81C803209F0AF
+:103BD00088CF80910C0280FFC8C08091080290912C
+:103BE00009020097D1F02091060130910701E8E029
+:103BF000F1E0AC014E0F5F1FF999FECF32BD21BD40
+:103C0000819180BDFA9AF99A2F5F3F4F4E175F0757
+:103C100099F7309307012093060184E10E94E41C88
+:103C200080E10E94E41C33CF0E94B81C80930601FF
+:103C30000E94B81C809307010E94EC1C28CF84E0EE
+:103C40000E94231D80E00E94051D21CF0E94B81C08
+:103C5000809309020E94B81C809308020E94B81C3D
+:103C6000853409F4F4C080910C028E7F80930C029D
+:103C70008091060190910701880F991F9093070189
+:103C8000809306010E94B81C803209F000CF84E1C5
+:103C90000E94E41C2091080230910902211531058F
+:103CA00019F1C0E0D0E0E0910601F09107018091A8
+:103CB0000C0280FFC4C0F999FECFF2BDE1BDF89AB5
+:103CC00080B50E94E41CE0910601F0910701319655
+:103CD000F0930701E0930601209108023091090258
+:103CE0002196C217D30718F380E10E94E41CCFCEBF
+:103CF00083E00E94051DCBCE0E94B81C803209F0E3
+:103D0000F0CE84E10E94E41C8EE10E94E41C84E970
+:103D10000E94E41C86E00E94E41C80E10E94E41CF6
+:103D2000B6CEC0E0D0E008E011E00E94B81CF80177
+:103D300081938F0121968091080290910902C81702
+:103D4000D90798F341CF80910C02816080930C02D7
+:103D500034CF82E00E94051D9ACE81E00E94051DAD
+:103D600096CE80E10E94051D92CE8091070187FDCD
+:103D700080C010920B028091060190910701880F7C
+:103D8000991F90930701809306018091080280FF9C
+:103D900009C080910802909109020196909309024E
+:103DA00080930802F894F999FECF1127E09106015B
+:103DB000F0910701C8E0D1E08091080290910902DA
+:103DC000103091F40091570001700130D9F303E0F5
+:103DD00000935700E8950091570001700130D9F326
+:103DE00001E100935700E895099019900091570060
+:103DF00001700130D9F301E000935700E895139565
+:103E0000103498F011270091570001700130D9F358
+:103E100005E000935700E8950091570001700130CC
+:103E2000D9F301E100935700E8953296029709F023
+:103E3000C7CF103011F00296E5CF1124EECE81FFEE
+:103E40000CC03196F0930701E093060149CF8091B1
+:103E50000C02816080930C0215CF84910E94E41CB7
+:103E60002091080230910902E0910601F0910701CA
+:103E7000E8CF81E080930B027ECF0F931F930E94C7
+:103E8000B81C182F0E94E41C0E94B81C082F0E9426
+:103E9000E41C11362CF0175501363CF0075508C0CC
+:103EA0001033D4F310530136CCF700330CF0005329
+:103EB0001295107F100F812F992787FD90951F91E4
+:103EC0000F9108951F93282F992787FD9095807F44
+:103ED00090709595879595958795959587959595E6
+:103EE00087958A304CF0982F995A822F8F708A309C
+:103EF0004CF0182F195A08C0982F905D822F8F70A0
+:103F00008A30BCF7182F105D892F0E94E41C812F86
+:083F10000E94E41C1F910895BA
+:023F1800800027
+:0400000300003800C1
+:00000001FF
diff --git a/bootloaders/lilypad/src/ATmegaBOOT.c b/bootloaders/lilypad/src/ATmegaBOOT.c
new file mode 100644
index 0000000..915bc57
--- /dev/null
+++ b/bootloaders/lilypad/src/ATmegaBOOT.c
@@ -0,0 +1,979 @@
+/**********************************************************/
+/* Serial Bootloader for Atmel megaAVR Controllers */
+/* */
+/* tested with ATmega8, ATmega128 and ATmega168 */
+/* should work with other mega's, see code for details */
+/* */
+/* ATmegaBOOT.c */
+/* */
+/* 20070626: hacked for Arduino Diecimila (which auto- */
+/* resets when a USB connection is made to it) */
+/* by D. Mellis */
+/* 20060802: hacked for Arduino by D. Cuartielles */
+/* based on a previous hack by D. Mellis */
+/* and D. Cuartielles */
+/* */
+/* Monitor and debug functions were added to the original */
+/* code by Dr. Erik Lins, chip45.com. (See below) */
+/* */
+/* Thanks to Karl Pitrich for fixing a bootloader pin */
+/* problem and more informative LED blinking! */
+/* */
+/* For the latest version see: */
+/* http://www.chip45.com/ */
+/* */
+/* ------------------------------------------------------ */
+/* */
+/* based on stk500boot.c */
+/* Copyright (c) 2003, Jason P. Kyle */
+/* All rights reserved. */
+/* see avr1.org for original file and information */
+/* */
+/* 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 */
+/* (at your option) 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. */
+/* */
+/* You should have received a copy of the GNU General */
+/* Public License along with this program; if not, write */
+/* to the Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/* */
+/* Licence can be viewed at */
+/* http://www.fsf.org/licenses/gpl.txt */
+/* */
+/* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */
+/* m8515,m8535. ATmega161 has a very small boot block so */
+/* isn't supported. */
+/* */
+/* Tested with m168 */
+/**********************************************************/
+
+/* $Id$ */
+
+
+/* some includes */
+#include <inttypes.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+
+
+/* the current avr-libc eeprom functions do not support the ATmega168 */
+/* own eeprom write/read functions are used instead */
+#ifndef __AVR_ATmega168__
+#include <avr/eeprom.h>
+#endif
+
+/* Use the F_CPU defined in Makefile */
+
+/* 20060803: hacked by DojoCorp */
+/* 20070626: hacked by David A. Mellis to decrease waiting time for auto-reset */
+/* set the waiting time for the bootloader */
+/* get this from the Makefile instead */
+/* #define MAX_TIME_COUNT (F_CPU>>4) */
+
+/* 20070707: hacked by David A. Mellis - after this many errors give up and launch application */
+#define MAX_ERROR_COUNT 5
+
+/* set the UART baud rate */
+/* 20060803: hacked by DojoCorp */
+//#define BAUD_RATE 115200
+#define BAUD_RATE 19200
+
+
+/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */
+/* never allow AVR Studio to do an update !!!! */
+#define HW_VER 0x02
+#define SW_MAJOR 0x01
+#define SW_MINOR 0x10
+
+
+/* Adjust to suit whatever pin your hardware uses to enter the bootloader */
+/* ATmega128 has two UARTS so two pins are used to enter bootloader and select UART */
+/* BL0... means UART0, BL1... means UART1 */
+#ifdef __AVR_ATmega128__
+#define BL_DDR DDRF
+#define BL_PORT PORTF
+#define BL_PIN PINF
+#define BL0 PINF7
+#define BL1 PINF6
+#else
+/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */
+#define BL_DDR DDRD
+#define BL_PORT PORTD
+#define BL_PIN PIND
+#define BL PIND6
+#endif
+
+
+/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */
+/* if monitor functions are included, LED goes on after monitor was entered */
+#ifdef __AVR_ATmega128__
+/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128) */
+#define LED_DDR DDRB
+#define LED_PORT PORTB
+#define LED_PIN PINB
+#define LED PINB7
+#else
+/* Onboard LED is connected to pin PB2 (e.g. Crumb8, Crumb168) */
+#define LED_DDR DDRB
+#define LED_PORT PORTB
+#define LED_PIN PINB
+/* 20060803: hacked by DojoCorp, LED pin is B5 in Arduino */
+/* #define LED PINB2 */
+#define LED PINB5
+#endif
+
+
+/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */
+#ifdef __AVR_ATmega128__
+#define MONITOR
+#endif
+
+
+/* define various device id's */
+/* manufacturer byte is always the same */
+#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :(
+
+#if defined __AVR_ATmega128__
+#define SIG2 0x97
+#define SIG3 0x02
+#define PAGE_SIZE 0x80U //128 words
+
+#elif defined __AVR_ATmega64__
+#define SIG2 0x96
+#define SIG3 0x02
+#define PAGE_SIZE 0x80U //128 words
+
+#elif defined __AVR_ATmega32__
+#define SIG2 0x95
+#define SIG3 0x02
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega16__
+#define SIG2 0x94
+#define SIG3 0x03
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega8__
+#define SIG2 0x93
+#define SIG3 0x07
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega88__
+#define SIG2 0x93
+#define SIG3 0x0a
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega168__
+#define SIG2 0x94
+#define SIG3 0x06
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega162__
+#define SIG2 0x94
+#define SIG3 0x04
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega163__
+#define SIG2 0x94
+#define SIG3 0x02
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega169__
+#define SIG2 0x94
+#define SIG3 0x05
+#define PAGE_SIZE 0x40U //64 words
+
+#elif defined __AVR_ATmega8515__
+#define SIG2 0x93
+#define SIG3 0x06
+#define PAGE_SIZE 0x20U //32 words
+
+#elif defined __AVR_ATmega8535__
+#define SIG2 0x93
+#define SIG3 0x08
+#define PAGE_SIZE 0x20U //32 words
+#endif
+
+
+/* function prototypes */
+void putch(char);
+char getch(void);
+void getNch(uint8_t);
+void byte_response(uint8_t);
+void nothing_response(void);
+char gethex(void);
+void puthex(char);
+void flash_led(uint8_t);
+
+/* some variables */
+union address_union {
+ uint16_t word;
+ uint8_t byte[2];
+} address;
+
+union length_union {
+ uint16_t word;
+ uint8_t byte[2];
+} length;
+
+struct flags_struct {
+ unsigned eeprom : 1;
+ unsigned rampz : 1;
+} flags;
+
+uint8_t buff[256];
+uint8_t address_high;
+
+uint8_t pagesz=0x80;
+
+uint8_t i;
+uint8_t bootuart = 0;
+
+uint8_t error_count = 0;
+
+void (*app_start)(void) = 0x0000;
+
+
+/* main program starts here */
+int main(void)
+{
+ uint8_t ch,ch2;
+ uint16_t w;
+
+ asm volatile("nop\n\t");
+
+ /* set pin direction for bootloader pin and enable pullup */
+ /* for ATmega128, two pins need to be initialized */
+#ifdef __AVR_ATmega128__
+ BL_DDR &= ~_BV(BL0);
+ BL_DDR &= ~_BV(BL1);
+ BL_PORT |= _BV(BL0);
+ BL_PORT |= _BV(BL1);
+#else
+ /* We run the bootloader regardless of the state of this pin. Thus, don't
+ put it in a different state than the other pins. --DAM, 070709
+ BL_DDR &= ~_BV(BL);
+ BL_PORT |= _BV(BL);
+ */
+#endif
+
+
+#ifdef __AVR_ATmega128__
+ /* check which UART should be used for booting */
+ if(bit_is_clear(BL_PIN, BL0)) {
+ bootuart = 1;
+ }
+ else if(bit_is_clear(BL_PIN, BL1)) {
+ bootuart = 2;
+ }
+#endif
+
+ /* check if flash is programmed already, if not start bootloader anyway */
+ if(pgm_read_byte_near(0x0000) != 0xFF) {
+
+#ifdef __AVR_ATmega128__
+ /* no UART was selected, start application */
+ if(!bootuart) {
+ app_start();
+ }
+#else
+ /* check if bootloader pin is set low */
+ /* we don't start this part neither for the m8, nor m168 */
+ //if(bit_is_set(BL_PIN, BL)) {
+ // app_start();
+ // }
+#endif
+ }
+
+#ifdef __AVR_ATmega128__
+ /* no bootuart was selected, default to uart 0 */
+ if(!bootuart) {
+ bootuart = 1;
+ }
+#endif
+
+
+ /* initialize UART(s) depending on CPU defined */
+#ifdef __AVR_ATmega128__
+ if(bootuart == 1) {
+ UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSR0A = 0x00;
+ UCSR0C = 0x06;
+ UCSR0B = _BV(TXEN0)|_BV(RXEN0);
+ }
+ if(bootuart == 2) {
+ UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSR1A = 0x00;
+ UCSR1C = 0x06;
+ UCSR1B = _BV(TXEN1)|_BV(RXEN1);
+ }
+#elif defined __AVR_ATmega163__
+ UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSRA = 0x00;
+ UCSRB = _BV(TXEN)|_BV(RXEN);
+#elif defined __AVR_ATmega168__
+ UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSR0B = (1<<RXEN0) | (1<<TXEN0);
+ UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);
+
+ /* Enable internal pull-up resistor on pin D0 (RX), in order
+ to supress line noise that prevents the bootloader from
+ timing out (DAM: 20070509) */
+ DDRD &= ~_BV(PIND0);
+ PORTD |= _BV(PIND0);
+#elif defined __AVR_ATmega8__
+ /* m8 */
+ UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate
+ UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
+ UCSRB = (1<<RXEN)|(1<<TXEN); // enable Rx & Tx
+ UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // config USART; 8N1
+#else
+ /* m16,m32,m169,m8515,m8535 */
+ UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
+ UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
+ UCSRA = 0x00;
+ UCSRC = 0x06;
+ UCSRB = _BV(TXEN)|_BV(RXEN);
+#endif
+
+ /* set LED pin as output */
+ LED_DDR |= _BV(LED);
+
+
+ /* flash onboard LED to signal entering of bootloader */
+#ifdef __AVR_ATmega128__
+ // 4x for UART0, 5x for UART1
+ flash_led(NUM_LED_FLASHES + bootuart);
+#else
+ flash_led(NUM_LED_FLASHES);
+#endif
+
+ /* 20050803: by DojoCorp, this is one of the parts provoking the
+ system to stop listening, cancelled from the original */
+ //putch('\0');
+
+
+ /* forever loop */
+ for (;;) {
+
+ /* get character from UART */
+ ch = getch();
+
+ /* A bunch of if...else if... gives smaller code than switch...case ! */
+
+ /* Hello is anyone home ? */
+ if(ch=='0') {
+ nothing_response();
+ }
+
+
+ /* Request programmer ID */
+ /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry */
+ /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares. */
+ else if(ch=='1') {
+ if (getch() == ' ') {
+ putch(0x14);
+ putch('A');
+ putch('V');
+ putch('R');
+ putch(' ');
+ putch('I');
+ putch('S');
+ putch('P');
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+ }
+
+
+ /* AVR ISP/STK500 board commands DON'T CARE so default nothing_response */
+ else if(ch=='@') {
+ ch2 = getch();
+ if (ch2>0x85) getch();
+ nothing_response();
+ }
+
+
+ /* AVR ISP/STK500 board requests */
+ else if(ch=='A') {
+ ch2 = getch();
+ if(ch2==0x80) byte_response(HW_VER); // Hardware version
+ else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version
+ else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version
+ else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56
+ else byte_response(0x00); // Covers various unnecessary responses we don't care about
+ }
+
+
+ /* Device Parameters DON'T CARE, DEVICE IS FIXED */
+ else if(ch=='B') {
+ getNch(20);
+ nothing_response();
+ }
+
+
+ /* Parallel programming stuff DON'T CARE */
+ else if(ch=='E') {
+ getNch(5);
+ nothing_response();
+ }
+
+
+ /* Enter programming mode */
+ else if(ch=='P') {
+ nothing_response();
+ }
+
+
+ /* Leave programming mode */
+ else if(ch=='Q') {
+ nothing_response();
+ }
+
+
+ /* Erase device, don't care as we will erase one page at a time anyway. */
+ else if(ch=='R') {
+ nothing_response();
+ }
+
+
+ /* Set address, little endian. EEPROM in bytes, FLASH in words */
+ /* Perhaps extra address bytes may be added in future to support > 128kB FLASH. */
+ /* This might explain why little endian was used here, big endian used everywhere else. */
+ else if(ch=='U') {
+ address.byte[0] = getch();
+ address.byte[1] = getch();
+ nothing_response();
+ }
+
+
+ /* Universal SPI programming command, disabled. Would be used for fuses and lock bits. */
+ else if(ch=='V') {
+ getNch(4);
+ byte_response(0x00);
+ }
+
+
+ /* Write memory, length is big endian and is in bytes */
+ else if(ch=='d') {
+ length.byte[1] = getch();
+ length.byte[0] = getch();
+ flags.eeprom = 0;
+ if (getch() == 'E') flags.eeprom = 1;
+ for (w=0;w<length.word;w++) {
+ buff[w] = getch(); // Store data in buffer, can't keep up with serial data stream whilst programming pages
+ }
+ if (getch() == ' ') {
+ if (flags.eeprom) { //Write to EEPROM one byte at a time
+ for(w=0;w<length.word;w++) {
+#ifdef __AVR_ATmega168__
+ while(EECR & (1<<EEPE));
+ EEAR = (uint16_t)(void *)address.word;
+ EEDR = buff[w];
+ EECR |= (1<<EEMPE);
+ EECR |= (1<<EEPE);
+#else
+ eeprom_write_byte((void *)address.word,buff[w]);
+#endif
+ address.word++;
+ }
+ }
+ else { //Write to FLASH one page at a time
+ if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME
+ else address_high = 0x00;
+#ifdef __AVR_ATmega128__
+ RAMPZ = address_high;
+#endif
+ address.word = address.word << 1; //address * 2 -> byte location
+ /* if ((length.byte[0] & 0x01) == 0x01) length.word++; //Even up an odd number of bytes */
+ if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes
+ cli(); //Disable interrupts, just to be sure
+ // HACKME: EEPE used to be EEWE
+ while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete
+ asm volatile(
+ "clr r17 \n\t" //page_word_count
+ "lds r30,address \n\t" //Address of FLASH location (in bytes)
+ "lds r31,address+1 \n\t"
+ "ldi r28,lo8(buff) \n\t" //Start of buffer array in RAM
+ "ldi r29,hi8(buff) \n\t"
+ "lds r24,length \n\t" //Length of data to be written (in bytes)
+ "lds r25,length+1 \n\t"
+ "length_loop: \n\t" //Main loop, repeat for number of words in block
+ "cpi r17,0x00 \n\t" //If page_word_count=0 then erase page
+ "brne no_page_erase \n\t"
+ "wait_spm1: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm1 \n\t"
+ "ldi r16,0x03 \n\t" //Erase page pointed to by Z
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "wait_spm2: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm2 \n\t"
+
+ "ldi r16,0x11 \n\t" //Re-enable RWW section
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "no_page_erase: \n\t"
+ "ld r0,Y+ \n\t" //Write 2 bytes into page buffer
+ "ld r1,Y+ \n\t"
+
+ "wait_spm3: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm3 \n\t"
+ "ldi r16,0x01 \n\t" //Load r0,r1 into FLASH page buffer
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+
+ "inc r17 \n\t" //page_word_count++
+ "cpi r17,%1 \n\t"
+ "brlo same_page \n\t" //Still same page in FLASH
+ "write_page: \n\t"
+ "clr r17 \n\t" //New page, write current one first
+ "wait_spm4: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm4 \n\t"
+#ifdef __AVR_ATmega163__
+ "andi r30,0x80 \n\t" // m163 requires Z6:Z1 to be zero during page write
+#endif
+ "ldi r16,0x05 \n\t" //Write page pointed to by Z
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+ "ori r30,0x7E \n\t" // recover Z6:Z1 state after page write (had to be zero during write)
+#endif
+ "wait_spm5: \n\t"
+ "lds r16,%0 \n\t" //Wait for previous spm to complete
+ "andi r16,1 \n\t"
+ "cpi r16,1 \n\t"
+ "breq wait_spm5 \n\t"
+ "ldi r16,0x11 \n\t" //Re-enable RWW section
+ "sts %0,r16 \n\t"
+ "spm \n\t"
+#ifdef __AVR_ATmega163__
+ ".word 0xFFFF \n\t"
+ "nop \n\t"
+#endif
+ "same_page: \n\t"
+ "adiw r30,2 \n\t" //Next word in FLASH
+ "sbiw r24,2 \n\t" //length-2
+ "breq final_write \n\t" //Finished
+ "rjmp length_loop \n\t"
+ "final_write: \n\t"
+ "cpi r17,0 \n\t"
+ "breq block_done \n\t"
+ "adiw r24,2 \n\t" //length+2, fool above check on length after short page write
+ "rjmp write_page \n\t"
+ "block_done: \n\t"
+ "clr __zero_reg__ \n\t" //restore zero register
+#if defined __AVR_ATmega168__
+ : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
+#else
+ : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
+#endif
+ );
+ /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */
+ /* exit the bootloader without a power cycle anyhow */
+ }
+ putch(0x14);
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+ }
+
+
+ /* Read memory block mode, length is big endian. */
+ else if(ch=='t') {
+ length.byte[1] = getch();
+ length.byte[0] = getch();
+#if defined __AVR_ATmega128__
+ if (address.word>0x7FFF) flags.rampz = 1; // No go with m256, FIXME
+ else flags.rampz = 0;
+#endif
+ if (getch() == 'E') flags.eeprom = 1;
+ else {
+ flags.eeprom = 0;
+ address.word = address.word << 1; // address * 2 -> byte location
+ }
+ if (getch() == ' ') { // Command terminator
+ putch(0x14);
+ for (w=0;w < length.word;w++) { // Can handle odd and even lengths okay
+ if (flags.eeprom) { // Byte access EEPROM read
+#ifdef __AVR_ATmega168__
+ while(EECR & (1<<EEPE));
+ EEAR = (uint16_t)(void *)address.word;
+ EECR |= (1<<EERE);
+ putch(EEDR);
+#else
+ putch(eeprom_read_byte((void *)address.word));
+#endif
+ address.word++;
+ }
+ else {
+
+ if (!flags.rampz) putch(pgm_read_byte_near(address.word));
+#if defined __AVR_ATmega128__
+ else putch(pgm_read_byte_far(address.word + 0x10000));
+ // Hmmmm, yuck FIXME when m256 arrvies
+#endif
+ address.word++;
+ }
+ }
+ putch(0x10);
+ }
+ }
+
+
+ /* Get device signature bytes */
+ else if(ch=='u') {
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(SIG1);
+ putch(SIG2);
+ putch(SIG3);
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+ }
+
+
+ /* Read oscillator calibration byte */
+ else if(ch=='v') {
+ byte_response(0x00);
+ }
+
+
+#ifdef MONITOR
+
+ /* here come the extended monitor commands by Erik Lins */
+
+ /* check for three times exclamation mark pressed */
+ else if(ch=='!') {
+ ch = getch();
+ if(ch=='!') {
+ ch = getch();
+ if(ch=='!') {
+
+#ifdef __AVR_ATmega128__
+ uint16_t extaddr;
+#endif
+ uint8_t addrl, addrh;
+
+#ifdef CRUMB128
+ PGM_P welcome = {"ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
+#elif defined PROBOMEGA128
+ PGM_P welcome = {"ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
+#elif defined SAVVY128
+ PGM_P welcome = {"ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
+#endif
+
+ /* turn on LED */
+ LED_DDR |= _BV(LED);
+ LED_PORT &= ~_BV(LED);
+
+ /* print a welcome message and command overview */
+ for(i=0; welcome[i] != '\0'; ++i) {
+ putch(welcome[i]);
+ }
+
+ /* test for valid commands */
+ for(;;) {
+ putch('\n');
+ putch('\r');
+ putch(':');
+ putch(' ');
+
+ ch = getch();
+ putch(ch);
+
+ /* toggle LED */
+ if(ch == 't') {
+ if(bit_is_set(LED_PIN,LED)) {
+ LED_PORT &= ~_BV(LED);
+ putch('1');
+ } else {
+ LED_PORT |= _BV(LED);
+ putch('0');
+ }
+
+ }
+
+ /* read byte from address */
+ else if(ch == 'r') {
+ ch = getch(); putch(ch);
+ addrh = gethex();
+ addrl = gethex();
+ putch('=');
+ ch = *(uint8_t *)((addrh << 8) + addrl);
+ puthex(ch);
+ }
+
+ /* write a byte to address */
+ else if(ch == 'w') {
+ ch = getch(); putch(ch);
+ addrh = gethex();
+ addrl = gethex();
+ ch = getch(); putch(ch);
+ ch = gethex();
+ *(uint8_t *)((addrh << 8) + addrl) = ch;
+
+ }
+
+ /* read from uart and echo back */
+ else if(ch == 'u') {
+ for(;;) {
+ putch(getch());
+ }
+ }
+#ifdef __AVR_ATmega128__
+ /* external bus loop */
+ else if(ch == 'b') {
+ putch('b');
+ putch('u');
+ putch('s');
+ MCUCR = 0x80;
+ XMCRA = 0;
+ XMCRB = 0;
+ extaddr = 0x1100;
+ for(;;) {
+ ch = *(volatile uint8_t *)extaddr;
+ if(++extaddr == 0) {
+ extaddr = 0x1100;
+ }
+ }
+ }
+#endif
+
+ else if(ch == 'j') {
+ app_start();
+ }
+
+ }
+ /* end of monitor functions */
+
+ }
+ }
+ }
+ /* end of monitor */
+#endif
+ else if (++error_count == MAX_ERROR_COUNT) {
+ app_start();
+ }
+ }
+ /* end of forever loop */
+
+}
+
+
+char gethex(void) {
+ char ah,al;
+
+ ah = getch(); putch(ah);
+ al = getch(); putch(al);
+ if(ah >= 'a') {
+ ah = ah - 'a' + 0x0a;
+ } else if(ah >= '0') {
+ ah -= '0';
+ }
+ if(al >= 'a') {
+ al = al - 'a' + 0x0a;
+ } else if(al >= '0') {
+ al -= '0';
+ }
+ return (ah << 4) + al;
+}
+
+
+void puthex(char ch) {
+ char ah,al;
+
+ ah = (ch & 0xf0) >> 4;
+ if(ah >= 0x0a) {
+ ah = ah - 0x0a + 'a';
+ } else {
+ ah += '0';
+ }
+ al = (ch & 0x0f);
+ if(al >= 0x0a) {
+ al = al - 0x0a + 'a';
+ } else {
+ al += '0';
+ }
+ putch(ah);
+ putch(al);
+}
+
+
+void putch(char ch)
+{
+#ifdef __AVR_ATmega128__
+ if(bootuart == 1) {
+ while (!(UCSR0A & _BV(UDRE0)));
+ UDR0 = ch;
+ }
+ else if (bootuart == 2) {
+ while (!(UCSR1A & _BV(UDRE1)));
+ UDR1 = ch;
+ }
+#elif defined __AVR_ATmega168__
+ while (!(UCSR0A & _BV(UDRE0)));
+ UDR0 = ch;
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ while (!(UCSRA & _BV(UDRE)));
+ UDR = ch;
+#endif
+}
+
+
+char getch(void)
+{
+#ifdef __AVR_ATmega128__
+ if(bootuart == 1) {
+ while(!(UCSR0A & _BV(RXC0)));
+ return UDR0;
+ }
+ else if(bootuart == 2) {
+ while(!(UCSR1A & _BV(RXC1)));
+ return UDR1;
+ }
+ return 0;
+#elif defined __AVR_ATmega168__
+ uint32_t count = 0;
+ while(!(UCSR0A & _BV(RXC0))){
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+ return UDR0;
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ uint32_t count = 0;
+ while(!(UCSRA & _BV(RXC))){
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ /* HACKME:: here is a good place to count times*/
+ count++;
+ if (count > MAX_TIME_COUNT)
+ app_start();
+ }
+ return UDR;
+#endif
+}
+
+
+void getNch(uint8_t count)
+{
+ uint8_t i;
+ for(i=0;i<count;i++) {
+#ifdef __AVR_ATmega128__
+ if(bootuart == 1) {
+ while(!(UCSR0A & _BV(RXC0)));
+ UDR0;
+ }
+ else if(bootuart == 2) {
+ while(!(UCSR1A & _BV(RXC1)));
+ UDR1;
+ }
+#elif defined __AVR_ATmega168__
+ while(!(UCSR0A & _BV(RXC0)));
+ UDR0;
+#else
+ /* m8,16,32,169,8515,8535,163 */
+ /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
+ //while(!(UCSRA & _BV(RXC)));
+ //UDR;
+ uint8_t i;
+ for(i=0;i<count;i++) {
+ getch(); // need to handle time out
+ }
+#endif
+ }
+}
+
+
+void byte_response(uint8_t val)
+{
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(val);
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+}
+
+
+void nothing_response(void)
+{
+ if (getch() == ' ') {
+ putch(0x14);
+ putch(0x10);
+ } else {
+ if (++error_count == MAX_ERROR_COUNT)
+ app_start();
+ }
+}
+
+void flash_led(uint8_t count)
+{
+ /* flash onboard LED three times to signal entering of bootloader */
+ /* l needs to be volatile or the delay loops below might get
+ optimized away if compiling with optimizations (DAM). */
+ volatile uint32_t l;
+
+ if (count == 0) {
+ count = 3;
+ }
+
+ for (i = 0; i < count; ++i) {
+ LED_PORT |= _BV(LED);
+ for(l = 0; l < (F_CPU / 1000); ++l);
+ LED_PORT &= ~_BV(LED);
+ for(l = 0; l < (F_CPU / 1000); ++l);
+ }
+}
+
+
+/* end of file ATmegaBOOT.c */
diff --git a/bootloaders/lilypad/src/Makefile b/bootloaders/lilypad/src/Makefile
new file mode 100644
index 0000000..516d5b2
--- /dev/null
+++ b/bootloaders/lilypad/src/Makefile
@@ -0,0 +1,84 @@
+# Makefile for ATmegaBOOT
+# E.Lins, 18.7.2005
+# $Id$
+
+# Instructions
+#
+# To build the bootloader for the LilyPad:
+# make lily
+
+
+# program name should not be changed...
+PROGRAM = ATmegaBOOT_168
+
+# enter the target CPU frequency
+AVR_FREQ = 8000000L
+
+# enter the parameters for the avrdude isp tool
+ISPTOOL = stk500v2
+ISPPORT = usb
+ISPSPEED = -b 115200
+
+MCU_TARGET = atmega168
+LDSECTION = --section-start=.text=0x3800
+
+# the efuse should really be 0xf8; since, however, only the lower
+# three bits of that byte are used on the atmega168, avrdude gets
+# confused if you specify 1's for the higher bits, see:
+# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
+#
+# similarly, the lock bits should be 0xff instead of 0x3f (to
+# unlock the bootloader section) and 0xcf instead of 0x0f (to
+# lock it), but since the high two bits of the lock byte are
+# unused, avrdude would get confused.
+ISPFUSES = avrdude -c $(ISPTOOL) -p m168 -P $(ISPPORT) $(ISPSPEED) -e -u -U lock:w:0x3f:m -U efuse:w:0x00:m -U hfuse:w:0xdd:m -U lfuse:w:0xff:m
+ISPFLASH = avrdude -c $(ISPTOOL) -p m168 -P $(ISPPORT) $(ISPSPEED) -U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f:m
+
+
+OBJ = $(PROGRAM).o
+OPTIMIZE = -O2
+
+DEFS =
+LIBS =
+
+CC = avr-gcc
+
+
+# Override is only needed by avr-lib build system.
+
+override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
+override LDFLAGS = -Wl,$(LDSECTION)
+#override LDFLAGS = -Wl,-Map,$(PROGRAM).map,$(LDSECTION)
+
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+
+all:
+
+lily: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>1' '-DNUM_LED_FLASHES=3'
+lily: $(PROGRAM).hex
+
+$(PROGRAM).hex: $(PROGRAM).elf
+ $(OBJCOPY) -j .text -j .data -O ihex $< $@
+
+$(PROGRAM).elf: $(OBJ)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+$(OBJ):
+ avr-gcc $(CFLAGS) $(LDFLAGS) -c -g -O2 -Wall -mmcu=atmega168 ATmegaBOOT.c -o ATmegaBOOT_168.o
+
+%.lst: %.elf
+ $(OBJDUMP) -h -S $< > $@
+
+%.srec: %.elf
+ $(OBJCOPY) -j .text -j .data -O srec $< $@
+
+%.bin: %.elf
+ $(OBJCOPY) -j .text -j .data -O binary $< $@
+
+clean:
+ rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
+
+install:
+ avrdude -p m168 -c stk500v2 -P /dev/cu.USA19H1b1P1.1 -e -u -U lock:w:0x3f:m -U efuse:w:0x00:m -U hfuse:w:0xdd:m -U lfuse:w:0xe2:m
+ avrdude -p m168 -c stk500v2 -P /dev/cu.USA19H1b1P1.1 -e -u -U flash:w:ATmegaBOOT_168.hex -U lock:w:0x0f:m
diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp
new file mode 100755
index 0000000..f8a959a
--- /dev/null
+++ b/cores/arduino/HardwareSerial.cpp
@@ -0,0 +1,191 @@
+/*
+ HardwareSerial.cpp - Hardware serial library for Wiring
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Modified 23 November 2006 by David A. Mellis
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include "wiring.h"
+#include "wiring_private.h"
+
+#include "HardwareSerial.h"
+
+// Define constants and variables for buffering incoming serial data. We're
+// using a ring buffer (I think), in which rx_buffer_head is the index of the
+// location to which to write the next incoming character and rx_buffer_tail
+// is the index of the location from which to read.
+#define RX_BUFFER_SIZE 128
+
+struct ring_buffer {
+ unsigned char buffer[RX_BUFFER_SIZE];
+ int head;
+ int tail;
+};
+
+ring_buffer rx_buffer = { { 0 }, 0, 0 };
+
+#if defined(__AVR_ATmega1280__)
+ring_buffer rx_buffer1 = { { 0 }, 0, 0 };
+ring_buffer rx_buffer2 = { { 0 }, 0, 0 };
+ring_buffer rx_buffer3 = { { 0 }, 0, 0 };
+#endif
+
+inline void store_char(unsigned char c, ring_buffer *rx_buffer)
+{
+ int i = (rx_buffer->head + 1) % RX_BUFFER_SIZE;
+
+ // if we should be storing the received character into the location
+ // just before the tail (meaning that the head would advance to the
+ // current location of the tail), we're about to overflow the buffer
+ // and so we don't write the character or advance the head.
+ if (i != rx_buffer->tail) {
+ rx_buffer->buffer[rx_buffer->head] = c;
+ rx_buffer->head = i;
+ }
+}
+
+#if defined(__AVR_ATmega1280__)
+
+SIGNAL(SIG_USART0_RECV)
+{
+ unsigned char c = UDR0;
+ store_char(c, &rx_buffer);
+}
+
+SIGNAL(SIG_USART1_RECV)
+{
+ unsigned char c = UDR1;
+ store_char(c, &rx_buffer1);
+}
+
+SIGNAL(SIG_USART2_RECV)
+{
+ unsigned char c = UDR2;
+ store_char(c, &rx_buffer2);
+}
+
+SIGNAL(SIG_USART3_RECV)
+{
+ unsigned char c = UDR3;
+ store_char(c, &rx_buffer3);
+}
+
+#else
+
+#if defined(__AVR_ATmega8__)
+SIGNAL(SIG_UART_RECV)
+#else
+SIGNAL(USART_RX_vect)
+#endif
+{
+#if defined(__AVR_ATmega8__)
+ unsigned char c = UDR;
+#else
+ unsigned char c = UDR0;
+#endif
+ store_char(c, &rx_buffer);
+}
+
+#endif
+
+// Constructors ////////////////////////////////////////////////////////////////
+
+HardwareSerial::HardwareSerial(ring_buffer *rx_buffer,
+ volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
+ volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
+ volatile uint8_t *udr,
+ uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre)
+{
+ _rx_buffer = rx_buffer;
+ _ubrrh = ubrrh;
+ _ubrrl = ubrrl;
+ _ucsra = ucsra;
+ _ucsrb = ucsrb;
+ _udr = udr;
+ _rxen = rxen;
+ _txen = txen;
+ _rxcie = rxcie;
+ _udre = udre;
+}
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+void HardwareSerial::begin(long speed)
+{
+ *_ubrrh = ((F_CPU / 16 + speed / 2) / speed - 1) >> 8;
+ *_ubrrl = ((F_CPU / 16 + speed / 2) / speed - 1);
+ sbi(*_ucsrb, _rxen);
+ sbi(*_ucsrb, _txen);
+ sbi(*_ucsrb, _rxcie);
+}
+
+uint8_t HardwareSerial::available(void)
+{
+ return (RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
+}
+
+int HardwareSerial::read(void)
+{
+ // if the head isn't ahead of the tail, we don't have any characters
+ if (_rx_buffer->head == _rx_buffer->tail) {
+ return -1;
+ } else {
+ unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
+ _rx_buffer->tail = (_rx_buffer->tail + 1) % RX_BUFFER_SIZE;
+ return c;
+ }
+}
+
+void HardwareSerial::flush()
+{
+ // don't reverse this or there may be problems if the RX interrupt
+ // occurs after reading the value of rx_buffer_head but before writing
+ // the value to rx_buffer_tail; the previous value of rx_buffer_head
+ // may be written to rx_buffer_tail, making it appear as if the buffer
+ // don't reverse this or there may be problems if the RX interrupt
+ // occurs after reading the value of rx_buffer_head but before writing
+ // the value to rx_buffer_tail; the previous value of rx_buffer_head
+ // may be written to rx_buffer_tail, making it appear as if the buffer
+ // were full, not empty.
+ _rx_buffer->head = _rx_buffer->tail;
+}
+
+void HardwareSerial::write(uint8_t c)
+{
+ while (!((*_ucsra) & (1 << _udre)))
+ ;
+
+ *_udr = c;
+}
+
+// Preinstantiate Objects //////////////////////////////////////////////////////
+
+#if defined(__AVR_ATmega8__)
+HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE);
+#else
+HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0);
+#endif
+
+#if defined(__AVR_ATmega1280__)
+HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1);
+HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2);
+HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3);
+#endif
+
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h
new file mode 100755
index 0000000..8610f5a
--- /dev/null
+++ b/cores/arduino/HardwareSerial.h
@@ -0,0 +1,65 @@
+/*
+ HardwareSerial.h - Hardware serial library for Wiring
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef HardwareSerial_h
+#define HardwareSerial_h
+
+#include <inttypes.h>
+
+#include "Print.h"
+
+struct ring_buffer;
+
+class HardwareSerial : public Print
+{
+ private:
+ ring_buffer *_rx_buffer;
+ volatile uint8_t *_ubrrh;
+ volatile uint8_t *_ubrrl;
+ volatile uint8_t *_ucsra;
+ volatile uint8_t *_ucsrb;
+ volatile uint8_t *_udr;
+ uint8_t _rxen;
+ uint8_t _txen;
+ uint8_t _rxcie;
+ uint8_t _udre;
+ public:
+ HardwareSerial(ring_buffer *rx_buffer,
+ volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
+ volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
+ volatile uint8_t *udr,
+ uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre);
+ void begin(long);
+ uint8_t available(void);
+ int read(void);
+ void flush(void);
+ virtual void write(uint8_t);
+ using Print::write; // pull in write(str) and write(buf, size) from Print
+};
+
+extern HardwareSerial Serial;
+
+#if defined(__AVR_ATmega1280__)
+extern HardwareSerial Serial1;
+extern HardwareSerial Serial2;
+extern HardwareSerial Serial3;
+#endif
+
+#endif
+
diff --git a/cores/arduino/Makefile b/cores/arduino/Makefile
new file mode 100755
index 0000000..30ea655
--- /dev/null
+++ b/cores/arduino/Makefile
@@ -0,0 +1,243 @@
+# Arduino 0015 Makefile
+# Arduino adaptation by mellis, eighthave, oli.keller
+#
+# This makefile allows you to build sketches from the command line
+# without the Arduino environment (or Java).
+#
+# Detailed instructions for using the makefile:
+#
+# 1. Copy this file into the folder with your sketch. There should be a
+# file with the same name as the folder and with the extension .pde
+# (e.g. foo.pde in the foo/ folder).
+#
+# 2. Modify the line containg "INSTALL_DIR" to point to the directory that
+# contains the Arduino installation (for example, under Mac OS X, this
+# might be /Applications/arduino-0012).
+#
+# 3. Modify the line containing "PORT" to refer to the filename
+# representing the USB or serial connection to your Arduino board
+# (e.g. PORT = /dev/tty.USB0). If the exact name of this file
+# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.usb*).
+#
+# 4. Set the line containing "MCU" to match your board's processor.
+# Older one's are atmega8 based, newer ones like Arduino Mini, Bluetooth
+# or Diecimila have the atmega168. If you're using a LilyPad Arduino,
+# change F_CPU to 8000000.
+#
+# 5. At the command line, change to the directory containing your
+# program's file and the makefile.
+#
+# 6. Type "make" and press enter to compile/verify your program.
+#
+# 7. Type "make upload", reset your Arduino board, and press enter to
+# upload your program to the Arduino board.
+#
+# $Id$
+
+TARGET = $(notdir $(CURDIR))
+INSTALL_DIR = ../../..
+PORT = /dev/tty.usb*
+UPLOAD_RATE = 19200
+AVRDUDE_PROGRAMMER = stk500v1
+MCU = atmega168
+F_CPU = 16000000
+
+############################################################################
+# Below here nothing should be changed...
+
+ARDUINO = $(INSTALL_DIR)/hardware/cores/arduino
+AVR_TOOLS_PATH = $(INSTALL_DIR)/hardware/tools/avr/bin
+SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
+$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
+$(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \
+$(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c
+CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WMath.cpp \
+$(ARDUINO)/Print.cpp
+FORMAT = ihex
+
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# Place -I options here
+CINCS = -I$(ARDUINO)
+CXXINCS = -I$(ARDUINO)
+
+# 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
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS = -lm
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -V -F -C $(INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf \
+-p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+-b $(UPLOAD_RATE)
+
+# Program settings
+CC = $(AVR_TOOLS_PATH)/avr-gcc
+CXX = $(AVR_TOOLS_PATH)/avr-g++
+OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy
+OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump
+AR = $(AVR_TOOLS_PATH)/avr-ar
+SIZE = $(AVR_TOOLS_PATH)/avr-size
+NM = $(AVR_TOOLS_PATH)/avr-nm
+AVRDUDE = $(AVR_TOOLS_PATH)/avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: applet_files build sizeafter
+
+build: elf hex
+
+applet_files: $(TARGET).pde
+ # Here is the "preprocessing".
+ # It creates a .cpp file based with the same name as the .pde file.
+ # On top of the new .cpp file comes the WProgram.h header.
+ # At the end there is a generic main() function attached.
+ # Then the .cpp file will be compiled. Errors during compile will
+ # refer to this new, automatically generated, file.
+ # Not the original .pde file you actually edit...
+ test -d applet || mkdir applet
+ echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+ cat $(TARGET).pde >> applet/$(TARGET).cpp
+ cat $(ARDUINO)/main.cxx >> applet/$(TARGET).cpp
+
+elf: applet/$(TARGET).elf
+hex: applet/$(TARGET).hex
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss
+sym: applet/$(TARGET).sym
+
+# Program the device.
+upload: applet/$(TARGET).hex
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+ # Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) applet/$(TARGET).hex
+ELFSIZE = $(SIZE) applet/$(TARGET).elf
+sizebefore:
+ @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
+
+sizeafter:
+ @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(HEXSIZE); echo; fi
+
+
+# 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: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf $(TARGET).cof
+
+
+extcoff: $(TARGET).elf
+ $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf $(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym
+
+.elf.hex:
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+ $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+ $(NM) -n $< > $@
+
+ # Link: create ELF output file from library.
+applet/$(TARGET).elf: $(TARGET).pde applet/core.a
+ $(CC) $(ALL_CFLAGS) -o $@ applet/$(TARGET).cpp -L. applet/core.a $(LDFLAGS)
+
+applet/core.a: $(OBJ)
+ @for i in $(OBJ); do echo $(AR) rcs applet/core.a $$i; $(AR) rcs applet/core.a $$i; done
+
+
+
+# Compile: create object files from C++ source files.
+.cpp.o:
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+# Automatic dependencies
+%.d: %.c
+ $(CC) -M $(ALL_CFLAGS) $< | sed "s;$(notdir $*).o:;$*.o $*.d:;" > $@
+
+%.d: %.cpp
+ $(CXX) -M $(ALL_CXXFLAGS) $< | sed "s;$(notdir $*).o:;$*.o $*.d:;" > $@
+
+
+# Target: clean project.
+clean:
+ $(REMOVE) applet/$(TARGET).hex applet/$(TARGET).eep applet/$(TARGET).cof applet/$(TARGET).elf \
+ applet/$(TARGET).map applet/$(TARGET).sym applet/$(TARGET).lss applet/core.a \
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+
+.PHONY: all build elf hex eep lss sym program coff extcoff clean applet_files sizebefore sizeafter
+
+include $(SRC:.c=.d)
+include $(CXXSRC:.cpp=.d)
diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp
new file mode 100755
index 0000000..74d0e5b
--- /dev/null
+++ b/cores/arduino/Print.cpp
@@ -0,0 +1,215 @@
+/*
+ Print.cpp - Base class that provides print() and println()
+ Copyright (c) 2008 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Modified 23 November 2006 by David A. Mellis
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "wiring.h"
+
+#include "Print.h"
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+/* default implementation: may be overridden */
+void Print::write(const char *str)
+{
+ while (*str)
+ write(*str++);
+}
+
+/* default implementation: may be overridden */
+void Print::write(const uint8_t *buffer, size_t size)
+{
+ while (size--)
+ write(*buffer++);
+}
+
+void Print::print(uint8_t b)
+{
+ this->write(b);
+}
+
+void Print::print(char c)
+{
+ print((byte) c);
+}
+
+void Print::print(const char str[])
+{
+ write(str);
+}
+
+void Print::print(int n)
+{
+ print((long) n);
+}
+
+void Print::print(unsigned int n)
+{
+ print((unsigned long) n);
+}
+
+void Print::print(long n)
+{
+ if (n < 0) {
+ print('-');
+ n = -n;
+ }
+ printNumber(n, 10);
+}
+
+void Print::print(unsigned long n)
+{
+ printNumber(n, 10);
+}
+
+void Print::print(long n, int base)
+{
+ if (base == 0)
+ print((char) n);
+ else if (base == 10)
+ print(n);
+ else
+ printNumber(n, base);
+}
+
+void Print::print(double n)
+{
+ printFloat(n, 2);
+}
+
+void Print::println(void)
+{
+ print('\r');
+ print('\n');
+}
+
+void Print::println(char c)
+{
+ print(c);
+ println();
+}
+
+void Print::println(const char c[])
+{
+ print(c);
+ println();
+}
+
+void Print::println(uint8_t b)
+{
+ print(b);
+ println();
+}
+
+void Print::println(int n)
+{
+ print(n);
+ println();
+}
+
+void Print::println(unsigned int n)
+{
+ print(n);
+ println();
+}
+
+void Print::println(long n)
+{
+ print(n);
+ println();
+}
+
+void Print::println(unsigned long n)
+{
+ print(n);
+ println();
+}
+
+void Print::println(long n, int base)
+{
+ print(n, base);
+ println();
+}
+
+void Print::println(double n)
+{
+ print(n);
+ println();
+}
+
+// Private Methods /////////////////////////////////////////////////////////////
+
+void Print::printNumber(unsigned long n, uint8_t base)
+{
+ unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
+ unsigned long i = 0;
+
+ if (n == 0) {
+ print('0');
+ return;
+ }
+
+ while (n > 0) {
+ buf[i++] = n % base;
+ n /= base;
+ }
+
+ for (; i > 0; i--)
+ print((char) (buf[i - 1] < 10 ?
+ '0' + buf[i - 1] :
+ 'A' + buf[i - 1] - 10));
+}
+
+void Print::printFloat(double number, uint8_t digits)
+{
+ // Handle negative numbers
+ if (number < 0.0)
+ {
+ print('-');
+ number = -number;
+ }
+
+ // Round correctly so that print(1.999, 2) prints as "2.00"
+ double rounding = 0.5;
+ for (uint8_t i=0; i<digits; ++i)
+ rounding /= 10.0;
+
+ number += rounding;
+
+ // Extract the integer part of the number and print it
+ unsigned long int_part = (unsigned long)number;
+ double remainder = number - (double)int_part;
+ print(int_part);
+
+ // Print the decimal point, but only if there are digits beyond
+ if (digits > 0)
+ print(".");
+
+ // Extract digits from the remainder one at a time
+ while (digits-- > 0)
+ {
+ remainder *= 10.0;
+ int toPrint = int(remainder);
+ print(toPrint);
+ remainder -= toPrint;
+ }
+}
diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h
new file mode 100755
index 0000000..a69e85d
--- /dev/null
+++ b/cores/arduino/Print.h
@@ -0,0 +1,62 @@
+/*
+ Print.h - Base class that provides print() and println()
+ Copyright (c) 2008 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef Print_h
+#define Print_h
+
+#include <inttypes.h>
+#include <stdio.h> // for size_t
+
+#define DEC 10
+#define HEX 16
+#define OCT 8
+#define BIN 2
+#define BYTE 0
+
+class Print
+{
+ private:
+ void printNumber(unsigned long, uint8_t);
+ void printFloat(double, uint8_t);
+ public:
+ virtual void write(uint8_t) = 0;
+ virtual void write(const char *str);
+ virtual void write(const uint8_t *buffer, size_t size);
+ void print(char);
+ void print(const char[]);
+ void print(uint8_t);
+ void print(int);
+ void print(unsigned int);
+ void print(long);
+ void print(unsigned long);
+ void print(long, int);
+ void print(double);
+ void println(void);
+ void println(char);
+ void println(const char[]);
+ void println(uint8_t);
+ void println(int);
+ void println(unsigned int);
+ void println(long);
+ void println(unsigned long);
+ void println(long, int);
+ void println(double);
+};
+
+#endif
diff --git a/cores/arduino/WConstants.h b/cores/arduino/WConstants.h
new file mode 100644
index 0000000..3e19ac4
--- /dev/null
+++ b/cores/arduino/WConstants.h
@@ -0,0 +1 @@
+#include "wiring.h"
diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c
new file mode 100755
index 0000000..69a78b0
--- /dev/null
+++ b/cores/arduino/WInterrupts.c
@@ -0,0 +1,215 @@
+/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ Part of the Wiring project - http://wiring.uniandes.edu.co
+
+ Copyright (c) 2004-05 Hernando Barragan
+
+ 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
+
+ Modified 24 November 2006 by David A. Mellis
+*/
+
+#include <inttypes.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include <stdio.h>
+
+#include "WConstants.h"
+#include "wiring_private.h"
+
+volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
+// volatile static voidFuncPtr twiIntFunc;
+
+#if defined(__AVR_ATmega8__)
+#define EICRA MCUCR
+#define EIMSK GICR
+#endif
+
+void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
+ if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
+ intFunc[interruptNum] = userFunc;
+
+ // Configure the interrupt mode (trigger on low input, any change, rising
+ // edge, or falling edge). The mode constants were chosen to correspond
+ // to the configuration bits in the hardware register, so we simply shift
+ // the mode into place.
+
+ // Enable the interrupt.
+
+ switch (interruptNum) {
+#if defined(__AVR_ATmega1280__)
+ case 2:
+ EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
+ EIMSK |= (1 << INT0);
+ break;
+ case 3:
+ EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
+ EIMSK |= (1 << INT1);
+ break;
+ case 4:
+ EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
+ EIMSK |= (1 << INT2);
+ break;
+ case 5:
+ EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
+ EIMSK |= (1 << INT3);
+ break;
+ case 0:
+ EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
+ EIMSK |= (1 << INT4);
+ break;
+ case 1:
+ EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
+ EIMSK |= (1 << INT5);
+ break;
+ case 6:
+ EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
+ EIMSK |= (1 << INT6);
+ break;
+ case 7:
+ EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
+ EIMSK |= (1 << INT7);
+ break;
+#else
+ case 0:
+ EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
+ EIMSK |= (1 << INT0);
+ break;
+ case 1:
+ EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
+ EIMSK |= (1 << INT1);
+ break;
+#endif
+ }
+ }
+}
+
+void detachInterrupt(uint8_t interruptNum) {
+ if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
+ // Disable the interrupt. (We can't assume that interruptNum is equal
+ // to the number of the EIMSK bit to clear, as this isn't true on the
+ // ATmega8. There, INT0 is 6 and INT1 is 7.)
+ switch (interruptNum) {
+#if defined(__AVR_ATmega1280__)
+ case 2:
+ EIMSK &= ~(1 << INT0);
+ break;
+ case 3:
+ EIMSK &= ~(1 << INT1);
+ break;
+ case 4:
+ EIMSK &= ~(1 << INT2);
+ break;
+ case 5:
+ EIMSK &= ~(1 << INT3);
+ break;
+ case 0:
+ EIMSK &= ~(1 << INT4);
+ break;
+ case 1:
+ EIMSK &= ~(1 << INT5);
+ break;
+ case 6:
+ EIMSK &= ~(1 << INT6);
+ break;
+ case 7:
+ EIMSK &= ~(1 << INT7);
+ break;
+#else
+ case 0:
+ EIMSK &= ~(1 << INT0);
+ break;
+ case 1:
+ EIMSK &= ~(1 << INT1);
+ break;
+#endif
+ }
+
+ intFunc[interruptNum] = 0;
+ }
+}
+
+/*
+void attachInterruptTwi(void (*userFunc)(void) ) {
+ twiIntFunc = userFunc;
+}
+*/
+
+#if defined(__AVR_ATmega1280__)
+
+SIGNAL(INT0_vect) {
+ if(intFunc[EXTERNAL_INT_2])
+ intFunc[EXTERNAL_INT_2]();
+}
+
+SIGNAL(INT1_vect) {
+ if(intFunc[EXTERNAL_INT_3])
+ intFunc[EXTERNAL_INT_3]();
+}
+
+SIGNAL(INT2_vect) {
+ if(intFunc[EXTERNAL_INT_4])
+ intFunc[EXTERNAL_INT_4]();
+}
+
+SIGNAL(INT3_vect) {
+ if(intFunc[EXTERNAL_INT_5])
+ intFunc[EXTERNAL_INT_5]();
+}
+
+SIGNAL(INT4_vect) {
+ if(intFunc[EXTERNAL_INT_0])
+ intFunc[EXTERNAL_INT_0]();
+}
+
+SIGNAL(INT5_vect) {
+ if(intFunc[EXTERNAL_INT_1])
+ intFunc[EXTERNAL_INT_1]();
+}
+
+SIGNAL(INT6_vect) {
+ if(intFunc[EXTERNAL_INT_6])
+ intFunc[EXTERNAL_INT_6]();
+}
+
+SIGNAL(INT7_vect) {
+ if(intFunc[EXTERNAL_INT_7])
+ intFunc[EXTERNAL_INT_7]();
+}
+
+#else
+
+SIGNAL(INT0_vect) {
+ if(intFunc[EXTERNAL_INT_0])
+ intFunc[EXTERNAL_INT_0]();
+}
+
+SIGNAL(INT1_vect) {
+ if(intFunc[EXTERNAL_INT_1])
+ intFunc[EXTERNAL_INT_1]();
+}
+
+#endif
+
+/*
+SIGNAL(SIG_2WIRE_SERIAL) {
+ if(twiIntFunc)
+ twiIntFunc();
+}
+*/
+
diff --git a/cores/arduino/WMath.cpp b/cores/arduino/WMath.cpp
new file mode 100644
index 0000000..2120c4c
--- /dev/null
+++ b/cores/arduino/WMath.cpp
@@ -0,0 +1,60 @@
+/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ Part of the Wiring project - http://wiring.org.co
+ Copyright (c) 2004-06 Hernando Barragan
+ Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
+
+ 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$
+*/
+
+extern "C" {
+ #include "stdlib.h"
+}
+
+void randomSeed(unsigned int seed)
+{
+ if (seed != 0) {
+ srandom(seed);
+ }
+}
+
+long random(long howbig)
+{
+ if (howbig == 0) {
+ return 0;
+ }
+ return random() % howbig;
+}
+
+long random(long howsmall, long howbig)
+{
+ if (howsmall >= howbig) {
+ return howsmall;
+ }
+ long diff = howbig - howsmall;
+ return random(diff) + howsmall;
+}
+
+long map(long x, long in_min, long in_max, long out_min, long out_max)
+{
+ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
+unsigned int makeWord(unsigned int w) { return w; }
+unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; } \ No newline at end of file
diff --git a/cores/arduino/WProgram.h b/cores/arduino/WProgram.h
new file mode 100755
index 0000000..fc14923
--- /dev/null
+++ b/cores/arduino/WProgram.h
@@ -0,0 +1,29 @@
+#ifndef WProgram_h
+#define WProgram_h
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <avr/interrupt.h>
+
+#include "wiring.h"
+
+#ifdef __cplusplus
+#include "HardwareSerial.h"
+
+uint16_t makeWord(uint16_t w);
+uint16_t makeWord(byte h, byte l);
+
+#define word(...) makeWord(__VA_ARGS__)
+
+unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
+
+// WMath prototypes
+long random(long);
+long random(long, long);
+void randomSeed(unsigned int);
+long map(long, long, long, long, long);
+#endif
+
+#endif \ No newline at end of file
diff --git a/cores/arduino/binary.h b/cores/arduino/binary.h
new file mode 100644
index 0000000..af14980
--- /dev/null
+++ b/cores/arduino/binary.h
@@ -0,0 +1,515 @@
+#ifndef Binary_h
+#define Binary_h
+
+#define B0 0
+#define B00 0
+#define B000 0
+#define B0000 0
+#define B00000 0
+#define B000000 0
+#define B0000000 0
+#define B00000000 0
+#define B1 1
+#define B01 1
+#define B001 1
+#define B0001 1
+#define B00001 1
+#define B000001 1
+#define B0000001 1
+#define B00000001 1
+#define B10 2
+#define B010 2
+#define B0010 2
+#define B00010 2
+#define B000010 2
+#define B0000010 2
+#define B00000010 2
+#define B11 3
+#define B011 3
+#define B0011 3
+#define B00011 3
+#define B000011 3
+#define B0000011 3
+#define B00000011 3
+#define B100 4
+#define B0100 4
+#define B00100 4
+#define B000100 4
+#define B0000100 4
+#define B00000100 4
+#define B101 5
+#define B0101 5
+#define B00101 5
+#define B000101 5
+#define B0000101 5
+#define B00000101 5
+#define B110 6
+#define B0110 6
+#define B00110 6
+#define B000110 6
+#define B0000110 6
+#define B00000110 6
+#define B111 7
+#define B0111 7
+#define B00111 7
+#define B000111 7
+#define B0000111 7
+#define B00000111 7
+#define B1000 8
+#define B01000 8
+#define B001000 8
+#define B0001000 8
+#define B00001000 8
+#define B1001 9
+#define B01001 9
+#define B001001 9
+#define B0001001 9
+#define B00001001 9
+#define B1010 10
+#define B01010 10
+#define B001010 10
+#define B0001010 10
+#define B00001010 10
+#define B1011 11
+#define B01011 11
+#define B001011 11
+#define B0001011 11
+#define B00001011 11
+#define B1100 12
+#define B01100 12
+#define B001100 12
+#define B0001100 12
+#define B00001100 12
+#define B1101 13
+#define B01101 13
+#define B001101 13
+#define B0001101 13
+#define B00001101 13
+#define B1110 14
+#define B01110 14
+#define B001110 14
+#define B0001110 14
+#define B00001110 14
+#define B1111 15
+#define B01111 15
+#define B001111 15
+#define B0001111 15
+#define B00001111 15
+#define B10000 16
+#define B010000 16
+#define B0010000 16
+#define B00010000 16
+#define B10001 17
+#define B010001 17
+#define B0010001 17
+#define B00010001 17
+#define B10010 18
+#define B010010 18
+#define B0010010 18
+#define B00010010 18
+#define B10011 19
+#define B010011 19
+#define B0010011 19
+#define B00010011 19
+#define B10100 20
+#define B010100 20
+#define B0010100 20
+#define B00010100 20
+#define B10101 21
+#define B010101 21
+#define B0010101 21
+#define B00010101 21
+#define B10110 22
+#define B010110 22
+#define B0010110 22
+#define B00010110 22
+#define B10111 23
+#define B010111 23
+#define B0010111 23
+#define B00010111 23
+#define B11000 24
+#define B011000 24
+#define B0011000 24
+#define B00011000 24
+#define B11001 25
+#define B011001 25
+#define B0011001 25
+#define B00011001 25
+#define B11010 26
+#define B011010 26
+#define B0011010 26
+#define B00011010 26
+#define B11011 27
+#define B011011 27
+#define B0011011 27
+#define B00011011 27
+#define B11100 28
+#define B011100 28
+#define B0011100 28
+#define B00011100 28
+#define B11101 29
+#define B011101 29
+#define B0011101 29
+#define B00011101 29
+#define B11110 30
+#define B011110 30
+#define B0011110 30
+#define B00011110 30
+#define B11111 31
+#define B011111 31
+#define B0011111 31
+#define B00011111 31
+#define B100000 32
+#define B0100000 32
+#define B00100000 32
+#define B100001 33
+#define B0100001 33
+#define B00100001 33
+#define B100010 34
+#define B0100010 34
+#define B00100010 34
+#define B100011 35
+#define B0100011 35
+#define B00100011 35
+#define B100100 36
+#define B0100100 36
+#define B00100100 36
+#define B100101 37
+#define B0100101 37
+#define B00100101 37
+#define B100110 38
+#define B0100110 38
+#define B00100110 38
+#define B100111 39
+#define B0100111 39
+#define B00100111 39
+#define B101000 40
+#define B0101000 40
+#define B00101000 40
+#define B101001 41
+#define B0101001 41
+#define B00101001 41
+#define B101010 42
+#define B0101010 42
+#define B00101010 42
+#define B101011 43
+#define B0101011 43
+#define B00101011 43
+#define B101100 44
+#define B0101100 44
+#define B00101100 44
+#define B101101 45
+#define B0101101 45
+#define B00101101 45
+#define B101110 46
+#define B0101110 46
+#define B00101110 46
+#define B101111 47
+#define B0101111 47
+#define B00101111 47
+#define B110000 48
+#define B0110000 48
+#define B00110000 48
+#define B110001 49
+#define B0110001 49
+#define B00110001 49
+#define B110010 50
+#define B0110010 50
+#define B00110010 50
+#define B110011 51
+#define B0110011 51
+#define B00110011 51
+#define B110100 52
+#define B0110100 52
+#define B00110100 52
+#define B110101 53
+#define B0110101 53
+#define B00110101 53
+#define B110110 54
+#define B0110110 54
+#define B00110110 54
+#define B110111 55
+#define B0110111 55
+#define B00110111 55
+#define B111000 56
+#define B0111000 56
+#define B00111000 56
+#define B111001 57
+#define B0111001 57
+#define B00111001 57
+#define B111010 58
+#define B0111010 58
+#define B00111010 58
+#define B111011 59
+#define B0111011 59
+#define B00111011 59
+#define B111100 60
+#define B0111100 60
+#define B00111100 60
+#define B111101 61
+#define B0111101 61
+#define B00111101 61
+#define B111110 62
+#define B0111110 62
+#define B00111110 62
+#define B111111 63
+#define B0111111 63
+#define B00111111 63
+#define B1000000 64
+#define B01000000 64
+#define B1000001 65
+#define B01000001 65
+#define B1000010 66
+#define B01000010 66
+#define B1000011 67
+#define B01000011 67
+#define B1000100 68
+#define B01000100 68
+#define B1000101 69
+#define B01000101 69
+#define B1000110 70
+#define B01000110 70
+#define B1000111 71
+#define B01000111 71
+#define B1001000 72
+#define B01001000 72
+#define B1001001 73
+#define B01001001 73
+#define B1001010 74
+#define B01001010 74
+#define B1001011 75
+#define B01001011 75
+#define B1001100 76
+#define B01001100 76
+#define B1001101 77
+#define B01001101 77
+#define B1001110 78
+#define B01001110 78
+#define B1001111 79
+#define B01001111 79
+#define B1010000 80
+#define B01010000 80
+#define B1010001 81
+#define B01010001 81
+#define B1010010 82
+#define B01010010 82
+#define B1010011 83
+#define B01010011 83
+#define B1010100 84
+#define B01010100 84
+#define B1010101 85
+#define B01010101 85
+#define B1010110 86
+#define B01010110 86
+#define B1010111 87
+#define B01010111 87
+#define B1011000 88
+#define B01011000 88
+#define B1011001 89
+#define B01011001 89
+#define B1011010 90
+#define B01011010 90
+#define B1011011 91
+#define B01011011 91
+#define B1011100 92
+#define B01011100 92
+#define B1011101 93
+#define B01011101 93
+#define B1011110 94
+#define B01011110 94
+#define B1011111 95
+#define B01011111 95
+#define B1100000 96
+#define B01100000 96
+#define B1100001 97
+#define B01100001 97
+#define B1100010 98
+#define B01100010 98
+#define B1100011 99
+#define B01100011 99
+#define B1100100 100
+#define B01100100 100
+#define B1100101 101
+#define B01100101 101
+#define B1100110 102
+#define B01100110 102
+#define B1100111 103
+#define B01100111 103
+#define B1101000 104
+#define B01101000 104
+#define B1101001 105
+#define B01101001 105
+#define B1101010 106
+#define B01101010 106
+#define B1101011 107
+#define B01101011 107
+#define B1101100 108
+#define B01101100 108
+#define B1101101 109
+#define B01101101 109
+#define B1101110 110
+#define B01101110 110
+#define B1101111 111
+#define B01101111 111
+#define B1110000 112
+#define B01110000 112
+#define B1110001 113
+#define B01110001 113
+#define B1110010 114
+#define B01110010 114
+#define B1110011 115
+#define B01110011 115
+#define B1110100 116
+#define B01110100 116
+#define B1110101 117
+#define B01110101 117
+#define B1110110 118
+#define B01110110 118
+#define B1110111 119
+#define B01110111 119
+#define B1111000 120
+#define B01111000 120
+#define B1111001 121
+#define B01111001 121
+#define B1111010 122
+#define B01111010 122
+#define B1111011 123
+#define B01111011 123
+#define B1111100 124
+#define B01111100 124
+#define B1111101 125
+#define B01111101 125
+#define B1111110 126
+#define B01111110 126
+#define B1111111 127
+#define B01111111 127
+#define B10000000 128
+#define B10000001 129
+#define B10000010 130
+#define B10000011 131
+#define B10000100 132
+#define B10000101 133
+#define B10000110 134
+#define B10000111 135
+#define B10001000 136
+#define B10001001 137
+#define B10001010 138
+#define B10001011 139
+#define B10001100 140
+#define B10001101 141
+#define B10001110 142
+#define B10001111 143
+#define B10010000 144
+#define B10010001 145
+#define B10010010 146
+#define B10010011 147
+#define B10010100 148
+#define B10010101 149
+#define B10010110 150
+#define B10010111 151
+#define B10011000 152
+#define B10011001 153
+#define B10011010 154
+#define B10011011 155
+#define B10011100 156
+#define B10011101 157
+#define B10011110 158
+#define B10011111 159
+#define B10100000 160
+#define B10100001 161
+#define B10100010 162
+#define B10100011 163
+#define B10100100 164
+#define B10100101 165
+#define B10100110 166
+#define B10100111 167
+#define B10101000 168
+#define B10101001 169
+#define B10101010 170
+#define B10101011 171
+#define B10101100 172
+#define B10101101 173
+#define B10101110 174
+#define B10101111 175
+#define B10110000 176
+#define B10110001 177
+#define B10110010 178
+#define B10110011 179
+#define B10110100 180
+#define B10110101 181
+#define B10110110 182
+#define B10110111 183
+#define B10111000 184
+#define B10111001 185
+#define B10111010 186
+#define B10111011 187
+#define B10111100 188
+#define B10111101 189
+#define B10111110 190
+#define B10111111 191
+#define B11000000 192
+#define B11000001 193
+#define B11000010 194
+#define B11000011 195
+#define B11000100 196
+#define B11000101 197
+#define B11000110 198
+#define B11000111 199
+#define B11001000 200
+#define B11001001 201
+#define B11001010 202
+#define B11001011 203
+#define B11001100 204
+#define B11001101 205
+#define B11001110 206
+#define B11001111 207
+#define B11010000 208
+#define B11010001 209
+#define B11010010 210
+#define B11010011 211
+#define B11010100 212
+#define B11010101 213
+#define B11010110 214
+#define B11010111 215
+#define B11011000 216
+#define B11011001 217
+#define B11011010 218
+#define B11011011 219
+#define B11011100 220
+#define B11011101 221
+#define B11011110 222
+#define B11011111 223
+#define B11100000 224
+#define B11100001 225
+#define B11100010 226
+#define B11100011 227
+#define B11100100 228
+#define B11100101 229
+#define B11100110 230
+#define B11100111 231
+#define B11101000 232
+#define B11101001 233
+#define B11101010 234
+#define B11101011 235
+#define B11101100 236
+#define B11101101 237
+#define B11101110 238
+#define B11101111 239
+#define B11110000 240
+#define B11110001 241
+#define B11110010 242
+#define B11110011 243
+#define B11110100 244
+#define B11110101 245
+#define B11110110 246
+#define B11110111 247
+#define B11111000 248
+#define B11111001 249
+#define B11111010 250
+#define B11111011 251
+#define B11111100 252
+#define B11111101 253
+#define B11111110 254
+#define B11111111 255
+
+#endif
diff --git a/cores/arduino/main.cxx b/cores/arduino/main.cxx
new file mode 100755
index 0000000..52351e4
--- /dev/null
+++ b/cores/arduino/main.cxx
@@ -0,0 +1,12 @@
+int main(void)
+{
+ init();
+
+ setup();
+
+ for (;;)
+ loop();
+
+ return 0;
+}
+
diff --git a/cores/arduino/pins_arduino.c b/cores/arduino/pins_arduino.c
new file mode 100755
index 0000000..1c1c088
--- /dev/null
+++ b/cores/arduino/pins_arduino.c
@@ -0,0 +1,469 @@
+/*
+ pins_arduino.c - pin definitions for the Arduino board
+ Part of Arduino / Wiring Lite
+
+ Copyright (c) 2005 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$
+*/
+
+#include <avr/io.h>
+#include "wiring_private.h"
+#include "pins_arduino.h"
+
+// On the Arduino board, digital pins are also used
+// for the analog output (software PWM). Analog input
+// pins are a separate set.
+
+// ATMEL ATMEGA8 & 168 / ARDUINO
+//
+// +-\/-+
+// PC6 1| |28 PC5 (AI 5)
+// (D 0) PD0 2| |27 PC4 (AI 4)
+// (D 1) PD1 3| |26 PC3 (AI 3)
+// (D 2) PD2 4| |25 PC2 (AI 2)
+// PWM+ (D 3) PD3 5| |24 PC1 (AI 1)
+// (D 4) PD4 6| |23 PC0 (AI 0)
+// VCC 7| |22 GND
+// GND 8| |21 AREF
+// PB6 9| |20 AVCC
+// PB7 10| |19 PB5 (D 13)
+// PWM+ (D 5) PD5 11| |18 PB4 (D 12)
+// PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM
+// (D 7) PD7 13| |16 PB2 (D 10) PWM
+// (D 8) PB0 14| |15 PB1 (D 9) PWM
+// +----+
+//
+// (PWM+ indicates the additional PWM pins on the ATmega168.)
+
+// ATMEL ATMEGA1280 / ARDUINO
+//
+// 0-7 PE0-PE7 works
+// 8-13 PB0-PB5 works
+// 14-21 PA0-PA7 works
+// 22-29 PH0-PH7 works
+// 30-35 PG5-PG0 works
+// 36-43 PC7-PC0 works
+// 44-51 PJ7-PJ0 works
+// 52-59 PL7-PL0 works
+// 60-67 PD7-PD0 works
+// A0-A7 PF0-PF7
+// A8-A15 PK0-PK7
+
+#define PA 1
+#define PB 2
+#define PC 3
+#define PD 4
+#define PE 5
+#define PF 6
+#define PG 7
+#define PH 8
+#define PJ 10
+#define PK 11
+#define PL 12
+
+#define REPEAT8(x) x, x, x, x, x, x, x, x
+#define BV0TO7 _BV(0), _BV(1), _BV(2), _BV(3), _BV(4), _BV(5), _BV(6), _BV(7)
+#define BV7TO0 _BV(7), _BV(6), _BV(5), _BV(4), _BV(3), _BV(2), _BV(1), _BV(0)
+
+
+#if defined(__AVR_ATmega1280__)
+const uint16_t PROGMEM port_to_mode_PGM[] = {
+ NOT_A_PORT,
+ &DDRA,
+ &DDRB,
+ &DDRC,
+ &DDRD,
+ &DDRE,
+ &DDRF,
+ &DDRG,
+ &DDRH,
+ NOT_A_PORT,
+ &DDRJ,
+ &DDRK,
+ &DDRL,
+};
+
+const uint16_t PROGMEM port_to_output_PGM[] = {
+ NOT_A_PORT,
+ &PORTA,
+ &PORTB,
+ &PORTC,
+ &PORTD,
+ &PORTE,
+ &PORTF,
+ &PORTG,
+ &PORTH,
+ NOT_A_PORT,
+ &PORTJ,
+ &PORTK,
+ &PORTL,
+};
+
+const uint16_t PROGMEM port_to_input_PGM[] = {
+ NOT_A_PIN,
+ &PINA,
+ &PINB,
+ &PINC,
+ &PIND,
+ &PINE,
+ &PINF,
+ &PING,
+ &PINH,
+ NOT_A_PIN,
+ &PINJ,
+ &PINK,
+ &PINL,
+};
+
+const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
+ // PORTLIST
+ // -------------------------------------------
+ PE , // PE 0 ** 0 ** USART0_RX
+ PE , // PE 1 ** 1 ** USART0_TX
+ PE , // PE 4 ** 2 ** PWM2
+ PE , // PE 5 ** 3 ** PWM3
+ PG , // PG 5 ** 4 ** PWM4
+ PE , // PE 3 ** 5 ** PWM5
+ PH , // PH 3 ** 6 ** PWM6
+ PH , // PH 4 ** 7 ** PWM7
+ PH , // PH 5 ** 8 ** PWM8
+ PH , // PH 6 ** 9 ** PWM9
+ PB , // PB 4 ** 10 ** PWM10
+ PB , // PB 5 ** 11 ** PWM11
+ PB , // PB 6 ** 12 ** PWM12
+ PB , // PB 7 ** 13 ** PWM13
+ PJ , // PJ 1 ** 14 ** USART3_TX
+ PJ , // PJ 0 ** 15 ** USART3_RX
+ PH , // PH 1 ** 16 ** USART2_TX
+ PH , // PH 0 ** 17 ** USART2_RX
+ PD , // PD 3 ** 18 ** USART1_TX
+ PD , // PD 2 ** 19 ** USART1_RX
+ PD , // PD 1 ** 20 ** I2C_SDA
+ PD , // PD 0 ** 21 ** I2C_SCL
+ PA , // PA 0 ** 22 ** D22
+ PA , // PA 1 ** 23 ** D23
+ PA , // PA 2 ** 24 ** D24
+ PA , // PA 3 ** 25 ** D25
+ PA , // PA 4 ** 26 ** D26
+ PA , // PA 5 ** 27 ** D27
+ PA , // PA 6 ** 28 ** D28
+ PA , // PA 7 ** 29 ** D29
+ PC , // PC 7 ** 30 ** D30
+ PC , // PC 6 ** 31 ** D31
+ PC , // PC 5 ** 32 ** D32
+ PC , // PC 4 ** 33 ** D33
+ PC , // PC 3 ** 34 ** D34
+ PC , // PC 2 ** 35 ** D35
+ PC , // PC 1 ** 36 ** D36
+ PC , // PC 0 ** 37 ** D37
+ PD , // PD 7 ** 38 ** D38
+ PG , // PG 2 ** 39 ** D39
+ PG , // PG 1 ** 40 ** D40
+ PG , // PG 0 ** 41 ** D41
+ PL , // PL 7 ** 42 ** D42
+ PL , // PL 6 ** 43 ** D43
+ PL , // PL 5 ** 44 ** D44
+ PL , // PL 4 ** 45 ** D45
+ PL , // PL 3 ** 46 ** D46
+ PL , // PL 2 ** 47 ** D47
+ PL , // PL 1 ** 48 ** D48
+ PL , // PL 0 ** 49 ** D49
+ PB , // PB 3 ** 50 ** SPI_MISO
+ PB , // PB 2 ** 51 ** SPI_MOSI
+ PB , // PB 1 ** 52 ** SPI_SCK
+ PB , // PB 0 ** 53 ** SPI_SS
+ PF , // PF 0 ** 54 ** A0
+ PF , // PF 1 ** 55 ** A1
+ PF , // PF 2 ** 56 ** A2
+ PF , // PF 3 ** 57 ** A3
+ PF , // PF 4 ** 58 ** A4
+ PF , // PF 5 ** 59 ** A5
+ PF , // PF 6 ** 60 ** A6
+ PF , // PF 7 ** 61 ** A7
+ PK , // PK 0 ** 62 ** A8
+ PK , // PK 1 ** 63 ** A9
+ PK , // PK 2 ** 64 ** A10
+ PK , // PK 3 ** 65 ** A11
+ PK , // PK 4 ** 66 ** A12
+ PK , // PK 5 ** 67 ** A13
+ PK , // PK 6 ** 68 ** A14
+ PK , // PK 7 ** 69 ** A15
+};
+
+const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
+ // PIN IN PORT
+ // -------------------------------------------
+ _BV( 0 ) , // PE 0 ** 0 ** USART0_RX
+ _BV( 1 ) , // PE 1 ** 1 ** USART0_TX
+ _BV( 4 ) , // PE 4 ** 2 ** PWM2
+ _BV( 5 ) , // PE 5 ** 3 ** PWM3
+ _BV( 5 ) , // PG 5 ** 4 ** PWM4
+ _BV( 3 ) , // PE 3 ** 5 ** PWM5
+ _BV( 3 ) , // PH 3 ** 6 ** PWM6
+ _BV( 4 ) , // PH 4 ** 7 ** PWM7
+ _BV( 5 ) , // PH 5 ** 8 ** PWM8
+ _BV( 6 ) , // PH 6 ** 9 ** PWM9
+ _BV( 4 ) , // PB 4 ** 10 ** PWM10
+ _BV( 5 ) , // PB 5 ** 11 ** PWM11
+ _BV( 6 ) , // PB 6 ** 12 ** PWM12
+ _BV( 7 ) , // PB 7 ** 13 ** PWM13
+ _BV( 1 ) , // PJ 1 ** 14 ** USART3_TX
+ _BV( 0 ) , // PJ 0 ** 15 ** USART3_RX
+ _BV( 1 ) , // PH 1 ** 16 ** USART2_TX
+ _BV( 0 ) , // PH 0 ** 17 ** USART2_RX
+ _BV( 3 ) , // PD 3 ** 18 ** USART1_TX
+ _BV( 2 ) , // PD 2 ** 19 ** USART1_RX
+ _BV( 1 ) , // PD 1 ** 20 ** I2C_SDA
+ _BV( 0 ) , // PD 0 ** 21 ** I2C_SCL
+ _BV( 0 ) , // PA 0 ** 22 ** D22
+ _BV( 1 ) , // PA 1 ** 23 ** D23
+ _BV( 2 ) , // PA 2 ** 24 ** D24
+ _BV( 3 ) , // PA 3 ** 25 ** D25
+ _BV( 4 ) , // PA 4 ** 26 ** D26
+ _BV( 5 ) , // PA 5 ** 27 ** D27
+ _BV( 6 ) , // PA 6 ** 28 ** D28
+ _BV( 7 ) , // PA 7 ** 29 ** D29
+ _BV( 7 ) , // PC 7 ** 30 ** D30
+ _BV( 6 ) , // PC 6 ** 31 ** D31
+ _BV( 5 ) , // PC 5 ** 32 ** D32
+ _BV( 4 ) , // PC 4 ** 33 ** D33
+ _BV( 3 ) , // PC 3 ** 34 ** D34
+ _BV( 2 ) , // PC 2 ** 35 ** D35
+ _BV( 1 ) , // PC 1 ** 36 ** D36
+ _BV( 0 ) , // PC 0 ** 37 ** D37
+ _BV( 7 ) , // PD 7 ** 38 ** D38
+ _BV( 2 ) , // PG 2 ** 39 ** D39
+ _BV( 1 ) , // PG 1 ** 40 ** D40
+ _BV( 0 ) , // PG 0 ** 41 ** D41
+ _BV( 7 ) , // PL 7 ** 42 ** D42
+ _BV( 6 ) , // PL 6 ** 43 ** D43
+ _BV( 5 ) , // PL 5 ** 44 ** D44
+ _BV( 4 ) , // PL 4 ** 45 ** D45
+ _BV( 3 ) , // PL 3 ** 46 ** D46
+ _BV( 2 ) , // PL 2 ** 47 ** D47
+ _BV( 1 ) , // PL 1 ** 48 ** D48
+ _BV( 0 ) , // PL 0 ** 49 ** D49
+ _BV( 3 ) , // PB 3 ** 50 ** SPI_MISO
+ _BV( 2 ) , // PB 2 ** 51 ** SPI_MOSI
+ _BV( 1 ) , // PB 1 ** 52 ** SPI_SCK
+ _BV( 0 ) , // PB 0 ** 53 ** SPI_SS
+ _BV( 0 ) , // PF 0 ** 54 ** A0
+ _BV( 1 ) , // PF 1 ** 55 ** A1
+ _BV( 2 ) , // PF 2 ** 56 ** A2
+ _BV( 3 ) , // PF 3 ** 57 ** A3
+ _BV( 4 ) , // PF 4 ** 58 ** A4
+ _BV( 5 ) , // PF 5 ** 59 ** A5
+ _BV( 6 ) , // PF 6 ** 60 ** A6
+ _BV( 7 ) , // PF 7 ** 61 ** A7
+ _BV( 0 ) , // PK 0 ** 62 ** A8
+ _BV( 1 ) , // PK 1 ** 63 ** A9
+ _BV( 2 ) , // PK 2 ** 64 ** A10
+ _BV( 3 ) , // PK 3 ** 65 ** A11
+ _BV( 4 ) , // PK 4 ** 66 ** A12
+ _BV( 5 ) , // PK 5 ** 67 ** A13
+ _BV( 6 ) , // PK 6 ** 68 ** A14
+ _BV( 7 ) , // PK 7 ** 69 ** A15
+};
+
+const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
+ // TIMERS
+ // -------------------------------------------
+ NOT_ON_TIMER , // PE 0 ** 0 ** USART0_RX
+ NOT_ON_TIMER , // PE 1 ** 1 ** USART0_TX
+ TIMER3B , // PE 4 ** 2 ** PWM2
+ TIMER3C , // PE 5 ** 3 ** PWM3
+ TIMER0B , // PG 5 ** 4 ** PWM4
+ TIMER3A , // PE 3 ** 5 ** PWM5
+ TIMER4A , // PH 3 ** 6 ** PWM6
+ TIMER4B , // PH 4 ** 7 ** PWM7
+ TIMER4C , // PH 5 ** 8 ** PWM8
+ TIMER2B , // PH 6 ** 9 ** PWM9
+ TIMER2A , // PB 4 ** 10 ** PWM10
+ TIMER1A , // PB 5 ** 11 ** PWM11
+ TIMER1B , // PB 6 ** 12 ** PWM12
+ TIMER0A , // PB 7 ** 13 ** PWM13
+ NOT_ON_TIMER , // PJ 1 ** 14 ** USART3_TX
+ NOT_ON_TIMER , // PJ 0 ** 15 ** USART3_RX
+ NOT_ON_TIMER , // PH 1 ** 16 ** USART2_TX
+ NOT_ON_TIMER , // PH 0 ** 17 ** USART2_RX
+ NOT_ON_TIMER , // PD 3 ** 18 ** USART1_TX
+ NOT_ON_TIMER , // PD 2 ** 19 ** USART1_RX
+ NOT_ON_TIMER , // PD 1 ** 20 ** I2C_SDA
+ NOT_ON_TIMER , // PD 0 ** 21 ** I2C_SCL
+ NOT_ON_TIMER , // PA 0 ** 22 ** D22
+ NOT_ON_TIMER , // PA 1 ** 23 ** D23
+ NOT_ON_TIMER , // PA 2 ** 24 ** D24
+ NOT_ON_TIMER , // PA 3 ** 25 ** D25
+ NOT_ON_TIMER , // PA 4 ** 26 ** D26
+ NOT_ON_TIMER , // PA 5 ** 27 ** D27
+ NOT_ON_TIMER , // PA 6 ** 28 ** D28
+ NOT_ON_TIMER , // PA 7 ** 29 ** D29
+ NOT_ON_TIMER , // PC 7 ** 30 ** D30
+ NOT_ON_TIMER , // PC 6 ** 31 ** D31
+ NOT_ON_TIMER , // PC 5 ** 32 ** D32
+ NOT_ON_TIMER , // PC 4 ** 33 ** D33
+ NOT_ON_TIMER , // PC 3 ** 34 ** D34
+ NOT_ON_TIMER , // PC 2 ** 35 ** D35
+ NOT_ON_TIMER , // PC 1 ** 36 ** D36
+ NOT_ON_TIMER , // PC 0 ** 37 ** D37
+ NOT_ON_TIMER , // PD 7 ** 38 ** D38
+ NOT_ON_TIMER , // PG 2 ** 39 ** D39
+ NOT_ON_TIMER , // PG 1 ** 40 ** D40
+ NOT_ON_TIMER , // PG 0 ** 41 ** D41
+ NOT_ON_TIMER , // PL 7 ** 42 ** D42
+ NOT_ON_TIMER , // PL 6 ** 43 ** D43
+ TIMER5C , // PL 5 ** 44 ** D44
+ TIMER5B , // PL 4 ** 45 ** D45
+ TIMER5A , // PL 3 ** 46 ** D46
+ NOT_ON_TIMER , // PL 2 ** 47 ** D47
+ NOT_ON_TIMER , // PL 1 ** 48 ** D48
+ NOT_ON_TIMER , // PL 0 ** 49 ** D49
+ NOT_ON_TIMER , // PB 3 ** 50 ** SPI_MISO
+ NOT_ON_TIMER , // PB 2 ** 51 ** SPI_MOSI
+ NOT_ON_TIMER , // PB 1 ** 52 ** SPI_SCK
+ NOT_ON_TIMER , // PB 0 ** 53 ** SPI_SS
+ NOT_ON_TIMER , // PF 0 ** 54 ** A0
+ NOT_ON_TIMER , // PF 1 ** 55 ** A1
+ NOT_ON_TIMER , // PF 2 ** 56 ** A2
+ NOT_ON_TIMER , // PF 3 ** 57 ** A3
+ NOT_ON_TIMER , // PF 4 ** 58 ** A4
+ NOT_ON_TIMER , // PF 5 ** 59 ** A5
+ NOT_ON_TIMER , // PF 6 ** 60 ** A6
+ NOT_ON_TIMER , // PF 7 ** 61 ** A7
+ NOT_ON_TIMER , // PK 0 ** 62 ** A8
+ NOT_ON_TIMER , // PK 1 ** 63 ** A9
+ NOT_ON_TIMER , // PK 2 ** 64 ** A10
+ NOT_ON_TIMER , // PK 3 ** 65 ** A11
+ NOT_ON_TIMER , // PK 4 ** 66 ** A12
+ NOT_ON_TIMER , // PK 5 ** 67 ** A13
+ NOT_ON_TIMER , // PK 6 ** 68 ** A14
+ NOT_ON_TIMER , // PK 7 ** 69 ** A15
+};
+#else
+// 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,
+ &DDRB,
+ &DDRC,
+ &DDRD,
+};
+
+const uint16_t PROGMEM port_to_output_PGM[] = {
+ NOT_A_PORT,
+ NOT_A_PORT,
+ &PORTB,
+ &PORTC,
+ &PORTD,
+};
+
+const uint16_t PROGMEM port_to_input_PGM[] = {
+ NOT_A_PORT,
+ NOT_A_PORT,
+ &PINB,
+ &PINC,
+ &PIND,
+};
+
+const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
+ PD, /* 0 */
+ PD,
+ PD,
+ PD,
+ PD,
+ PD,
+ PD,
+ PD,
+ PB, /* 8 */
+ PB,
+ PB,
+ PB,
+ PB,
+ PB,
+ PC, /* 14 */
+ PC,
+ PC,
+ PC,
+ PC,
+ PC,
+};
+
+const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
+ _BV(0), /* 0, port D */
+ _BV(1),
+ _BV(2),
+ _BV(3),
+ _BV(4),
+ _BV(5),
+ _BV(6),
+ _BV(7),
+ _BV(0), /* 8, port B */
+ _BV(1),
+ _BV(2),
+ _BV(3),
+ _BV(4),
+ _BV(5),
+ _BV(0), /* 14, port C */
+ _BV(1),
+ _BV(2),
+ _BV(3),
+ _BV(4),
+ _BV(5),
+};
+
+const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
+ NOT_ON_TIMER, /* 0 - port D */
+ NOT_ON_TIMER,
+ NOT_ON_TIMER,
+ // on the ATmega168, digital pin 3 has hardware pwm
+#if defined(__AVR_ATmega8__)
+ NOT_ON_TIMER,
+#else
+ TIMER2B,
+#endif
+ NOT_ON_TIMER,
+ // on the ATmega168, digital pins 5 and 6 have hardware pwm
+#if defined(__AVR_ATmega8__)
+ NOT_ON_TIMER,
+ NOT_ON_TIMER,
+#else
+ TIMER0B,
+ TIMER0A,
+#endif
+ NOT_ON_TIMER,
+ NOT_ON_TIMER, /* 8 - port B */
+ TIMER1A,
+ TIMER1B,
+#if defined(__AVR_ATmega8__)
+ TIMER2,
+#else
+ TIMER2A,
+#endif
+ NOT_ON_TIMER,
+ NOT_ON_TIMER,
+ NOT_ON_TIMER,
+ NOT_ON_TIMER, /* 14 - port C */
+ NOT_ON_TIMER,
+ NOT_ON_TIMER,
+ NOT_ON_TIMER,
+ NOT_ON_TIMER,
+};
+#endif
diff --git a/cores/arduino/pins_arduino.h b/cores/arduino/pins_arduino.h
new file mode 100644
index 0000000..c7e40fd
--- /dev/null
+++ b/cores/arduino/pins_arduino.h
@@ -0,0 +1,76 @@
+/*
+ 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 <avr/pgmspace.h>
+
+#define NOT_A_PIN 0
+#define NOT_A_PORT 0
+
+#define NOT_ON_TIMER 0
+#define TIMER0A 1
+#define TIMER0B 2
+#define TIMER1A 3
+#define TIMER1B 4
+#define TIMER2 5
+#define TIMER2A 6
+#define TIMER2B 7
+
+#define TIMER3A 8
+#define TIMER3B 9
+#define TIMER3C 10
+#define TIMER4A 11
+#define TIMER4B 12
+#define TIMER4C 13
+#define TIMER5A 14
+#define TIMER5B 15
+#define TIMER5C 16
+
+// On the ATmega1280, the addresses of some of the port registers are
+// greater than 255, so we can't store them in uint8_t's.
+extern const uint16_t PROGMEM port_to_mode_PGM[];
+extern const uint16_t PROGMEM port_to_input_PGM[];
+extern const uint16_t PROGMEM port_to_output_PGM[];
+
+extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
+// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
+extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
+extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
+
+// Get the bit location within the hardware port of the given virtual pin.
+// This comes from the pins_*.c file for the active board configuration.
+//
+// These perform slightly better as macros compared to inline functions
+//
+#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
+#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
+#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
+#define analogInPinToBit(P) (P)
+#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
+#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
+#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
+
+#endif
diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c
new file mode 100755
index 0000000..72bc282
--- /dev/null
+++ b/cores/arduino/wiring.c
@@ -0,0 +1,250 @@
+/*
+ wiring.c - Partial implementation of the Wiring API for the ATmega8.
+ Part of Arduino - http://www.arduino.cc/
+
+ Copyright (c) 2005-2006 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$
+*/
+
+#include "wiring_private.h"
+
+// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
+// the overflow handler is called every 256 ticks.
+#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
+
+// the whole number of milliseconds per timer0 overflow
+#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
+
+// the fractional number of milliseconds per timer0 overflow. we shift right
+// by three to fit these numbers into a byte. (for the clock speeds we care
+// about - 8 and 16 MHz - this doesn't lose precision.)
+#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
+#define FRACT_MAX (1000 >> 3)
+
+volatile unsigned long timer0_overflow_count = 0;
+volatile unsigned long timer0_millis = 0;
+static unsigned char timer0_fract = 0;
+
+SIGNAL(TIMER0_OVF_vect)
+{
+ // copy these to local variables so they can be stored in registers
+ // (volatile variables must be read from memory on every access)
+ unsigned long m = timer0_millis;
+ unsigned char f = timer0_fract;
+
+ m += MILLIS_INC;
+ f += FRACT_INC;
+ if (f >= FRACT_MAX) {
+ f -= FRACT_MAX;
+ m += 1;
+ }
+
+ timer0_fract = f;
+ timer0_millis = m;
+ timer0_overflow_count++;
+}
+
+unsigned long millis()
+{
+ unsigned long m;
+ uint8_t oldSREG = SREG;
+
+ // disable interrupts while we read timer0_millis or we might get an
+ // inconsistent value (e.g. in the middle of a write to timer0_millis)
+ cli();
+ m = timer0_millis;
+ SREG = oldSREG;
+
+ return m;
+}
+
+unsigned long micros() {
+ unsigned long m, t;
+ uint8_t oldSREG = SREG;
+
+ cli();
+ t = TCNT0;
+
+#ifdef TIFR0
+ if ((TIFR0 & _BV(TOV0)) && (t == 0))
+ t = 256;
+#else
+ if ((TIFR & _BV(TOV0)) && (t == 0))
+ t = 256;
+#endif
+
+ m = timer0_overflow_count;
+ SREG = oldSREG;
+
+ return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
+}
+
+void delay(unsigned long ms)
+{
+ unsigned long start = millis();
+
+ while (millis() - start <= ms)
+ ;
+}
+
+/* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock.
+ * Disables interrupts, which will disrupt the millis() function if used
+ * too frequently. */
+void delayMicroseconds(unsigned int us)
+{
+ uint8_t oldSREG;
+
+ // calling avrlib's delay_us() function with low values (e.g. 1 or
+ // 2 microseconds) gives delays longer than desired.
+ //delay_us(us);
+
+#if F_CPU >= 16000000L
+ // for the 16 MHz clock on most Arduino boards
+
+ // for a one-microsecond delay, simply return. the overhead
+ // of the function call yields a delay of approximately 1 1/8 us.
+ if (--us == 0)
+ return;
+
+ // the following loop takes a quarter of a microsecond (4 cycles)
+ // per iteration, so execute it four times for each microsecond of
+ // delay requested.
+ us <<= 2;
+
+ // account for the time taken in the preceeding commands.
+ us -= 2;
+#else
+ // for the 8 MHz internal clock on the ATmega168
+
+ // for a one- or two-microsecond delay, simply return. the overhead of
+ // the function calls takes more than two microseconds. can't just
+ // subtract two, since us is unsigned; we'd overflow.
+ if (--us == 0)
+ return;
+ if (--us == 0)
+ return;
+
+ // the following loop takes half of a microsecond (4 cycles)
+ // per iteration, so execute it twice for each microsecond of
+ // delay requested.
+ us <<= 1;
+
+ // partially compensate for the time taken by the preceeding commands.
+ // we can't subtract any more than this or we'd overflow w/ small delays.
+ us--;
+#endif
+
+ // disable interrupts, otherwise the timer 0 overflow interrupt that
+ // tracks milliseconds will make us delay longer than we want.
+ oldSREG = SREG;
+ cli();
+
+ // busy wait
+ __asm__ __volatile__ (
+ "1: sbiw %0,1" "\n\t" // 2 cycles
+ "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
+ );
+
+ // reenable interrupts.
+ SREG = oldSREG;
+}
+
+void init()
+{
+ // this needs to be called before setup() or some functions won't
+ // work there
+ sei();
+
+ // on the ATmega168, timer 0 is also used for fast hardware pwm
+ // (using phase-correct PWM would mean that timer 0 overflowed half as often
+ // resulting in different millis() behavior on the ATmega8 and ATmega168)
+#if !defined(__AVR_ATmega8__)
+ sbi(TCCR0A, WGM01);
+ sbi(TCCR0A, WGM00);
+#endif
+ // set timer 0 prescale factor to 64
+#if defined(__AVR_ATmega8__)
+ sbi(TCCR0, CS01);
+ sbi(TCCR0, CS00);
+#else
+ sbi(TCCR0B, CS01);
+ sbi(TCCR0B, CS00);
+#endif
+ // enable timer 0 overflow interrupt
+#if defined(__AVR_ATmega8__)
+ sbi(TIMSK, TOIE0);
+#else
+ sbi(TIMSK0, TOIE0);
+#endif
+
+ // timers 1 and 2 are used for phase-correct hardware pwm
+ // this is better for motors as it ensures an even waveform
+ // note, however, that fast pwm mode can achieve a frequency of up
+ // 8 MHz (with a 16 MHz clock) at 50% duty cycle
+
+ // set timer 1 prescale factor to 64
+ sbi(TCCR1B, CS11);
+ sbi(TCCR1B, CS10);
+ // put timer 1 in 8-bit phase correct pwm mode
+ sbi(TCCR1A, WGM10);
+
+ // set timer 2 prescale factor to 64
+#if defined(__AVR_ATmega8__)
+ sbi(TCCR2, CS22);
+#else
+ sbi(TCCR2B, CS22);
+#endif
+ // configure timer 2 for phase correct pwm (8-bit)
+#if defined(__AVR_ATmega8__)
+ sbi(TCCR2, WGM20);
+#else
+ sbi(TCCR2A, WGM20);
+#endif
+
+#if defined(__AVR_ATmega1280__)
+ // set timer 3, 4, 5 prescale factor to 64
+ sbi(TCCR3B, CS31); sbi(TCCR3B, CS30);
+ sbi(TCCR4B, CS41); sbi(TCCR4B, CS40);
+ sbi(TCCR5B, CS51); sbi(TCCR5B, CS50);
+ // put timer 3, 4, 5 in 8-bit phase correct pwm mode
+ sbi(TCCR3A, WGM30);
+ sbi(TCCR4A, WGM40);
+ sbi(TCCR5A, WGM50);
+#endif
+
+ // set a2d prescale factor to 128
+ // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
+ // XXX: this will not work properly for other clock speeds, and
+ // this code should use F_CPU to determine the prescale factor.
+ sbi(ADCSRA, ADPS2);
+ sbi(ADCSRA, ADPS1);
+ sbi(ADCSRA, ADPS0);
+
+ // enable a2d conversions
+ sbi(ADCSRA, ADEN);
+
+ // the bootloader connects pins 0 and 1 to the USART; disconnect them
+ // here so they can be used as normal digital i/o; they will be
+ // reconnected in Serial.begin()
+#if defined(__AVR_ATmega8__)
+ UCSRB = 0;
+#else
+ UCSR0B = 0;
+#endif
+} \ No newline at end of file
diff --git a/cores/arduino/wiring.h b/cores/arduino/wiring.h
new file mode 100755
index 0000000..f0ba04c
--- /dev/null
+++ b/cores/arduino/wiring.h
@@ -0,0 +1,137 @@
+/*
+ wiring.h - Partial implementation of the Wiring API for the ATmega8.
+ Part of Arduino - http://www.arduino.cc/
+
+ Copyright (c) 2005-2006 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$
+*/
+
+#ifndef Wiring_h
+#define Wiring_h
+
+#include <avr/io.h>
+#include "binary.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#ifndef ARDUINO
+#define ARDUINO 16
+#endif
+
+#define HIGH 0x1
+#define LOW 0x0
+
+#define INPUT 0x0
+#define OUTPUT 0x1
+
+#define true 0x1
+#define false 0x0
+
+#define PI 3.1415926535897932384626433832795
+#define HALF_PI 1.5707963267948966192313216916398
+#define TWO_PI 6.283185307179586476925286766559
+#define DEG_TO_RAD 0.017453292519943295769236907684886
+#define RAD_TO_DEG 57.295779513082320876798154814105
+
+#define SERIAL 0x0
+#define DISPLAY 0x1
+
+#define LSBFIRST 0
+#define MSBFIRST 1
+
+#define CHANGE 1
+#define FALLING 2
+#define RISING 3
+
+#define INTERNAL 3
+#define DEFAULT 1
+#define EXTERNAL 0
+
+// undefine stdlib's abs if encountered
+#ifdef abs
+#undef abs
+#endif
+
+#define min(a,b) ((a)<(b)?(a):(b))
+#define max(a,b) ((a)>(b)?(a):(b))
+#define abs(x) ((x)>0?(x):-(x))
+#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
+#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
+#define radians(deg) ((deg)*DEG_TO_RAD)
+#define degrees(rad) ((rad)*RAD_TO_DEG)
+#define sq(x) ((x)*(x))
+
+#define interrupts() sei()
+#define noInterrupts() cli()
+
+#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
+#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
+#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
+
+#define lowByte(w) ((uint8_t) ((w) & 0xff))
+#define highByte(w) ((uint8_t) ((w) >> 8))
+
+#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
+#define bitSet(value, bit) ((value) |= (1UL << (bit)))
+#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
+#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
+
+typedef unsigned int word;
+
+#define bit(b) (1UL << (b))
+
+typedef uint8_t boolean;
+typedef uint8_t byte;
+
+void init(void);
+
+void pinMode(uint8_t, uint8_t);
+void digitalWrite(uint8_t, uint8_t);
+int digitalRead(uint8_t);
+int analogRead(uint8_t);
+void analogReference(uint8_t mode);
+void analogWrite(uint8_t, int);
+
+void beginSerial(long);
+void serialWrite(unsigned char);
+int serialAvailable(void);
+int serialRead(void);
+void serialFlush(void);
+
+unsigned long millis(void);
+unsigned long micros(void);
+void delay(unsigned long);
+void delayMicroseconds(unsigned int us);
+unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
+
+void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val);
+
+void attachInterrupt(uint8_t, void (*)(void), int mode);
+void detachInterrupt(uint8_t);
+
+void setup(void);
+void loop(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c
new file mode 100755
index 0000000..529ad52
--- /dev/null
+++ b/cores/arduino/wiring_analog.c
@@ -0,0 +1,179 @@
+/*
+ wiring_analog.c - analog input and output
+ Part of Arduino - http://www.arduino.cc/
+
+ Copyright (c) 2005-2006 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.c 248 2007-02-03 15:36:30Z mellis $
+*/
+
+#include "wiring_private.h"
+#include "pins_arduino.h"
+
+uint8_t analog_reference = DEFAULT;
+
+void analogReference(uint8_t mode)
+{
+ // can't actually set the register here because the default setting
+ // will connect AVCC and the AREF pin, which would cause a short if
+ // there's something connected to AREF.
+ analog_reference = mode;
+}
+
+int analogRead(uint8_t pin)
+{
+ uint8_t low, high;
+
+ // set the analog reference (high two bits of ADMUX) and select the
+ // channel (low 4 bits). this also sets ADLAR (left-adjust result)
+ // to 0 (the default).
+ ADMUX = (analog_reference << 6) | (pin & 0x07);
+
+#if defined(__AVR_ATmega1280__)
+ // the MUX5 bit of ADCSRB selects whether we're reading from channels
+ // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
+ ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
+#endif
+
+ // without a delay, we seem to read from the wrong channel
+ //delay(1);
+
+ // start the conversion
+ sbi(ADCSRA, ADSC);
+
+ // ADSC is cleared when the conversion finishes
+ while (bit_is_set(ADCSRA, ADSC));
+
+ // we have to read ADCL first; doing so locks both ADCL
+ // and ADCH until ADCH is read. reading ADCL second would
+ // cause the results of each conversion to be discarded,
+ // as ADCL and ADCH would be locked when it completed.
+ low = ADCL;
+ high = ADCH;
+
+ // combine the two bytes
+ return (high << 8) | low;
+}
+
+// Right now, PWM output only works on the pins with
+// hardware support. These are defined in the appropriate
+// pins_*.c file. For the rest of the pins, we default
+// to digital output.
+void analogWrite(uint8_t pin, int val)
+{
+ // We need to make sure the PWM output is enabled for those pins
+ // that support it, as we turn it off when digitally reading or
+ // writing with them. Also, make sure the pin is in output mode
+ // for consistenty with Wiring, which doesn't require a pinMode
+ // call for the analog output pins.
+ pinMode(pin, OUTPUT);
+
+ if (digitalPinToTimer(pin) == TIMER1A) {
+ // connect pwm to pin on timer 1, channel A
+ sbi(TCCR1A, COM1A1);
+ // set pwm duty
+ OCR1A = val;
+ } else if (digitalPinToTimer(pin) == TIMER1B) {
+ // connect pwm to pin on timer 1, channel B
+ sbi(TCCR1A, COM1B1);
+ // set pwm duty
+ OCR1B = val;
+#if defined(__AVR_ATmega8__)
+ } else if (digitalPinToTimer(pin) == TIMER2) {
+ // connect pwm to pin on timer 2, channel B
+ sbi(TCCR2, COM21);
+ // set pwm duty
+ OCR2 = val;
+#else
+ } else if (digitalPinToTimer(pin) == TIMER0A) {
+ if (val == 0) {
+ digitalWrite(pin, LOW);
+ } else {
+ // connect pwm to pin on timer 0, channel A
+ sbi(TCCR0A, COM0A1);
+ // set pwm duty
+ OCR0A = val;
+ }
+ } else if (digitalPinToTimer(pin) == TIMER0B) {
+ if (val == 0) {
+ digitalWrite(pin, LOW);
+ } else {
+ // connect pwm to pin on timer 0, channel B
+ sbi(TCCR0A, COM0B1);
+ // set pwm duty
+ OCR0B = val;
+ }
+ } else if (digitalPinToTimer(pin) == TIMER2A) {
+ // connect pwm to pin on timer 2, channel A
+ sbi(TCCR2A, COM2A1);
+ // set pwm duty
+ OCR2A = val;
+ } else if (digitalPinToTimer(pin) == TIMER2B) {
+ // connect pwm to pin on timer 2, channel B
+ sbi(TCCR2A, COM2B1);
+ // set pwm duty
+ OCR2B = val;
+#endif
+#if defined(__AVR_ATmega1280__)
+ // XXX: need to handle other timers here
+ } else if (digitalPinToTimer(pin) == TIMER3A) {
+ // connect pwm to pin on timer 3, channel A
+ sbi(TCCR3A, COM3A1);
+ // set pwm duty
+ OCR3A = val;
+ } else if (digitalPinToTimer(pin) == TIMER3B) {
+ // connect pwm to pin on timer 3, channel B
+ sbi(TCCR3A, COM3B1);
+ // set pwm duty
+ OCR3B = val;
+ } else if (digitalPinToTimer(pin) == TIMER3C) {
+ // connect pwm to pin on timer 3, channel C
+ sbi(TCCR3A, COM3C1);
+ // set pwm duty
+ OCR3C = val;
+ } else if (digitalPinToTimer(pin) == TIMER4A) {
+ // connect pwm to pin on timer 4, channel A
+ sbi(TCCR4A, COM4A1);
+ // set pwm duty
+ OCR4A = val;
+ } else if (digitalPinToTimer(pin) == TIMER4B) {
+ // connect pwm to pin on timer 4, channel B
+ sbi(TCCR4A, COM4B1);
+ // set pwm duty
+ OCR4B = val;
+ } else if (digitalPinToTimer(pin) == TIMER4C) {
+ // connect pwm to pin on timer 4, channel C
+ sbi(TCCR4A, COM4C1);
+ // set pwm duty
+ OCR4C = val;
+ } else if (digitalPinToTimer(pin) == TIMER5A) {
+ // connect pwm to pin on timer 5, channel A
+ sbi(TCCR5A, COM5A1);
+ // set pwm duty
+ OCR5A = val;
+ } else if (digitalPinToTimer(pin) == TIMER5B) {
+ // connect pwm to pin on timer 5, channel B
+ sbi(TCCR5A, COM5B1);
+ // set pwm duty
+ OCR5B = val;
+#endif
+ } else if (val < 128)
+ digitalWrite(pin, LOW);
+ else
+ digitalWrite(pin, HIGH);
+}
diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c
new file mode 100755
index 0000000..1cdbf6c
--- /dev/null
+++ b/cores/arduino/wiring_digital.c
@@ -0,0 +1,111 @@
+/*
+ wiring_digital.c - digital input and output functions
+ Part of Arduino - http://www.arduino.cc/
+
+ Copyright (c) 2005-2006 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.c 248 2007-02-03 15:36:30Z mellis $
+*/
+
+#include "wiring_private.h"
+#include "pins_arduino.h"
+
+void pinMode(uint8_t pin, uint8_t mode)
+{
+ uint8_t bit = digitalPinToBitMask(pin);
+ uint8_t port = digitalPinToPort(pin);
+ volatile uint8_t *reg;
+
+ if (port == NOT_A_PIN) return;
+
+ // JWS: can I let the optimizer do this?
+ reg = portModeRegister(port);
+
+ if (mode == INPUT) *reg &= ~bit;
+ else *reg |= bit;
+}
+
+// Forcing this inline keeps the callers from having to push their own stuff
+// on the stack. It is a good performance win and only takes 1 more byte per
+// user than calling. (It will take more bytes on the 168.)
+//
+// But shouldn't this be moved into pinMode? Seems silly to check and do on
+// each digitalread or write.
+//
+static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline));
+static inline void turnOffPWM(uint8_t timer)
+{
+ if (timer == TIMER1A) cbi(TCCR1A, COM1A1);
+ if (timer == TIMER1B) cbi(TCCR1A, COM1B1);
+
+#if defined(__AVR_ATmega8__)
+ if (timer == TIMER2) cbi(TCCR2, COM21);
+#else
+ if (timer == TIMER0A) cbi(TCCR0A, COM0A1);
+ if (timer == TIMER0B) cbi(TCCR0A, COM0B1);
+ if (timer == TIMER2A) cbi(TCCR2A, COM2A1);
+ if (timer == TIMER2B) cbi(TCCR2A, COM2B1);
+#endif
+
+#if defined(__AVR_ATmega1280__)
+ if (timer == TIMER3A) cbi(TCCR3A, COM3A1);
+ if (timer == TIMER3B) cbi(TCCR3A, COM3B1);
+ if (timer == TIMER3C) cbi(TCCR3A, COM3C1);
+ if (timer == TIMER4A) cbi(TCCR4A, COM4A1);
+ if (timer == TIMER4B) cbi(TCCR4A, COM4B1);
+ if (timer == TIMER4C) cbi(TCCR4A, COM4C1);
+ if (timer == TIMER5A) cbi(TCCR5A, COM5A1);
+ if (timer == TIMER5B) cbi(TCCR5A, COM5B1);
+ if (timer == TIMER5C) cbi(TCCR5A, COM5C1);
+#endif
+}
+
+void digitalWrite(uint8_t pin, uint8_t val)
+{
+ uint8_t timer = digitalPinToTimer(pin);
+ uint8_t bit = digitalPinToBitMask(pin);
+ uint8_t port = digitalPinToPort(pin);
+ volatile uint8_t *out;
+
+ if (port == NOT_A_PIN) return;
+
+ // If the pin that support PWM output, we need to turn it off
+ // before doing a digital write.
+ if (timer != NOT_ON_TIMER) turnOffPWM(timer);
+
+ out = portOutputRegister(port);
+
+ if (val == LOW) *out &= ~bit;
+ else *out |= bit;
+}
+
+int digitalRead(uint8_t pin)
+{
+ uint8_t timer = digitalPinToTimer(pin);
+ uint8_t bit = digitalPinToBitMask(pin);
+ uint8_t port = digitalPinToPort(pin);
+
+ if (port == NOT_A_PIN) return LOW;
+
+ // If the pin that support PWM output, we need to turn it off
+ // before getting a digital reading.
+ if (timer != NOT_ON_TIMER) turnOffPWM(timer);
+
+ if (*portInputRegister(port) & bit) return HIGH;
+ return LOW;
+}
diff --git a/cores/arduino/wiring_private.h b/cores/arduino/wiring_private.h
new file mode 100755
index 0000000..2dfe552
--- /dev/null
+++ b/cores/arduino/wiring_private.h
@@ -0,0 +1,68 @@
+/*
+ wiring_private.h - Internal header file.
+ Part of Arduino - http://www.arduino.cc/
+
+ Copyright (c) 2005-2006 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 239 2007-01-12 17:58:39Z mellis $
+*/
+
+#ifndef WiringPrivate_h
+#define WiringPrivate_h
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/delay.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "wiring.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#ifndef cbi
+#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+#endif
+#ifndef sbi
+#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#endif
+
+#define EXTERNAL_INT_0 0
+#define EXTERNAL_INT_1 1
+#define EXTERNAL_INT_2 2
+#define EXTERNAL_INT_3 3
+#define EXTERNAL_INT_4 4
+#define EXTERNAL_INT_5 5
+#define EXTERNAL_INT_6 6
+#define EXTERNAL_INT_7 7
+
+#if defined(__AVR_ATmega1280__)
+#define EXTERNAL_NUM_INTERRUPTS 8
+#else
+#define EXTERNAL_NUM_INTERRUPTS 2
+#endif
+
+typedef void (*voidFuncPtr)(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/cores/arduino/wiring_pulse.c b/cores/arduino/wiring_pulse.c
new file mode 100755
index 0000000..8f232f1
--- /dev/null
+++ b/cores/arduino/wiring_pulse.c
@@ -0,0 +1,66 @@
+/*
+ wiring_pulse.c - pulseIn() function
+ Part of Arduino - http://www.arduino.cc/
+
+ Copyright (c) 2005-2006 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.c 248 2007-02-03 15:36:30Z mellis $
+*/
+
+#include "wiring_private.h"
+#include "pins_arduino.h"
+
+/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
+ * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
+ * to 3 minutes in length, but must be called at least a few dozen microseconds
+ * before the start of the pulse. */
+unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
+{
+ // cache the port and bit of the pin in order to speed up the
+ // pulse width measuring loop and achieve finer resolution. calling
+ // digitalRead() instead yields much coarser resolution.
+ uint8_t bit = digitalPinToBitMask(pin);
+ uint8_t port = digitalPinToPort(pin);
+ uint8_t stateMask = (state ? bit : 0);
+ unsigned long width = 0; // keep initialization out of time critical area
+
+ // convert the timeout from microseconds to a number of times through
+ // the initial loop; it takes 16 clock cycles per iteration.
+ unsigned long numloops = 0;
+ unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
+
+ // wait for any previous pulse to end
+ while ((*portInputRegister(port) & bit) == stateMask)
+ if (numloops++ == maxloops)
+ return 0;
+
+ // wait for the pulse to start
+ while ((*portInputRegister(port) & bit) != stateMask)
+ if (numloops++ == maxloops)
+ return 0;
+
+ // wait for the pulse to stop
+ while ((*portInputRegister(port) & bit) == stateMask)
+ width++;
+
+ // convert the reading to microseconds. The loop has been determined
+ // to be 10 clock cycles long and have about 16 clocks between the edge
+ // and the start of the loop. There will be some error introduced by
+ // the interrupt handlers.
+ return clockCyclesToMicroseconds(width * 10 + 16);
+}
diff --git a/cores/arduino/wiring_shift.c b/cores/arduino/wiring_shift.c
new file mode 100755
index 0000000..956f864
--- /dev/null
+++ b/cores/arduino/wiring_shift.c
@@ -0,0 +1,40 @@
+/*
+ wiring_shift.c - shiftOut() function
+ Part of Arduino - http://www.arduino.cc/
+
+ Copyright (c) 2005-2006 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.c 248 2007-02-03 15:36:30Z mellis $
+*/
+
+#include "wiring_private.h"
+
+void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (bitOrder == LSBFIRST)
+ digitalWrite(dataPin, !!(val & (1 << i)));
+ else
+ digitalWrite(dataPin, !!(val & (1 << (7 - i))));
+
+ digitalWrite(clockPin, HIGH);
+ digitalWrite(clockPin, LOW);
+ }
+}
diff --git a/cores/atmega8/pins_atmega8.c b/cores/atmega8/pins_atmega8.c
new file mode 100755
index 0000000..ed1b2bd
--- /dev/null
+++ b/cores/atmega8/pins_atmega8.c
@@ -0,0 +1,119 @@
+/*
+ pin_atmega8.c - pin definitions for the atmega8
+ Part of Arduino / Wiring Lite
+
+ Copyright (c) 2005 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$
+*/
+
+#include <avr/io.h>
+#include "wiring.h"
+
+// We map the pin numbers passed to digitalRead() or
+// analogRead() directly to the corresponding pin
+// numbers on the Atmega8. No distinction is made
+// between analog and digital pins.
+
+// ATMEL ATMEGA8
+//
+// +-\/-+
+// PC6 1| |28 PC5
+// PD0 2| |27 PC4
+// PD1 3| |26 PC3
+// PD2 4| |25 PC2
+// PD3 5| |24 PC1
+// PD4 6| |23 PC0
+// VCC 7| |22 GND
+// GND 8| |21 AREF
+// PB6 9| |20 AVCC
+// PB7 10| |19 PB5
+// PD5 11| |18 PB4
+// PD6 12| |17 PB3
+// PD7 13| |16 PB2
+// PB0 14| |15 PB1
+// +----+
+
+#define NUM_PINS 28
+#define NUM_PORTS 4
+
+#define PB 2
+#define PC 3
+#define PD 4
+
+int port_to_mode[NUM_PORTS + 1] = {
+ NOT_A_PORT,
+ NOT_A_PORT,
+ _SFR_IO_ADDR(DDRB),
+ _SFR_IO_ADDR(DDRC),
+ _SFR_IO_ADDR(DDRD),
+};
+
+int port_to_output[NUM_PORTS + 1] = {
+ NOT_A_PORT,
+ NOT_A_PORT,
+ _SFR_IO_ADDR(PORTB),
+ _SFR_IO_ADDR(PORTC),
+ _SFR_IO_ADDR(PORTD),
+};
+
+int port_to_input[NUM_PORTS + 1] = {
+ NOT_A_PORT,
+ NOT_A_PORT,
+ _SFR_IO_ADDR(PINB),
+ _SFR_IO_ADDR(PINC),
+ _SFR_IO_ADDR(PIND),
+};
+
+pin_t digital_pin_to_port_array[] = {
+ { NOT_A_PIN, NOT_A_PIN },
+
+ { PC, 6 },
+ { PD, 0 },
+ { PD, 1 },
+ { PD, 2 },
+ { PD, 3 },
+ { PD, 4 },
+ { NOT_A_PIN, NOT_A_PIN },
+ { NOT_A_PIN, NOT_A_PIN },
+ { PB, 6 },
+ { PB, 7 },
+ { PD, 5 },
+ { PD, 6 },
+ { PD, 7 },
+ { PB, 0 },
+
+ { PB, 1 },
+ { PB, 2 },
+ { PB, 3 },
+ { PB, 4 },
+ { PB, 5 },
+ { NOT_A_PIN, NOT_A_PIN },
+ { NOT_A_PIN, NOT_A_PIN },
+ { NOT_A_PIN, NOT_A_PIN },
+ { PC, 0 },
+ { PC, 1 },
+ { PC, 2 },
+ { PC, 3 },
+ { PC, 4 },
+ { PC, 5 },
+};
+
+pin_t *digital_pin_to_port = digital_pin_to_port_array;
+pin_t *analog_in_pin_to_port = digital_pin_to_port_array;
+pin_t *analog_out_pin_to_port = digital_pin_to_port_array;
diff --git a/cores/blank/WProgram.h b/cores/blank/WProgram.h
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/cores/blank/WProgram.h
diff --git a/cores/blank/main.cxx b/cores/blank/main.cxx
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cores/blank/main.cxx
diff --git a/libraries/EEPROM/EEPROM.cpp b/libraries/EEPROM/EEPROM.cpp
new file mode 100755
index 0000000..3a361e7
--- /dev/null
+++ b/libraries/EEPROM/EEPROM.cpp
@@ -0,0 +1,50 @@
+/*
+ EEPROM.cpp - EEPROM library
+ Copyright (c) 2006 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/******************************************************************************
+ * Includes
+ ******************************************************************************/
+
+#include <avr/eeprom.h>
+#include "WConstants.h"
+#include "EEPROM.h"
+
+/******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/******************************************************************************
+ * Constructors
+ ******************************************************************************/
+
+/******************************************************************************
+ * User API
+ ******************************************************************************/
+
+uint8_t EEPROMClass::read(int address)
+{
+ return eeprom_read_byte((unsigned char *) address);
+}
+
+void EEPROMClass::write(int address, uint8_t value)
+{
+ eeprom_write_byte((unsigned char *) address, value);
+}
+
+EEPROMClass EEPROM;
diff --git a/libraries/EEPROM/EEPROM.h b/libraries/EEPROM/EEPROM.h
new file mode 100755
index 0000000..aa2b577
--- /dev/null
+++ b/libraries/EEPROM/EEPROM.h
@@ -0,0 +1,35 @@
+/*
+ EEPROM.h - EEPROM library
+ Copyright (c) 2006 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef EEPROM_h
+#define EEPROM_h
+
+#include <inttypes.h>
+
+class EEPROMClass
+{
+ public:
+ uint8_t read(int);
+ void write(int, uint8_t);
+};
+
+extern EEPROMClass EEPROM;
+
+#endif
+
diff --git a/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.pde b/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.pde
new file mode 100644
index 0000000..36af68e
--- /dev/null
+++ b/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.pde
@@ -0,0 +1,21 @@
+/*
+ * EEPROM Clear
+ *
+ * Sets all of the bytes of the EEPROM to 0.
+ */
+
+#include <EEPROM.h>
+
+void setup()
+{
+ // write a 0 to all 512 bytes of the EEPROM
+ for (int i = 0; i < 512; i++)
+ EEPROM.write(i, 0);
+
+ // turn the LED on when we're done
+ digitalWrite(13, HIGH);
+}
+
+void loop()
+{
+}
diff --git a/libraries/EEPROM/examples/eeprom_read/eeprom_read.pde b/libraries/EEPROM/examples/eeprom_read/eeprom_read.pde
new file mode 100644
index 0000000..2e30708
--- /dev/null
+++ b/libraries/EEPROM/examples/eeprom_read/eeprom_read.pde
@@ -0,0 +1,38 @@
+/*
+ * EEPROM Read
+ *
+ * Reads the value of each byte of the EEPROM and prints it
+ * to the computer.
+ */
+
+#include <EEPROM.h>
+
+// start reading from the first byte (address 0) of the EEPROM
+int address = 0;
+byte value;
+
+void setup()
+{
+ Serial.begin(9600);
+}
+
+void loop()
+{
+ // read a byte from the current address of the EEPROM
+ value = EEPROM.read(address);
+
+ Serial.print(address);
+ Serial.print("\t");
+ Serial.print(value, DEC);
+ Serial.println();
+
+ // advance to the next address of the EEPROM
+ address = address + 1;
+
+ // there are only 512 bytes of EEPROM, from 0 to 511, so if we're
+ // on address 512, wrap around to address 0
+ if (address == 512)
+ address = 0;
+
+ delay(500);
+}
diff --git a/libraries/EEPROM/examples/eeprom_write/eeprom_write.pde b/libraries/EEPROM/examples/eeprom_write/eeprom_write.pde
new file mode 100644
index 0000000..ae7c57e
--- /dev/null
+++ b/libraries/EEPROM/examples/eeprom_write/eeprom_write.pde
@@ -0,0 +1,38 @@
+/*
+ * EEPROM Write
+ *
+ * Stores values read from analog input 0 into the EEPROM.
+ * These values will stay in the EEPROM when the board is
+ * turned off and may be retrieved later by another sketch.
+ */
+
+#include <EEPROM.h>
+
+// the current address in the EEPROM (i.e. which byte
+// we're going to write to next)
+int addr = 0;
+
+void setup()
+{
+}
+
+void loop()
+{
+ // need to divide by 4 because analog inputs range from
+ // 0 to 1023 and each byte of the EEPROM can only hold a
+ // value from 0 to 255.
+ int val = analogRead(0) / 4;
+
+ // write the value to the appropriate byte of the EEPROM.
+ // these values will remain there when the board is
+ // turned off.
+ EEPROM.write(addr, val);
+
+ // advance to the next address. there are 512 bytes in
+ // the EEPROM, so go back to 0 when we hit 512.
+ addr = addr + 1;
+ if (addr == 512)
+ addr = 0;
+
+ delay(100);
+}
diff --git a/libraries/EEPROM/keywords.txt b/libraries/EEPROM/keywords.txt
new file mode 100644
index 0000000..d3218fe
--- /dev/null
+++ b/libraries/EEPROM/keywords.txt
@@ -0,0 +1,18 @@
+#######################################
+# Syntax Coloring Map For Ultrasound
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+EEPROM KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
diff --git a/libraries/Ethernet/Client.cpp b/libraries/Ethernet/Client.cpp
new file mode 100644
index 0000000..ebbb08d
--- /dev/null
+++ b/libraries/Ethernet/Client.cpp
@@ -0,0 +1,140 @@
+extern "C" {
+ #include "types.h"
+ #include "w5100.h"
+ #include "socket.h"
+ #include "string.h"
+}
+
+#include "WProgram.h"
+
+#include "Ethernet.h"
+#include "Client.h"
+#include "Server.h"
+
+uint16_t Client::_srcport = 0;
+
+Client::Client(uint8_t sock) {
+ _sock = sock;
+}
+
+Client::Client(uint8_t *ip, uint16_t port) {
+ _ip = ip;
+ _port = port;
+ _sock = 255;
+}
+
+uint8_t Client::connect() {
+ if (_sock != 255)
+ return 0;
+
+ for (int i = 0; i < MAX_SOCK_NUM; i++) {
+ uint8_t s = getSn_SR(i);
+ if (s == SOCK_CLOSED || s == SOCK_FIN_WAIT) {
+ _sock = i;
+ break;
+ }
+ }
+
+ if (_sock == 255)
+ return 0;
+
+ _srcport++;
+ if (_srcport + 1024 == 0) _srcport = 0;
+ socket(_sock, Sn_MR_TCP, _srcport + 1024, 0);
+
+ if (!::connect(_sock, _ip, _port)) {
+ _sock = 255;
+ return 0;
+ }
+
+ while (status() != SOCK_ESTABLISHED) {
+ delay(1);
+ if (status() == SOCK_CLOSED) {
+ _sock = 255;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+void Client::write(uint8_t b) {
+ if (_sock != 255)
+ send(_sock, &b, 1);
+}
+
+void Client::write(const char *str) {
+ if (_sock != 255)
+ send(_sock, (const uint8_t *)str, strlen(str));
+}
+
+void Client::write(const uint8_t *buf, size_t size) {
+ if (_sock != 255)
+ send(_sock, buf, size);
+}
+
+int Client::available() {
+ if (_sock != 255)
+ return getSn_RX_RSR(_sock);
+ return 0;
+}
+
+int Client::read() {
+ uint8_t b;
+ if (!available())
+ return -1;
+ recv(_sock, &b, 1);
+ return b;
+}
+
+void Client::flush() {
+ while (available())
+ read();
+}
+
+void Client::stop() {
+ if (_sock == 255)
+ return;
+
+ // attempt to close the connection gracefully (send a FIN to other side)
+ disconnect(_sock);
+ unsigned long start = millis();
+
+ // wait a second for the connection to close
+ while (status() != SOCK_CLOSED && millis() - start < 1000)
+ delay(1);
+
+ // if it hasn't closed, close it forcefully
+ if (status() != SOCK_CLOSED)
+ close(_sock);
+
+ EthernetClass::_server_port[_sock] = 0;
+ _sock = 255;
+}
+
+uint8_t Client::connected() {
+ uint8_t s = status();
+ return !(s == SOCK_LISTEN || s == SOCK_CLOSED || s == SOCK_FIN_WAIT ||
+ (s == SOCK_CLOSE_WAIT && !available()));
+}
+
+uint8_t Client::status() {
+ return getSn_SR(_sock);
+}
+
+// the next three functions are a hack so we can compare the client returned
+// by Server::available() to null, or use it as the condition in an
+// if-statement. this lets us stay compatible with the Processing network
+// library.
+
+uint8_t Client::operator==(int p) {
+ return _sock == 255;
+}
+
+uint8_t Client::operator!=(int p) {
+ return _sock != 255;
+}
+
+Client::operator bool() {
+ return _sock != 255;
+}
diff --git a/libraries/Ethernet/Client.h b/libraries/Ethernet/Client.h
new file mode 100644
index 0000000..7c0ccdf
--- /dev/null
+++ b/libraries/Ethernet/Client.h
@@ -0,0 +1,31 @@
+#ifndef Client_h
+#define Client_h
+
+#include "Print.h"
+
+class Client : public Print {
+private:
+ static uint16_t _srcport;
+ uint8_t _sock;
+ uint8_t *_ip;
+ uint16_t _port;
+public:
+ Client(uint8_t);
+ Client(uint8_t *, uint16_t);
+ uint8_t status();
+ uint8_t connect();
+ virtual void write(uint8_t);
+ virtual void write(const char *str);
+ virtual void write(const uint8_t *buf, size_t size);
+ int available();
+ int read();
+ void flush();
+ void stop();
+ uint8_t connected();
+ uint8_t operator==(int);
+ uint8_t operator!=(int);
+ operator bool();
+ friend class Server;
+};
+
+#endif
diff --git a/libraries/Ethernet/Ethernet.cpp b/libraries/Ethernet/Ethernet.cpp
new file mode 100644
index 0000000..cb74876
--- /dev/null
+++ b/libraries/Ethernet/Ethernet.cpp
@@ -0,0 +1,38 @@
+extern "C" {
+ #include "types.h"
+ #include "w5100.h"
+}
+
+#include "Ethernet.h"
+
+// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
+uint8_t EthernetClass::_state[MAX_SOCK_NUM] = { 0, 0, 0, 0 };
+uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 };
+
+void EthernetClass::begin(uint8_t *mac, uint8_t *ip)
+{
+ uint8_t gateway[4];
+ gateway[0] = ip[0];
+ gateway[1] = ip[1];
+ gateway[2] = ip[2];
+ gateway[3] = 1;
+ begin(mac, ip, gateway);
+}
+
+void EthernetClass::begin(uint8_t *mac, uint8_t *ip, uint8_t *gateway)
+{
+ uint8_t subnet[] = { 255, 255, 255, 0 };
+ begin(mac, ip, gateway, subnet);
+}
+
+void EthernetClass::begin(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)
+{
+ iinchip_init();
+ sysinit(0x55, 0x55);
+ setSHAR(mac);
+ setSIPR(ip);
+ setGAR(gateway);
+ setSUBR(subnet);
+}
+
+EthernetClass Ethernet;
diff --git a/libraries/Ethernet/Ethernet.h b/libraries/Ethernet/Ethernet.h
new file mode 100644
index 0000000..bdfc4dd
--- /dev/null
+++ b/libraries/Ethernet/Ethernet.h
@@ -0,0 +1,22 @@
+#ifndef Ethernet_h
+#define Ethernet_h
+
+#include <inttypes.h>
+#include "Client.h"
+#include "Server.h"
+
+class EthernetClass {
+private:
+public:
+ static uint8_t _state[MAX_SOCK_NUM];
+ static uint16_t _server_port[MAX_SOCK_NUM];
+ void begin(uint8_t *, uint8_t *);
+ void begin(uint8_t *, uint8_t *, uint8_t *);
+ void begin(uint8_t *, uint8_t *, uint8_t *, uint8_t *);
+ friend class Client;
+ friend class Server;
+};
+
+extern EthernetClass Ethernet;
+
+#endif
diff --git a/libraries/Ethernet/Server.cpp b/libraries/Ethernet/Server.cpp
new file mode 100644
index 0000000..d17a5d3
--- /dev/null
+++ b/libraries/Ethernet/Server.cpp
@@ -0,0 +1,91 @@
+extern "C" {
+ #include "types.h"
+ #include "w5100.h"
+ #include "socket.h"
+ #include "string.h"
+}
+
+#include "Ethernet.h"
+#include "Client.h"
+#include "Server.h"
+
+Server::Server(uint16_t port)
+{
+ _port = port;
+}
+
+void Server::begin()
+{
+ for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
+ Client client(sock);
+ if (client.status() == SOCK_CLOSED) {
+ socket(sock, Sn_MR_TCP, _port, 0);
+ listen(sock);
+ EthernetClass::_server_port[sock] = _port;
+ break;
+ }
+ }
+}
+
+void Server::accept()
+{
+ int listening = 0;
+
+ for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
+ Client client(sock);
+
+ if (EthernetClass::_server_port[sock] == _port) {
+ if (client.status() == SOCK_LISTEN) {
+ listening = 1;
+ } else if (client.status() == SOCK_CLOSE_WAIT && !client.available()) {
+ client.stop();
+ }
+ }
+ }
+
+ if (!listening) {
+ begin();
+ }
+}
+
+Client Server::available()
+{
+ accept();
+
+ for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
+ Client client(sock);
+ if (EthernetClass::_server_port[sock] == _port &&
+ client.status() == SOCK_ESTABLISHED) {
+ if (client.available()) {
+ // XXX: don't always pick the lowest numbered socket.
+ return client;
+ }
+ }
+ }
+
+ return Client(255);
+}
+
+void Server::write(uint8_t b)
+{
+ write(&b, 1);
+}
+
+void Server::write(const char *str)
+{
+ write((const uint8_t *)str, strlen(str));
+}
+
+void Server::write(const uint8_t *buffer, size_t size)
+{
+ accept();
+
+ for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
+ Client client(sock);
+
+ if (EthernetClass::_server_port[sock] == _port &&
+ client.status() == SOCK_ESTABLISHED) {
+ client.write(buffer, size);
+ }
+ }
+}
diff --git a/libraries/Ethernet/Server.h b/libraries/Ethernet/Server.h
new file mode 100644
index 0000000..73d6a5e
--- /dev/null
+++ b/libraries/Ethernet/Server.h
@@ -0,0 +1,25 @@
+#ifndef Server_h
+#define Server_h
+
+extern "C" {
+ #include "utility/types.h"
+}
+
+#include "Print.h"
+
+class Client;
+
+class Server : public Print {
+private:
+ uint16_t _port;
+ void accept();
+public:
+ Server(uint16_t);
+ Client available();
+ void begin();
+ virtual void write(uint8_t);
+ virtual void write(const char *str);
+ virtual void write(const uint8_t *buf, size_t size);
+};
+
+#endif
diff --git a/libraries/Ethernet/examples/ChatServer/ChatServer.pde b/libraries/Ethernet/examples/ChatServer/ChatServer.pde
new file mode 100644
index 0000000..825d2f8
--- /dev/null
+++ b/libraries/Ethernet/examples/ChatServer/ChatServer.pde
@@ -0,0 +1,34 @@
+/*
+ * Chat Server
+ *
+ * A simple server that distributes any incoming messages to all
+ * connected clients. To use telnet to 10.0.0.177 and type!
+ */
+
+#include <Ethernet.h>
+
+// network configuration. gateway and subnet are optional.
+byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+byte ip[] = { 10, 0, 0, 177 };
+byte gateway[] = { 10, 0, 0, 1 };
+byte subnet[] = { 255, 255, 0, 0 };
+
+// telnet defaults to port 23
+Server server(23);
+
+void setup()
+{
+ // initialize the ethernet device
+ Ethernet.begin(mac, ip, gateway, subnet);
+
+ // start listening for clients
+ server.begin();
+}
+
+void loop()
+{
+ Client client = server.available();
+ if (client) {
+ server.write(client.read());
+ }
+}
diff --git a/libraries/Ethernet/examples/WebClient/WebClient.pde b/libraries/Ethernet/examples/WebClient/WebClient.pde
new file mode 100644
index 0000000..74a6094
--- /dev/null
+++ b/libraries/Ethernet/examples/WebClient/WebClient.pde
@@ -0,0 +1,41 @@
+#include <Ethernet.h>
+
+byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+byte ip[] = { 10, 0, 0, 177 };
+byte server[] = { 64, 233, 187, 99 }; // Google
+
+Client client(server, 80);
+
+void setup()
+{
+ Ethernet.begin(mac, ip);
+ Serial.begin(9600);
+
+ delay(1000);
+
+ Serial.println("connecting...");
+
+ if (client.connect()) {
+ Serial.println("connected");
+ client.println("GET /search?q=arduino HTTP/1.0");
+ client.println();
+ } else {
+ Serial.println("connection failed");
+ }
+}
+
+void loop()
+{
+ if (client.available()) {
+ char c = client.read();
+ Serial.print(c);
+ }
+
+ if (!client.connected()) {
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
+ for(;;)
+ ;
+ }
+}
diff --git a/libraries/Ethernet/examples/WebServer/WebServer.pde b/libraries/Ethernet/examples/WebServer/WebServer.pde
new file mode 100644
index 0000000..b337a8e
--- /dev/null
+++ b/libraries/Ethernet/examples/WebServer/WebServer.pde
@@ -0,0 +1,61 @@
+/*
+ * Web Server
+ *
+ * A simple web server that shows the value of the analog input pins.
+ */
+
+#include <Ethernet.h>
+
+byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+byte ip[] = { 10, 0, 0, 177 };
+
+Server server(80);
+
+void setup()
+{
+ Ethernet.begin(mac, ip);
+ server.begin();
+}
+
+void loop()
+{
+ Client client = server.available();
+ if (client) {
+ // an http request ends with a blank line
+ boolean current_line_is_blank = true;
+ while (client.connected()) {
+ if (client.available()) {
+ char c = client.read();
+ // if we've gotten to the end of the line (received a newline
+ // character) and the line is blank, the http request has ended,
+ // so we can send a reply
+ if (c == '\n' && current_line_is_blank) {
+ // send a standard http response header
+ client.println("HTTP/1.1 200 OK");
+ client.println("Content-Type: text/html");
+ client.println();
+
+ // output the value of each analog input pin
+ for (int i = 0; i < 6; i++) {
+ client.print("analog input ");
+ client.print(i);
+ client.print(" is ");
+ client.print(analogRead(i));
+ client.println("<br />");
+ }
+ break;
+ }
+ if (c == '\n') {
+ // we're starting a new line
+ current_line_is_blank = true;
+ } else if (c != '\r') {
+ // we've gotten a character on the current line
+ current_line_is_blank = false;
+ }
+ }
+ }
+ // give the web browser time to receive the data
+ delay(1);
+ client.stop();
+ }
+}
diff --git a/libraries/Ethernet/utility/socket.c b/libraries/Ethernet/utility/socket.c
new file mode 100755
index 0000000..88c81a8
--- /dev/null
+++ b/libraries/Ethernet/utility/socket.c
@@ -0,0 +1,558 @@
+/*
+*
+@file socket.c
+@brief setting chip register for socket
+ last update : 2008. Jan
+*
+*/
+
+#include "types.h"
+#include "w5100.h"
+#include "socket.h"
+
+static uint16 local_port;
+
+
+/**
+@brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
+@return 1 for sucess else 0.
+*/
+uint8 socket(
+ SOCKET s, /**< for socket number */
+ uint8 protocol, /**< for socket protocol */
+ uint16 port, /**< the source port for the socket */
+ uint8 flag /**< the option for the socket */
+ )
+{
+ uint8 ret;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("socket()\r\n");
+#endif
+ if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
+ {
+ close(s);
+ IINCHIP_WRITE(Sn_MR(s),protocol | flag);
+ if (port != 0) {
+ IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
+ } else {
+ local_port++; // if don't set the source port, set local_port number.
+ IINCHIP_WRITE(Sn_PORT0(s),(uint8)((local_port & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(local_port & 0x00ff));
+ }
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
+
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+ /* ------- */
+ ret = 1;
+ }
+ else
+ {
+ ret = 0;
+ }
+#ifdef __DEF_IINCHIP_DBG__
+ printf("Sn_SR = %.2x , Protocol = %.2x\r\n", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
+#endif
+ return ret;
+}
+
+
+/**
+@brief This function close the socket and parameter is "s" which represent the socket number
+*/
+void close(SOCKET s)
+{
+#ifdef __DEF_IINCHIP_DBG__
+ printf("close()\r\n");
+#endif
+
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
+
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+ /* ------- */
+
+ /* +2008.01 [hwkim]: clear interrupt */
+ #ifdef __DEF_IINCHIP_INT__
+ /* m2008.01 [bj] : all clear */
+ putISR(s, 0x00);
+ #else
+ /* m2008.01 [bj] : all clear */
+ IINCHIP_WRITE(Sn_IR(s), 0xFF);
+ #endif
+}
+
+
+/**
+@brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
+@return 1 for success else 0.
+*/
+uint8 listen(
+ SOCKET s /**< the socket number */
+ )
+{
+ uint8 ret;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("listen()\r\n");
+#endif
+ if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
+ {
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+ /* ------- */
+ ret = 1;
+ }
+ else
+ {
+ ret = 0;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("Fail[invalid ip,port]\r\n");
+#endif
+ }
+ return ret;
+}
+
+
+/**
+@brief This function established the connection for the channel in Active (client) mode.
+ This function waits for the untill the connection is established.
+
+@return 1 for success else 0.
+*/
+uint8 connect(SOCKET s, uint8 * addr, uint16 port)
+{
+ uint8 ret;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("connect()\r\n");
+#endif
+ if
+ (
+ ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
+ ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
+ (port == 0x00)
+ )
+ {
+ ret = 0;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("Fail[invalid ip,port]\r\n");
+#endif
+ }
+ else
+ {
+ ret = 1;
+ // set destination IP
+ IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
+ IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
+ /* m2008.01 [bj] : wait for completion */
+ while ( IINCHIP_READ(Sn_CR(s)) ) ;
+
+ }
+
+ return ret;
+}
+
+
+
+/**
+@brief This function used for disconnect the socket and parameter is "s" which represent the socket number
+@return 1 for success else 0.
+*/
+void disconnect(SOCKET s)
+{
+#ifdef __DEF_IINCHIP_DBG__
+ printf("disconnect()\r\n");
+#endif
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
+
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+ /* ------- */
+}
+
+
+/**
+@brief This function used to send the data in TCP mode
+@return 1 for success else 0.
+*/
+uint16 send(
+ SOCKET s, /**< the socket index */
+ const uint8 * buf, /**< a pointer to data */
+ uint16 len /**< the data size to be send */
+ )
+{
+ uint8 status=0;
+ uint16 ret=0;
+ uint16 freesize=0;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("send()\r\n");
+#endif
+
+ if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
+ else ret = len;
+
+ // if freebuf is available, start.
+ do
+ {
+ freesize = getSn_TX_FSR(s);
+ status = IINCHIP_READ(Sn_SR(s));
+ if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
+ {
+ ret = 0;
+ break;
+ }
+#ifdef __DEF_IINCHIP_DBG__
+ printf("socket %d freesize(%d) empty or error\r\n", s, freesize);
+#endif
+ } while (freesize < ret);
+
+ // copy data
+ send_data_processing(s, (uint8 *)buf, ret);
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
+
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+ /* ------- */
+
+/* +2008.01 bj */
+#ifdef __DEF_IINCHIP_INT__
+ while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
+#else
+ while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
+#endif
+ {
+ /* m2008.01 [bj] : reduce code */
+ if ( IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED )
+ {
+#ifdef __DEF_IINCHIP_DBG__
+ printf("SOCK_CLOSED.\r\n");
+#endif
+ close(s);
+ return 0;
+ }
+ }
+/* +2008.01 bj */
+#ifdef __DEF_IINCHIP_INT__
+ putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
+#else
+ IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
+#endif
+ return ret;
+}
+
+
+/**
+@brief This function is an application I/F function which is used to receive the data in TCP mode.
+ It continues to wait for data as much as the application wants to receive.
+
+@return received data size for success else -1.
+*/
+uint16 recv(
+ SOCKET s, /**< socket index */
+ uint8 * buf, /**< a pointer to copy the data to be received */
+ uint16 len /**< the data size to be read */
+ )
+{
+ uint16 ret=0;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("recv()\r\n");
+#endif
+
+
+ if ( len > 0 )
+ {
+ recv_data_processing(s, buf, len);
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
+
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+ /* ------- */
+ ret = len;
+ }
+ return ret;
+}
+
+
+/**
+@brief This function is an application I/F function which is used to send the data for other then TCP mode.
+ Unlike TCP transmission, The peer's destination address and the port is needed.
+
+@return This function return send data size for success else -1.
+*/
+uint16 sendto(
+ SOCKET s, /**< socket index */
+ const uint8 * buf, /**< a pointer to the data */
+ uint16 len, /**< the data size to send */
+ uint8 * addr, /**< the peer's Destination IP address */
+ uint16 port /**< the peer's destination port number */
+ )
+{
+// uint8 status=0;
+// uint8 isr=0;
+ uint16 ret=0;
+
+#ifdef __DEF_IINCHIP_DBG__
+ printf("sendto()\r\n");
+#endif
+ if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
+ else ret = len;
+
+ if
+ (
+ ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
+ ((port == 0x00)) ||(ret == 0)
+ )
+ {
+ /* +2008.01 [bj] : added return value */
+ ret = 0;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("%d Fail[%.2x.%.2x.%.2x.%.2x, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
+ printf("Fail[invalid ip,port]\r\n");
+#endif
+ }
+ else
+ {
+ IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
+ IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
+
+ // copy data
+ send_data_processing(s, (uint8 *)buf, ret);
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
+
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+ /* ------- */
+
+/* +2008.01 bj */
+#ifdef __DEF_IINCHIP_INT__
+ while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
+#else
+ while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
+#endif
+ {
+#ifdef __DEF_IINCHIP_INT__
+ if (getISR(s) & Sn_IR_TIMEOUT)
+#else
+ if (IINCHIP_READ(Sn_IR(s)) & Sn_IR_TIMEOUT)
+#endif
+ {
+#ifdef __DEF_IINCHIP_DBG__
+ printf("send fail.\r\n");
+#endif
+/* +2008.01 [bj]: clear interrupt */
+#ifdef __DEF_IINCHIP_INT__
+ putISR(s, getISR(s) & ~(Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
+#else
+ IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
+#endif
+ return 0;
+ }
+ }
+
+/* +2008.01 bj */
+#ifdef __DEF_IINCHIP_INT__
+ putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
+#else
+ IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
+#endif
+
+ }
+ return ret;
+}
+
+
+/**
+@brief This function is an application I/F function which is used to receive the data in other then
+ TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
+
+@return This function return received data size for success else -1.
+*/
+uint16 recvfrom(
+ SOCKET s, /**< the socket number */
+ uint8 * buf, /**< a pointer to copy the data to be received */
+ uint16 len, /**< the data size to read */
+ uint8 * addr, /**< a pointer to store the peer's IP address */
+ uint16 *port /**< a pointer to store the peer's port number. */
+ )
+{
+ uint8 head[8];
+ uint16 data_len=0;
+ uint16 ptr=0;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("recvfrom()\r\n");
+#endif
+
+ if ( len > 0 )
+ {
+ ptr = IINCHIP_READ(Sn_RX_RD0(s));
+ ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
+#ifdef __DEF_IINCHIP_DBG__
+ printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
+#endif
+ switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
+ {
+ case Sn_MR_UDP :
+ read_data(s, (uint8 *)ptr, head, 0x08);
+ ptr += 8;
+ // read peer's IP address, port number.
+ addr[0] = head[0];
+ addr[1] = head[1];
+ addr[2] = head[2];
+ addr[3] = head[3];
+ *port = head[4];
+ *port = (*port << 8) + head[5];
+ data_len = head[6];
+ data_len = (data_len << 8) + head[7];
+
+#ifdef __DEF_IINCHIP_DBG__
+ printf("UDP msg arrived\r\n");
+ printf("source Port : %d\r\n", *port);
+ printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
+#endif
+
+ read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
+ ptr += data_len;
+
+ IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
+ break;
+
+ case Sn_MR_IPRAW :
+ read_data(s, (uint8 *)ptr, head, 0x06);
+ ptr += 6;
+
+ addr[0] = head[0];
+ addr[1] = head[1];
+ addr[2] = head[2];
+ addr[3] = head[3];
+ data_len = head[4];
+ data_len = (data_len << 8) + head[5];
+
+#ifdef __DEF_IINCHIP_DBG__
+ printf("IP RAW msg arrived\r\n");
+ printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
+#endif
+ read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
+ ptr += data_len;
+
+ IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
+ break;
+ case Sn_MR_MACRAW :
+ read_data(s,(uint8*)ptr,head,2);
+ ptr+=2;
+ data_len = head[0];
+ data_len = (data_len<<8) + head[1] - 2;
+
+ read_data(s,(uint8*) ptr,buf,data_len);
+ ptr += data_len;
+ IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
+
+#ifdef __DEF_IINCHIP_DGB__
+ printf("MAC RAW msg arrived\r\n");
+ printf("dest mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
+ printf("src mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
+ printf("type =%.2X%.2X\r\n",buf[12],buf[13]);
+#endif
+ break;
+
+ default :
+ break;
+ }
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
+
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+ /* ------- */
+ }
+#ifdef __DEF_IINCHIP_DBG__
+ printf("recvfrom() end ..\r\n");
+#endif
+ return data_len;
+}
+
+
+uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len)
+{
+ uint8 status=0;
+// uint8 isr=0;
+ uint16 ret=0;
+
+#ifdef __DEF_IINCHIP_DBG__
+ printf("igmpsend()\r\n");
+#endif
+ if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
+ else ret = len;
+
+ if (ret == 0)
+ {
+ ;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("%d Fail[%d]\r\n",len);
+#endif
+ }
+ else
+ {
+ // copy data
+ send_data_processing(s, (uint8 *)buf, ret);
+ IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
+/* +2008.01 bj */
+ while( IINCHIP_READ(Sn_CR(s)) )
+ ;
+/* ------- */
+
+/* +2008.01 bj */
+#ifdef __DEF_IINCHIP_INT__
+ while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
+#else
+ while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
+#endif
+ {
+ status = IINCHIP_READ(Sn_SR(s));
+#ifdef __DEF_IINCHIP_INT__
+ if (getISR(s) & Sn_IR_TIMEOUT)
+#else
+ if (IINCHIP_READ(Sn_IR(s)) & Sn_IR_TIMEOUT)
+#endif
+ {
+#ifdef __DEF_IINCHIP_DBG__
+ printf("igmpsend fail.\r\n");
+#endif
+ /* in case of igmp, if send fails, then socket closed */
+ /* if you want change, remove this code. */
+ close(s);
+ /* ----- */
+
+ return 0;
+ }
+ }
+
+/* +2008.01 bj */
+#ifdef __DEF_IINCHIP_INT__
+ putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
+#else
+ IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
+#endif
+ }
+ return ret;
+}
+
diff --git a/libraries/Ethernet/utility/socket.h b/libraries/Ethernet/utility/socket.h
new file mode 100755
index 0000000..a5cce42
--- /dev/null
+++ b/libraries/Ethernet/utility/socket.h
@@ -0,0 +1,23 @@
+/*
+*
+@file socket.h
+@brief define function of socket API
+*
+*/
+
+#ifndef _SOCKET_H_
+#define _SOCKET_H_
+
+extern uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint8 flag); // Opens a socket(TCP or UDP or IP_RAW mode)
+extern void close(SOCKET s); // Close socket
+extern uint8 connect(SOCKET s, uint8 * addr, uint16 port); // Establish TCP connection (Active connection)
+extern void disconnect(SOCKET s); // disconnect the connection
+extern uint8 listen(SOCKET s); // Establish TCP connection (Passive connection)
+extern uint16 send(SOCKET s, const uint8 * buf, uint16 len); // Send data (TCP)
+extern uint16 recv(SOCKET s, uint8 * buf, uint16 len); // Receive data (TCP)
+extern uint16 sendto(SOCKET s, const uint8 * buf, uint16 len, uint8 * addr, uint16 port); // Send data (UDP/IP RAW)
+extern uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port); // Receive data (UDP/IP RAW)
+
+extern uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len);
+#endif
+/* _SOCKET_H_ */
diff --git a/libraries/Ethernet/utility/spi.h b/libraries/Ethernet/utility/spi.h
new file mode 100755
index 0000000..000705d
--- /dev/null
+++ b/libraries/Ethernet/utility/spi.h
@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------------
+//AVR Mega168 SPI HAL
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+
+#define SPI0_SS_BIT BIT2
+#define SPI0_SS_DDR DDRB
+#define SPI0_SS_PORT PORTB
+
+#define SPI0_SCLK_BIT BIT5
+#define SPI0_SCLK_DDR DDRB
+#define SPI0_SCLK_PORT PORTB
+
+#define SPI0_MOSI_BIT BIT3
+#define SPI0_MOSI_DDR DDRB
+#define SPI0_MOSI_PORT PORTB
+
+#define SPI0_MISO_BIT BIT4
+#define SPI0_MISO_DDR DDRB
+#define SPI0_MISO_PORT PORTB
+
+
+#define SPI0_WaitForReceive()
+#define SPI0_RxData() (SPDR)
+
+#define SPI0_TxData(Data) (SPDR = Data)
+#define SPI0_WaitForSend() while( (SPSR & 0x80)==0x00 )
+
+#define SPI0_SendByte(Data) SPI0_TxData(Data);SPI0_WaitForSend()
+#define SPI0_RecvBute() SPI0_RxData()
+
+// PB4(MISO), PB3(MOSI), PB5(SCK), PB2(/SS) // CS=1, waiting for SPI start // SPI mode 0, 4MHz
+#define SPI0_Init() DDRB |= SPI0_SS_BIT|SPI0_SCLK_BIT|SPI0_MOSI_BIT;\
+ PORTB |= SPI0_SS_BIT; PORTB &= ~(SPI0_SCLK_BIT|SPI0_MOSI_BIT);\
+ SPCR = 0x50
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+//IInChip SPI HAL
+#define IINCHIP_SpiInit SPI0_Init
+#define IINCHIP_SpiSendData SPI0_SendByte
+#define IINCHIP_SpiRecvData SPI0_RxData
+
+
+#define IINCHIP_CS_BIT BIT2
+#define IINCHIP_CS_DDR DDRB
+#define IINCHIP_CS_PORT PORTB
+
+#define IINCHIP_CSInit() (IINCHIP_CS_DDR |= IINCHIP_CS_BIT)
+#define IINCHIP_CSon() (IINCHIP_CS_PORT |= IINCHIP_CS_BIT)
+#define IINCHIP_CSoff() (IINCHIP_CS_PORT &= ~IINCHIP_CS_BIT)
+//-----------------------------------------------------------------------------
diff --git a/libraries/Ethernet/utility/types.h b/libraries/Ethernet/utility/types.h
new file mode 100755
index 0000000..6c350da
--- /dev/null
+++ b/libraries/Ethernet/utility/types.h
@@ -0,0 +1,165 @@
+/*
+*
+@file type.h
+*
+*/
+
+#ifndef _TYPE_H_
+#define _TYPE_H_
+
+
+/***************************************************
+ * attribute for mcu ( types, ... )
+ ***************************************************/
+//#include "mcu_define.h"
+#define __MCU_AVR__ 1
+#define __MCU_TYPE__ __MCU_AVR__
+
+//---- Refer "Rom File Maker Manual Vx.x.pdf"
+#include <avr/pgmspace.h>
+
+#define _ENDIAN_LITTLE_ 0 /**< This must be defined if system is little-endian alignment */
+#define _ENDIAN_BIG_ 1
+#define SYSTEM_ENDIAN _ENDIAN_LITTLE_
+
+#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */
+#define CLK_CPU F_CPU /**< 8Mhz(for serial) */
+
+/* ## __DEF_IINCHIP_xxx__ : define option for iinchip driver *****************/
+//#define __DEF_IINCHIP_DBG__ /* involve debug code in driver (socket.c) */
+//#define __DEF_IINCHIP_INT__ /**< involve interrupt service routine (socket.c) */
+//#define __DEF_IINCHIP_PPP__ /* involve pppoe routine (socket.c) */
+ /* If it is defined, the source files(md5.h,md5.c) must be included in your project.
+ Otherwize, the source files must be removed in your project. */
+
+#define __DEF_IINCHIP_DIRECT_MODE__ 1
+#define __DEF_IINCHIP_INDIRECT_MODE__ 2
+#define __DEF_IINCHIP_SPI_MODE__ 3
+
+//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_DIRECT_MODE__
+//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_INDIRECT_MODE__
+#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_SPI_MODE__ /*Enable SPI_mode*/
+
+
+/**
+@brief __DEF_IINCHIP_MAP_xxx__ : define memory map for iinchip
+*/
+#define __DEF_IINCHIP_MAP_BASE__ 0x8000
+#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
+ #define COMMON_BASE __DEF_IINCHIP_MAP_BASE__
+#else
+ #define COMMON_BASE 0x0000
+#endif
+#define __DEF_IINCHIP_MAP_TXBUF__ (COMMON_BASE + 0x4000) /* Internal Tx buffer address of the iinchip */
+#define __DEF_IINCHIP_MAP_RXBUF__ (COMMON_BASE + 0x6000) /* Internal Rx buffer address of the iinchip */
+
+
+#if (__MCU_TYPE__ == __MCU_AVR__)
+ #ifdef __DEF_IINCHIP_INT__
+ // iinchip use external interrupt 4
+ #define IINCHIP_ISR_DISABLE() (EIMSK &= ~(0x10))
+ #define IINCHIP_ISR_ENABLE() (EIMSK |= 0x10)
+ #define IINCHIP_ISR_GET(X) (X = EIMSK)
+ #define IINCHIP_ISR_SET(X) (EIMSK = X)
+ #else
+ #define IINCHIP_ISR_DISABLE()
+ #define IINCHIP_ISR_ENABLE()
+ #define IINCHIP_ISR_GET(X)
+ #define IINCHIP_ISR_SET(X)
+ #endif
+#else
+#error "unknown MCU type"
+#endif
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+//typedef enum { false, true } bool;
+
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef unsigned int size_t;
+#endif
+
+/**
+ * The 8-bit signed data type.
+ */
+typedef char int8;
+/**
+ * The volatile 8-bit signed data type.
+ */
+typedef volatile char vint8;
+/**
+ * The 8-bit unsigned data type.
+ */
+typedef unsigned char uint8;
+/**
+ * The volatile 8-bit unsigned data type.
+ */
+typedef volatile unsigned char vuint8;
+
+/**
+ * The 16-bit signed data type.
+ */
+typedef int int16;
+/**
+ * The volatile 16-bit signed data type.
+ */
+typedef volatile int vint16;
+/**
+ * The 16-bit unsigned data type.
+ */
+typedef unsigned int uint16;
+/**
+ * The volatile 16-bit unsigned data type.
+ */
+typedef volatile unsigned int vuint16;
+/**
+ * The 32-bit signed data type.
+ */
+typedef long int32;
+/**
+ * The volatile 32-bit signed data type.
+ */
+typedef volatile long vint32;
+/**
+ * The 32-bit unsigned data type.
+ */
+typedef unsigned long uint32;
+/**
+ * The volatile 32-bit unsigned data type.
+ */
+typedef volatile unsigned long vuint32;
+
+/* bsd */
+typedef uint8 u_char; /**< 8-bit value */
+typedef uint8 SOCKET;
+typedef uint16 u_short; /**< 16-bit value */
+typedef uint16 u_int; /**< 16-bit value */
+typedef uint32 u_long; /**< 32-bit value */
+
+typedef union _un_l2cval {
+ u_long lVal;
+ u_char cVal[4];
+}un_l2cval;
+
+typedef union _un_i2cval {
+ u_int iVal;
+ u_char cVal[2];
+}un_i2cval;
+
+
+/** global define */
+#define FW_VERSION 0x01010000 /* System F/W Version : 1.1.0.0 */
+#define HW_VERSION 0x01000000
+
+
+#define TX_RX_MAX_BUF_SIZE 2048
+#define TX_BUF 0x1100
+#define RX_BUF (TX_BUF+TX_RX_MAX_BUF_SIZE)
+
+#define UART_DEVICE_CNT 1 /**< UART device number */
+/* #define SUPPORT_UART_ONE */
+
+#endif /* _TYPE_H_ */
diff --git a/libraries/Ethernet/utility/w5100.c b/libraries/Ethernet/utility/w5100.c
new file mode 100755
index 0000000..7d0f55a
--- /dev/null
+++ b/libraries/Ethernet/utility/w5100.c
@@ -0,0 +1,1302 @@
+/*
+ * (c)COPYRIGHT
+ * ALL RIGHT RESERVED
+ *
+ * FileName : w5100.c
+ * Revision History :
+ * ---------- ------- ------------------------------------------------
+ * Date version Description
+ * ---------- ------- ------------------------------------------------
+ * 01/25/2007 1.1 Bug is Fixed in the Indirect Mode
+ * : Memory mapping error
+ * ---------- ------- ------------------------------------------------
+ * 01/08/2008 1.2 Modification of Socket Command Part
+ * : Check if the appropriately performed after writing Sn_CR
+ *
+ * Modification of SPI Part
+ * : SPI code changed by adding 'spi.h'.
+ * : Change control type for SPI port from byte to bit.
+ * ---------- ------- ------------------------------------------------
+ * 01/15/2008 1.3 Bug is Fixed in the pppinit() fuction.
+ * : do not clear interrupt value, so fixed.
+ *
+ * Modification of ISR
+ * : Do not exit ISR, if there is interrupt.
+ * ---------- ------- ------------------------------------------------
+ * 03/21/2008 1.4 Modification of SetMR() function
+ * : Use IINCHIP_WRITE() function in Direct or SPI mode.
+ * ---------- ------- ------------------------------------------------
+ */
+#include <stdio.h>
+#include <string.h>
+
+#include <avr/interrupt.h>
+// #include <avr/io.h>
+
+#include "types.h"
+#include "socket.h"
+#include "w5100.h"
+
+
+
+#ifdef __DEF_IINCHIP_PPP__
+ #include "md5.h"
+#endif
+
+
+#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
+#include "spi.h" //+2007113[jhpark]
+#endif
+
+static uint8 I_STATUS[MAX_SOCK_NUM];
+static uint16 SMASK[MAX_SOCK_NUM]; /**< Variable for Tx buffer MASK in each channel */
+static uint16 RMASK[MAX_SOCK_NUM]; /**< Variable for Rx buffer MASK in each channel */
+static uint16 SSIZE[MAX_SOCK_NUM]; /**< Max Tx buffer size by each channel */
+static uint16 RSIZE[MAX_SOCK_NUM]; /**< Max Rx buffer size by each channel */
+static uint16 SBUFBASEADDRESS[MAX_SOCK_NUM]; /**< Tx buffer base address by each channel */
+static uint16 RBUFBASEADDRESS[MAX_SOCK_NUM]; /**< Rx buffer base address by each channel */
+
+uint8 getISR(uint8 s)
+{
+ return I_STATUS[s];
+}
+
+void putISR(uint8 s, uint8 val)
+{
+ I_STATUS[s] = val;
+}
+
+uint16 getIINCHIP_RxMAX(uint8 s)
+{
+ return RSIZE[s];
+}
+uint16 getIINCHIP_TxMAX(uint8 s)
+{
+ return SSIZE[s];
+}
+uint16 getIINCHIP_RxMASK(uint8 s)
+{
+ return RMASK[s];
+}
+uint16 getIINCHIP_TxMASK(uint8 s)
+{
+ return SMASK[s];
+}
+uint16 getIINCHIP_RxBASE(uint8 s)
+{
+ return RBUFBASEADDRESS[s];
+}
+uint16 getIINCHIP_TxBASE(uint8 s)
+{
+ return SBUFBASEADDRESS[s];
+}
+
+ /**
+@brief This function writes the data into W5100 registers.
+*/
+uint8 IINCHIP_WRITE(uint16 addr,uint8 data)
+{
+// DIRECT MODE I/F
+#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
+ IINCHIP_ISR_DISABLE();
+ *((vuint8*)(addr)) = data;
+ IINCHIP_ISR_ENABLE();
+#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__) /* INDIRECT MODE I/F */
+ IINCHIP_ISR_DISABLE();
+ *((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
+ *((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
+ *((vuint8*)IDM_DR) = data;
+ IINCHIP_ISR_ENABLE();
+#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
+ IINCHIP_ISR_DISABLE();
+ IINCHIP_SpiInit();
+
+ //SPI MODE I/F
+ IINCHIP_CSoff(); // CS=0, SPI start
+
+ IINCHIP_SpiSendData(0xF0);
+ IINCHIP_SpiSendData((addr & 0xFF00) >> 8);
+ IINCHIP_SpiSendData(addr & 0x00FF);
+ IINCHIP_SpiSendData(data);
+
+ IINCHIP_CSon();
+
+ IINCHIP_ISR_ENABLE();
+#else
+ #error "unknown bus type"
+#endif
+ return 1;
+}
+
+
+/**
+@brief This function reads the value from W5100 registers.
+*/
+uint8 IINCHIP_READ(uint16 addr)
+{
+ uint8 data;
+
+// DIRECT MODE I/F
+
+#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
+ IINCHIP_ISR_DISABLE();
+ data = *((vuint8*)(addr));
+ IINCHIP_ISR_ENABLE();
+#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
+ IINCHIP_ISR_DISABLE();
+ *((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
+ *((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
+ data = *((vuint8*)IDM_DR);
+ IINCHIP_ISR_ENABLE();
+
+#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
+ IINCHIP_ISR_DISABLE();
+ IINCHIP_SpiInit();
+ IINCHIP_CSoff(); // CS=0, SPI start
+
+ IINCHIP_SpiSendData(0x0F);
+ IINCHIP_SpiSendData((addr & 0xFF00) >> 8);
+ IINCHIP_SpiSendData(addr & 0x00FF);
+
+
+ IINCHIP_SpiSendData(0);
+ data = IINCHIP_SpiRecvData();
+
+ IINCHIP_CSon(); // SPI end
+ IINCHIP_ISR_ENABLE();
+#else
+ #error "unknown bus type"
+#endif
+ return data;
+}
+
+
+/**
+@brief This function writes into W5100 memory(Buffer)
+*/
+uint16 wiz_write_buf(uint16 addr,uint8* buf,uint16 len)
+{
+#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
+ IINCHIP_ISR_DISABLE();
+ memcpy((uint8 *)addr, buf, len);
+ IINCHIP_ISR_ENABLE();
+#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
+ uint16 idx = 0;
+ IINCHIP_ISR_DISABLE();
+ *((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
+ *((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
+ for (idx = 0; idx < len ; idx++) *((vuint8*)IDM_DR) = buf[idx];
+ IINCHIP_ISR_ENABLE();
+#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
+ uint16 idx = 0;
+
+ IINCHIP_ISR_DISABLE();
+ IINCHIP_SpiInit();
+
+ //SPI MODE I/F
+ for(idx=0;idx<len;idx++)
+ {
+ IINCHIP_CSoff(); // CS=0, SPI start
+
+ IINCHIP_SpiSendData(0xF0);
+ IINCHIP_SpiSendData(((addr+idx) & 0xFF00) >> 8);
+ IINCHIP_SpiSendData((addr+idx) & 0x00FF);
+ IINCHIP_SpiSendData(buf[idx]);
+
+ IINCHIP_CSon(); // CS=0, SPI end
+ }
+
+ IINCHIP_ISR_ENABLE();
+#else
+ #error "unknown bus type"
+#endif
+ return len;
+}
+
+
+/**
+@brief This function reads into W5100 memory(Buffer)
+*/
+uint16 wiz_read_buf(uint16 addr, uint8* buf,uint16 len)
+{
+#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
+ IINCHIP_ISR_DISABLE();
+ memcpy(buf, (uint8 *)addr, len);
+ IINCHIP_ISR_ENABLE();
+#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
+ uint16 idx = 0;
+ IINCHIP_ISR_DISABLE();
+ *((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
+ *((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
+ for (idx = 0; idx < len ; idx++) buf[idx] = *((vuint8*)IDM_DR);
+ IINCHIP_ISR_ENABLE();
+#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
+ uint16 idx = 0;
+ IINCHIP_ISR_DISABLE();
+
+ IINCHIP_SpiInit();
+
+ for (idx=0; idx<len; idx++)
+ {
+ IINCHIP_CSoff(); // CS=0, SPI start
+
+ IINCHIP_SpiSendData(0x0F);
+ IINCHIP_SpiSendData(((addr+idx) & 0xFF00) >> 8);
+ IINCHIP_SpiSendData((addr+idx) & 0x00FF);
+
+
+ IINCHIP_SpiSendData(0);
+ buf[idx] = IINCHIP_SpiRecvData();
+
+ IINCHIP_CSon(); // CS=0, SPI end
+ }
+
+ IINCHIP_ISR_ENABLE();
+#else
+ #error "unknown bus type"
+#endif
+ return len;
+}
+
+
+/**
+@brief Socket interrupt routine
+*/
+#ifdef __DEF_IINCHIP_INT__
+ISR(INT4_vect)
+{
+ uint8 int_val;
+ IINCHIP_ISR_DISABLE();
+ int_val = IINCHIP_READ(IR);
+
+ /* +200801[bj] process all of interupt */
+ do {
+ /*---*/
+
+ if (int_val & IR_CONFLICT)
+ {
+ printf("IP conflict : %.2x\r\n", int_val);
+ }
+ if (int_val & IR_UNREACH)
+ {
+ printf("INT Port Unreachable : %.2x\r\n", int_val);
+ printf("UIPR0 : %d.%d.%d.%d\r\n", IINCHIP_READ(UIPR0), IINCHIP_READ(UIPR0+1), IINCHIP_READ(UIPR0+2), IINCHIP_READ(UIPR0+3));
+ printf("UPORT0 : %.2x %.2x\r\n", IINCHIP_READ(UPORT0), IINCHIP_READ(UPORT0+1));
+ }
+
+ /* +200801[bj] interrupt clear */
+ IINCHIP_WRITE(IR, 0xf0);
+ /*---*/
+
+ if (int_val & IR_SOCK(0))
+ {
+ /* +-200801[bj] save interrupt value*/
+ I_STATUS[0] |= IINCHIP_READ(Sn_IR(0)); // can be come to over two times.
+ IINCHIP_WRITE(Sn_IR(0), I_STATUS[0]);
+ /*---*/
+ }
+ if (int_val & IR_SOCK(1))
+ {
+ /* +-200801[bj] save interrupt value*/
+ I_STATUS[1] |= IINCHIP_READ(Sn_IR(1));
+ IINCHIP_WRITE(Sn_IR(1), I_STATUS[1]);
+ /*---*/
+ }
+ if (int_val & IR_SOCK(2))
+ {
+ /* +-200801[bj] save interrupt value*/
+ I_STATUS[2] |= IINCHIP_READ(Sn_IR(2));
+ IINCHIP_WRITE(Sn_IR(2), I_STATUS[2]);
+ /*---*/
+ }
+ if (int_val & IR_SOCK(3))
+ {
+ /* +-200801[bj] save interrupt value*/
+ I_STATUS[3] |= IINCHIP_READ(Sn_IR(3));
+ IINCHIP_WRITE(Sn_IR(3), I_STATUS[3]);
+ /*---*/
+ }
+
+ /* +-200801[bj] re-read interrupt value*/
+ int_val = IINCHIP_READ(IR);
+
+ /* +200801[bj] if exist, contiue to process */
+ } while (int_val != 0x00);
+ /*---*/
+
+ IINCHIP_ISR_ENABLE();
+}
+#endif
+
+/**
+@brief This function is for resetting of the iinchip. Initializes the iinchip to work in whether DIRECT or INDIRECT mode
+*/
+void iinchip_init(void)
+{
+ setMR( MR_RST );
+#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
+ setMR( MR_IND | MR_AI );
+#ifdef __DEF_IINCHIP_DBG__
+ printf("MR value is %d \r\n",IINCHIP_READ(MR));
+#endif
+#endif
+}
+
+
+/**
+@brief This function set the transmit & receive buffer size as per the channels is used
+
+Note for TMSR and RMSR bits are as follows\n
+bit 1-0 : memory size of channel #0 \n
+bit 3-2 : memory size of channel #1 \n
+bit 5-4 : memory size of channel #2 \n
+bit 7-6 : memory size of channel #3 \n\n
+Maximum memory size for Tx, Rx in the W5100 is 8K Bytes,\n
+In the range of 8KBytes, the memory size could be allocated dynamically by each channel.\n
+Be attentive to sum of memory size shouldn't exceed 8Kbytes\n
+and to data transmission and receiption from non-allocated channel may cause some problems.\n
+If the 8KBytes memory is already assigned to centain channel, \n
+other 3 channels couldn't be used, for there's no available memory.\n
+If two 4KBytes memory are assigned to two each channels, \n
+other 2 channels couldn't be used, for there's no available memory.\n
+*/
+void sysinit(
+ uint8 tx_size, /**< tx_size Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte) */
+ uint8 rx_size /**< rx_size Rx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte) */
+ )
+{
+ int16 i;
+ int16 ssum,rsum;
+
+#ifdef __DEF_IINCHIP_DBG__
+ printf("sysinit()\r\n");
+#endif
+
+ ssum = 0;
+ rsum = 0;
+
+ IINCHIP_WRITE(TMSR,tx_size); /* Set Tx memory size for each channel */
+ IINCHIP_WRITE(RMSR,rx_size); /* Set Rx memory size for each channel */
+
+ SBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_TXBUF__); /* Set base address of Tx memory for channel #0 */
+ RBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_RXBUF__); /* Set base address of Rx memory for channel #0 */
+
+#ifdef __DEF_IINCHIP_DBG__
+ printf("Channel : SEND MEM SIZE : RECV MEM SIZE\r\n");
+#endif
+
+ for (i = 0 ; i < MAX_SOCK_NUM; i++) // Set the size, masking and base address of Tx & Rx memory by each channel
+ {
+ SSIZE[i] = (int16)(0);
+ RSIZE[i] = (int16)(0);
+ if (ssum < 8192)
+ {
+ switch((tx_size >> i*2) & 0x03) // Set Tx memory size
+ {
+ case 0:
+ SSIZE[i] = (int16)(1024);
+ SMASK[i] = (uint16)(0x03FF);
+ break;
+ case 1:
+ SSIZE[i] = (int16)(2048);
+ SMASK[i] = (uint16)(0x07FF);
+ break;
+ case 2:
+ SSIZE[i] = (int16)(4096);
+ SMASK[i] = (uint16)(0x0FFF);
+ break;
+ case 3:
+ SSIZE[i] = (int16)(8192);
+ SMASK[i] = (uint16)(0x1FFF);
+ break;
+ }
+ }
+ if (rsum < 8192)
+ {
+ switch((rx_size >> i*2) & 0x03) // Set Rx memory size
+ {
+ case 0:
+ RSIZE[i] = (int16)(1024);
+ RMASK[i] = (uint16)(0x03FF);
+ break;
+ case 1:
+ RSIZE[i] = (int16)(2048);
+ RMASK[i] = (uint16)(0x07FF);
+ break;
+ case 2:
+ RSIZE[i] = (int16)(4096);
+ RMASK[i] = (uint16)(0x0FFF);
+ break;
+ case 3:
+ RSIZE[i] = (int16)(8192);
+ RMASK[i] = (uint16)(0x1FFF);
+ break;
+ }
+ }
+ ssum += SSIZE[i];
+ rsum += RSIZE[i];
+
+ if (i != 0) // Sets base address of Tx and Rx memory for channel #1,#2,#3
+ {
+ SBUFBASEADDRESS[i] = SBUFBASEADDRESS[i-1] + SSIZE[i-1];
+ RBUFBASEADDRESS[i] = RBUFBASEADDRESS[i-1] + RSIZE[i-1];
+ }
+#ifdef __DEF_IINCHIP_DBG__
+ printf("%d : %.4x : %.4x : %.4x : %.4x\r\n", i, (uint16)SBUFBASEADDRESS[i], (uint16)RBUFBASEADDRESS[i], SSIZE[i], RSIZE[i]);
+#endif
+ }
+}
+
+
+void setMR(uint8 val)
+{
+
+#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
+ *((volatile uint8*)(MR)) = val;
+#else
+ /* DIRECT ACCESS */
+ IINCHIP_WRITE(MR,val);
+#endif
+}
+
+
+/**
+@brief This function sets up gateway IP address.
+*/
+void setGAR(
+ uint8 * addr /**< a pointer to a 4 -byte array responsible to set the Gateway IP address. */
+ )
+{
+ IINCHIP_WRITE((GAR0 + 0),addr[0]);
+ IINCHIP_WRITE((GAR0 + 1),addr[1]);
+ IINCHIP_WRITE((GAR0 + 2),addr[2]);
+ IINCHIP_WRITE((GAR0 + 3),addr[3]);
+}
+void getGWIP(uint8 * addr)
+{
+ addr[0] = IINCHIP_READ((GAR0 + 0));
+ addr[1] = IINCHIP_READ((GAR0 + 1));
+ addr[2] = IINCHIP_READ((GAR0 + 2));
+ addr[3] = IINCHIP_READ((GAR0 + 3));
+}
+
+
+/**
+@brief It sets up SubnetMask address
+*/
+void setSUBR(
+ uint8 * addr /**< a pointer to a 4 -byte array responsible to set the SubnetMask address */
+ )
+{
+ IINCHIP_WRITE((SUBR0 + 0),addr[0]);
+ IINCHIP_WRITE((SUBR0 + 1),addr[1]);
+ IINCHIP_WRITE((SUBR0 + 2),addr[2]);
+ IINCHIP_WRITE((SUBR0 + 3),addr[3]);
+}
+
+
+/**
+@brief This function sets up MAC address.
+*/
+void setSHAR(
+ uint8 * addr /**< a pointer to a 6 -byte array responsible to set the MAC address. */
+ )
+{
+ IINCHIP_WRITE((SHAR0 + 0),addr[0]);
+ IINCHIP_WRITE((SHAR0 + 1),addr[1]);
+ IINCHIP_WRITE((SHAR0 + 2),addr[2]);
+ IINCHIP_WRITE((SHAR0 + 3),addr[3]);
+ IINCHIP_WRITE((SHAR0 + 4),addr[4]);
+ IINCHIP_WRITE((SHAR0 + 5),addr[5]);
+}
+
+
+/**
+@brief This function sets up Source IP address.
+*/
+void setSIPR(
+ uint8 * addr /**< a pointer to a 4 -byte array responsible to set the Source IP address. */
+ )
+{
+ IINCHIP_WRITE((SIPR0 + 0),addr[0]);
+ IINCHIP_WRITE((SIPR0 + 1),addr[1]);
+ IINCHIP_WRITE((SIPR0 + 2),addr[2]);
+ IINCHIP_WRITE((SIPR0 + 3),addr[3]);
+}
+
+
+/**
+@brief This function gets Interrupt register in common register.
+ */
+uint8 getIR( void )
+{
+ return IINCHIP_READ(IR);
+}
+
+
+
+/**
+@brief This function sets up Retransmission time.
+
+If there is no response from the peer or delay in response then retransmission
+will be there as per RTR (Retry Time-value Register)setting
+*/
+void setRTR(uint16 timeout)
+{
+ IINCHIP_WRITE(RTR0,(uint8)((timeout & 0xff00) >> 8));
+ IINCHIP_WRITE((RTR0 + 1),(uint8)(timeout & 0x00ff));
+}
+
+
+/**
+@brief This function set the number of Retransmission.
+
+If there is no response from the peer or delay in response then recorded time
+as per RTR & RCR register seeting then time out will occur.
+*/
+void setRCR(uint8 retry)
+{
+ IINCHIP_WRITE(RCR,retry);
+}
+
+
+/**
+@brief This function set the interrupt mask Enable/Disable appropriate Interrupt. ('1' : interrupt enable)
+
+If any bit in IMR is set as '0' then there is not interrupt signal though the bit is
+set in IR register.
+*/
+void setIMR(uint8 mask)
+{
+ IINCHIP_WRITE(IMR,mask); // must be setted 0x10.
+}
+
+
+/**
+@brief These below functions are used to get the Gateway, SubnetMask
+ and Source Hardware Address (MAC Address) and Source IP address
+*/
+void getGAR(uint8 * addr)
+{
+ addr[0] = IINCHIP_READ(GAR0);
+ addr[1] = IINCHIP_READ(GAR0+1);
+ addr[2] = IINCHIP_READ(GAR0+2);
+ addr[3] = IINCHIP_READ(GAR0+3);
+}
+void getSUBR(uint8 * addr)
+{
+ addr[0] = IINCHIP_READ(SUBR0);
+ addr[1] = IINCHIP_READ(SUBR0+1);
+ addr[2] = IINCHIP_READ(SUBR0+2);
+ addr[3] = IINCHIP_READ(SUBR0+3);
+}
+void getSHAR(uint8 * addr)
+{
+ addr[0] = IINCHIP_READ(SHAR0);
+ addr[1] = IINCHIP_READ(SHAR0+1);
+ addr[2] = IINCHIP_READ(SHAR0+2);
+ addr[3] = IINCHIP_READ(SHAR0+3);
+ addr[4] = IINCHIP_READ(SHAR0+4);
+ addr[5] = IINCHIP_READ(SHAR0+5);
+}
+void getSIPR(uint8 * addr)
+{
+ addr[0] = IINCHIP_READ(SIPR0);
+ addr[1] = IINCHIP_READ(SIPR0+1);
+ addr[2] = IINCHIP_READ(SIPR0+2);
+ addr[3] = IINCHIP_READ(SIPR0+3);
+}
+
+
+/**
+@brief These below functions are used to get the Destination Hardware Address (MAC Address), Destination IP address and Destination Port.
+*/
+void getSn_DHAR(SOCKET s, uint8 * addr)
+{
+ addr[0] = IINCHIP_READ(Sn_DHAR0(s));
+ addr[1] = IINCHIP_READ(Sn_DHAR0(s)+1);
+ addr[2] = IINCHIP_READ(Sn_DHAR0(s)+2);
+ addr[3] = IINCHIP_READ(Sn_DHAR0(s)+3);
+ addr[4] = IINCHIP_READ(Sn_DHAR0(s)+4);
+ addr[5] = IINCHIP_READ(Sn_DHAR0(s)+5);
+}
+void setSn_DHAR(SOCKET s, uint8 * addr)
+{
+ IINCHIP_WRITE((Sn_DHAR0(s) + 0),addr[0]);
+ IINCHIP_WRITE((Sn_DHAR0(s) + 1),addr[1]);
+ IINCHIP_WRITE((Sn_DHAR0(s) + 2),addr[2]);
+ IINCHIP_WRITE((Sn_DHAR0(s) + 3),addr[3]);
+ IINCHIP_WRITE((Sn_DHAR0(s) + 4),addr[4]);
+ IINCHIP_WRITE((Sn_DHAR0(s) + 5),addr[5]);
+}
+void getSn_DIPR(SOCKET s, uint8 * addr)
+{
+ addr[0] = IINCHIP_READ(Sn_DIPR0(s));
+ addr[1] = IINCHIP_READ(Sn_DIPR0(s)+1);
+ addr[2] = IINCHIP_READ(Sn_DIPR0(s)+2);
+ addr[3] = IINCHIP_READ(Sn_DIPR0(s)+3);
+}
+void setSn_DIPR(SOCKET s, uint8 * addr)
+{
+ IINCHIP_WRITE((Sn_DIPR0(s) + 0),addr[0]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
+ IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
+}
+void getSn_DPORT(SOCKET s, uint8 * addr)
+{
+ addr[0] = IINCHIP_READ(Sn_DPORT0(s));
+ addr[1] = IINCHIP_READ(Sn_DPORT0(s)+1);
+}
+void setSn_DPORT(SOCKET s, uint8 * addr)
+{
+ IINCHIP_WRITE((Sn_DPORT0(s) + 0),addr[0]);
+ IINCHIP_WRITE((Sn_DPORT0(s) + 1),addr[1]);
+}
+
+
+/**
+@brief This sets the maximum segment size of TCP in Active Mode), while in Passive Mode this is set by peer
+*/
+void setSn_MSS(SOCKET s, uint16 Sn_MSSR0)
+{
+ IINCHIP_WRITE(Sn_MSSR0(s),(uint8)((Sn_MSSR0 & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_MSSR0(s) + 1),(uint8)(Sn_MSSR0 & 0x00ff));
+}
+
+void setSn_TTL(SOCKET s, uint8 ttl)
+{
+ IINCHIP_WRITE(Sn_TTL(s), ttl);
+}
+
+
+/**
+@brief These below function is used to setup the Protocol Field of IP Header when
+ executing the IP Layer RAW mode.
+*/
+void setSn_PROTO(SOCKET s, uint8 proto)
+{
+ IINCHIP_WRITE(Sn_PROTO(s),proto);
+}
+
+
+/**
+@brief get socket interrupt status
+
+These below functions are used to read the Interrupt & Soket Status register
+*/
+uint8 getSn_IR(SOCKET s)
+{
+ return IINCHIP_READ(Sn_IR(s));
+}
+
+
+/**
+@brief get socket status
+*/
+uint8 getSn_SR(SOCKET s)
+{
+ return IINCHIP_READ(Sn_SR(s));
+}
+
+
+/**
+@brief get socket TX free buf size
+
+This gives free buffer size of transmit buffer. This is the data size that user can transmit.
+User shuold check this value first and control the size of transmitting data
+*/
+uint16 getSn_TX_FSR(SOCKET s)
+{
+ uint16 val=0,val1=0;
+ do
+ {
+ val1 = IINCHIP_READ(Sn_TX_FSR0(s));
+ val1 = (val1 << 8) + IINCHIP_READ(Sn_TX_FSR0(s) + 1);
+ if (val1 != 0)
+ {
+ val = IINCHIP_READ(Sn_TX_FSR0(s));
+ val = (val << 8) + IINCHIP_READ(Sn_TX_FSR0(s) + 1);
+ }
+ } while (val != val1);
+ return val;
+}
+
+
+/**
+@brief get socket RX recv buf size
+
+This gives size of received data in receive buffer.
+*/
+uint16 getSn_RX_RSR(SOCKET s)
+{
+ uint16 val=0,val1=0;
+ do
+ {
+ val1 = IINCHIP_READ(Sn_RX_RSR0(s));
+ val1 = (val1 << 8) + IINCHIP_READ(Sn_RX_RSR0(s) + 1);
+ if(val1 != 0)
+ {
+ val = IINCHIP_READ(Sn_RX_RSR0(s));
+ val = (val << 8) + IINCHIP_READ(Sn_RX_RSR0(s) + 1);
+ }
+ } while (val != val1);
+ return val;
+}
+
+
+/**
+@brief This function is being called by send() and sendto() function also.
+
+This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
+register. User should read upper byte first and lower byte later to get proper value.
+*/
+void send_data_processing(SOCKET s, uint8 *data, uint16 len)
+{
+ uint16 ptr;
+ ptr = IINCHIP_READ(Sn_TX_WR0(s));
+ ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR0(s) + 1);
+ write_data(s, data, (uint8 *)(ptr), len);
+ ptr += len;
+ IINCHIP_WRITE(Sn_TX_WR0(s),(uint8)((ptr & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_TX_WR0(s) + 1),(uint8)(ptr & 0x00ff));
+}
+
+
+/**
+@brief This function is being called by recv() also.
+
+This function read the Rx read pointer register
+and after copy the data from receive buffer update the Rx write pointer register.
+User should read upper byte first and lower byte later to get proper value.
+*/
+void recv_data_processing(SOCKET s, uint8 *data, uint16 len)
+{
+ uint16 ptr;
+ ptr = IINCHIP_READ(Sn_RX_RD0(s));
+ ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
+#ifdef __DEF_IINCHIP_DBG__
+ printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
+#endif
+ read_data(s, (uint8 *)ptr, data, len); // read data
+ ptr += len;
+ IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
+ IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
+}
+
+
+/**
+@brief for copy the data form application buffer to Transmite buffer of the chip.
+
+This function is being used for copy the data form application buffer to Transmite
+buffer of the chip. It calculate the actual physical address where one has to write
+the data in transmite buffer. Here also take care of the condition while it exceed
+the Tx memory uper-bound of socket.
+*/
+void write_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len)
+{
+ uint16 size;
+ uint16 dst_mask;
+ uint8 * dst_ptr;
+
+ dst_mask = (uint16)dst & getIINCHIP_TxMASK(s);
+ dst_ptr = (uint8 *)(getIINCHIP_TxBASE(s) + dst_mask);
+
+ if (dst_mask + len > getIINCHIP_TxMAX(s))
+ {
+ size = getIINCHIP_TxMAX(s) - dst_mask;
+ wiz_write_buf((uint16)dst_ptr, (uint8*)src, size);
+ src += size;
+ size = len - size;
+ dst_ptr = (uint8 *)(getIINCHIP_TxBASE(s));
+ wiz_write_buf((uint16)dst_ptr, (uint8*)src, size);
+ }
+ else
+ {
+ wiz_write_buf((uint16)dst_ptr, (uint8*)src, len);
+ }
+}
+
+
+/**
+@brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
+
+It calculate the actual physical address where one has to read
+the data from Receive buffer. Here also take care of the condition while it exceed
+the Rx memory uper-bound of socket.
+*/
+void read_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len)
+{
+ uint16 size;
+ uint16 src_mask;
+ uint8 * src_ptr;
+
+ src_mask = (uint16)src & getIINCHIP_RxMASK(s);
+ src_ptr = (uint8 *)(getIINCHIP_RxBASE(s) + src_mask);
+
+ if( (src_mask + len) > getIINCHIP_RxMAX(s) )
+ {
+ size = getIINCHIP_RxMAX(s) - src_mask;
+ wiz_read_buf((uint16)src_ptr, (uint8*)dst,size);
+ dst += size;
+ size = len - size;
+ src_ptr = (uint8 *)(getIINCHIP_RxBASE(s));
+ wiz_read_buf((uint16)src_ptr, (uint8*) dst,size);
+ }
+ else
+ {
+ wiz_read_buf((uint16)src_ptr, (uint8*) dst,len);
+ }
+}
+
+
+#ifdef __DEF_IINCHIP_PPP__
+#define PPP_OPTION_BUF_LEN 64
+
+uint8 pppinit_in(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen);
+
+
+/**
+@brief make PPPoE connection
+@return 1 => success to connect, 2 => Auth fail, 3 => timeout, 4 => Auth type not support
+
+*/
+uint8 pppinit(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen)
+{
+ uint8 ret;
+ uint8 isr;
+
+ // PHASE0. W5100 PPPoE(ADSL) setup
+ // enable pppoe mode
+ printf("-- PHASE 0. W5100 PPPoE(ADSL) setup process --\r\n");
+ printf("\r\n");
+ IINCHIP_WRITE(MR,IINCHIP_READ(MR) | MR_PPPOE);
+
+ // open socket in pppoe mode
+ isr = IINCHIP_READ(Sn_IR(0));// first clear isr(0), W5100 at present time
+ IINCHIP_WRITE(Sn_IR(0),isr);
+
+ IINCHIP_WRITE(PTIMER,200); // 5sec timeout
+ IINCHIP_WRITE(PMAGIC,0x01); // magic number
+ IINCHIP_WRITE(Sn_MR(0),Sn_MR_PPPOE);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_OPEN);
+
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+
+ ret = pppinit_in(id, idlen, passwd, passwdlen);
+
+ // close ppp connection socket
+ /* +200801 (hwkim) */
+ close(0);
+ /* ------- */
+
+ return ret;
+}
+
+
+uint8 pppinit_in(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen)
+{
+ uint8 loop_idx = 0;
+ uint8 isr = 0;
+ uint8 buf[PPP_OPTION_BUF_LEN];
+ uint16 len;
+ uint8 str[PPP_OPTION_BUF_LEN];
+ uint8 str_idx,dst_idx;
+
+ // PHASE1. PPPoE Discovery
+ // start to connect pppoe connection
+ printf("-- PHASE 1. PPPoE Discovery process --");
+ printf(" ok\r\n");
+ printf("\r\n");
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCON);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+
+ wait_10ms(100);
+
+ loop_idx = 0;
+ //check whether PPPoE discovery end or not
+ while (!(IINCHIP_READ(Sn_IR(0)) & Sn_IR_PNEXT))
+ {
+ printf(".");
+ if (loop_idx++ == 10) // timeout
+ {
+ printf("timeout before LCP\r\n");
+ return 3;
+ }
+ wait_10ms(100);
+ }
+
+ /* +200801[bj] clear interrupt value*/
+ IINCHIP_WRITE(Sn_IR(0), 0xff);
+ /*---*/
+
+ // PHASE2. LCP process
+ printf("-- PHASE 2. LCP process --");
+
+ // send LCP Request
+ {
+ // Magic number option
+ // option format (type value + length value + data)
+ // write magic number value
+ buf[0] = 0x05; // type value
+ buf[1] = 0x06; // length value
+ buf[2] = 0x01; buf[3] = 0x01; buf[4] = 0x01; buf[5]= 0x01; // data
+ // for MRU option, 1492 0x05d4
+ // buf[6] = 0x01; buf[7] = 0x04; buf[8] = 0x05; buf[9] = 0xD4;
+ }
+ send_data_processing(0, buf, 0x06);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send request
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+
+ wait_10ms(100);
+
+ while (!((isr = IINCHIP_READ(Sn_IR(0))) & Sn_IR_PNEXT))
+ {
+ if (isr & Sn_IR_PRECV) // Not support option
+ {
+ /* +200801[bj] clear interrupt value*/
+ IINCHIP_WRITE(Sn_IR(0), Sn_IR_PRECV);
+ /*---*/
+ len = getSn_RX_RSR(0);
+ if ( len > 0 )
+ {
+ recv_data_processing(0, str, len);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+
+ // for debug
+ //printf("LCP proc\r\n"); for (i = 0; i < len; i++) printf ("%02x ", str[i]); printf("\r\n");
+ // get option length
+ len = str[4]; len = ((len & 0x00ff) << 8) + str[5];
+ len += 2;
+ str_idx = 6; dst_idx = 0; // ppp header is 6 byte, so starts at 6.
+ do
+ {
+ if ((str[str_idx] == 0x01) || (str[str_idx] == 0x02) || (str[str_idx] == 0x03) || (str[str_idx] == 0x05))
+ {
+ // skip as length of support option. str_idx+1 is option's length.
+ str_idx += str[str_idx+1];
+ }
+ else
+ {
+ // not support option , REJECT
+ memcpy((uint8 *)(buf+dst_idx), (uint8 *)(str+str_idx), str[str_idx+1]);
+ dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
+ }
+ } while (str_idx != len);
+ // for debug
+ // printf("LCP dst proc\r\n"); for (i = 0; i < dst_idx; i++) printf ("%02x ", dst[i]); printf("\r\n");
+
+ // send LCP REJECT packet
+ send_data_processing(0, buf, dst_idx);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCJ);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ }
+ }
+ printf(".");
+ if (loop_idx++ == 10) // timeout
+ {
+ printf("timeout after LCP\r\n");
+ return 3;
+ }
+ wait_10ms(100);
+ }
+ printf(" ok\r\n");
+ printf("\r\n");
+
+ /* +200801[bj] clear interrupt value*/
+ IINCHIP_WRITE(Sn_IR(0), 0xff);
+ /*---*/
+
+ printf("-- PHASE 3. PPPoE(ADSL) Authentication mode --\r\n");
+ printf("Authentication protocol : %.2x %.2x, ", IINCHIP_READ(PATR0), IINCHIP_READ(PATR0+1));
+
+ loop_idx = 0;
+ if (IINCHIP_READ(PATR0) == 0xc0 && IINCHIP_READ(PATR0+1) == 0x23)
+ {
+ printf("PAP\r\n"); // in case of adsl normally supports PAP.
+ // send authentication data
+ // copy (idlen + id + passwdlen + passwd)
+ buf[loop_idx] = idlen; loop_idx++;
+ memcpy((uint8 *)(buf+loop_idx), (uint8 *)(id), idlen); loop_idx += idlen;
+ buf[loop_idx] = passwdlen; loop_idx++;
+ memcpy((uint8 *)(buf+loop_idx), (uint8 *)(passwd), passwdlen); loop_idx += passwdlen;
+ send_data_processing(0, buf, loop_idx);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ wait_10ms(100);
+ }
+ else if (IINCHIP_READ(PATR0) == 0xc2 && IINCHIP_READ(PATR0+1) == 0x23)
+ {
+ uint8 chal_len;
+ md5_ctx context;
+ uint8 digest[16];
+
+ len = getSn_RX_RSR(0);
+ if ( len > 0 )
+ {
+ recv_data_processing(0, str, len);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+#ifdef __DEF_IINCHIP_DBG__
+ printf("recv CHAP\r\n");
+ {
+ int16 i;
+
+ for (i = 0; i < 32; i++)
+ printf ("%02x ", str[i]);
+ }
+ printf("\r\n");
+#endif
+// str is C2 23 xx CHAL_ID xx xx CHAP_LEN CHAP_DATA
+// index 0 1 2 3 4 5 6 7 ...
+
+ memset(buf,0x00,64);
+ buf[loop_idx] = str[3]; loop_idx++; // chal_id
+ memcpy((uint8 *)(buf+loop_idx), (uint8 *)(passwd), passwdlen); loop_idx += passwdlen; //passwd
+ chal_len = str[6]; // chal_id
+ memcpy((uint8 *)(buf+loop_idx), (uint8 *)(str+7), chal_len); loop_idx += chal_len; //challenge
+ buf[loop_idx] = 0x80;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("CHAP proc d1\r\n");
+ {
+ int16 i;
+ for (i = 0; i < 64; i++)
+ printf ("%02x ", buf[i]);
+ }
+ printf("\r\n");
+#endif
+
+ md5_init(&context);
+ md5_update(&context, buf, loop_idx);
+ md5_final(digest, &context);
+
+#ifdef __DEF_IINCHIP_DBG__
+ printf("CHAP proc d1\r\n");
+ {
+ int16 i;
+ for (i = 0; i < 16; i++)
+ printf ("%02x", digest[i]);
+ }
+ printf("\r\n");
+#endif
+ loop_idx = 0;
+ buf[loop_idx] = 16; loop_idx++; // hash_len
+ memcpy((uint8 *)(buf+loop_idx), (uint8 *)(digest), 16); loop_idx += 16; // hashed value
+ memcpy((uint8 *)(buf+loop_idx), (uint8 *)(id), idlen); loop_idx += idlen; // id
+ send_data_processing(0, buf, loop_idx);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ wait_10ms(100);
+ }
+ }
+ else
+ {
+ printf("Not support\r\n");
+#ifdef __DEF_IINCHIP_DBG__
+ printf("Not support PPP Auth type: %.2x%.2x\r\n",IINCHIP_READ(PATR0), IINCHIP_READ(PATR0+1));
+#endif
+ return 4;
+ }
+ printf("\r\n");
+
+ printf("-- Waiting for PPPoE server's admission --");
+ loop_idx = 0;
+ while (!((isr = IINCHIP_READ(Sn_IR(0))) & Sn_IR_PNEXT))
+ {
+ if (isr & Sn_IR_PFAIL)
+ {
+ /* +200801[bj] clear interrupt value*/
+ IINCHIP_WRITE(Sn_IR(0), 0xff);
+ /*---*/
+ printf("failed\r\nReinput id, password..\r\n");
+ return 2;
+ }
+ printf(".");
+ if (loop_idx++ == 10) // timeout
+ {
+ /* +200801[bj] clear interrupt value*/
+ IINCHIP_WRITE(Sn_IR(0), 0xff);
+ /*---*/
+ printf("timeout after PAP\r\n");
+ return 3;
+ }
+ wait_10ms(100);
+ }
+ /* +200801[bj] clear interrupt value*/
+ IINCHIP_WRITE(Sn_IR(0), 0xff);
+ /*---*/
+ printf("ok\r\n");
+ printf("\r\n");
+ printf("-- PHASE 4. IPCP process --");
+ // IP Address
+ buf[0] = 0x03; buf[1] = 0x06; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00;
+ send_data_processing(0, buf, 6);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ wait_10ms(100);
+
+ loop_idx = 0;
+ while (1)
+ {
+ if (IINCHIP_READ(Sn_IR(0)) & Sn_IR_PRECV)
+ {
+ /* +200801[bj] clear interrupt value*/
+ IINCHIP_WRITE(Sn_IR(0), 0xff);
+ /*---*/
+ len = getSn_RX_RSR(0);
+ if ( len > 0 )
+ {
+ recv_data_processing(0, str, len);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ //for debug
+ //printf("IPCP proc\r\n"); for (i = 0; i < len; i++) printf ("%02x ", str[i]); printf("\r\n");
+ str_idx = 6; dst_idx = 0;
+ if (str[2] == 0x03) // in case of NAK
+ {
+ do
+ {
+ if (str[str_idx] == 0x03) // request only ip information
+ {
+ memcpy((uint8 *)(buf+dst_idx), (uint8 *)(str+str_idx), str[str_idx+1]);
+ dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
+ }
+ else
+ {
+ // skip byte
+ str_idx += str[str_idx+1];
+ }
+ // for debug
+ //printf("s: %d, d: %d, l: %d", str_idx, dst_idx, len);
+ } while (str_idx != len);
+ send_data_processing(0, buf, dst_idx);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send ipcp request
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ wait_10ms(100);
+ break;
+ }
+ }
+ }
+ printf(".");
+ if (loop_idx++ == 10) // timeout
+ {
+ printf("timeout after IPCP\r\n");
+ return 3;
+ }
+ wait_10ms(100);
+ send_data_processing(0, buf, 6);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); //ipcp re-request
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ }
+
+ loop_idx = 0;
+ while (!(IINCHIP_READ(Sn_IR(0)) & Sn_IR_PNEXT))
+ {
+ printf(".");
+ if (loop_idx++ == 10) // timeout
+ {
+ printf("timeout after IPCP NAK\r\n");
+ return 3;
+ }
+ wait_10ms(100);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send ipcp request
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ }
+ /* +200801[bj] clear interrupt value*/
+ IINCHIP_WRITE(Sn_IR(0), 0xff);
+ /*---*/
+ printf("ok\r\n");
+ printf("\r\n");
+ return 1;
+ // after this function, User must save the pppoe server's mac address and pppoe session id in current connection
+}
+
+
+/**
+@brief terminate PPPoE connection
+*/
+uint8 pppterm(uint8 * mac, uint8 * sessionid)
+{
+ uint16 i;
+ uint8 isr;
+#ifdef __DEF_IINCHIP_DBG__
+ printf("pppterm()\r\n");
+#endif
+ /* Set PPPoE bit in MR(Common Mode Register) : enable socket0 pppoe */
+ IINCHIP_WRITE(MR,IINCHIP_READ(MR) | MR_PPPOE);
+
+ // write pppoe server's mac address and session id
+ // must be setted these value.
+ for (i = 0; i < 6; i++) IINCHIP_WRITE((Sn_DHAR0(0)+i),mac[i]);
+ for (i = 0; i < 2; i++) IINCHIP_WRITE((Sn_DPORT0(0)+i),sessionid[i]);
+ isr = IINCHIP_READ(Sn_IR(0));
+ IINCHIP_WRITE(Sn_IR(0),isr);
+
+ //open socket in pppoe mode
+ IINCHIP_WRITE(Sn_MR(0),Sn_MR_PPPOE);
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_OPEN);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ wait_1us(1);
+ // close pppoe connection
+ IINCHIP_WRITE(Sn_CR(0),Sn_CR_PDISCON);
+ /* +20071122[chungs]:wait to process the command... */
+ while( IINCHIP_READ(Sn_CR(0)) )
+ ;
+ /* ------- */
+ wait_10ms(100);
+ // close socket
+ /* +200801 (hwkim) */
+ close(0);
+ /* ------- */
+
+
+#ifdef __DEF_IINCHIP_DBG__
+ printf("pppterm() end ..\r\n");
+#endif
+
+ return 1;
+}
+#endif
diff --git a/libraries/Ethernet/utility/w5100.h b/libraries/Ethernet/utility/w5100.h
new file mode 100755
index 0000000..6eddf91
--- /dev/null
+++ b/libraries/Ethernet/utility/w5100.h
@@ -0,0 +1,299 @@
+/*
+@file w5100.h
+*/
+
+#ifndef _W5100_H_
+#define _W5100_H_
+
+
+#define MR __DEF_IINCHIP_MAP_BASE__
+#define IDM_OR ((__DEF_IINCHIP_MAP_BASE__ + 0x00))
+#define IDM_AR0 ((__DEF_IINCHIP_MAP_BASE__ + 0x01))
+#define IDM_AR1 ((__DEF_IINCHIP_MAP_BASE__ + 0x02))
+#define IDM_DR ((__DEF_IINCHIP_MAP_BASE__ + 0x03))
+
+
+/**
+ @brief Gateway IP Register address
+ */
+#define GAR0 (COMMON_BASE + 0x0001)
+/**
+ @brief Subnet mask Register address
+ */
+#define SUBR0 (COMMON_BASE + 0x0005)
+/**
+ @brief Source MAC Register address
+ */
+#define SHAR0 (COMMON_BASE + 0x0009)
+/**
+ @brief Source IP Register address
+ */
+#define SIPR0 (COMMON_BASE + 0x000F)
+/**
+ @brief Interrupt Register
+ */
+#define IR (COMMON_BASE + 0x0015)
+/**
+ @brief Interrupt mask register
+ */
+#define IMR (COMMON_BASE + 0x0016)
+/**
+ @brief Timeout register address( 1 is 100us )
+ */
+#define RTR0 (COMMON_BASE + 0x0017)
+/**
+ @brief Retry count reigster
+ */
+#define RCR (COMMON_BASE + 0x0019)
+/**
+ @brief Receive memory size reigster
+ */
+#define RMSR (COMMON_BASE + 0x001A)
+/**
+ @brief Transmit memory size reigster
+ */
+#define TMSR (COMMON_BASE + 0x001B)
+/**
+ @brief Authentication type register address in PPPoE mode
+ */
+#define PATR0 (COMMON_BASE + 0x001C)
+//#define PPPALGO (COMMON_BASE + 0x001D)
+#define PTIMER (COMMON_BASE + 0x0028)
+#define PMAGIC (COMMON_BASE + 0x0029)
+
+/**
+ @brief Unreachable IP register address in UDP mode
+ */
+#define UIPR0 (COMMON_BASE + 0x002A)
+/**
+ @brief Unreachable Port register address in UDP mode
+ */
+#define UPORT0 (COMMON_BASE + 0x002E)
+
+/**
+ @brief socket register
+*/
+#define CH_BASE (COMMON_BASE + 0x0400)
+/**
+ @brief size of each channel register map
+ */
+#define CH_SIZE 0x0100
+/**
+ @brief socket Mode register
+ */
+#define Sn_MR(ch) (CH_BASE + ch * CH_SIZE + 0x0000)
+/**
+ @brief channel Sn_CR register
+ */
+#define Sn_CR(ch) (CH_BASE + ch * CH_SIZE + 0x0001)
+/**
+ @brief channel interrupt register
+ */
+#define Sn_IR(ch) (CH_BASE + ch * CH_SIZE + 0x0002)
+/**
+ @brief channel status register
+ */
+#define Sn_SR(ch) (CH_BASE + ch * CH_SIZE + 0x0003)
+/**
+ @brief source port register
+ */
+#define Sn_PORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0004)
+/**
+ @brief Peer MAC register address
+ */
+#define Sn_DHAR0(ch) (CH_BASE + ch * CH_SIZE + 0x0006)
+/**
+ @brief Peer IP register address
+ */
+#define Sn_DIPR0(ch) (CH_BASE + ch * CH_SIZE + 0x000C)
+/**
+ @brief Peer port register address
+ */
+#define Sn_DPORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0010)
+/**
+ @brief Maximum Segment Size(Sn_MSSR0) register address
+ */
+#define Sn_MSSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0012)
+/**
+ @brief Protocol of IP Header field register in IP raw mode
+ */
+#define Sn_PROTO(ch) (CH_BASE + ch * CH_SIZE + 0x0014)
+
+/**
+ @brief IP Type of Service(TOS) Register
+ */
+#define Sn_TOS(ch) (CH_BASE + ch * CH_SIZE + 0x0015)
+/**
+ @brief IP Time to live(TTL) Register
+ */
+#define Sn_TTL(ch) (CH_BASE + ch * CH_SIZE + 0x0016)
+
+/**
+ @brief Transmit free memory size register
+ */
+#define Sn_TX_FSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0020)
+/**
+ @brief Transmit memory read pointer register address
+ */
+#define Sn_TX_RD0(ch) (CH_BASE + ch * CH_SIZE + 0x0022)
+/**
+ @brief Transmit memory write pointer register address
+ */
+#define Sn_TX_WR0(ch) (CH_BASE + ch * CH_SIZE + 0x0024)
+/**
+ @brief Received data size register
+ */
+#define Sn_RX_RSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0026)
+/**
+ @brief Read point of Receive memory
+ */
+#define Sn_RX_RD0(ch) (CH_BASE + ch * CH_SIZE + 0x0028)
+/**
+ @brief Write point of Receive memory
+ */
+#define Sn_RX_WR0(ch) (CH_BASE + ch * CH_SIZE + 0x002A)
+
+
+
+/* MODE register values */
+#define MR_RST 0x80 /**< reset */
+#define MR_PB 0x10 /**< ping block */
+#define MR_PPPOE 0x08 /**< enable pppoe */
+#define MR_LB 0x04 /**< little or big endian selector in indirect mode */
+#define MR_AI 0x02 /**< auto-increment in indirect mode */
+#define MR_IND 0x01 /**< enable indirect mode */
+
+/* IR register values */
+#define IR_CONFLICT 0x80 /**< check ip confict */
+#define IR_UNREACH 0x40 /**< get the destination unreachable message in UDP sending */
+#define IR_PPPoE 0x20 /**< get the PPPoE close message */
+#define IR_SOCK(ch) (0x01 << ch) /**< check socket interrupt */
+
+/* Sn_MR values */
+#define Sn_MR_CLOSE 0x00 /**< unused socket */
+#define Sn_MR_TCP 0x01 /**< TCP */
+#define Sn_MR_UDP 0x02 /**< UDP */
+#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
+#define Sn_MR_MACRAW 0x04 /**< MAC LAYER RAW SOCK */
+#define Sn_MR_PPPOE 0x05 /**< PPPoE */
+#define Sn_MR_ND 0x20 /**< No Delayed Ack(TCP) flag */
+#define Sn_MR_MULTI 0x80 /**< support multicating */
+
+
+/* Sn_CR values */
+#define Sn_CR_OPEN 0x01 /**< initialize or open socket */
+#define Sn_CR_LISTEN 0x02 /**< wait connection request in tcp mode(Server mode) */
+#define Sn_CR_CONNECT 0x04 /**< send connection request in tcp mode(Client mode) */
+#define Sn_CR_DISCON 0x08 /**< send closing reqeuset in tcp mode */
+#define Sn_CR_CLOSE 0x10 /**< close socket */
+#define Sn_CR_SEND 0x20 /**< updata txbuf pointer, send data */
+#define Sn_CR_SEND_MAC 0x21 /**< send data with MAC address, so without ARP process */
+#define Sn_CR_SEND_KEEP 0x22 /**< send keep alive message */
+#define Sn_CR_RECV 0x40 /**< update rxbuf pointer, recv data */
+
+#ifdef __DEF_IINCHIP_PPP__
+ #define Sn_CR_PCON 0x23
+ #define Sn_CR_PDISCON 0x24
+ #define Sn_CR_PCR 0x25
+ #define Sn_CR_PCN 0x26
+ #define Sn_CR_PCJ 0x27
+#endif
+
+/* Sn_IR values */
+#ifdef __DEF_IINCHIP_PPP__
+ #define Sn_IR_PRECV 0x80
+ #define Sn_IR_PFAIL 0x40
+ #define Sn_IR_PNEXT 0x20
+#endif
+#define Sn_IR_SEND_OK 0x10 /**< complete sending */
+#define Sn_IR_TIMEOUT 0x08 /**< assert timeout */
+#define Sn_IR_RECV 0x04 /**< receiving data */
+#define Sn_IR_DISCON 0x02 /**< closed socket */
+#define Sn_IR_CON 0x01 /**< established connection */
+
+/* Sn_SR values */
+#define SOCK_CLOSED 0x00 /**< closed */
+#define SOCK_INIT 0x13 /**< init state */
+#define SOCK_LISTEN 0x14 /**< listen state */
+#define SOCK_SYNSENT 0x15 /**< connection state */
+#define SOCK_SYNRECV 0x16 /**< connection state */
+#define SOCK_ESTABLISHED 0x17 /**< success to connect */
+#define SOCK_FIN_WAIT 0x18 /**< closing state */
+#define SOCK_CLOSING 0x1A /**< closing state */
+#define SOCK_TIME_WAIT 0x1B /**< closing state */
+#define SOCK_CLOSE_WAIT 0x1C /**< closing state */
+#define SOCK_LAST_ACK 0x1D /**< closing state */
+#define SOCK_UDP 0x22 /**< udp socket */
+#define SOCK_IPRAW 0x32 /**< ip raw mode socket */
+#define SOCK_MACRAW 0x42 /**< mac raw mode socket */
+#define SOCK_PPPOE 0x5F /**< pppoe socket */
+
+/* IP PROTOCOL */
+#define IPPROTO_IP 0 /**< Dummy for IP */
+#define IPPROTO_ICMP 1 /**< Control message protocol */
+#define IPPROTO_IGMP 2 /**< Internet group management protocol */
+#define IPPROTO_GGP 3 /**< Gateway^2 (deprecated) */
+#define IPPROTO_TCP 6 /**< TCP */
+#define IPPROTO_PUP 12 /**< PUP */
+#define IPPROTO_UDP 17 /**< UDP */
+#define IPPROTO_IDP 22 /**< XNS idp */
+#define IPPROTO_ND 77 /**< UNOFFICIAL net disk protocol */
+#define IPPROTO_RAW 255 /**< Raw IP packet */
+
+
+/*********************************************************
+* iinchip access function
+*********************************************************/
+extern uint8 IINCHIP_READ(uint16 addr);
+extern uint8 IINCHIP_WRITE(uint16 addr,uint8 data);
+extern uint16 wiz_read_buf(uint16 addr, uint8* buf,uint16 len);
+extern uint16 wiz_write_buf(uint16 addr,uint8* buf,uint16 len);
+
+extern void iinchip_init(void); // reset iinchip
+extern void sysinit(uint8 tx_size, uint8 rx_size); // setting tx/rx buf size
+extern uint8 getISR(uint8 s);
+extern void putISR(uint8 s, uint8 val);
+extern uint16 getIINCHIP_RxMAX(uint8 s);
+extern uint16 getIINCHIP_TxMAX(uint8 s);
+extern uint16 getIINCHIP_RxMASK(uint8 s);
+extern uint16 getIINCHIP_TxMASK(uint8 s);
+extern uint16 getIINCHIP_RxBASE(uint8 s);
+extern uint16 getIINCHIP_TxBASE(uint8 s);
+extern void setGAR(uint8 * addr); // set gateway address
+extern void setSUBR(uint8 * addr); // set subnet mask address
+extern void setSHAR(uint8 * addr); // set local MAC address
+extern void setSIPR(uint8 * addr); // set local IP address
+extern void setRTR(uint16 timeout); // set retry duration for data transmission, connection, closing ...
+extern void setRCR(uint8 retry); // set retry count (above the value, assert timeout interrupt)
+extern void setIMR(uint8 mask); // set interrupt mask.
+extern void getGAR(uint8 * addr);
+extern void getSUBR(uint8 * addr);
+extern void getSHAR(uint8 * addr);
+extern void getSIPR(uint8 * addr);
+extern uint8 getIR( void );
+extern void setSn_MSS(SOCKET s, uint16 Sn_MSSR0); // set maximum segment size
+extern void setSn_PROTO(SOCKET s, uint8 proto); // set IP Protocol value using IP-Raw mode
+extern uint8 getSn_IR(SOCKET s); // get socket interrupt status
+extern uint8 getSn_SR(SOCKET s); // get socket status
+extern uint16 getSn_TX_FSR(SOCKET s); // get socket TX free buf size
+extern uint16 getSn_RX_RSR(SOCKET s); // get socket RX recv buf size
+extern void setSn_DHAR(SOCKET s, uint8 * addr);
+extern void setSn_DIPR(SOCKET s, uint8 * addr);
+extern void setSn_DPORT(SOCKET s, uint8 * addr);
+extern void getSn_DHAR(SOCKET s, uint8 * addr);
+extern void getSn_DIPR(SOCKET s, uint8 * addr);
+extern void getSn_DPORT(SOCKET s, uint8 * addr);
+extern void setSn_TTL(SOCKET s, uint8 ttl);
+extern void setMR(uint8 val);
+
+#ifdef __DEF_IINCHIP_PPP__
+extern uint8 pppinit(uint8 *id, uint8 idlen, uint8 *passwd, uint8 passwdlen);
+extern uint8 pppterm(uint8 *mac,uint8 *sessionid);
+#endif
+
+extern void send_data_processing(SOCKET s, uint8 *data, uint16 len);
+extern void recv_data_processing(SOCKET s, uint8 *data, uint16 len);
+extern void read_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len);
+extern void write_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len);
+
+#endif
diff --git a/libraries/Firmata/Firmata.cpp b/libraries/Firmata/Firmata.cpp
new file mode 100644
index 0000000..4e59d27
--- /dev/null
+++ b/libraries/Firmata/Firmata.cpp
@@ -0,0 +1,445 @@
+/*
+ Firmata.cpp - Firmata library
+ Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
+
+ 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.
+
+ See file LICENSE.txt for further informations on licensing terms.
+*/
+
+//******************************************************************************
+//* Includes
+//******************************************************************************
+
+#include "WProgram.h"
+#include "HardwareSerial.h"
+#include "Firmata.h"
+
+extern "C" {
+#include <string.h>
+#include <stdlib.h>
+}
+
+//******************************************************************************
+//* Support Functions
+//******************************************************************************
+
+void sendValueAsTwo7bitBytes(int value)
+{
+ Serial.print(value & B01111111, BYTE); // LSB
+ Serial.print(value >> 7 & B01111111, BYTE); // MSB
+}
+
+void startSysex(void)
+{
+ Serial.print(START_SYSEX, BYTE);
+}
+
+void endSysex(void)
+{
+ Serial.print(END_SYSEX, BYTE);
+}
+
+//******************************************************************************
+//* Constructors
+//******************************************************************************
+
+FirmataClass::FirmataClass(void)
+{
+ firmwareVersionCount = 0;
+ systemReset();
+}
+
+//******************************************************************************
+//* Public Methods
+//******************************************************************************
+
+/* begin method for overriding default serial bitrate */
+void FirmataClass::begin(void)
+{
+ Serial.begin(115200);
+ blinkVersion();
+ delay(300);
+ printVersion();
+}
+
+/* begin method for overriding default serial bitrate */
+void FirmataClass::begin(long speed)
+{
+ blinkVersion();
+#if defined(__AVR_ATmega128__) // Wiring
+ Serial.begin((uint32_t)speed);
+#else
+ Serial.begin(speed);
+#endif
+ delay(300);
+ printVersion();
+ printFirmwareVersion();
+}
+
+// output the protocol version message to the serial port
+void FirmataClass::printVersion(void) {
+ Serial.print(REPORT_VERSION, BYTE);
+ Serial.print(FIRMATA_MAJOR_VERSION, BYTE);
+ Serial.print(FIRMATA_MINOR_VERSION, BYTE);
+}
+
+void FirmataClass::blinkVersion(void)
+{
+ // flash the pin with the protocol version
+ pinMode(VERSION_BLINK_PIN,OUTPUT);
+ pin13strobe(FIRMATA_MAJOR_VERSION, 200, 400);
+ delay(300);
+ pin13strobe(2,1,4); // separator, a quick burst
+ delay(300);
+ pin13strobe(FIRMATA_MINOR_VERSION, 200, 400);
+}
+
+void FirmataClass::printFirmwareVersion(void)
+{
+ byte i;
+
+ if(firmwareVersionCount) { // make sure that the name has been set before reporting
+ startSysex();
+ Serial.print(REPORT_FIRMWARE, BYTE);
+ Serial.print(firmwareVersionVector[0]); // major version number
+ Serial.print(firmwareVersionVector[1]); // minor version number
+ for(i=2; i<firmwareVersionCount; ++i) {
+ sendValueAsTwo7bitBytes(firmwareVersionVector[i]);
+ }
+ endSysex();
+ }
+}
+
+void FirmataClass::setFirmwareNameAndVersion(const char *name, byte major, byte minor)
+{
+ const char *filename;
+ char *extension;
+
+// parse out ".cpp" and "applet/" that comes from using __FILE__
+ extension = strstr(name, ".cpp");
+ filename = strrchr(name, '/') + 1; //points to slash, +1 gets to start of filename
+ // add two bytes for version numbers
+ if(extension && filename) {
+ firmwareVersionCount = extension - filename + 2;
+ } else {
+ firmwareVersionCount = strlen(name) + 2;
+ filename = name;
+ }
+ firmwareVersionVector = (byte *) malloc(firmwareVersionCount);
+ firmwareVersionVector[firmwareVersionCount] = 0;
+ firmwareVersionVector[0] = major;
+ firmwareVersionVector[1] = minor;
+ strncpy((char*)firmwareVersionVector + 2, filename, firmwareVersionCount - 2);
+// alas, no snprintf on Arduino
+// snprintf(firmwareVersionVector, MAX_DATA_BYTES, "%c%c%s",
+// (char)major, (char)minor, firmwareVersionVector);
+}
+
+//------------------------------------------------------------------------------
+// Serial Receive Handling
+
+int FirmataClass::available(void)
+{
+ return Serial.available();
+}
+
+
+void FirmataClass::processSysexMessage(void)
+{
+ switch(storedInputData[0]) { //first byte in buffer is command
+ case REPORT_FIRMWARE:
+ printFirmwareVersion();
+ break;
+ case FIRMATA_STRING:
+ if(currentStringCallback) {
+ byte bufferLength = (sysexBytesRead - 1) / 2;
+ char *buffer = (char*)malloc(bufferLength * sizeof(char));
+ byte i = 1;
+ byte j = 0;
+ while(j < bufferLength) {
+ buffer[j] = (char)storedInputData[i];
+ i++;
+ buffer[j] += (char)(storedInputData[i] << 7);
+ i++;
+ j++;
+ }
+ (*currentStringCallback)(buffer);
+ }
+ break;
+ default:
+ if(currentSysexCallback)
+ (*currentSysexCallback)(storedInputData[0], sysexBytesRead - 1, storedInputData + 1);
+ }
+}
+
+void FirmataClass::processInput(void)
+{
+ int inputData = Serial.read(); // this is 'int' to handle -1 when no data
+ int command;
+
+ // TODO make sure it handles -1 properly
+
+ if (parsingSysex) {
+ if(inputData == END_SYSEX) {
+ //stop sysex byte
+ parsingSysex = false;
+ //fire off handler function
+ processSysexMessage();
+ } else {
+ //normal data byte - add to buffer
+ storedInputData[sysexBytesRead] = inputData;
+ sysexBytesRead++;
+ }
+ } else if( (waitForData > 0) && (inputData < 128) ) {
+ waitForData--;
+ storedInputData[waitForData] = inputData;
+ if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message
+ switch(executeMultiByteCommand) {
+ case ANALOG_MESSAGE:
+ if(currentAnalogCallback) {
+ (*currentAnalogCallback)(multiByteChannel,
+ (storedInputData[0] << 7)
+ + storedInputData[1]);
+ }
+ break;
+ case DIGITAL_MESSAGE:
+ if(currentDigitalCallback) {
+ (*currentDigitalCallback)(multiByteChannel,
+ (storedInputData[0] << 7)
+ + storedInputData[1]);
+ }
+ break;
+ case SET_PIN_MODE:
+ if(currentPinModeCallback)
+ (*currentPinModeCallback)(storedInputData[1], storedInputData[0]);
+ break;
+ case REPORT_ANALOG:
+ if(currentReportAnalogCallback)
+ (*currentReportAnalogCallback)(multiByteChannel,storedInputData[0]);
+ break;
+ case REPORT_DIGITAL:
+ if(currentReportDigitalCallback)
+ (*currentReportDigitalCallback)(multiByteChannel,storedInputData[0]);
+ break;
+ }
+ executeMultiByteCommand = 0;
+ }
+ } else {
+ // remove channel info from command byte if less than 0xF0
+ if(inputData < 0xF0) {
+ command = inputData & 0xF0;
+ multiByteChannel = inputData & 0x0F;
+ } else {
+ command = inputData;
+ // commands in the 0xF* range don't use channel data
+ }
+ switch (command) {
+ case ANALOG_MESSAGE:
+ case DIGITAL_MESSAGE:
+ case SET_PIN_MODE:
+ waitForData = 2; // two data bytes needed
+ executeMultiByteCommand = command;
+ break;
+ case REPORT_ANALOG:
+ case REPORT_DIGITAL:
+ waitForData = 1; // two data bytes needed
+ executeMultiByteCommand = command;
+ break;
+ case START_SYSEX:
+ parsingSysex = true;
+ sysexBytesRead = 0;
+ break;
+ case SYSTEM_RESET:
+ systemReset();
+ break;
+ case REPORT_VERSION:
+ Firmata.printVersion();
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// Serial Send Handling
+
+// send an analog message
+void FirmataClass::sendAnalog(byte pin, int value)
+{
+ // pin can only be 0-15, so chop higher bits
+ Serial.print(ANALOG_MESSAGE | (pin & 0xF), BYTE);
+ sendValueAsTwo7bitBytes(value);
+}
+
+// send a single digital pin in a digital message
+void FirmataClass::sendDigital(byte pin, int value)
+{
+ /* TODO add single pin digital messages to the protocol, this needs to
+ * track the last digital data sent so that it can be sure to change just
+ * one bit in the packet. This is complicated by the fact that the
+ * numbering of the pins will probably differ on Arduino, Wiring, and
+ * other boards. The DIGITAL_MESSAGE sends 14 bits at a time, but it is
+ * probably easier to send 8 bit ports for any board with more than 14
+ * digital pins.
+ */
+
+ // TODO: the digital message should not be sent on the serial port every
+ // time sendDigital() is called. Instead, it should add it to an int
+ // which will be sent on a schedule. If a pin changes more than once
+ // before the digital message is sent on the serial port, it should send a
+ // digital message for each change.
+
+// if(value == 0)
+// sendDigitalPortPair();
+}
+
+
+// send 14-bits in a single digital message (protocol v1)
+// send an 8-bit port in a single digital message (protocol v2)
+void FirmataClass::sendDigitalPort(byte portNumber, int portData)
+{
+ Serial.print(DIGITAL_MESSAGE | (portNumber & 0xF),BYTE);
+ Serial.print(portData % 128, BYTE); // Tx bits 0-6
+ Serial.print(portData >> 7, BYTE); // Tx bits 7-13
+}
+
+
+void FirmataClass::sendSysex(byte command, byte bytec, byte* bytev)
+{
+ byte i;
+ startSysex();
+ Serial.print(command, BYTE);
+ for(i=0; i<bytec; i++) {
+ sendValueAsTwo7bitBytes(bytev[i]);
+ }
+ endSysex();
+}
+
+void FirmataClass::sendString(byte command, const char* string)
+{
+ sendSysex(command, strlen(string), (byte *)string);
+}
+
+
+// send a string as the protocol string type
+void FirmataClass::sendString(const char* string)
+{
+ sendString(FIRMATA_STRING, string);
+}
+
+
+// Internal Actions/////////////////////////////////////////////////////////////
+
+// generic callbacks
+void FirmataClass::attach(byte command, callbackFunction newFunction)
+{
+ switch(command) {
+ case ANALOG_MESSAGE: currentAnalogCallback = newFunction; break;
+ case DIGITAL_MESSAGE: currentDigitalCallback = newFunction; break;
+ case REPORT_ANALOG: currentReportAnalogCallback = newFunction; break;
+ case REPORT_DIGITAL: currentReportDigitalCallback = newFunction; break;
+ case SET_PIN_MODE: currentPinModeCallback = newFunction; break;
+ }
+}
+
+void FirmataClass::attach(byte command, systemResetCallbackFunction newFunction)
+{
+ switch(command) {
+ case SYSTEM_RESET: currentSystemResetCallback = newFunction; break;
+ }
+}
+
+void FirmataClass::attach(byte command, stringCallbackFunction newFunction)
+{
+ switch(command) {
+ case FIRMATA_STRING: currentStringCallback = newFunction; break;
+ }
+}
+
+void FirmataClass::attach(byte command, sysexCallbackFunction newFunction)
+{
+ currentSysexCallback = newFunction;
+}
+
+void FirmataClass::detach(byte command)
+{
+ switch(command) {
+ case SYSTEM_RESET: currentSystemResetCallback = NULL; break;
+ case FIRMATA_STRING: currentStringCallback = NULL; break;
+ case START_SYSEX: currentSysexCallback = NULL; break;
+ default:
+ attach(command, (callbackFunction)NULL);
+ }
+}
+
+// sysex callbacks
+/*
+ * this is too complicated for analogReceive, but maybe for Sysex?
+ void FirmataClass::attachSysex(sysexFunction newFunction)
+ {
+ byte i;
+ byte tmpCount = analogReceiveFunctionCount;
+ analogReceiveFunction* tmpArray = analogReceiveFunctionArray;
+ analogReceiveFunctionCount++;
+ analogReceiveFunctionArray = (analogReceiveFunction*) calloc(analogReceiveFunctionCount, sizeof(analogReceiveFunction));
+ for(i = 0; i < tmpCount; i++) {
+ analogReceiveFunctionArray[i] = tmpArray[i];
+ }
+ analogReceiveFunctionArray[tmpCount] = newFunction;
+ free(tmpArray);
+ }
+*/
+
+//******************************************************************************
+//* Private Methods
+//******************************************************************************
+
+
+
+// resets the system state upon a SYSTEM_RESET message from the host software
+void FirmataClass::systemReset(void)
+{
+ byte i;
+
+ waitForData = 0; // this flag says the next serial input will be data
+ executeMultiByteCommand = 0; // execute this after getting multi-byte data
+ multiByteChannel = 0; // channel data for multiByteCommands
+
+
+ for(i=0; i<MAX_DATA_BYTES; i++) {
+ storedInputData[i] = 0;
+ }
+
+ parsingSysex = false;
+ sysexBytesRead = 0;
+
+ if(currentSystemResetCallback)
+ (*currentSystemResetCallback)();
+
+ //flush(); //TODO uncomment when Firmata is a subclass of HardwareSerial
+}
+
+
+
+// =============================================================================
+// used for flashing the pin for the version number
+void FirmataClass::pin13strobe(int count, int onInterval, int offInterval)
+{
+ byte i;
+ pinMode(VERSION_BLINK_PIN, OUTPUT);
+ for(i=0; i<count; i++) {
+ delay(offInterval);
+ digitalWrite(VERSION_BLINK_PIN, HIGH);
+ delay(onInterval);
+ digitalWrite(VERSION_BLINK_PIN, LOW);
+ }
+}
+
+
+// make one instance for the user to use
+FirmataClass Firmata;
+
+
diff --git a/libraries/Firmata/Firmata.h b/libraries/Firmata/Firmata.h
new file mode 100644
index 0000000..a926462
--- /dev/null
+++ b/libraries/Firmata/Firmata.h
@@ -0,0 +1,169 @@
+/*
+ Firmata.h - Firmata library
+ Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
+
+ 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.
+
+ See file LICENSE.txt for further informations on licensing terms.
+*/
+
+#ifndef Firmata_h
+#define Firmata_h
+
+#include <WProgram.h>
+#include <inttypes.h>
+
+
+/* Version numbers for the protocol. The protocol is still changing, so these
+ * version numbers are important. This number can be queried so that host
+ * software can test whether it will be compatible with the currently
+ * installed firmware. */
+#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
+#define FIRMATA_MINOR_VERSION 0 // for backwards compatible changes
+#define VERSION_BLINK_PIN 13 // digital pin to blink version on
+
+#define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
+
+// message command bytes (128-255/0x80-0xFF)
+#define DIGITAL_MESSAGE 0x90 // send data for a digital pin
+#define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM)
+#define REPORT_ANALOG 0xC0 // enable analog input by pin #
+#define REPORT_DIGITAL 0xD0 // enable digital input by port pair
+//
+#define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc
+//
+#define REPORT_VERSION 0xF9 // report protocol version
+#define SYSTEM_RESET 0xFF // reset from MIDI
+//
+#define START_SYSEX 0xF0 // start a MIDI Sysex message
+#define END_SYSEX 0xF7 // end a MIDI Sysex message
+
+// extended command set using sysex (0-127/0x00-0x7F)
+/* 0x00-0x0F reserved for custom commands */
+#define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
+#define FIRMATA_STRING 0x71 // a string message with 14-bits per char
+#define REPORT_FIRMWARE 0x79 // report name and version of the firmware
+#define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
+#define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
+
+// pin modes
+//#define INPUT 0x00 // defined in wiring.h
+//#define OUTPUT 0x01 // defined in wiring.h
+#define ANALOG 0x02 // analog pin in analogInput mode
+#define PWM 0x03 // digital pin in PWM output mode
+#define SERVO 0x04 // digital pin in Servo output mode
+
+
+extern "C" {
+// callback function types
+ typedef void (*callbackFunction)(byte, int);
+ typedef void (*systemResetCallbackFunction)(void);
+ typedef void (*stringCallbackFunction)(char*);
+ typedef void (*sysexCallbackFunction)(byte command, byte argc, byte*argv);
+}
+
+
+// TODO make it a subclass of HardwareSerial
+class FirmataClass
+{
+public:
+ FirmataClass();
+/* Arduino constructors */
+ void begin();
+ void begin(long);
+/* querying functions */
+ void printVersion(void);
+ void blinkVersion(void);
+ void printFirmwareVersion(void);
+// void setFirmwareVersion(byte major, byte minor); // see macro below
+ void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
+/* serial receive handling */
+ int available(void);
+ void processInput(void);
+/* serial send handling */
+ void sendAnalog(byte pin, int value);
+ void sendDigital(byte pin, int value);
+ void sendDigitalPort(byte portNumber, int portData);
+ void sendString(const char* string);
+ void sendString(byte command, const char* string);
+ void sendSysex(byte command, byte bytec, byte* bytev);
+// void print(); // TODO implement so it's compatible to Serial
+// void println(); // TODO implement so it's compatible to Serial
+/* attach & detach callback functions to messages */
+ void attach(byte command, callbackFunction newFunction);
+ void attach(byte command, systemResetCallbackFunction newFunction);
+ void attach(byte command, stringCallbackFunction newFunction);
+ void attach(byte command, sysexCallbackFunction newFunction);
+ void detach(byte command);
+// void flush(); // TODO implement flush, probably by subclassing
+
+private:
+/* firmware name and version */
+ byte firmwareVersionCount;
+ byte *firmwareVersionVector;
+/* input message handling */
+ byte waitForData; // this flag says the next serial input will be data
+ byte executeMultiByteCommand; // execute this after getting multi-byte data
+ byte multiByteChannel; // channel data for multiByteCommands
+ byte storedInputData[MAX_DATA_BYTES]; // multi-byte data
+/* sysex */
+ boolean parsingSysex;
+ int sysexBytesRead;
+/* callback functions */
+ callbackFunction currentAnalogCallback;
+ callbackFunction currentDigitalCallback;
+ callbackFunction currentReportAnalogCallback;
+ callbackFunction currentReportDigitalCallback;
+ callbackFunction currentPinModeCallback;
+ systemResetCallbackFunction currentSystemResetCallback;
+ stringCallbackFunction currentStringCallback;
+ sysexCallbackFunction currentSysexCallback;
+
+/* private methods ------------------------------ */
+ void processSysexMessage(void);
+ void systemReset(void);
+ void pin13strobe(int count, int onInterval, int offInterval);
+};
+
+extern FirmataClass Firmata;
+
+/*==============================================================================
+ * MACROS
+ *============================================================================*/
+
+/* shortcut for setFirmwareNameAndVersion() that uses __FILE__ to set the
+ * firmware name. It needs to be a macro so that __FILE__ is included in the
+ * firmware source file rather than the library source file.
+ */
+#define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y)
+
+// total number of pins currently supported
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) // Arduino NG and Diecimila
+#define TOTAL_ANALOG_PINS 8
+#define TOTAL_DIGITAL_PINS 22 // 14 digital + 8 analog
+#define TOTAL_PORTS 3 // total number of ports for the board
+#define ANALOG_PORT 2 // port# of analog used as digital
+#elif defined(__AVR_ATmega8__) // old Arduinos
+#define TOTAL_ANALOG_PINS 6
+#define TOTAL_DIGITAL_PINS 20 // 14 digital + 6 analog
+#define TOTAL_PORTS 3 // total number of ports for the board
+#define ANALOG_PORT 2 // port# of analog used as digital
+#elif defined(__AVR_ATmega128__)// Wiring
+#define TOTAL_ANALOG_PINS 8
+#define TOTAL_DIGITAL_PINS 51
+#define TOTAL_PORTS 6 // total number of ports for the board
+#define ANALOG_PORT 2 // port# of analog used as digital
+#else // anything else
+#define TOTAL_ANALOG_PINS 6
+#define TOTAL_DIGITAL_PINS 14
+#define TOTAL_PORTS 3 // total number of ports for the board
+#define ANALOG_PORT 2 // port# of analog used as digital
+#endif
+
+
+
+#endif /* Firmata_h */
+
diff --git a/libraries/Firmata/LICENSE.txt b/libraries/Firmata/LICENSE.txt
new file mode 100644
index 0000000..77cec6d
--- /dev/null
+++ b/libraries/Firmata/LICENSE.txt
@@ -0,0 +1,458 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
diff --git a/libraries/Firmata/TODO.txt b/libraries/Firmata/TODO.txt
new file mode 100644
index 0000000..86c9858
--- /dev/null
+++ b/libraries/Firmata/TODO.txt
@@ -0,0 +1,14 @@
+
+- make Firmata a subclass of HardwareSerial
+
+- per-pin digital callback, since the per-port callback is a bit complicated
+ for beginners (maybe Firmata is not for beginners...)
+
+- simplify SimpleDigitalFirmata, take out the code that checks to see if the
+ data has changed, since it is a bit complicated for this example. Ideally
+ this example would be based on a call
+
+- turn current SimpleDigitalFirmata into DigitalPortFirmata for a more complex
+ example using the code which checks for changes before doing anything
+
+- test integration with Wiring
diff --git a/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.pde b/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.pde
new file mode 100644
index 0000000..fcd8e5e
--- /dev/null
+++ b/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.pde
@@ -0,0 +1,83 @@
+/* This firmware supports as many analog ports as possible, all analog inputs,
+ * four PWM outputs, and two with servo support.
+ *
+ * This example code is in the public domain.
+ */
+#include <Firmata.h>
+#include <Servo.h>
+
+/*==============================================================================
+ * GLOBAL VARIABLES
+ *============================================================================*/
+
+/* servos */
+Servo servo9, servo10; // one instance per pin
+/* analog inputs */
+int analogInputsToReport = 0; // bitwise array to store pin reporting
+int analogPin = 0; // counter for reading analog pins
+/* timer variables */
+unsigned long currentMillis; // store the current value from millis()
+unsigned long nextExecuteMillis; // for comparison with currentMillis
+
+
+/*==============================================================================
+ * FUNCTIONS
+ *============================================================================*/
+
+void analogWriteCallback(byte pin, int value)
+{
+ switch(pin) {
+ case 9: servo9.write(value); break;
+ case 10: servo10.write(value); break;
+ case 3:
+ case 5:
+ case 6:
+ case 11: // PWM pins
+ analogWrite(pin, value);
+ break;
+ }
+}
+// -----------------------------------------------------------------------------
+// sets bits in a bit array (int) to toggle the reporting of the analogIns
+void reportAnalogCallback(byte pin, int value)
+{
+ if(value == 0) {
+ analogInputsToReport = analogInputsToReport &~ (1 << pin);
+ }
+ else { // everything but 0 enables reporting of that pin
+ analogInputsToReport = analogInputsToReport | (1 << pin);
+ }
+ // TODO: save status to EEPROM here, if changed
+}
+
+/*==============================================================================
+ * SETUP()
+ *============================================================================*/
+void setup()
+{
+ Firmata.setFirmwareVersion(0, 2);
+ Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
+ Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
+
+ servo9.attach(9);
+ servo10.attach(10);
+ Firmata.begin();
+}
+
+/*==============================================================================
+ * LOOP()
+ *============================================================================*/
+void loop()
+{
+ while(Firmata.available())
+ Firmata.processInput();
+ currentMillis = millis();
+ if(currentMillis > nextExecuteMillis) {
+ nextExecuteMillis = currentMillis + 19; // run this every 20ms
+ for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
+ if( analogInputsToReport & (1 << analogPin) )
+ Firmata.sendAnalog(analogPin, analogRead(analogPin));
+ }
+ }
+}
+
diff --git a/libraries/Firmata/examples/AnalogFirmata/Makefile b/libraries/Firmata/examples/AnalogFirmata/Makefile
new file mode 100644
index 0000000..e968c0a
--- /dev/null
+++ b/libraries/Firmata/examples/AnalogFirmata/Makefile
@@ -0,0 +1,263 @@
+# Arduino makefile
+#
+# This makefile allows you to build sketches from the command line
+# without the Arduino environment (or Java).
+#
+# The Arduino environment does preliminary processing on a sketch before
+# compiling it. If you're using this makefile instead, you'll need to do
+# a few things differently:
+#
+# - Give your program's file a .cpp extension (e.g. foo.cpp).
+#
+# - Put this line at top of your code: #include <WProgram.h>
+#
+# - Write prototypes for all your functions (or define them before you
+# call them). A prototype declares the types of parameters a
+# function will take and what type of value it will return. This
+# means that you can have a call to a function before the definition
+# of the function. A function prototype looks like the first line of
+# the function, with a semi-colon at the end. For example:
+# int digitalRead(int pin);
+#
+# Instructions for using the makefile:
+#
+# 1. Copy this file into the folder with your sketch.
+#
+# 2. Below, modify the line containing "TARGET" to refer to the name of
+# of your program's file without an extension (e.g. TARGET = foo).
+#
+# 3. Modify the line containg "ARDUINO" to point the directory that
+# contains the Arduino core (for normal Arduino installations, this
+# is the hardware/cores/arduino sub-directory).
+#
+# 4. Modify the line containing "PORT" to refer to the filename
+# representing the USB or serial connection to your Arduino board
+# (e.g. PORT = /dev/tty.USB0). If the exact name of this file
+# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
+#
+# 5. At the command line, change to the directory containing your
+# program's file and the makefile.
+#
+# 6. Type "make" and press enter to compile/verify your program.
+#
+# 7. Type "make upload", reset your Arduino board, and press enter to
+# upload your program to the Arduino board.
+#
+# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $
+
+PORT = /dev/tty.usbserial-*
+TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|')
+ARDUINO = /Applications/arduino
+ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
+ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
+INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
+ -I$(ARDUINO_LIB_SRC)/EEPROM \
+ -I$(ARDUINO_LIB_SRC)/Firmata \
+ -I$(ARDUINO_LIB_SRC)/Servo \
+ -I$(ARDUINO_LIB_SRC)
+SRC = $(wildcard $(ARDUINO_SRC)/*.c)
+CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
+ $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
+ $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
+ $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \
+ $(ARDUINO_SRC)/WMath.cpp
+HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
+
+MCU = atmega168
+#MCU = atmega8
+F_CPU = 16000000
+FORMAT = ihex
+UPLOAD_RATE = 19200
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# 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
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS =
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PROGRAMMER = stk500
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+ -b $(UPLOAD_RATE) -q -V
+
+# Program settings
+CC = avr-gcc
+CXX = avr-g++
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+NM = avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: build
+
+build: applet/$(TARGET).hex
+
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss
+sym: applet/$(TARGET).sym
+
+
+# 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: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+extcoff: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym .pde
+
+.elf.hex:
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+ $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+ $(NM) -n $< > $@
+
+
+# Compile: create object files from C++ source files.
+.cpp.o: $(HEADERS)
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o: $(HEADERS)
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+
+applet/$(TARGET).cpp: $(TARGET).pde
+ test -d applet || mkdir applet
+ echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+ echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp
+ sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \
+ grep -v 'loop()' >> applet/$(TARGET).cpp
+ cat $(TARGET).pde >> applet/$(TARGET).cpp
+ cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp
+
+# Link: create ELF output file from object files.
+applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
+ $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
+
+pd_close_serial:
+ echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
+
+# Program the device.
+upload: applet/$(TARGET).hex
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+pd_test: build pd_close_serial upload
+
+# Target: clean project.
+clean:
+ $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \
+ applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \
+ applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+ rmdir -- applet
+
+depend:
+ if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
+ then \
+ sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
+ $(MAKEFILE).$$$$ && \
+ $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
+ fi
+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
+ >> $(MAKEFILE); \
+ $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE)
+
+.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test
+
+# for emacs
+etags:
+ make etags_`uname -s`
+ etags *.pde \
+ $(ARDUINO_SRC)/*.[ch] \
+ $(ARDUINO_SRC)/*.cpp \
+ $(ARDUINO_LIB_SRC)/*/*.[ch] \
+ $(ARDUINO_LIB_SRC)/*/*.cpp \
+ $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \
+ $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch]
+
+etags_Darwin:
+# etags -a
+
+etags_Linux:
+# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h
+
+etags_MINGW:
+# etags -a /usr/include/*.h /usr/include/sys/*.h
+
+
+
diff --git a/libraries/Firmata/examples/EchoString/EchoString.pde b/libraries/Firmata/examples/EchoString/EchoString.pde
new file mode 100644
index 0000000..ed13ad8
--- /dev/null
+++ b/libraries/Firmata/examples/EchoString/EchoString.pde
@@ -0,0 +1,40 @@
+/* This sketch accepts strings and raw sysex messages and echos them back.
+ *
+ * This example code is in the public domain.
+ */
+#include <Firmata.h>
+
+byte analogPin;
+
+void stringCallback(char *myString)
+{
+ Firmata.sendString(myString);
+}
+
+
+void sysexCallback(byte command, byte argc, byte*argv)
+{
+ Serial.print(START_SYSEX, BYTE);
+ Serial.print(command, BYTE);
+ for(byte i=0; i<argc; i++) {
+ Serial.print(argv[i], BYTE);
+ }
+ Serial.print(END_SYSEX, BYTE);
+}
+
+void setup()
+{
+ Firmata.setFirmwareVersion(0, 1);
+ Firmata.attach(FIRMATA_STRING, stringCallback);
+ Firmata.attach(START_SYSEX, sysexCallback);
+ Firmata.begin();
+}
+
+void loop()
+{
+ while(Firmata.available()) {
+ Firmata.processInput();
+ }
+}
+
+
diff --git a/libraries/Firmata/examples/EchoString/Makefile b/libraries/Firmata/examples/EchoString/Makefile
new file mode 100644
index 0000000..e968c0a
--- /dev/null
+++ b/libraries/Firmata/examples/EchoString/Makefile
@@ -0,0 +1,263 @@
+# Arduino makefile
+#
+# This makefile allows you to build sketches from the command line
+# without the Arduino environment (or Java).
+#
+# The Arduino environment does preliminary processing on a sketch before
+# compiling it. If you're using this makefile instead, you'll need to do
+# a few things differently:
+#
+# - Give your program's file a .cpp extension (e.g. foo.cpp).
+#
+# - Put this line at top of your code: #include <WProgram.h>
+#
+# - Write prototypes for all your functions (or define them before you
+# call them). A prototype declares the types of parameters a
+# function will take and what type of value it will return. This
+# means that you can have a call to a function before the definition
+# of the function. A function prototype looks like the first line of
+# the function, with a semi-colon at the end. For example:
+# int digitalRead(int pin);
+#
+# Instructions for using the makefile:
+#
+# 1. Copy this file into the folder with your sketch.
+#
+# 2. Below, modify the line containing "TARGET" to refer to the name of
+# of your program's file without an extension (e.g. TARGET = foo).
+#
+# 3. Modify the line containg "ARDUINO" to point the directory that
+# contains the Arduino core (for normal Arduino installations, this
+# is the hardware/cores/arduino sub-directory).
+#
+# 4. Modify the line containing "PORT" to refer to the filename
+# representing the USB or serial connection to your Arduino board
+# (e.g. PORT = /dev/tty.USB0). If the exact name of this file
+# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
+#
+# 5. At the command line, change to the directory containing your
+# program's file and the makefile.
+#
+# 6. Type "make" and press enter to compile/verify your program.
+#
+# 7. Type "make upload", reset your Arduino board, and press enter to
+# upload your program to the Arduino board.
+#
+# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $
+
+PORT = /dev/tty.usbserial-*
+TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|')
+ARDUINO = /Applications/arduino
+ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
+ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
+INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
+ -I$(ARDUINO_LIB_SRC)/EEPROM \
+ -I$(ARDUINO_LIB_SRC)/Firmata \
+ -I$(ARDUINO_LIB_SRC)/Servo \
+ -I$(ARDUINO_LIB_SRC)
+SRC = $(wildcard $(ARDUINO_SRC)/*.c)
+CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
+ $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
+ $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
+ $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \
+ $(ARDUINO_SRC)/WMath.cpp
+HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
+
+MCU = atmega168
+#MCU = atmega8
+F_CPU = 16000000
+FORMAT = ihex
+UPLOAD_RATE = 19200
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# 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
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS =
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PROGRAMMER = stk500
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+ -b $(UPLOAD_RATE) -q -V
+
+# Program settings
+CC = avr-gcc
+CXX = avr-g++
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+NM = avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: build
+
+build: applet/$(TARGET).hex
+
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss
+sym: applet/$(TARGET).sym
+
+
+# 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: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+extcoff: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym .pde
+
+.elf.hex:
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+ $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+ $(NM) -n $< > $@
+
+
+# Compile: create object files from C++ source files.
+.cpp.o: $(HEADERS)
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o: $(HEADERS)
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+
+applet/$(TARGET).cpp: $(TARGET).pde
+ test -d applet || mkdir applet
+ echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+ echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp
+ sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \
+ grep -v 'loop()' >> applet/$(TARGET).cpp
+ cat $(TARGET).pde >> applet/$(TARGET).cpp
+ cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp
+
+# Link: create ELF output file from object files.
+applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
+ $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
+
+pd_close_serial:
+ echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
+
+# Program the device.
+upload: applet/$(TARGET).hex
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+pd_test: build pd_close_serial upload
+
+# Target: clean project.
+clean:
+ $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \
+ applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \
+ applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+ rmdir -- applet
+
+depend:
+ if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
+ then \
+ sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
+ $(MAKEFILE).$$$$ && \
+ $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
+ fi
+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
+ >> $(MAKEFILE); \
+ $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE)
+
+.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test
+
+# for emacs
+etags:
+ make etags_`uname -s`
+ etags *.pde \
+ $(ARDUINO_SRC)/*.[ch] \
+ $(ARDUINO_SRC)/*.cpp \
+ $(ARDUINO_LIB_SRC)/*/*.[ch] \
+ $(ARDUINO_LIB_SRC)/*/*.cpp \
+ $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \
+ $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch]
+
+etags_Darwin:
+# etags -a
+
+etags_Linux:
+# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h
+
+etags_MINGW:
+# etags -a /usr/include/*.h /usr/include/sys/*.h
+
+
+
diff --git a/libraries/Firmata/examples/ServoFirmata/Makefile b/libraries/Firmata/examples/ServoFirmata/Makefile
new file mode 100644
index 0000000..e968c0a
--- /dev/null
+++ b/libraries/Firmata/examples/ServoFirmata/Makefile
@@ -0,0 +1,263 @@
+# Arduino makefile
+#
+# This makefile allows you to build sketches from the command line
+# without the Arduino environment (or Java).
+#
+# The Arduino environment does preliminary processing on a sketch before
+# compiling it. If you're using this makefile instead, you'll need to do
+# a few things differently:
+#
+# - Give your program's file a .cpp extension (e.g. foo.cpp).
+#
+# - Put this line at top of your code: #include <WProgram.h>
+#
+# - Write prototypes for all your functions (or define them before you
+# call them). A prototype declares the types of parameters a
+# function will take and what type of value it will return. This
+# means that you can have a call to a function before the definition
+# of the function. A function prototype looks like the first line of
+# the function, with a semi-colon at the end. For example:
+# int digitalRead(int pin);
+#
+# Instructions for using the makefile:
+#
+# 1. Copy this file into the folder with your sketch.
+#
+# 2. Below, modify the line containing "TARGET" to refer to the name of
+# of your program's file without an extension (e.g. TARGET = foo).
+#
+# 3. Modify the line containg "ARDUINO" to point the directory that
+# contains the Arduino core (for normal Arduino installations, this
+# is the hardware/cores/arduino sub-directory).
+#
+# 4. Modify the line containing "PORT" to refer to the filename
+# representing the USB or serial connection to your Arduino board
+# (e.g. PORT = /dev/tty.USB0). If the exact name of this file
+# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
+#
+# 5. At the command line, change to the directory containing your
+# program's file and the makefile.
+#
+# 6. Type "make" and press enter to compile/verify your program.
+#
+# 7. Type "make upload", reset your Arduino board, and press enter to
+# upload your program to the Arduino board.
+#
+# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $
+
+PORT = /dev/tty.usbserial-*
+TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|')
+ARDUINO = /Applications/arduino
+ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
+ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
+INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
+ -I$(ARDUINO_LIB_SRC)/EEPROM \
+ -I$(ARDUINO_LIB_SRC)/Firmata \
+ -I$(ARDUINO_LIB_SRC)/Servo \
+ -I$(ARDUINO_LIB_SRC)
+SRC = $(wildcard $(ARDUINO_SRC)/*.c)
+CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
+ $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
+ $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
+ $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \
+ $(ARDUINO_SRC)/WMath.cpp
+HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
+
+MCU = atmega168
+#MCU = atmega8
+F_CPU = 16000000
+FORMAT = ihex
+UPLOAD_RATE = 19200
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# 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
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS =
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PROGRAMMER = stk500
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+ -b $(UPLOAD_RATE) -q -V
+
+# Program settings
+CC = avr-gcc
+CXX = avr-g++
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+NM = avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: build
+
+build: applet/$(TARGET).hex
+
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss
+sym: applet/$(TARGET).sym
+
+
+# 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: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+extcoff: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym .pde
+
+.elf.hex:
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+ $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+ $(NM) -n $< > $@
+
+
+# Compile: create object files from C++ source files.
+.cpp.o: $(HEADERS)
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o: $(HEADERS)
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+
+applet/$(TARGET).cpp: $(TARGET).pde
+ test -d applet || mkdir applet
+ echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+ echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp
+ sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \
+ grep -v 'loop()' >> applet/$(TARGET).cpp
+ cat $(TARGET).pde >> applet/$(TARGET).cpp
+ cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp
+
+# Link: create ELF output file from object files.
+applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
+ $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
+
+pd_close_serial:
+ echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
+
+# Program the device.
+upload: applet/$(TARGET).hex
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+pd_test: build pd_close_serial upload
+
+# Target: clean project.
+clean:
+ $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \
+ applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \
+ applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+ rmdir -- applet
+
+depend:
+ if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
+ then \
+ sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
+ $(MAKEFILE).$$$$ && \
+ $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
+ fi
+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
+ >> $(MAKEFILE); \
+ $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE)
+
+.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test
+
+# for emacs
+etags:
+ make etags_`uname -s`
+ etags *.pde \
+ $(ARDUINO_SRC)/*.[ch] \
+ $(ARDUINO_SRC)/*.cpp \
+ $(ARDUINO_LIB_SRC)/*/*.[ch] \
+ $(ARDUINO_LIB_SRC)/*/*.cpp \
+ $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \
+ $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch]
+
+etags_Darwin:
+# etags -a
+
+etags_Linux:
+# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h
+
+etags_MINGW:
+# etags -a /usr/include/*.h /usr/include/sys/*.h
+
+
+
diff --git a/libraries/Firmata/examples/ServoFirmata/ServoFirmata.pde b/libraries/Firmata/examples/ServoFirmata/ServoFirmata.pde
new file mode 100644
index 0000000..a3c609c
--- /dev/null
+++ b/libraries/Firmata/examples/ServoFirmata/ServoFirmata.pde
@@ -0,0 +1,39 @@
+/* This firmware supports as many servos as possible using the Servo" library
+ * included in Arduino 0012
+ *
+ * TODO add message to configure minPulse/maxPulse/degrees
+ *
+ * This example code is in the public domain.
+ */
+
+#include <Firmata.h>
+#include <Servo.h>
+
+Servo servo9;
+Servo servo10;
+
+void analogWriteCallback(byte pin, int value)
+{
+ if(pin == 9)
+ servo9.write(value);
+ if(pin == 10)
+ servo10.write(value);
+}
+
+void setup()
+{
+ Firmata.setFirmwareVersion(0, 2);
+ Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
+
+ servo9.attach(9);
+ servo10.attach(10);
+
+ Firmata.begin();
+}
+
+void loop()
+{
+ while(Firmata.available())
+ Firmata.processInput();
+}
+
diff --git a/libraries/Firmata/examples/SimpleAnalogFirmata/Makefile b/libraries/Firmata/examples/SimpleAnalogFirmata/Makefile
new file mode 100644
index 0000000..e968c0a
--- /dev/null
+++ b/libraries/Firmata/examples/SimpleAnalogFirmata/Makefile
@@ -0,0 +1,263 @@
+# Arduino makefile
+#
+# This makefile allows you to build sketches from the command line
+# without the Arduino environment (or Java).
+#
+# The Arduino environment does preliminary processing on a sketch before
+# compiling it. If you're using this makefile instead, you'll need to do
+# a few things differently:
+#
+# - Give your program's file a .cpp extension (e.g. foo.cpp).
+#
+# - Put this line at top of your code: #include <WProgram.h>
+#
+# - Write prototypes for all your functions (or define them before you
+# call them). A prototype declares the types of parameters a
+# function will take and what type of value it will return. This
+# means that you can have a call to a function before the definition
+# of the function. A function prototype looks like the first line of
+# the function, with a semi-colon at the end. For example:
+# int digitalRead(int pin);
+#
+# Instructions for using the makefile:
+#
+# 1. Copy this file into the folder with your sketch.
+#
+# 2. Below, modify the line containing "TARGET" to refer to the name of
+# of your program's file without an extension (e.g. TARGET = foo).
+#
+# 3. Modify the line containg "ARDUINO" to point the directory that
+# contains the Arduino core (for normal Arduino installations, this
+# is the hardware/cores/arduino sub-directory).
+#
+# 4. Modify the line containing "PORT" to refer to the filename
+# representing the USB or serial connection to your Arduino board
+# (e.g. PORT = /dev/tty.USB0). If the exact name of this file
+# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
+#
+# 5. At the command line, change to the directory containing your
+# program's file and the makefile.
+#
+# 6. Type "make" and press enter to compile/verify your program.
+#
+# 7. Type "make upload", reset your Arduino board, and press enter to
+# upload your program to the Arduino board.
+#
+# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $
+
+PORT = /dev/tty.usbserial-*
+TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|')
+ARDUINO = /Applications/arduino
+ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
+ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
+INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
+ -I$(ARDUINO_LIB_SRC)/EEPROM \
+ -I$(ARDUINO_LIB_SRC)/Firmata \
+ -I$(ARDUINO_LIB_SRC)/Servo \
+ -I$(ARDUINO_LIB_SRC)
+SRC = $(wildcard $(ARDUINO_SRC)/*.c)
+CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
+ $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
+ $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
+ $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \
+ $(ARDUINO_SRC)/WMath.cpp
+HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
+
+MCU = atmega168
+#MCU = atmega8
+F_CPU = 16000000
+FORMAT = ihex
+UPLOAD_RATE = 19200
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# 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
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS =
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PROGRAMMER = stk500
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+ -b $(UPLOAD_RATE) -q -V
+
+# Program settings
+CC = avr-gcc
+CXX = avr-g++
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+NM = avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: build
+
+build: applet/$(TARGET).hex
+
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss
+sym: applet/$(TARGET).sym
+
+
+# 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: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+extcoff: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym .pde
+
+.elf.hex:
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+ $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+ $(NM) -n $< > $@
+
+
+# Compile: create object files from C++ source files.
+.cpp.o: $(HEADERS)
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o: $(HEADERS)
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+
+applet/$(TARGET).cpp: $(TARGET).pde
+ test -d applet || mkdir applet
+ echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+ echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp
+ sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \
+ grep -v 'loop()' >> applet/$(TARGET).cpp
+ cat $(TARGET).pde >> applet/$(TARGET).cpp
+ cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp
+
+# Link: create ELF output file from object files.
+applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
+ $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
+
+pd_close_serial:
+ echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
+
+# Program the device.
+upload: applet/$(TARGET).hex
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+pd_test: build pd_close_serial upload
+
+# Target: clean project.
+clean:
+ $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \
+ applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \
+ applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+ rmdir -- applet
+
+depend:
+ if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
+ then \
+ sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
+ $(MAKEFILE).$$$$ && \
+ $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
+ fi
+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
+ >> $(MAKEFILE); \
+ $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE)
+
+.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test
+
+# for emacs
+etags:
+ make etags_`uname -s`
+ etags *.pde \
+ $(ARDUINO_SRC)/*.[ch] \
+ $(ARDUINO_SRC)/*.cpp \
+ $(ARDUINO_LIB_SRC)/*/*.[ch] \
+ $(ARDUINO_LIB_SRC)/*/*.cpp \
+ $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \
+ $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch]
+
+etags_Darwin:
+# etags -a
+
+etags_Linux:
+# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h
+
+etags_MINGW:
+# etags -a /usr/include/*.h /usr/include/sys/*.h
+
+
+
diff --git a/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.pde b/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.pde
new file mode 100644
index 0000000..2950c01
--- /dev/null
+++ b/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.pde
@@ -0,0 +1,32 @@
+/* Supports as many analog inputs and analog PWM outputs as possible.
+ *
+ * This example code is in the public domain.
+ */
+#include <Firmata.h>
+
+byte analogPin;
+
+void analogWriteCallback(byte pin, int value)
+{
+ pinMode(pin,OUTPUT);
+ analogWrite(pin, value);
+}
+
+void setup()
+{
+ Firmata.setFirmwareVersion(0, 1);
+ Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
+ Firmata.begin();
+}
+
+void loop()
+{
+ while(Firmata.available()) {
+ Firmata.processInput();
+ }
+ for(analogPin = 0; analogPin < TOTAL_ANALOG_PINS; analogPin++) {
+ Firmata.sendAnalog(analogPin, analogRead(analogPin));
+ }
+}
+
+
diff --git a/libraries/Firmata/examples/SimpleDigitalFirmata/Makefile b/libraries/Firmata/examples/SimpleDigitalFirmata/Makefile
new file mode 100644
index 0000000..e968c0a
--- /dev/null
+++ b/libraries/Firmata/examples/SimpleDigitalFirmata/Makefile
@@ -0,0 +1,263 @@
+# Arduino makefile
+#
+# This makefile allows you to build sketches from the command line
+# without the Arduino environment (or Java).
+#
+# The Arduino environment does preliminary processing on a sketch before
+# compiling it. If you're using this makefile instead, you'll need to do
+# a few things differently:
+#
+# - Give your program's file a .cpp extension (e.g. foo.cpp).
+#
+# - Put this line at top of your code: #include <WProgram.h>
+#
+# - Write prototypes for all your functions (or define them before you
+# call them). A prototype declares the types of parameters a
+# function will take and what type of value it will return. This
+# means that you can have a call to a function before the definition
+# of the function. A function prototype looks like the first line of
+# the function, with a semi-colon at the end. For example:
+# int digitalRead(int pin);
+#
+# Instructions for using the makefile:
+#
+# 1. Copy this file into the folder with your sketch.
+#
+# 2. Below, modify the line containing "TARGET" to refer to the name of
+# of your program's file without an extension (e.g. TARGET = foo).
+#
+# 3. Modify the line containg "ARDUINO" to point the directory that
+# contains the Arduino core (for normal Arduino installations, this
+# is the hardware/cores/arduino sub-directory).
+#
+# 4. Modify the line containing "PORT" to refer to the filename
+# representing the USB or serial connection to your Arduino board
+# (e.g. PORT = /dev/tty.USB0). If the exact name of this file
+# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
+#
+# 5. At the command line, change to the directory containing your
+# program's file and the makefile.
+#
+# 6. Type "make" and press enter to compile/verify your program.
+#
+# 7. Type "make upload", reset your Arduino board, and press enter to
+# upload your program to the Arduino board.
+#
+# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $
+
+PORT = /dev/tty.usbserial-*
+TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|')
+ARDUINO = /Applications/arduino
+ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
+ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
+INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
+ -I$(ARDUINO_LIB_SRC)/EEPROM \
+ -I$(ARDUINO_LIB_SRC)/Firmata \
+ -I$(ARDUINO_LIB_SRC)/Servo \
+ -I$(ARDUINO_LIB_SRC)
+SRC = $(wildcard $(ARDUINO_SRC)/*.c)
+CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
+ $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
+ $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
+ $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \
+ $(ARDUINO_SRC)/WMath.cpp
+HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
+
+MCU = atmega168
+#MCU = atmega8
+F_CPU = 16000000
+FORMAT = ihex
+UPLOAD_RATE = 19200
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# 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
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS =
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PROGRAMMER = stk500
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+ -b $(UPLOAD_RATE) -q -V
+
+# Program settings
+CC = avr-gcc
+CXX = avr-g++
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+NM = avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: build
+
+build: applet/$(TARGET).hex
+
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss
+sym: applet/$(TARGET).sym
+
+
+# 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: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+extcoff: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym .pde
+
+.elf.hex:
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+ $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+ $(NM) -n $< > $@
+
+
+# Compile: create object files from C++ source files.
+.cpp.o: $(HEADERS)
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o: $(HEADERS)
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+
+applet/$(TARGET).cpp: $(TARGET).pde
+ test -d applet || mkdir applet
+ echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+ echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp
+ sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \
+ grep -v 'loop()' >> applet/$(TARGET).cpp
+ cat $(TARGET).pde >> applet/$(TARGET).cpp
+ cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp
+
+# Link: create ELF output file from object files.
+applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
+ $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
+
+pd_close_serial:
+ echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
+
+# Program the device.
+upload: applet/$(TARGET).hex
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+pd_test: build pd_close_serial upload
+
+# Target: clean project.
+clean:
+ $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \
+ applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \
+ applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+ rmdir -- applet
+
+depend:
+ if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
+ then \
+ sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
+ $(MAKEFILE).$$$$ && \
+ $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
+ fi
+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
+ >> $(MAKEFILE); \
+ $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE)
+
+.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test
+
+# for emacs
+etags:
+ make etags_`uname -s`
+ etags *.pde \
+ $(ARDUINO_SRC)/*.[ch] \
+ $(ARDUINO_SRC)/*.cpp \
+ $(ARDUINO_LIB_SRC)/*/*.[ch] \
+ $(ARDUINO_LIB_SRC)/*/*.cpp \
+ $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \
+ $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch]
+
+etags_Darwin:
+# etags -a
+
+etags_Linux:
+# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h
+
+etags_MINGW:
+# etags -a /usr/include/*.h /usr/include/sys/*.h
+
+
+
diff --git a/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.pde b/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.pde
new file mode 100644
index 0000000..1104a92
--- /dev/null
+++ b/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.pde
@@ -0,0 +1,58 @@
+/* Supports as many digital inputs and outputs as possible.
+ *
+ * This example code is in the public domain.
+ */
+#include <Firmata.h>
+
+byte previousPIN[2]; // PIN means PORT for input
+byte previousPORT[2];
+
+void outputPort(byte portNumber, byte portValue)
+{
+// only send the data when it changes, otherwise you get too many messages!
+ if(previousPIN[portNumber] != portValue) {
+ Firmata.sendDigitalPort(portNumber, portValue);
+ previousPIN[portNumber] = portValue;
+ Firmata.sendDigitalPort(portNumber, portValue);
+ }
+}
+
+void setPinModeCallback(byte pin, int mode) {
+ if(pin > 1) { // don't touch RxTx pins (0,1)
+ pinMode(pin, mode);
+ }
+}
+
+void digitalWriteCallback(byte port, int value)
+{
+ byte i;
+ byte currentPinValue, previousPinValue;
+
+ if(value != previousPORT[port]) {
+ for(i=0; i<8; i++) {
+ currentPinValue = (byte) value & (1 << i);
+ previousPinValue = previousPORT[port] & (1 << i);
+ if(currentPinValue != previousPinValue) {
+ digitalWrite(i + (port*8), currentPinValue);
+ }
+ }
+ previousPORT[port] = value;
+ }
+}
+
+void setup()
+{
+ Firmata.setFirmwareVersion(0, 1);
+ Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
+ Firmata.attach(SET_PIN_MODE, setPinModeCallback);
+ Firmata.begin();
+}
+
+void loop()
+{
+ outputPort(0, PIND &~ B00000011); // pins 0-7, ignoring Rx/Tx pins (0/1)
+ outputPort(1, PINB); // pins 8-13
+ while(Firmata.available()) {
+ Firmata.processInput();
+ }
+}
diff --git a/libraries/Firmata/examples/StandardFirmata/LICENSE.txt b/libraries/Firmata/examples/StandardFirmata/LICENSE.txt
new file mode 100644
index 0000000..77cec6d
--- /dev/null
+++ b/libraries/Firmata/examples/StandardFirmata/LICENSE.txt
@@ -0,0 +1,458 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
diff --git a/libraries/Firmata/examples/StandardFirmata/Makefile b/libraries/Firmata/examples/StandardFirmata/Makefile
new file mode 100644
index 0000000..55ca8c2
--- /dev/null
+++ b/libraries/Firmata/examples/StandardFirmata/Makefile
@@ -0,0 +1,261 @@
+# Arduino makefile
+#
+# This makefile allows you to build sketches from the command line
+# without the Arduino environment (or Java).
+#
+# The Arduino environment does preliminary processing on a sketch before
+# compiling it. If you're using this makefile instead, you'll need to do
+# a few things differently:
+#
+# - Give your program's file a .cpp extension (e.g. foo.cpp).
+#
+# - Put this line at top of your code: #include <WProgram.h>
+#
+# - Write prototypes for all your functions (or define them before you
+# call them). A prototype declares the types of parameters a
+# function will take and what type of value it will return. This
+# means that you can have a call to a function before the definition
+# of the function. A function prototype looks like the first line of
+# the function, with a semi-colon at the end. For example:
+# int digitalRead(int pin);
+#
+# Instructions for using the makefile:
+#
+# 1. Copy this file into the folder with your sketch.
+#
+# 2. Below, modify the line containing "TARGET" to refer to the name of
+# of your program's file without an extension (e.g. TARGET = foo).
+#
+# 3. Modify the line containg "ARDUINO" to point the directory that
+# contains the Arduino core (for normal Arduino installations, this
+# is the hardware/cores/arduino sub-directory).
+#
+# 4. Modify the line containing "PORT" to refer to the filename
+# representing the USB or serial connection to your Arduino board
+# (e.g. PORT = /dev/tty.USB0). If the exact name of this file
+# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
+#
+# 5. At the command line, change to the directory containing your
+# program's file and the makefile.
+#
+# 6. Type "make" and press enter to compile/verify your program.
+#
+# 7. Type "make upload", reset your Arduino board, and press enter to
+# upload your program to the Arduino board.
+#
+# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $
+
+PORT = /dev/tty.usbserial-*
+TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|')
+ARDUINO = /Applications/arduino
+ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
+ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
+INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
+ -I$(ARDUINO_LIB_SRC)/EEPROM \
+ -I$(ARDUINO_LIB_SRC)/Firmata \
+ -I$(ARDUINO_LIB_SRC)
+SRC = $(wildcard $(ARDUINO_SRC)/*.c)
+CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
+ $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
+ $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
+ $(ARDUINO_SRC)/WMath.cpp
+HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
+
+MCU = atmega168
+#MCU = atmega8
+F_CPU = 16000000
+FORMAT = ihex
+UPLOAD_RATE = 19200
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# 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
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS =
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PROGRAMMER = stk500
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+ -b $(UPLOAD_RATE) -q -V
+
+# Program settings
+CC = avr-gcc
+CXX = avr-g++
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+NM = avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: build
+
+build: applet/$(TARGET).hex
+
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss
+sym: applet/$(TARGET).sym
+
+
+# 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: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+extcoff: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym .pde
+
+.elf.hex:
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+ $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+ $(NM) -n $< > $@
+
+
+# Compile: create object files from C++ source files.
+.cpp.o: $(HEADERS)
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o: $(HEADERS)
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+
+applet/$(TARGET).cpp: $(TARGET).pde
+ test -d applet || mkdir applet
+ echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+ echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp
+ sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \
+ grep -v 'loop()' >> applet/$(TARGET).cpp
+ cat $(TARGET).pde >> applet/$(TARGET).cpp
+ cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp
+
+# Link: create ELF output file from object files.
+applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
+ $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
+
+pd_close_serial:
+ echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
+
+# Program the device.
+upload: applet/$(TARGET).hex
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+pd_test: build pd_close_serial upload
+
+# Target: clean project.
+clean:
+ $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \
+ applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \
+ applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+ rmdir -- applet
+
+depend:
+ if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
+ then \
+ sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
+ $(MAKEFILE).$$$$ && \
+ $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
+ fi
+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
+ >> $(MAKEFILE); \
+ $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE)
+
+.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test
+
+# for emacs
+etags:
+ make etags_`uname -s`
+ etags *.pde \
+ $(ARDUINO_SRC)/*.[ch] \
+ $(ARDUINO_SRC)/*.cpp \
+ $(ARDUINO_LIB_SRC)/*/*.[ch] \
+ $(ARDUINO_LIB_SRC)/*/*.cpp \
+ $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \
+ $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch]
+
+etags_Darwin:
+# etags -a
+
+etags_Linux:
+# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h
+
+etags_MINGW:
+# etags -a /usr/include/*.h /usr/include/sys/*.h
+
+
+
diff --git a/libraries/Firmata/examples/StandardFirmata/StandardFirmata.pde b/libraries/Firmata/examples/StandardFirmata/StandardFirmata.pde
new file mode 100644
index 0000000..4cc8539
--- /dev/null
+++ b/libraries/Firmata/examples/StandardFirmata/StandardFirmata.pde
@@ -0,0 +1,226 @@
+/*
+ Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
+
+ 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.
+
+ See file LICENSE.txt for further informations on licensing terms.
+ */
+
+/*
+ * TODO: add Servo support using setPinMode(pin, SERVO);
+ * TODO: use Program Control to load stored profiles from EEPROM
+ */
+
+#include <EEPROM.h>
+#include <Firmata.h>
+
+/*==============================================================================
+ * GLOBAL VARIABLES
+ *============================================================================*/
+
+/* analog inputs */
+int analogInputsToReport = 0; // bitwise array to store pin reporting
+int analogPin = 0; // counter for reading analog pins
+
+/* digital pins */
+byte reportPINs[TOTAL_PORTS]; // PIN == input port
+byte previousPINs[TOTAL_PORTS]; // PIN == input port
+byte pinStatus[TOTAL_DIGITAL_PINS]; // store pin status, default OUTPUT
+byte portStatus[TOTAL_PORTS];
+
+/* timer variables */
+unsigned long currentMillis; // store the current value from millis()
+unsigned long nextExecuteMillis; // for comparison with currentMillis
+
+
+/*==============================================================================
+ * FUNCTIONS
+ *============================================================================*/
+
+void outputPort(byte portNumber, byte portValue)
+{
+ portValue = portValue &~ portStatus[portNumber];
+ if(previousPINs[portNumber] != portValue) {
+ Firmata.sendDigitalPort(portNumber, portValue);
+ previousPINs[portNumber] = portValue;
+ Firmata.sendDigitalPort(portNumber, portValue);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * check all the active digital inputs for change of state, then add any events
+ * to the Serial output queue using Serial.print() */
+void checkDigitalInputs(void)
+{
+ byte i, tmp;
+ for(i=0; i < TOTAL_PORTS; i++) {
+ if(reportPINs[i]) {
+ switch(i) {
+ case 0: outputPort(0, PIND &~ B00000011); break; // ignore Rx/Tx 0/1
+ case 1: outputPort(1, PINB); break;
+ case ANALOG_PORT: outputPort(ANALOG_PORT, PINC); break;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+/* sets the pin mode to the correct state and sets the relevant bits in the
+ * two bit-arrays that track Digital I/O and PWM status
+ */
+void setPinModeCallback(byte pin, int mode) {
+ byte port = 0;
+ byte offset = 0;
+
+ if (pin < 8) {
+ port = 0;
+ offset = 0;
+ } else if (pin < 14) {
+ port = 1;
+ offset = 8;
+ } else if (pin < 22) {
+ port = 2;
+ offset = 14;
+ }
+
+ if(pin > 1) { // ignore RxTx (pins 0 and 1)
+ pinStatus[pin] = mode;
+ switch(mode) {
+ case INPUT:
+ pinMode(pin, INPUT);
+ portStatus[port] = portStatus[port] &~ (1 << (pin - offset));
+ break;
+ case OUTPUT:
+ digitalWrite(pin, LOW); // disable PWM
+ case PWM:
+ pinMode(pin, OUTPUT);
+ portStatus[port] = portStatus[port] | (1 << (pin - offset));
+ break;
+ //case ANALOG: // TODO figure this out
+ default:
+ Firmata.sendString("");
+ }
+ // TODO: save status to EEPROM here, if changed
+ }
+}
+
+void analogWriteCallback(byte pin, int value)
+{
+ setPinModeCallback(pin,PWM);
+ analogWrite(pin, value);
+}
+
+void digitalWriteCallback(byte port, int value)
+{
+ switch(port) {
+ case 0: // pins 2-7 (don't change Rx/Tx, pins 0 and 1)
+ // 0xFF03 == B1111111100000011 0x03 == B00000011
+ PORTD = (value &~ 0xFF03) | (PORTD & 0x03);
+ break;
+ case 1: // pins 8-13 (14,15 are disabled for the crystal)
+ PORTB = (byte)value;
+ break;
+ case 2: // analog pins used as digital
+ PORTC = (byte)value;
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------------
+/* sets bits in a bit array (int) to toggle the reporting of the analogIns
+ */
+//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
+//}
+void reportAnalogCallback(byte pin, int value)
+{
+ if(value == 0) {
+ analogInputsToReport = analogInputsToReport &~ (1 << pin);
+ }
+ else { // everything but 0 enables reporting of that pin
+ analogInputsToReport = analogInputsToReport | (1 << pin);
+ }
+ // TODO: save status to EEPROM here, if changed
+}
+
+void reportDigitalCallback(byte port, int value)
+{
+ reportPINs[port] = (byte)value;
+ if(port == ANALOG_PORT) // turn off analog reporting when used as digital
+ analogInputsToReport = 0;
+}
+
+/*==============================================================================
+ * SETUP()
+ *============================================================================*/
+void setup()
+{
+ byte i;
+
+ Firmata.setFirmwareVersion(2, 0);
+
+ Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
+ Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
+ Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
+ Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
+ Firmata.attach(SET_PIN_MODE, setPinModeCallback);
+
+ portStatus[0] = B00000011; // ignore Tx/RX pins
+ portStatus[1] = B11000000; // ignore 14/15 pins
+ portStatus[2] = B00000000;
+
+// for(i=0; i<TOTAL_DIGITAL_PINS; ++i) { // TODO make this work with analogs
+ for(i=0; i<14; ++i) {
+ setPinModeCallback(i,OUTPUT);
+ }
+ // set all outputs to 0 to make sure internal pull-up resistors are off
+ PORTB = 0; // pins 8-15
+ PORTC = 0; // analog port
+ PORTD = 0; // pins 0-7
+
+ // TODO rethink the init, perhaps it should report analog on default
+ for(i=0; i<TOTAL_PORTS; ++i) {
+ reportPINs[i] = false;
+ }
+ // TODO: load state from EEPROM here
+
+ /* send digital inputs here, if enabled, to set the initial state on the
+ * host computer, since once in the loop(), this firmware will only send
+ * digital data on change. */
+ if(reportPINs[0]) outputPort(0, PIND &~ B00000011); // ignore Rx/Tx 0/1
+ if(reportPINs[1]) outputPort(1, PINB);
+ if(reportPINs[ANALOG_PORT]) outputPort(ANALOG_PORT, PINC);
+
+ Firmata.begin();
+}
+
+/*==============================================================================
+ * LOOP()
+ *============================================================================*/
+void loop()
+{
+/* DIGITALREAD - as fast as possible, check for changes and output them to the
+ * FTDI buffer using Serial.print() */
+ checkDigitalInputs();
+ currentMillis = millis();
+ if(currentMillis > nextExecuteMillis) {
+ nextExecuteMillis = currentMillis + 19; // run this every 20ms
+ /* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
+ * all serialReads at once, i.e. empty the buffer */
+ while(Firmata.available())
+ Firmata.processInput();
+ /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
+ * 60 bytes. use a timer to sending an event character every 4 ms to
+ * trigger the buffer to dump. */
+
+ /* ANALOGREAD - right after the event character, do all of the
+ * analogReads(). These only need to be done every 4ms. */
+ for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
+ if( analogInputsToReport & (1 << analogPin) ) {
+ Firmata.sendAnalog(analogPin, analogRead(analogPin));
+ }
+ }
+ }
+}
diff --git a/libraries/Firmata/keywords.txt b/libraries/Firmata/keywords.txt
new file mode 100644
index 0000000..52e0a9c
--- /dev/null
+++ b/libraries/Firmata/keywords.txt
@@ -0,0 +1,62 @@
+#######################################
+# Syntax Coloring Map For Firmata
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+Firmata KEYWORD1
+callbackFunction KEYWORD1
+systemResetCallbackFunction KEYWORD1
+stringCallbackFunction KEYWORD1
+sysexCallbackFunction KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+begin KEYWORD2
+begin KEYWORD2
+printVersion KEYWORD2
+blinkVersion KEYWORD2
+printFirmwareVersion KEYWORD2
+setFirmwareVersion KEYWORD2
+setFirmwareNameAndVersion KEYWORD2
+available KEYWORD2
+processInput KEYWORD2
+sendAnalog KEYWORD2
+sendDigital KEYWORD2
+sendDigitalPortPair KEYWORD2
+sendDigitalPort KEYWORD2
+sendString KEYWORD2
+sendString KEYWORD2
+sendSysex KEYWORD2
+attach KEYWORD2
+detach KEYWORD2
+flush KEYWORD2
+
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
+MAX_DATA_BYTES LITERAL1
+
+DIGITAL_MESSAGE LITERAL1
+ANALOG_MESSAGE LITERAL1
+REPORT_ANALOG LITERAL1
+REPORT_DIGITAL LITERAL1
+REPORT_VERSION LITERAL1
+SET_PIN_MODE LITERAL1
+SYSTEM_RESET LITERAL1
+
+START_SYSEX LITERAL1
+END_SYSEX LITERAL1
+
+PWM LITERAL1
+
+TOTAL_ANALOG_PINS LITERAL1
+TOTAL_DIGITAL_PINS LITERAL1
+TOTAL_PORTS LITERAL1
+ANALOG_PORT LITERAL1
diff --git a/libraries/LiquidCrystal/LiquidCrystal.cpp b/libraries/LiquidCrystal/LiquidCrystal.cpp
new file mode 100755
index 0000000..b5f2cd4
--- /dev/null
+++ b/libraries/LiquidCrystal/LiquidCrystal.cpp
@@ -0,0 +1,128 @@
+#include "LiquidCrystal.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include "WProgram.h"
+
+// When the display powers up, it is configured as follows:
+//
+// 1. Display clear
+// 2. Function set:
+// DL = 1; 8-bit interface data
+// N = 0; 1-line display
+// F = 0; 5x8 dot character font
+// 3. Display on/off control:
+// D = 0; Display off
+// C = 0; Cursor off
+// B = 0; Blinking off
+// 4. Entry mode set:
+// I/D = 1; Increment by 1
+// S = 0; No shift
+//
+// Note, however, that resetting the Arduino doesn't reset the LCD, so we
+// can't assume that its in that state when a sketch starts (and the
+// LiquidCrystal constructor is called).
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) :
+ _four_bit_mode(0), _rs_pin(rs), _rw_pin(rw), _enable_pin(enable)
+{
+ _data_pins[0] = d0;
+ _data_pins[1] = d1;
+ _data_pins[2] = d2;
+ _data_pins[3] = d3;
+ _data_pins[4] = d4;
+ _data_pins[5] = d5;
+ _data_pins[6] = d6;
+ _data_pins[7] = d7;
+
+ pinMode(_rs_pin, OUTPUT);
+ pinMode(_rw_pin, OUTPUT);
+ pinMode(_enable_pin, OUTPUT);
+
+ for (int i = 0; i < 8; i++)
+ pinMode(_data_pins[i], OUTPUT);
+
+ command(0x38); // function set: 8 bits, 1 line, 5x8 dots
+ command(0x0C); // display control: turn display on, cursor off, no blinking
+ command(0x06); // entry mode set: increment automatically, display shift, right shift
+ clear();
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) :
+ _four_bit_mode(1), _rs_pin(rs), _rw_pin(rw), _enable_pin(enable)
+{
+ _data_pins[0] = d0;
+ _data_pins[1] = d1;
+ _data_pins[2] = d2;
+ _data_pins[3] = d3;
+
+ pinMode(_rs_pin, OUTPUT);
+ pinMode(_rw_pin, OUTPUT);
+ pinMode(_enable_pin, OUTPUT);
+
+ for (int i = 0; i < 4; i++)
+ pinMode(_data_pins[i], OUTPUT);
+
+ command(0x28); // function set: 4 bits, 1 line, 5x8 dots
+ command(0x0C); // display control: turn display on, cursor off, no blinking
+ command(0x06); // entry mode set: increment automatically, display shift, right shift
+ clear();
+}
+
+void LiquidCrystal::clear()
+{
+ command(0x01); // clear display, set cursor position to zero
+ delayMicroseconds(2000);
+}
+
+void LiquidCrystal::home()
+{
+ command(0x02); // set cursor position to zero
+ delayMicroseconds(2000);
+}
+
+void LiquidCrystal::setCursor(int col, int row)
+{
+ int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
+ command(0x80 | (col + row_offsets[row]));
+}
+
+void LiquidCrystal::command(uint8_t value) {
+ send(value, LOW);
+}
+
+void LiquidCrystal::write(uint8_t value) {
+ send(value, HIGH);
+}
+
+void LiquidCrystal::send(uint8_t value, uint8_t mode) {
+ digitalWrite(_rs_pin, mode);
+ digitalWrite(_rw_pin, LOW);
+
+ if (_four_bit_mode) {
+ for (int i = 0; i < 4; i++) {
+ digitalWrite(_data_pins[i], (value >> (i + 4)) & 0x01);
+ }
+
+ digitalWrite(_enable_pin, HIGH);
+ digitalWrite(_enable_pin, LOW);
+
+ for (int i = 0; i < 4; i++) {
+ digitalWrite(_data_pins[i], (value >> i) & 0x01);
+ }
+
+ digitalWrite(_enable_pin, HIGH);
+ digitalWrite(_enable_pin, LOW);
+ } else {
+ for (int i = 0; i < 8; i++) {
+ digitalWrite(_data_pins[i], (value >> i) & 0x01);
+ }
+
+ digitalWrite(_enable_pin, HIGH);
+ digitalWrite(_enable_pin, LOW);
+ }
+}
diff --git a/libraries/LiquidCrystal/LiquidCrystal.h b/libraries/LiquidCrystal/LiquidCrystal.h
new file mode 100755
index 0000000..a5edc5f
--- /dev/null
+++ b/libraries/LiquidCrystal/LiquidCrystal.h
@@ -0,0 +1,31 @@
+#ifndef LiquidCrystal_h
+#define LiquidCrystal_h
+
+#include <inttypes.h>
+#include "Print.h"
+
+class LiquidCrystal : public Print {
+public:
+ LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
+ LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
+ uint8_t, uint8_t, uint8_t, uint8_t);
+ void clear();
+ void home();
+ void setCursor(int, int);
+ /*
+ void shiftDisplayLeft();
+ void shiftDisplayRight();
+ */
+ virtual void write(uint8_t);
+ void command(uint8_t);
+private:
+ void send(uint8_t, uint8_t);
+
+ uint8_t _four_bit_mode;
+ uint8_t _rs_pin; // LOW: command. HIGH: character.
+ uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD.
+ uint8_t _enable_pin; // activated by a HIGH pulse.
+ uint8_t _data_pins[8];
+};
+
+#endif
diff --git a/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.pde b/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.pde
new file mode 100644
index 0000000..2f244d0
--- /dev/null
+++ b/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.pde
@@ -0,0 +1,18 @@
+#include <LiquidCrystal.h>
+
+// LiquidCrystal display with:
+// rs on pin 12
+// rw on pin 11
+// enable on pin 10
+// d4, d5, d6, d7 on pins 5, 4, 3, 2
+LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
+
+void setup()
+{
+ // Print a message to the LCD.
+ lcd.print("hello, world!");
+}
+
+void loop()
+{
+}
diff --git a/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.pde b/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.pde
new file mode 100644
index 0000000..0c4ce35
--- /dev/null
+++ b/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.pde
@@ -0,0 +1,34 @@
+/*
+ * Displays text sent over the serial port (e.g. from the Serial Monitor) on
+ * an attached LCD.
+ */
+
+#include <LiquidCrystal.h>
+
+// LiquidCrystal display with:
+// rs on pin 12
+// rw on pin 11
+// enable on pin 10
+// d4, d5, d6, d7 on pins 5, 4, 3, 2
+LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
+
+void setup()
+{
+ Serial.begin(9600);
+}
+
+void loop()
+{
+ // when characters arrive over the serial port...
+ if (Serial.available()) {
+ // wait a bit for the entire message to arrive
+ delay(100);
+ // clear the screen
+ lcd.clear();
+ // read all the available characters
+ while (Serial.available() > 0) {
+ // display each character to the LCD
+ lcd.write(Serial.read());
+ }
+ }
+}
diff --git a/libraries/LiquidCrystal/keywords.txt b/libraries/LiquidCrystal/keywords.txt
new file mode 100755
index 0000000..367ab1f
--- /dev/null
+++ b/libraries/LiquidCrystal/keywords.txt
@@ -0,0 +1,23 @@
+#######################################
+# Syntax Coloring Map For LiquidCrystal
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+LiquidCrystal KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+clear KEYWORD2
+home KEYWORD2
+print KEYWORD2
+setCursor KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
diff --git a/libraries/Matrix/Matrix.cpp b/libraries/Matrix/Matrix.cpp
new file mode 100755
index 0000000..2eb3e25
--- /dev/null
+++ b/libraries/Matrix/Matrix.cpp
@@ -0,0 +1,229 @@
+/*
+ Matrix.cpp - Max7219 LED Matrix library for Arduino & Wiring
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+// TODO: Support segment displays in api?
+// TODO: Support varying vendor layouts?
+
+/******************************************************************************
+ * Includes
+ ******************************************************************************/
+
+extern "C" {
+ // AVR LibC Includes
+ #include <inttypes.h>
+ #include <stdlib.h>
+
+ // Wiring Core Includes
+ #undef abs
+ #include "WConstants.h"
+
+ // Wiring Core Prototypes
+ //void pinMode(uint8_t, uint8_t);
+ //void digitalWrite(int, uint8_t);
+}
+
+#include "Sprite.h"
+#include "Matrix.h"
+
+/******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+// Matrix registers
+#define REG_NOOP 0x00
+#define REG_DIGIT0 0x01
+#define REG_DIGIT1 0x02
+#define REG_DIGIT2 0x03
+#define REG_DIGIT3 0x04
+#define REG_DIGIT4 0x05
+#define REG_DIGIT5 0x06
+#define REG_DIGIT6 0x07
+#define REG_DIGIT7 0x08
+#define REG_DECODEMODE 0x09
+#define REG_INTENSITY 0x0A
+#define REG_SCANLIMIT 0x0B
+#define REG_SHUTDOWN 0x0C
+#define REG_DISPLAYTEST 0x0F
+
+/******************************************************************************
+ * Constructors
+ ******************************************************************************/
+
+Matrix::Matrix(uint8_t data, uint8_t clock, uint8_t load, uint8_t screens /* = 1 */)
+{
+ // record pins for sw spi
+ _pinData = data;
+ _pinClock = clock;
+ _pinLoad = load;
+
+ // set ddr for sw spi pins
+ pinMode(_pinClock, OUTPUT);
+ pinMode(_pinData, OUTPUT);
+ pinMode(_pinLoad, OUTPUT);
+
+ // allocate screenbuffers
+ _screens = screens;
+ _buffer = (uint8_t*)calloc(_screens, 64);
+ _maximumX = (_screens * 8);
+
+ // initialize registers
+ clear(); // clear display
+ setScanLimit(0x07); // use all rows/digits
+ setBrightness(0x0F); // maximum brightness
+ setRegister(REG_SHUTDOWN, 0x01); // normal operation
+ setRegister(REG_DECODEMODE, 0x00); // pixels not integers
+ setRegister(REG_DISPLAYTEST, 0x00); // not in test mode
+}
+
+/******************************************************************************
+ * MAX7219 SPI
+ ******************************************************************************/
+
+// sends a single byte by sw spi (no latching)
+void Matrix::putByte(uint8_t data)
+{
+ uint8_t i = 8;
+ uint8_t mask;
+ while(i > 0) {
+ mask = 0x01 << (i - 1); // get bitmask
+ digitalWrite(_pinClock, LOW); // tick
+ if (data & mask){ // choose bit
+ digitalWrite(_pinData, HIGH); // set 1
+ }else{
+ digitalWrite(_pinData, LOW); // set 0
+ }
+ digitalWrite(_pinClock, HIGH); // tock
+ --i; // move to lesser bit
+ }
+}
+
+// sets register to a byte value for all screens
+void Matrix::setRegister(uint8_t reg, uint8_t data)
+{
+ digitalWrite(_pinLoad, LOW); // begin
+ for(uint8_t i = 0; i < _screens; ++i){
+ putByte(reg); // specify register
+ putByte(data); // send data
+ }
+ digitalWrite(_pinLoad, HIGH); // latch in data
+ digitalWrite(_pinLoad, LOW); // end
+}
+
+// syncs row of display with buffer
+void Matrix::syncRow(uint8_t row)
+{
+ if (!_buffer) return;
+
+ // uint8_t's can't be negative, so don't test for negative row
+ if (row >= 8) return;
+ digitalWrite(_pinLoad, LOW); // begin
+ for(uint8_t i = 0; i < _screens; ++i){
+ putByte(8 - row); // specify register
+ putByte(_buffer[row + (8 * i)]); // send data
+ }
+ digitalWrite(_pinLoad, HIGH); // latch in data
+ digitalWrite(_pinLoad, LOW); // end
+}
+
+/******************************************************************************
+ * MAX7219 Configuration
+ ******************************************************************************/
+
+// sets how many digits are displayed
+void Matrix::setScanLimit(uint8_t value)
+{
+ setRegister(REG_SCANLIMIT, value & 0x07);
+}
+
+// sets brightness of the display
+void Matrix::setBrightness(uint8_t value)
+{
+ setRegister(REG_INTENSITY, value & 0x0F);
+}
+
+/******************************************************************************
+ * Helper Functions
+ ******************************************************************************/
+
+void Matrix::buffer(uint8_t x, uint8_t y, uint8_t value)
+{
+ if (!_buffer) return;
+
+ // uint8_t's can't be negative, so don't test for negative x and y.
+ if (x >= _maximumX || y >= 8) return;
+
+ uint8_t offset = x; // record x
+ x %= 8; // make x relative to a single matrix
+ offset -= x; // calculate buffer offset
+
+ // wrap shift relative x for nexus module layout
+ if (x == 0){
+ x = 8;
+ }
+ --x;
+
+ // record value in buffer
+ if(value){
+ _buffer[y + offset] |= 0x01 << x;
+ }else{
+ _buffer[y + offset] &= ~(0x01 << x);
+ }
+}
+
+/******************************************************************************
+ * User API
+ ******************************************************************************/
+
+// buffers and writes to screen
+void Matrix::write(uint8_t x, uint8_t y, uint8_t value)
+{
+ buffer(x, y, value);
+
+ // update affected row
+ syncRow(y);
+}
+
+void Matrix::write(uint8_t x, uint8_t y, Sprite sprite)
+{
+ for (uint8_t i = 0; i < sprite.height(); i++){
+ for (uint8_t j = 0; j < sprite.width(); j++)
+ buffer(x + j, y + i, sprite.read(j, i));
+
+ syncRow(y + i);
+ }
+}
+
+// clears screens and buffers
+void Matrix::clear(void)
+{
+ if (!_buffer) return;
+
+ // clear buffer
+ for(uint8_t i = 0; i < 8; ++i){
+ for(uint8_t j = 0; j < _screens; ++j){
+ _buffer[i + (8 * j)] = 0x00;
+ }
+ }
+
+ // clear registers
+ for(uint8_t i = 0; i < 8; ++i){
+ syncRow(i);
+ }
+}
+
diff --git a/libraries/Matrix/Matrix.h b/libraries/Matrix/Matrix.h
new file mode 100755
index 0000000..7c6be91
--- /dev/null
+++ b/libraries/Matrix/Matrix.h
@@ -0,0 +1,54 @@
+/*
+ Matrix.h - Max7219 LED Matrix library for Arduino & Wiring
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef Matrix_h
+#define Matrix_h
+
+#include <inttypes.h>
+
+class Sprite;
+
+class Matrix
+{
+ private:
+ uint8_t _pinData;
+ uint8_t _pinClock;
+ uint8_t _pinLoad;
+
+ uint8_t* _buffer;
+ uint8_t _screens;
+ uint8_t _maximumX;
+
+ void putByte(uint8_t);
+ void setRegister(uint8_t, uint8_t);
+ void syncRow(uint8_t);
+
+ void setScanLimit(uint8_t);
+
+ void buffer(uint8_t, uint8_t, uint8_t);
+ public:
+ Matrix(uint8_t, uint8_t, uint8_t, uint8_t = 1);
+ void setBrightness(uint8_t);
+ void write(uint8_t, uint8_t, uint8_t);
+ void write(uint8_t, uint8_t, Sprite);
+ void clear(void);
+};
+
+#endif
+
diff --git a/libraries/Matrix/examples/hello_matrix/hello_matrix.pde b/libraries/Matrix/examples/hello_matrix/hello_matrix.pde
new file mode 100644
index 0000000..127917f
--- /dev/null
+++ b/libraries/Matrix/examples/hello_matrix/hello_matrix.pde
@@ -0,0 +1,42 @@
+#include <Sprite.h>
+#include <Matrix.h>
+
+// Hello Matrix
+// by Nicholas Zambetti <http://www.zambetti.com>
+
+// Demonstrates the use of the Matrix library
+// For MAX7219 LED Matrix Controllers
+// Blinks welcoming face on screen
+
+// Created 13 February 2006
+
+/* create a new Matrix instance
+ pin 0: data (din)
+ pin 1: load (load)
+ pin 2: clock (clk)
+*/
+Matrix myMatrix = Matrix(0, 2, 1);
+
+void setup()
+{
+}
+
+void loop()
+{
+ myMatrix.clear(); // clear display
+
+ delay(1000);
+
+ // turn some pixels on
+ myMatrix.write(1, 5, HIGH);
+ myMatrix.write(2, 2, HIGH);
+ myMatrix.write(2, 6, HIGH);
+ myMatrix.write(3, 6, HIGH);
+ myMatrix.write(4, 6, HIGH);
+ myMatrix.write(5, 2, HIGH);
+ myMatrix.write(5, 6, HIGH);
+ myMatrix.write(6, 5, HIGH);
+
+ delay(1000);
+}
+
diff --git a/libraries/Matrix/examples/sprite_animation/sprite_animation.pde b/libraries/Matrix/examples/sprite_animation/sprite_animation.pde
new file mode 100644
index 0000000..bf7c6f5
--- /dev/null
+++ b/libraries/Matrix/examples/sprite_animation/sprite_animation.pde
@@ -0,0 +1,48 @@
+#include <Sprite.h>
+#include <Matrix.h>
+
+// Sprite Animation
+// by Nicholas Zambetti <http://www.zambetti.com>
+
+// Demonstrates the use of the Matrix & Sprite libraries
+// Displays animated waveform graphic on screen
+
+// Created 29 March 2006
+
+/* create a new Matrix instance
+ pin 0: data (din)
+ pin 1: load (load)
+ pin 2: clock (clk)
+*/
+Matrix myMatrix = Matrix(0, 2, 1);
+
+/* create a new Sprite instance
+ 8 pixels wide, 4 pixels tall
+*/
+Sprite wave = Sprite(
+ 8, 4,
+ B00011000,
+ B00100100,
+ B01000010,
+ B10000001
+);
+
+void setup()
+{
+}
+
+int x = 0;
+
+void loop()
+{
+ myMatrix.write(x, 2, wave); // place sprite on screen
+ myMatrix.write(x - 8, 2, wave); // place sprite again, elsewhere on screen
+ delay(75); // wait a little bit
+ myMatrix.clear(); // clear the screen for next animation frame
+ if(x == 8) // if reached end of animation sequence
+ {
+ x = 0; // start from beginning
+ }
+ x++; // advance x coordinate to the right
+}
+
diff --git a/libraries/Matrix/keywords.txt b/libraries/Matrix/keywords.txt
new file mode 100644
index 0000000..b784f87
--- /dev/null
+++ b/libraries/Matrix/keywords.txt
@@ -0,0 +1,22 @@
+#######################################
+# Syntax Coloring Map For Matrix
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+Matrix KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+setBrightness KEYWORD2
+write KEYWORD2
+clear KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
diff --git a/libraries/Servo/Servo.cpp b/libraries/Servo/Servo.cpp
new file mode 100755
index 0000000..8578fef
--- /dev/null
+++ b/libraries/Servo/Servo.cpp
@@ -0,0 +1,133 @@
+#include <avr/interrupt.h>
+#include <wiring.h>
+#include <Servo.h>
+
+/*
+ Servo.h - Hardware Servo Timer Library
+ Author: Jim Studt, jim@federated.com
+ Copyright (c) 2007 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+
+uint8_t Servo::attached9 = 0;
+uint8_t Servo::attached10 = 0;
+
+void Servo::seizeTimer1()
+{
+ uint8_t oldSREG = SREG;
+
+ cli();
+ TCCR1A = _BV(WGM11); /* Fast PWM, ICR1 is top */
+ TCCR1B = _BV(WGM13) | _BV(WGM12) /* Fast PWM, ICR1 is top */
+ | _BV(CS11) /* div 8 clock prescaler */
+ ;
+ OCR1A = 3000;
+ OCR1B = 3000;
+ ICR1 = clockCyclesPerMicrosecond()*(20000L/8); // 20000 uS is a bit fast for the refresh, 20ms, but
+ // it keeps us from overflowing ICR1 at 20MHz clocks
+ // That "/8" at the end is the prescaler.
+#if defined(__AVR_ATmega8__)
+ TIMSK &= ~(_BV(TICIE1) | _BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );
+#else
+ TIMSK1 &= ~(_BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );
+#endif
+
+ SREG = oldSREG; // undo cli()
+}
+
+void Servo::releaseTimer1() {}
+
+#define NO_ANGLE (0xff)
+
+Servo::Servo() : pin(0), angle(NO_ANGLE) {}
+
+uint8_t Servo::attach(int pinArg)
+{
+ return attach(pinArg, 544, 2400);
+}
+
+uint8_t Servo::attach(int pinArg, int min, int max)
+{
+ if (pinArg != 9 && pinArg != 10) return 0;
+
+ min16 = min / 16;
+ max16 = max / 16;
+
+ pin = pinArg;
+ angle = NO_ANGLE;
+ digitalWrite(pin, LOW);
+ pinMode(pin, OUTPUT);
+
+ if (!attached9 && !attached10) seizeTimer1();
+
+ if (pin == 9) {
+ attached9 = 1;
+ TCCR1A = (TCCR1A & ~_BV(COM1A0)) | _BV(COM1A1);
+ }
+
+ if (pin == 10) {
+ attached10 = 1;
+ TCCR1A = (TCCR1A & ~_BV(COM1B0)) | _BV(COM1B1);
+ }
+ return 1;
+}
+
+void Servo::detach()
+{
+ // muck with timer flags
+ if (pin == 9) {
+ attached9 = 0;
+ TCCR1A = TCCR1A & ~_BV(COM1A0) & ~_BV(COM1A1);
+ pinMode(pin, INPUT);
+ }
+
+ if (pin == 10) {
+ attached10 = 0;
+ TCCR1A = TCCR1A & ~_BV(COM1B0) & ~_BV(COM1B1);
+ pinMode(pin, INPUT);
+ }
+
+ if (!attached9 && !attached10) releaseTimer1();
+}
+
+void Servo::write(int angleArg)
+{
+ uint16_t p;
+
+ if (angleArg < 0) angleArg = 0;
+ if (angleArg > 180) angleArg = 180;
+ angle = angleArg;
+
+ // bleh, have to use longs to prevent overflow, could be tricky if always a 16MHz clock, but not true
+ // That 8L on the end is the TCNT1 prescaler, it will need to change if the clock's prescaler changes,
+ // but then there will likely be an overflow problem, so it will have to be handled by a human.
+ p = (min16*16L*clockCyclesPerMicrosecond() + (max16-min16)*(16L*clockCyclesPerMicrosecond())*angle/180L)/8L;
+ if (pin == 9) OCR1A = p;
+ if (pin == 10) OCR1B = p;
+}
+
+uint8_t Servo::read()
+{
+ return angle;
+}
+
+uint8_t Servo::attached()
+{
+ if (pin == 9 && attached9) return 1;
+ if (pin == 10 && attached10) return 1;
+ return 0;
+}
diff --git a/libraries/Servo/Servo.h b/libraries/Servo/Servo.h
new file mode 100755
index 0000000..0b0e8db
--- /dev/null
+++ b/libraries/Servo/Servo.h
@@ -0,0 +1,52 @@
+#ifndef Servo_h
+#define Servo_h
+
+/*
+ Servo.h - Hardware Servo Timer Library
+ Author: Jim Studt, jim@federated.com
+ Copyright (c) 2007 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <inttypes.h>
+
+class Servo
+{
+ private:
+ uint8_t pin;
+ uint8_t angle; // in degrees
+ uint8_t min16; // minimum pulse, 16uS units (default is 34)
+ uint8_t max16; // maximum pulse, 16uS units, 0-4ms range (default is 150)
+ static void seizeTimer1();
+ static void releaseTimer1();
+ static uint8_t attached9;
+ static uint8_t attached10;
+ public:
+ Servo();
+ uint8_t attach(int);
+ // pulse length for 0 degrees in microseconds, 544uS default
+ // pulse length for 180 degrees in microseconds, 2400uS default
+ uint8_t attach(int, int, int);
+ // attach to a pin, sets pinMode, returns 0 on failure, won't
+ // position the servo until a subsequent write() happens
+ // Only works for 9 and 10.
+ void detach();
+ void write(int); // specify the angle in degrees, 0 to 180
+ uint8_t read();
+ uint8_t attached();
+};
+
+#endif
diff --git a/libraries/Servo/examples/Knob/Knob.pde b/libraries/Servo/examples/Knob/Knob.pde
new file mode 100644
index 0000000..886e107
--- /dev/null
+++ b/libraries/Servo/examples/Knob/Knob.pde
@@ -0,0 +1,22 @@
+// Controlling a servo position using a potentiometer (variable resistor)
+// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
+
+#include <Servo.h>
+
+Servo myservo; // create servo object to control a servo
+
+int potpin = 0; // analog pin used to connect the potentiometer
+int val; // variable to read the value from the analog pin
+
+void setup()
+{
+ myservo.attach(9); // attaches the servo on pin 9 to the servo object
+}
+
+void loop()
+{
+ val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
+ val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
+ myservo.write(val); // sets the servo position according to the scaled value
+ delay(15); // waits for the servo to get there
+}
diff --git a/libraries/Servo/examples/Sweep/Sweep.pde b/libraries/Servo/examples/Sweep/Sweep.pde
new file mode 100644
index 0000000..52e6056
--- /dev/null
+++ b/libraries/Servo/examples/Sweep/Sweep.pde
@@ -0,0 +1,29 @@
+// Sweep
+// by BARRAGAN <http://barraganstudio.com>
+
+#include <Servo.h>
+
+Servo myservo; // create servo object to control a servo
+ // a maximum of eight servo objects can be created
+
+int pos = 0; // variable to store the servo position
+
+void setup()
+{
+ myservo.attach(9); // attaches the servo on pin 9 to the servo object
+}
+
+
+void loop()
+{
+ for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
+ { // in steps of 1 degree
+ myservo.write(pos); // tell servo to go to position in variable 'pos'
+ delay(15); // waits 15ms for the servo to reach the position
+ }
+ for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
+ {
+ myservo.write(pos); // tell servo to go to position in variable 'pos'
+ delay(15); // waits 15ms for the servo to reach the position
+ }
+}
diff --git a/libraries/Servo/keywords.txt b/libraries/Servo/keywords.txt
new file mode 100755
index 0000000..918c46a
--- /dev/null
+++ b/libraries/Servo/keywords.txt
@@ -0,0 +1,22 @@
+#######################################
+# Syntax Coloring Map Servo
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+Servo KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+attach KEYWORD2
+detach KEYWORD2
+write KEYWORD2
+read KEYWORD2
+attached KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
diff --git a/libraries/SoftwareSerial/SoftwareSerial.cpp b/libraries/SoftwareSerial/SoftwareSerial.cpp
new file mode 100755
index 0000000..6df04d2
--- /dev/null
+++ b/libraries/SoftwareSerial/SoftwareSerial.cpp
@@ -0,0 +1,227 @@
+/*
+ SoftwareSerial.cpp - Software serial library
+ Copyright (c) 2006 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/******************************************************************************
+ * Includes
+ ******************************************************************************/
+
+#include "WConstants.h"
+#include "SoftwareSerial.h"
+
+/******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/******************************************************************************
+ * Constructors
+ ******************************************************************************/
+
+SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin)
+{
+ _receivePin = receivePin;
+ _transmitPin = transmitPin;
+ _baudRate = 0;
+}
+
+/******************************************************************************
+ * User API
+ ******************************************************************************/
+
+void SoftwareSerial::begin(long speed)
+{
+ _baudRate = speed;
+ _bitPeriod = 1000000 / _baudRate;
+
+ digitalWrite(_transmitPin, HIGH);
+ delayMicroseconds( _bitPeriod); // if we were low this establishes the end
+}
+
+int SoftwareSerial::read()
+{
+ int val = 0;
+ int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50);
+
+ // one byte of serial data (LSB first)
+ // ...--\ /--\/--\/--\/--\/--\/--\/--\/--\/--...
+ // \--/\--/\--/\--/\--/\--/\--/\--/\--/
+ // start 0 1 2 3 4 5 6 7 stop
+
+ while (digitalRead(_receivePin));
+
+ // confirm that this is a real start bit, not line noise
+ if (digitalRead(_receivePin) == LOW) {
+ // frame start indicated by a falling edge and low start bit
+ // jump to the middle of the low start bit
+ delayMicroseconds(bitDelay / 2 - clockCyclesToMicroseconds(50));
+
+ // offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
+ for (int offset = 0; offset < 8; offset++) {
+ // jump to middle of next bit
+ delayMicroseconds(bitDelay);
+
+ // read bit
+ val |= digitalRead(_receivePin) << offset;
+ }
+
+ delayMicroseconds(_bitPeriod);
+
+ return val;
+ }
+
+ return -1;
+}
+
+void SoftwareSerial::print(uint8_t b)
+{
+ if (_baudRate == 0)
+ return;
+
+ int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
+ byte mask;
+
+ digitalWrite(_transmitPin, LOW);
+ delayMicroseconds(bitDelay);
+
+ for (mask = 0x01; mask; mask <<= 1) {
+ if (b & mask){ // choose bit
+ digitalWrite(_transmitPin,HIGH); // send 1
+ }
+ else{
+ digitalWrite(_transmitPin,LOW); // send 1
+ }
+ delayMicroseconds(bitDelay);
+ }
+
+ digitalWrite(_transmitPin, HIGH);
+ delayMicroseconds(bitDelay);
+}
+
+void SoftwareSerial::print(const char *s)
+{
+ while (*s)
+ print(*s++);
+}
+
+void SoftwareSerial::print(char c)
+{
+ print((uint8_t) c);
+}
+
+void SoftwareSerial::print(int n)
+{
+ print((long) n);
+}
+
+void SoftwareSerial::print(unsigned int n)
+{
+ print((unsigned long) n);
+}
+
+void SoftwareSerial::print(long n)
+{
+ if (n < 0) {
+ print('-');
+ n = -n;
+ }
+ printNumber(n, 10);
+}
+
+void SoftwareSerial::print(unsigned long n)
+{
+ printNumber(n, 10);
+}
+
+void SoftwareSerial::print(long n, int base)
+{
+ if (base == 0)
+ print((char) n);
+ else if (base == 10)
+ print(n);
+ else
+ printNumber(n, base);
+}
+
+void SoftwareSerial::println(void)
+{
+ print('\r');
+ print('\n');
+}
+
+void SoftwareSerial::println(char c)
+{
+ print(c);
+ println();
+}
+
+void SoftwareSerial::println(const char c[])
+{
+ print(c);
+ println();
+}
+
+void SoftwareSerial::println(uint8_t b)
+{
+ print(b);
+ println();
+}
+
+void SoftwareSerial::println(int n)
+{
+ print(n);
+ println();
+}
+
+void SoftwareSerial::println(long n)
+{
+ print(n);
+ println();
+}
+
+void SoftwareSerial::println(unsigned long n)
+{
+ print(n);
+ println();
+}
+
+void SoftwareSerial::println(long n, int base)
+{
+ print(n, base);
+ println();
+}
+
+// Private Methods /////////////////////////////////////////////////////////////
+
+void SoftwareSerial::printNumber(unsigned long n, uint8_t base)
+{
+ unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
+ unsigned long i = 0;
+
+ if (n == 0) {
+ print('0');
+ return;
+ }
+
+ while (n > 0) {
+ buf[i++] = n % base;
+ n /= base;
+ }
+
+ for (; i > 0; i--)
+ print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
+}
diff --git a/libraries/SoftwareSerial/SoftwareSerial.h b/libraries/SoftwareSerial/SoftwareSerial.h
new file mode 100755
index 0000000..95753fc
--- /dev/null
+++ b/libraries/SoftwareSerial/SoftwareSerial.h
@@ -0,0 +1,56 @@
+/*
+ SoftwareSerial.h - Software serial library
+ Copyright (c) 2006 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef SoftwareSerial_h
+#define SoftwareSerial_h
+
+#include <inttypes.h>
+
+class SoftwareSerial
+{
+ private:
+ uint8_t _receivePin;
+ uint8_t _transmitPin;
+ long _baudRate;
+ int _bitPeriod;
+ void printNumber(unsigned long, uint8_t);
+ public:
+ SoftwareSerial(uint8_t, uint8_t);
+ void begin(long);
+ int read();
+ void print(char);
+ void print(const char[]);
+ void print(uint8_t);
+ void print(int);
+ void print(unsigned int);
+ void print(long);
+ void print(unsigned long);
+ void print(long, int);
+ void println(void);
+ void println(char);
+ void println(const char[]);
+ void println(uint8_t);
+ void println(int);
+ void println(long);
+ void println(unsigned long);
+ void println(long, int);
+};
+
+#endif
+
diff --git a/libraries/SoftwareSerial/keywords.txt b/libraries/SoftwareSerial/keywords.txt
new file mode 100644
index 0000000..de5a74c
--- /dev/null
+++ b/libraries/SoftwareSerial/keywords.txt
@@ -0,0 +1,18 @@
+#######################################
+# Syntax Coloring Map For Ultrasound
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+SoftwareSerial KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
diff --git a/libraries/Sprite/Sprite.cpp b/libraries/Sprite/Sprite.cpp
new file mode 100644
index 0000000..6055876
--- /dev/null
+++ b/libraries/Sprite/Sprite.cpp
@@ -0,0 +1,95 @@
+/*
+ Sprite.cpp - 2D sprite buffer library for Arduino & Wiring
+ Copyright (c) 2006 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <stdlib.h>
+#include <stdarg.h>
+//#include <stdio.h>
+
+#include "Sprite.h"
+
+void Sprite::init(uint8_t width, uint8_t height)
+{
+ _width = width >= 8 ? 8 : width;
+ _height = height >= 8 ? 8 : height;
+
+ // for now, do nothing if this allocation fails. methods that require it
+ // should silently fail if _buffer is null.
+ _buffer = (uint8_t *) calloc(_height, 1);
+}
+
+Sprite::Sprite(uint8_t width, uint8_t height)
+{
+ init(width, height);
+}
+
+Sprite::Sprite(uint8_t width, uint8_t height, uint8_t row, ...)
+{
+ init(width, height);
+
+ if (!_buffer) return;
+
+ va_list ap;
+ va_start(ap, row);
+
+ int y = 0;
+
+ for (y = 0; ; y++) {
+ for (int x = 0; x < width && x < 8; x++)
+ write(x, y, (row >> (width - x - 1)) & 0x01);
+
+ if (y == height - 1)
+ break;
+
+ row = va_arg(ap, int); // using '...' promotes uint8_t to int
+ }
+
+ va_end(ap);
+}
+
+uint8_t Sprite::width() const
+{
+ return _width;
+}
+
+uint8_t Sprite::height() const
+{
+ return _height;
+}
+
+void Sprite::write(uint8_t x, uint8_t y, uint8_t value)
+{
+ if (!_buffer) return;
+
+ // uint8_t's can't be negative, so don't test for negative x and y.
+ if (x >= _width || y >= _height) return;
+
+ // we need to bitwise-or the value of the other pixels in the byte with
+ // the new value, masked and shifted into the proper bits.
+ _buffer[y] = (_buffer[y] & ~(0x01 << x)) | ((value & 0x01) << x);
+}
+
+uint8_t Sprite::read(uint8_t x, uint8_t y) const
+{
+ if (!_buffer) return 0;
+
+ // uint8_t's can't be negative, so don't test for negative x and y.
+ if (x >= _width || y >= _height) return 0;
+
+ return (_buffer[y] >> x) & 0x01;
+}
diff --git a/libraries/Sprite/Sprite.h b/libraries/Sprite/Sprite.h
new file mode 100644
index 0000000..bdcfdb8
--- /dev/null
+++ b/libraries/Sprite/Sprite.h
@@ -0,0 +1,48 @@
+/*
+ Sprite.cpp - 2D sprite buffers library for Arduino & Wiring
+ Copyright (c) 2006 David A. Mellis. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef Sprite_h
+#define Sprite_h
+
+#include <inttypes.h>
+
+#include "binary.h"
+
+class Sprite
+{
+ private:
+ uint8_t _width;
+ uint8_t _height;
+ uint8_t _depth;
+ uint8_t _ppb;
+ uint8_t _bpr;
+ uint8_t _mask;
+ uint8_t *_buffer;
+
+ void init(uint8_t width, uint8_t height);
+ public:
+ Sprite(uint8_t width, uint8_t height);
+ Sprite(uint8_t width, uint8_t height, uint8_t row, ...);
+ uint8_t width() const;
+ uint8_t height() const;
+ void write(uint8_t x, uint8_t y, uint8_t value);
+ uint8_t read(uint8_t x, uint8_t y) const;
+};
+
+#endif
diff --git a/libraries/Sprite/binary.h b/libraries/Sprite/binary.h
new file mode 100644
index 0000000..af14980
--- /dev/null
+++ b/libraries/Sprite/binary.h
@@ -0,0 +1,515 @@
+#ifndef Binary_h
+#define Binary_h
+
+#define B0 0
+#define B00 0
+#define B000 0
+#define B0000 0
+#define B00000 0
+#define B000000 0
+#define B0000000 0
+#define B00000000 0
+#define B1 1
+#define B01 1
+#define B001 1
+#define B0001 1
+#define B00001 1
+#define B000001 1
+#define B0000001 1
+#define B00000001 1
+#define B10 2
+#define B010 2
+#define B0010 2
+#define B00010 2
+#define B000010 2
+#define B0000010 2
+#define B00000010 2
+#define B11 3
+#define B011 3
+#define B0011 3
+#define B00011 3
+#define B000011 3
+#define B0000011 3
+#define B00000011 3
+#define B100 4
+#define B0100 4
+#define B00100 4
+#define B000100 4
+#define B0000100 4
+#define B00000100 4
+#define B101 5
+#define B0101 5
+#define B00101 5
+#define B000101 5
+#define B0000101 5
+#define B00000101 5
+#define B110 6
+#define B0110 6
+#define B00110 6
+#define B000110 6
+#define B0000110 6
+#define B00000110 6
+#define B111 7
+#define B0111 7
+#define B00111 7
+#define B000111 7
+#define B0000111 7
+#define B00000111 7
+#define B1000 8
+#define B01000 8
+#define B001000 8
+#define B0001000 8
+#define B00001000 8
+#define B1001 9
+#define B01001 9
+#define B001001 9
+#define B0001001 9
+#define B00001001 9
+#define B1010 10
+#define B01010 10
+#define B001010 10
+#define B0001010 10
+#define B00001010 10
+#define B1011 11
+#define B01011 11
+#define B001011 11
+#define B0001011 11
+#define B00001011 11
+#define B1100 12
+#define B01100 12
+#define B001100 12
+#define B0001100 12
+#define B00001100 12
+#define B1101 13
+#define B01101 13
+#define B001101 13
+#define B0001101 13
+#define B00001101 13
+#define B1110 14
+#define B01110 14
+#define B001110 14
+#define B0001110 14
+#define B00001110 14
+#define B1111 15
+#define B01111 15
+#define B001111 15
+#define B0001111 15
+#define B00001111 15
+#define B10000 16
+#define B010000 16
+#define B0010000 16
+#define B00010000 16
+#define B10001 17
+#define B010001 17
+#define B0010001 17
+#define B00010001 17
+#define B10010 18
+#define B010010 18
+#define B0010010 18
+#define B00010010 18
+#define B10011 19
+#define B010011 19
+#define B0010011 19
+#define B00010011 19
+#define B10100 20
+#define B010100 20
+#define B0010100 20
+#define B00010100 20
+#define B10101 21
+#define B010101 21
+#define B0010101 21
+#define B00010101 21
+#define B10110 22
+#define B010110 22
+#define B0010110 22
+#define B00010110 22
+#define B10111 23
+#define B010111 23
+#define B0010111 23
+#define B00010111 23
+#define B11000 24
+#define B011000 24
+#define B0011000 24
+#define B00011000 24
+#define B11001 25
+#define B011001 25
+#define B0011001 25
+#define B00011001 25
+#define B11010 26
+#define B011010 26
+#define B0011010 26
+#define B00011010 26
+#define B11011 27
+#define B011011 27
+#define B0011011 27
+#define B00011011 27
+#define B11100 28
+#define B011100 28
+#define B0011100 28
+#define B00011100 28
+#define B11101 29
+#define B011101 29
+#define B0011101 29
+#define B00011101 29
+#define B11110 30
+#define B011110 30
+#define B0011110 30
+#define B00011110 30
+#define B11111 31
+#define B011111 31
+#define B0011111 31
+#define B00011111 31
+#define B100000 32
+#define B0100000 32
+#define B00100000 32
+#define B100001 33
+#define B0100001 33
+#define B00100001 33
+#define B100010 34
+#define B0100010 34
+#define B00100010 34
+#define B100011 35
+#define B0100011 35
+#define B00100011 35
+#define B100100 36
+#define B0100100 36
+#define B00100100 36
+#define B100101 37
+#define B0100101 37
+#define B00100101 37
+#define B100110 38
+#define B0100110 38
+#define B00100110 38
+#define B100111 39
+#define B0100111 39
+#define B00100111 39
+#define B101000 40
+#define B0101000 40
+#define B00101000 40
+#define B101001 41
+#define B0101001 41
+#define B00101001 41
+#define B101010 42
+#define B0101010 42
+#define B00101010 42
+#define B101011 43
+#define B0101011 43
+#define B00101011 43
+#define B101100 44
+#define B0101100 44
+#define B00101100 44
+#define B101101 45
+#define B0101101 45
+#define B00101101 45
+#define B101110 46
+#define B0101110 46
+#define B00101110 46
+#define B101111 47
+#define B0101111 47
+#define B00101111 47
+#define B110000 48
+#define B0110000 48
+#define B00110000 48
+#define B110001 49
+#define B0110001 49
+#define B00110001 49
+#define B110010 50
+#define B0110010 50
+#define B00110010 50
+#define B110011 51
+#define B0110011 51
+#define B00110011 51
+#define B110100 52
+#define B0110100 52
+#define B00110100 52
+#define B110101 53
+#define B0110101 53
+#define B00110101 53
+#define B110110 54
+#define B0110110 54
+#define B00110110 54
+#define B110111 55
+#define B0110111 55
+#define B00110111 55
+#define B111000 56
+#define B0111000 56
+#define B00111000 56
+#define B111001 57
+#define B0111001 57
+#define B00111001 57
+#define B111010 58
+#define B0111010 58
+#define B00111010 58
+#define B111011 59
+#define B0111011 59
+#define B00111011 59
+#define B111100 60
+#define B0111100 60
+#define B00111100 60
+#define B111101 61
+#define B0111101 61
+#define B00111101 61
+#define B111110 62
+#define B0111110 62
+#define B00111110 62
+#define B111111 63
+#define B0111111 63
+#define B00111111 63
+#define B1000000 64
+#define B01000000 64
+#define B1000001 65
+#define B01000001 65
+#define B1000010 66
+#define B01000010 66
+#define B1000011 67
+#define B01000011 67
+#define B1000100 68
+#define B01000100 68
+#define B1000101 69
+#define B01000101 69
+#define B1000110 70
+#define B01000110 70
+#define B1000111 71
+#define B01000111 71
+#define B1001000 72
+#define B01001000 72
+#define B1001001 73
+#define B01001001 73
+#define B1001010 74
+#define B01001010 74
+#define B1001011 75
+#define B01001011 75
+#define B1001100 76
+#define B01001100 76
+#define B1001101 77
+#define B01001101 77
+#define B1001110 78
+#define B01001110 78
+#define B1001111 79
+#define B01001111 79
+#define B1010000 80
+#define B01010000 80
+#define B1010001 81
+#define B01010001 81
+#define B1010010 82
+#define B01010010 82
+#define B1010011 83
+#define B01010011 83
+#define B1010100 84
+#define B01010100 84
+#define B1010101 85
+#define B01010101 85
+#define B1010110 86
+#define B01010110 86
+#define B1010111 87
+#define B01010111 87
+#define B1011000 88
+#define B01011000 88
+#define B1011001 89
+#define B01011001 89
+#define B1011010 90
+#define B01011010 90
+#define B1011011 91
+#define B01011011 91
+#define B1011100 92
+#define B01011100 92
+#define B1011101 93
+#define B01011101 93
+#define B1011110 94
+#define B01011110 94
+#define B1011111 95
+#define B01011111 95
+#define B1100000 96
+#define B01100000 96
+#define B1100001 97
+#define B01100001 97
+#define B1100010 98
+#define B01100010 98
+#define B1100011 99
+#define B01100011 99
+#define B1100100 100
+#define B01100100 100
+#define B1100101 101
+#define B01100101 101
+#define B1100110 102
+#define B01100110 102
+#define B1100111 103
+#define B01100111 103
+#define B1101000 104
+#define B01101000 104
+#define B1101001 105
+#define B01101001 105
+#define B1101010 106
+#define B01101010 106
+#define B1101011 107
+#define B01101011 107
+#define B1101100 108
+#define B01101100 108
+#define B1101101 109
+#define B01101101 109
+#define B1101110 110
+#define B01101110 110
+#define B1101111 111
+#define B01101111 111
+#define B1110000 112
+#define B01110000 112
+#define B1110001 113
+#define B01110001 113
+#define B1110010 114
+#define B01110010 114
+#define B1110011 115
+#define B01110011 115
+#define B1110100 116
+#define B01110100 116
+#define B1110101 117
+#define B01110101 117
+#define B1110110 118
+#define B01110110 118
+#define B1110111 119
+#define B01110111 119
+#define B1111000 120
+#define B01111000 120
+#define B1111001 121
+#define B01111001 121
+#define B1111010 122
+#define B01111010 122
+#define B1111011 123
+#define B01111011 123
+#define B1111100 124
+#define B01111100 124
+#define B1111101 125
+#define B01111101 125
+#define B1111110 126
+#define B01111110 126
+#define B1111111 127
+#define B01111111 127
+#define B10000000 128
+#define B10000001 129
+#define B10000010 130
+#define B10000011 131
+#define B10000100 132
+#define B10000101 133
+#define B10000110 134
+#define B10000111 135
+#define B10001000 136
+#define B10001001 137
+#define B10001010 138
+#define B10001011 139
+#define B10001100 140
+#define B10001101 141
+#define B10001110 142
+#define B10001111 143
+#define B10010000 144
+#define B10010001 145
+#define B10010010 146
+#define B10010011 147
+#define B10010100 148
+#define B10010101 149
+#define B10010110 150
+#define B10010111 151
+#define B10011000 152
+#define B10011001 153
+#define B10011010 154
+#define B10011011 155
+#define B10011100 156
+#define B10011101 157
+#define B10011110 158
+#define B10011111 159
+#define B10100000 160
+#define B10100001 161
+#define B10100010 162
+#define B10100011 163
+#define B10100100 164
+#define B10100101 165
+#define B10100110 166
+#define B10100111 167
+#define B10101000 168
+#define B10101001 169
+#define B10101010 170
+#define B10101011 171
+#define B10101100 172
+#define B10101101 173
+#define B10101110 174
+#define B10101111 175
+#define B10110000 176
+#define B10110001 177
+#define B10110010 178
+#define B10110011 179
+#define B10110100 180
+#define B10110101 181
+#define B10110110 182
+#define B10110111 183
+#define B10111000 184
+#define B10111001 185
+#define B10111010 186
+#define B10111011 187
+#define B10111100 188
+#define B10111101 189
+#define B10111110 190
+#define B10111111 191
+#define B11000000 192
+#define B11000001 193
+#define B11000010 194
+#define B11000011 195
+#define B11000100 196
+#define B11000101 197
+#define B11000110 198
+#define B11000111 199
+#define B11001000 200
+#define B11001001 201
+#define B11001010 202
+#define B11001011 203
+#define B11001100 204
+#define B11001101 205
+#define B11001110 206
+#define B11001111 207
+#define B11010000 208
+#define B11010001 209
+#define B11010010 210
+#define B11010011 211
+#define B11010100 212
+#define B11010101 213
+#define B11010110 214
+#define B11010111 215
+#define B11011000 216
+#define B11011001 217
+#define B11011010 218
+#define B11011011 219
+#define B11011100 220
+#define B11011101 221
+#define B11011110 222
+#define B11011111 223
+#define B11100000 224
+#define B11100001 225
+#define B11100010 226
+#define B11100011 227
+#define B11100100 228
+#define B11100101 229
+#define B11100110 230
+#define B11100111 231
+#define B11101000 232
+#define B11101001 233
+#define B11101010 234
+#define B11101011 235
+#define B11101100 236
+#define B11101101 237
+#define B11101110 238
+#define B11101111 239
+#define B11110000 240
+#define B11110001 241
+#define B11110010 242
+#define B11110011 243
+#define B11110100 244
+#define B11110101 245
+#define B11110110 246
+#define B11110111 247
+#define B11111000 248
+#define B11111001 249
+#define B11111010 250
+#define B11111011 251
+#define B11111100 252
+#define B11111101 253
+#define B11111110 254
+#define B11111111 255
+
+#endif
diff --git a/libraries/Sprite/keywords.txt b/libraries/Sprite/keywords.txt
new file mode 100644
index 0000000..73cd8d9
--- /dev/null
+++ b/libraries/Sprite/keywords.txt
@@ -0,0 +1,534 @@
+#######################################
+# Syntax Coloring Map For Sprite
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+Sprite KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+width KEYWORD2
+height KEYWORD2
+write KEYWORD2
+read KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
+B0 LITERAL1
+B00 LITERAL1
+B000 LITERAL1
+B0000 LITERAL1
+B00000 LITERAL1
+B000000 LITERAL1
+B0000000 LITERAL1
+B00000000 LITERAL1
+B1 LITERAL1
+B01 LITERAL1
+B001 LITERAL1
+B0001 LITERAL1
+B00001 LITERAL1
+B000001 LITERAL1
+B0000001 LITERAL1
+B00000001 LITERAL1
+B10 LITERAL1
+B010 LITERAL1
+B0010 LITERAL1
+B00010 LITERAL1
+B000010 LITERAL1
+B0000010 LITERAL1
+B00000010 LITERAL1
+B11 LITERAL1
+B011 LITERAL1
+B0011 LITERAL1
+B00011 LITERAL1
+B000011 LITERAL1
+B0000011 LITERAL1
+B00000011 LITERAL1
+B100 LITERAL1
+B0100 LITERAL1
+B00100 LITERAL1
+B000100 LITERAL1
+B0000100 LITERAL1
+B00000100 LITERAL1
+B101 LITERAL1
+B0101 LITERAL1
+B00101 LITERAL1
+B000101 LITERAL1
+B0000101 LITERAL1
+B00000101 LITERAL1
+B110 LITERAL1
+B0110 LITERAL1
+B00110 LITERAL1
+B000110 LITERAL1
+B0000110 LITERAL1
+B00000110 LITERAL1
+B111 LITERAL1
+B0111 LITERAL1
+B00111 LITERAL1
+B000111 LITERAL1
+B0000111 LITERAL1
+B00000111 LITERAL1
+B1000 LITERAL1
+B01000 LITERAL1
+B001000 LITERAL1
+B0001000 LITERAL1
+B00001000 LITERAL1
+B1001 LITERAL1
+B01001 LITERAL1
+B001001 LITERAL1
+B0001001 LITERAL1
+B00001001 LITERAL1
+B1010 LITERAL1
+B01010 LITERAL1
+B001010 LITERAL1
+B0001010 LITERAL1
+B00001010 LITERAL1
+B1011 LITERAL1
+B01011 LITERAL1
+B001011 LITERAL1
+B0001011 LITERAL1
+B00001011 LITERAL1
+B1100 LITERAL1
+B01100 LITERAL1
+B001100 LITERAL1
+B0001100 LITERAL1
+B00001100 LITERAL1
+B1101 LITERAL1
+B01101 LITERAL1
+B001101 LITERAL1
+B0001101 LITERAL1
+B00001101 LITERAL1
+B1110 LITERAL1
+B01110 LITERAL1
+B001110 LITERAL1
+B0001110 LITERAL1
+B00001110 LITERAL1
+B1111 LITERAL1
+B01111 LITERAL1
+B001111 LITERAL1
+B0001111 LITERAL1
+B00001111 LITERAL1
+B10000 LITERAL1
+B010000 LITERAL1
+B0010000 LITERAL1
+B00010000 LITERAL1
+B10001 LITERAL1
+B010001 LITERAL1
+B0010001 LITERAL1
+B00010001 LITERAL1
+B10010 LITERAL1
+B010010 LITERAL1
+B0010010 LITERAL1
+B00010010 LITERAL1
+B10011 LITERAL1
+B010011 LITERAL1
+B0010011 LITERAL1
+B00010011 LITERAL1
+B10100 LITERAL1
+B010100 LITERAL1
+B0010100 LITERAL1
+B00010100 LITERAL1
+B10101 LITERAL1
+B010101 LITERAL1
+B0010101 LITERAL1
+B00010101 LITERAL1
+B10110 LITERAL1
+B010110 LITERAL1
+B0010110 LITERAL1
+B00010110 LITERAL1
+B10111 LITERAL1
+B010111 LITERAL1
+B0010111 LITERAL1
+B00010111 LITERAL1
+B11000 LITERAL1
+B011000 LITERAL1
+B0011000 LITERAL1
+B00011000 LITERAL1
+B11001 LITERAL1
+B011001 LITERAL1
+B0011001 LITERAL1
+B00011001 LITERAL1
+B11010 LITERAL1
+B011010 LITERAL1
+B0011010 LITERAL1
+B00011010 LITERAL1
+B11011 LITERAL1
+B011011 LITERAL1
+B0011011 LITERAL1
+B00011011 LITERAL1
+B11100 LITERAL1
+B011100 LITERAL1
+B0011100 LITERAL1
+B00011100 LITERAL1
+B11101 LITERAL1
+B011101 LITERAL1
+B0011101 LITERAL1
+B00011101 LITERAL1
+B11110 LITERAL1
+B011110 LITERAL1
+B0011110 LITERAL1
+B00011110 LITERAL1
+B11111 LITERAL1
+B011111 LITERAL1
+B0011111 LITERAL1
+B00011111 LITERAL1
+B100000 LITERAL1
+B0100000 LITERAL1
+B00100000 LITERAL1
+B100001 LITERAL1
+B0100001 LITERAL1
+B00100001 LITERAL1
+B100010 LITERAL1
+B0100010 LITERAL1
+B00100010 LITERAL1
+B100011 LITERAL1
+B0100011 LITERAL1
+B00100011 LITERAL1
+B100100 LITERAL1
+B0100100 LITERAL1
+B00100100 LITERAL1
+B100101 LITERAL1
+B0100101 LITERAL1
+B00100101 LITERAL1
+B100110 LITERAL1
+B0100110 LITERAL1
+B00100110 LITERAL1
+B100111 LITERAL1
+B0100111 LITERAL1
+B00100111 LITERAL1
+B101000 LITERAL1
+B0101000 LITERAL1
+B00101000 LITERAL1
+B101001 LITERAL1
+B0101001 LITERAL1
+B00101001 LITERAL1
+B101010 LITERAL1
+B0101010 LITERAL1
+B00101010 LITERAL1
+B101011 LITERAL1
+B0101011 LITERAL1
+B00101011 LITERAL1
+B101100 LITERAL1
+B0101100 LITERAL1
+B00101100 LITERAL1
+B101101 LITERAL1
+B0101101 LITERAL1
+B00101101 LITERAL1
+B101110 LITERAL1
+B0101110 LITERAL1
+B00101110 LITERAL1
+B101111 LITERAL1
+B0101111 LITERAL1
+B00101111 LITERAL1
+B110000 LITERAL1
+B0110000 LITERAL1
+B00110000 LITERAL1
+B110001 LITERAL1
+B0110001 LITERAL1
+B00110001 LITERAL1
+B110010 LITERAL1
+B0110010 LITERAL1
+B00110010 LITERAL1
+B110011 LITERAL1
+B0110011 LITERAL1
+B00110011 LITERAL1
+B110100 LITERAL1
+B0110100 LITERAL1
+B00110100 LITERAL1
+B110101 LITERAL1
+B0110101 LITERAL1
+B00110101 LITERAL1
+B110110 LITERAL1
+B0110110 LITERAL1
+B00110110 LITERAL1
+B110111 LITERAL1
+B0110111 LITERAL1
+B00110111 LITERAL1
+B111000 LITERAL1
+B0111000 LITERAL1
+B00111000 LITERAL1
+B111001 LITERAL1
+B0111001 LITERAL1
+B00111001 LITERAL1
+B111010 LITERAL1
+B0111010 LITERAL1
+B00111010 LITERAL1
+B111011 LITERAL1
+B0111011 LITERAL1
+B00111011 LITERAL1
+B111100 LITERAL1
+B0111100 LITERAL1
+B00111100 LITERAL1
+B111101 LITERAL1
+B0111101 LITERAL1
+B00111101 LITERAL1
+B111110 LITERAL1
+B0111110 LITERAL1
+B00111110 LITERAL1
+B111111 LITERAL1
+B0111111 LITERAL1
+B00111111 LITERAL1
+B1000000 LITERAL1
+B01000000 LITERAL1
+B1000001 LITERAL1
+B01000001 LITERAL1
+B1000010 LITERAL1
+B01000010 LITERAL1
+B1000011 LITERAL1
+B01000011 LITERAL1
+B1000100 LITERAL1
+B01000100 LITERAL1
+B1000101 LITERAL1
+B01000101 LITERAL1
+B1000110 LITERAL1
+B01000110 LITERAL1
+B1000111 LITERAL1
+B01000111 LITERAL1
+B1001000 LITERAL1
+B01001000 LITERAL1
+B1001001 LITERAL1
+B01001001 LITERAL1
+B1001010 LITERAL1
+B01001010 LITERAL1
+B1001011 LITERAL1
+B01001011 LITERAL1
+B1001100 LITERAL1
+B01001100 LITERAL1
+B1001101 LITERAL1
+B01001101 LITERAL1
+B1001110 LITERAL1
+B01001110 LITERAL1
+B1001111 LITERAL1
+B01001111 LITERAL1
+B1010000 LITERAL1
+B01010000 LITERAL1
+B1010001 LITERAL1
+B01010001 LITERAL1
+B1010010 LITERAL1
+B01010010 LITERAL1
+B1010011 LITERAL1
+B01010011 LITERAL1
+B1010100 LITERAL1
+B01010100 LITERAL1
+B1010101 LITERAL1
+B01010101 LITERAL1
+B1010110 LITERAL1
+B01010110 LITERAL1
+B1010111 LITERAL1
+B01010111 LITERAL1
+B1011000 LITERAL1
+B01011000 LITERAL1
+B1011001 LITERAL1
+B01011001 LITERAL1
+B1011010 LITERAL1
+B01011010 LITERAL1
+B1011011 LITERAL1
+B01011011 LITERAL1
+B1011100 LITERAL1
+B01011100 LITERAL1
+B1011101 LITERAL1
+B01011101 LITERAL1
+B1011110 LITERAL1
+B01011110 LITERAL1
+B1011111 LITERAL1
+B01011111 LITERAL1
+B1100000 LITERAL1
+B01100000 LITERAL1
+B1100001 LITERAL1
+B01100001 LITERAL1
+B1100010 LITERAL1
+B01100010 LITERAL1
+B1100011 LITERAL1
+B01100011 LITERAL1
+B1100100 LITERAL1
+B01100100 LITERAL1
+B1100101 LITERAL1
+B01100101 LITERAL1
+B1100110 LITERAL1
+B01100110 LITERAL1
+B1100111 LITERAL1
+B01100111 LITERAL1
+B1101000 LITERAL1
+B01101000 LITERAL1
+B1101001 LITERAL1
+B01101001 LITERAL1
+B1101010 LITERAL1
+B01101010 LITERAL1
+B1101011 LITERAL1
+B01101011 LITERAL1
+B1101100 LITERAL1
+B01101100 LITERAL1
+B1101101 LITERAL1
+B01101101 LITERAL1
+B1101110 LITERAL1
+B01101110 LITERAL1
+B1101111 LITERAL1
+B01101111 LITERAL1
+B1110000 LITERAL1
+B01110000 LITERAL1
+B1110001 LITERAL1
+B01110001 LITERAL1
+B1110010 LITERAL1
+B01110010 LITERAL1
+B1110011 LITERAL1
+B01110011 LITERAL1
+B1110100 LITERAL1
+B01110100 LITERAL1
+B1110101 LITERAL1
+B01110101 LITERAL1
+B1110110 LITERAL1
+B01110110 LITERAL1
+B1110111 LITERAL1
+B01110111 LITERAL1
+B1111000 LITERAL1
+B01111000 LITERAL1
+B1111001 LITERAL1
+B01111001 LITERAL1
+B1111010 LITERAL1
+B01111010 LITERAL1
+B1111011 LITERAL1
+B01111011 LITERAL1
+B1111100 LITERAL1
+B01111100 LITERAL1
+B1111101 LITERAL1
+B01111101 LITERAL1
+B1111110 LITERAL1
+B01111110 LITERAL1
+B1111111 LITERAL1
+B01111111 LITERAL1
+B10000000 LITERAL1
+B10000001 LITERAL1
+B10000010 LITERAL1
+B10000011 LITERAL1
+B10000100 LITERAL1
+B10000101 LITERAL1
+B10000110 LITERAL1
+B10000111 LITERAL1
+B10001000 LITERAL1
+B10001001 LITERAL1
+B10001010 LITERAL1
+B10001011 LITERAL1
+B10001100 LITERAL1
+B10001101 LITERAL1
+B10001110 LITERAL1
+B10001111 LITERAL1
+B10010000 LITERAL1
+B10010001 LITERAL1
+B10010010 LITERAL1
+B10010011 LITERAL1
+B10010100 LITERAL1
+B10010101 LITERAL1
+B10010110 LITERAL1
+B10010111 LITERAL1
+B10011000 LITERAL1
+B10011001 LITERAL1
+B10011010 LITERAL1
+B10011011 LITERAL1
+B10011100 LITERAL1
+B10011101 LITERAL1
+B10011110 LITERAL1
+B10011111 LITERAL1
+B10100000 LITERAL1
+B10100001 LITERAL1
+B10100010 LITERAL1
+B10100011 LITERAL1
+B10100100 LITERAL1
+B10100101 LITERAL1
+B10100110 LITERAL1
+B10100111 LITERAL1
+B10101000 LITERAL1
+B10101001 LITERAL1
+B10101010 LITERAL1
+B10101011 LITERAL1
+B10101100 LITERAL1
+B10101101 LITERAL1
+B10101110 LITERAL1
+B10101111 LITERAL1
+B10110000 LITERAL1
+B10110001 LITERAL1
+B10110010 LITERAL1
+B10110011 LITERAL1
+B10110100 LITERAL1
+B10110101 LITERAL1
+B10110110 LITERAL1
+B10110111 LITERAL1
+B10111000 LITERAL1
+B10111001 LITERAL1
+B10111010 LITERAL1
+B10111011 LITERAL1
+B10111100 LITERAL1
+B10111101 LITERAL1
+B10111110 LITERAL1
+B10111111 LITERAL1
+B11000000 LITERAL1
+B11000001 LITERAL1
+B11000010 LITERAL1
+B11000011 LITERAL1
+B11000100 LITERAL1
+B11000101 LITERAL1
+B11000110 LITERAL1
+B11000111 LITERAL1
+B11001000 LITERAL1
+B11001001 LITERAL1
+B11001010 LITERAL1
+B11001011 LITERAL1
+B11001100 LITERAL1
+B11001101 LITERAL1
+B11001110 LITERAL1
+B11001111 LITERAL1
+B11010000 LITERAL1
+B11010001 LITERAL1
+B11010010 LITERAL1
+B11010011 LITERAL1
+B11010100 LITERAL1
+B11010101 LITERAL1
+B11010110 LITERAL1
+B11010111 LITERAL1
+B11011000 LITERAL1
+B11011001 LITERAL1
+B11011010 LITERAL1
+B11011011 LITERAL1
+B11011100 LITERAL1
+B11011101 LITERAL1
+B11011110 LITERAL1
+B11011111 LITERAL1
+B11100000 LITERAL1
+B11100001 LITERAL1
+B11100010 LITERAL1
+B11100011 LITERAL1
+B11100100 LITERAL1
+B11100101 LITERAL1
+B11100110 LITERAL1
+B11100111 LITERAL1
+B11101000 LITERAL1
+B11101001 LITERAL1
+B11101010 LITERAL1
+B11101011 LITERAL1
+B11101100 LITERAL1
+B11101101 LITERAL1
+B11101110 LITERAL1
+B11101111 LITERAL1
+B11110000 LITERAL1
+B11110001 LITERAL1
+B11110010 LITERAL1
+B11110011 LITERAL1
+B11110100 LITERAL1
+B11110101 LITERAL1
+B11110110 LITERAL1
+B11110111 LITERAL1
+B11111000 LITERAL1
+B11111001 LITERAL1
+B11111010 LITERAL1
+B11111011 LITERAL1
+B11111100 LITERAL1
+B11111101 LITERAL1
+B11111110 LITERAL1
+B11111111 LITERAL1
+
diff --git a/libraries/Stepper/Stepper.cpp b/libraries/Stepper/Stepper.cpp
new file mode 100644
index 0000000..d5c16a3
--- /dev/null
+++ b/libraries/Stepper/Stepper.cpp
@@ -0,0 +1,220 @@
+/*
+ Stepper.cpp - - Stepper library for Wiring/Arduino - Version 0.4
+
+ Original library (0.1) by Tom Igoe.
+ Two-wire modifications (0.2) by Sebastian Gassner
+ Combination version (0.3) by Tom Igoe and David Mellis
+ Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley
+
+ Drives a unipolar or bipolar stepper motor using 2 wires or 4 wires
+
+ When wiring multiple stepper motors to a microcontroller,
+ you quickly run out of output pins, with each motor requiring 4 connections.
+
+ By making use of the fact that at any time two of the four motor
+ coils are the inverse of the other two, the number of
+ control connections can be reduced from 4 to 2.
+
+ A slightly modified circuit around a Darlington transistor array or an L293 H-bridge
+ connects to only 2 microcontroler pins, inverts the signals received,
+ and delivers the 4 (2 plus 2 inverted ones) output signals required
+ for driving a stepper motor.
+
+ The sequence of control signals for 4 control wires is as follows:
+
+ Step C0 C1 C2 C3
+ 1 1 0 1 0
+ 2 0 1 1 0
+ 3 0 1 0 1
+ 4 1 0 0 1
+
+ The sequence of controls signals for 2 control wires is as follows
+ (columns C1 and C2 from above):
+
+ Step C0 C1
+ 1 0 1
+ 2 1 1
+ 3 1 0
+ 4 0 0
+
+ The circuits can be found at
+
+http://www.arduino.cc/en/Tutorial/Stepper
+
+
+ */
+
+
+#include "WProgram.h"
+#include "Stepper.h"
+
+/*
+ * two-wire constructor.
+ * Sets which wires should control the motor.
+ */
+Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2)
+{
+ this->step_number = 0; // which step the motor is on
+ this->speed = 0; // the motor speed, in revolutions per minute
+ this->direction = 0; // motor direction
+ this->last_step_time = 0; // time stamp in ms of the last step taken
+ this->number_of_steps = number_of_steps; // total number of steps for this motor
+
+ // Arduino pins for the motor control connection:
+ this->motor_pin_1 = motor_pin_1;
+ this->motor_pin_2 = motor_pin_2;
+
+ // setup the pins on the microcontroller:
+ pinMode(this->motor_pin_1, OUTPUT);
+ pinMode(this->motor_pin_2, OUTPUT);
+
+ // When there are only 2 pins, set the other two to 0:
+ this->motor_pin_3 = 0;
+ this->motor_pin_4 = 0;
+
+ // pin_count is used by the stepMotor() method:
+ this->pin_count = 2;
+}
+
+
+/*
+ * constructor for four-pin version
+ * Sets which wires should control the motor.
+ */
+
+Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4)
+{
+ this->step_number = 0; // which step the motor is on
+ this->speed = 0; // the motor speed, in revolutions per minute
+ this->direction = 0; // motor direction
+ this->last_step_time = 0; // time stamp in ms of the last step taken
+ this->number_of_steps = number_of_steps; // total number of steps for this motor
+
+ // Arduino pins for the motor control connection:
+ this->motor_pin_1 = motor_pin_1;
+ this->motor_pin_2 = motor_pin_2;
+ this->motor_pin_3 = motor_pin_3;
+ this->motor_pin_4 = motor_pin_4;
+
+ // setup the pins on the microcontroller:
+ pinMode(this->motor_pin_1, OUTPUT);
+ pinMode(this->motor_pin_2, OUTPUT);
+ pinMode(this->motor_pin_3, OUTPUT);
+ pinMode(this->motor_pin_4, OUTPUT);
+
+ // pin_count is used by the stepMotor() method:
+ this->pin_count = 4;
+}
+
+/*
+ Sets the speed in revs per minute
+
+*/
+void Stepper::setSpeed(long whatSpeed)
+{
+ this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
+}
+
+/*
+ Moves the motor steps_to_move steps. If the number is negative,
+ the motor moves in the reverse direction.
+ */
+void Stepper::step(int steps_to_move)
+{
+ int steps_left = abs(steps_to_move); // how many steps to take
+
+ // determine direction based on whether steps_to_mode is + or -:
+ if (steps_to_move > 0) {this->direction = 1;}
+ if (steps_to_move < 0) {this->direction = 0;}
+
+
+ // decrement the number of steps, moving one step each time:
+ while(steps_left > 0) {
+ // move only if the appropriate delay has passed:
+ if (millis() - this->last_step_time >= this->step_delay) {
+ // get the timeStamp of when you stepped:
+ this->last_step_time = millis();
+ // increment or decrement the step number,
+ // depending on direction:
+ if (this->direction == 1) {
+ this->step_number++;
+ if (this->step_number == this->number_of_steps) {
+ this->step_number = 0;
+ }
+ }
+ else {
+ if (this->step_number == 0) {
+ this->step_number = this->number_of_steps;
+ }
+ this->step_number--;
+ }
+ // decrement the steps left:
+ steps_left--;
+ // step the motor to step number 0, 1, 2, or 3:
+ stepMotor(this->step_number % 4);
+ }
+ }
+}
+
+/*
+ * Moves the motor forward or backwards.
+ */
+void Stepper::stepMotor(int thisStep)
+{
+ if (this->pin_count == 2) {
+ switch (thisStep) {
+ case 0: /* 01 */
+ digitalWrite(motor_pin_1, LOW);
+ digitalWrite(motor_pin_2, HIGH);
+ break;
+ case 1: /* 11 */
+ digitalWrite(motor_pin_1, HIGH);
+ digitalWrite(motor_pin_2, HIGH);
+ break;
+ case 2: /* 10 */
+ digitalWrite(motor_pin_1, HIGH);
+ digitalWrite(motor_pin_2, LOW);
+ break;
+ case 3: /* 00 */
+ digitalWrite(motor_pin_1, LOW);
+ digitalWrite(motor_pin_2, LOW);
+ break;
+ }
+ }
+ if (this->pin_count == 4) {
+ switch (thisStep) {
+ case 0: // 1010
+ digitalWrite(motor_pin_1, HIGH);
+ digitalWrite(motor_pin_2, LOW);
+ digitalWrite(motor_pin_3, HIGH);
+ digitalWrite(motor_pin_4, LOW);
+ break;
+ case 1: // 0110
+ digitalWrite(motor_pin_1, LOW);
+ digitalWrite(motor_pin_2, HIGH);
+ digitalWrite(motor_pin_3, HIGH);
+ digitalWrite(motor_pin_4, LOW);
+ break;
+ case 2: //0101
+ digitalWrite(motor_pin_1, LOW);
+ digitalWrite(motor_pin_2, HIGH);
+ digitalWrite(motor_pin_3, LOW);
+ digitalWrite(motor_pin_4, HIGH);
+ break;
+ case 3: //1001
+ digitalWrite(motor_pin_1, HIGH);
+ digitalWrite(motor_pin_2, LOW);
+ digitalWrite(motor_pin_3, LOW);
+ digitalWrite(motor_pin_4, HIGH);
+ break;
+ }
+ }
+}
+
+/*
+ version() returns the version of the library:
+*/
+int Stepper::version(void)
+{
+ return 4;
+}
diff --git a/libraries/Stepper/Stepper.h b/libraries/Stepper/Stepper.h
new file mode 100644
index 0000000..4094aee
--- /dev/null
+++ b/libraries/Stepper/Stepper.h
@@ -0,0 +1,83 @@
+/*
+ Stepper.h - - Stepper library for Wiring/Arduino - Version 0.4
+
+ Original library (0.1) by Tom Igoe.
+ Two-wire modifications (0.2) by Sebastian Gassner
+ Combination version (0.3) by Tom Igoe and David Mellis
+ Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley
+
+ Drives a unipolar or bipolar stepper motor using 2 wires or 4 wires
+
+ When wiring multiple stepper motors to a microcontroller,
+ you quickly run out of output pins, with each motor requiring 4 connections.
+
+ By making use of the fact that at any time two of the four motor
+ coils are the inverse of the other two, the number of
+ control connections can be reduced from 4 to 2.
+
+ A slightly modified circuit around a Darlington transistor array or an L293 H-bridge
+ connects to only 2 microcontroler pins, inverts the signals received,
+ and delivers the 4 (2 plus 2 inverted ones) output signals required
+ for driving a stepper motor.
+
+ The sequence of control signals for 4 control wires is as follows:
+
+ Step C0 C1 C2 C3
+ 1 1 0 1 0
+ 2 0 1 1 0
+ 3 0 1 0 1
+ 4 1 0 0 1
+
+ The sequence of controls signals for 2 control wires is as follows
+ (columns C1 and C2 from above):
+
+ Step C0 C1
+ 1 0 1
+ 2 1 1
+ 3 1 0
+ 4 0 0
+
+ The circuits can be found at
+ http://www.arduino.cc/en/Tutorial/Stepper
+*/
+
+// ensure this library description is only included once
+#ifndef Stepper_h
+#define Stepper_h
+
+// library interface description
+class Stepper {
+ public:
+ // constructors:
+ Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2);
+ Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4);
+
+ // speed setter method:
+ void setSpeed(long whatSpeed);
+
+ // mover method:
+ void step(int number_of_steps);
+
+ int version(void);
+
+ private:
+ void stepMotor(int this_step);
+
+ int direction; // Direction of rotation
+ int speed; // Speed in RPMs
+ unsigned long step_delay; // delay between steps, in ms, based on speed
+ int number_of_steps; // total number of steps this motor can take
+ int pin_count; // whether you're driving the motor with 2 or 4 pins
+ int step_number; // which step the motor is on
+
+ // motor pin numbers:
+ int motor_pin_1;
+ int motor_pin_2;
+ int motor_pin_3;
+ int motor_pin_4;
+
+ long last_step_time; // time stamp in ms of when the last step was taken
+};
+
+#endif
+
diff --git a/libraries/Stepper/examples/MotorKnob/MotorKnob.pde b/libraries/Stepper/examples/MotorKnob/MotorKnob.pde
new file mode 100644
index 0000000..062cac9
--- /dev/null
+++ b/libraries/Stepper/examples/MotorKnob/MotorKnob.pde
@@ -0,0 +1,40 @@
+/*
+ * MotorKnob
+ *
+ * A stepper motor follows the turns of a potentiometer
+ * (or other sensor) on analog input 0.
+ *
+ * http://www.arduino.cc/en/Reference/Stepper
+ */
+
+#include <Stepper.h>
+
+// change this to the number of steps on your motor
+#define STEPS 100
+
+// create an instance of the stepper class, specifying
+// the number of steps of the motor and the pins it's
+// attached to
+Stepper stepper(STEPS, 8, 9, 10, 11);
+
+// the previous reading from the analog input
+int previous = 0;
+
+void setup()
+{
+ // set the speed of the motor to 30 RPMs
+ stepper.setSpeed(30);
+}
+
+void loop()
+{
+ // get the sensor value
+ int val = analogRead(0);
+
+ // move a number of steps equal to the change in the
+ // sensor reading
+ stepper.step(val - previous);
+
+ // remember the previous value of the sensor
+ previous = val;
+} \ No newline at end of file
diff --git a/libraries/Stepper/keywords.txt b/libraries/Stepper/keywords.txt
new file mode 100644
index 0000000..19a0fad
--- /dev/null
+++ b/libraries/Stepper/keywords.txt
@@ -0,0 +1,28 @@
+#######################################
+# Syntax Coloring Map For Test
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+Stepper KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+step KEYWORD2
+setSpeed KEYWORD2
+version KEYWORD2
+
+######################################
+# Instances (KEYWORD2)
+#######################################
+direction KEYWORD2
+speed KEYWORD2
+
+
+#######################################
+# Constants (LITERAL1)
+#######################################
diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp
new file mode 100755
index 0000000..0ee3012
--- /dev/null
+++ b/libraries/Wire/Wire.cpp
@@ -0,0 +1,265 @@
+/*
+ TwoWire.cpp - TWI/I2C library for Wiring & Arduino
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+extern "C" {
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.h>
+ #include "twi.h"
+}
+
+#include "Wire.h"
+
+// Initialize Class Variables //////////////////////////////////////////////////
+
+uint8_t* TwoWire::rxBuffer = 0;
+uint8_t TwoWire::rxBufferIndex = 0;
+uint8_t TwoWire::rxBufferLength = 0;
+
+uint8_t TwoWire::txAddress = 0;
+uint8_t* TwoWire::txBuffer = 0;
+uint8_t TwoWire::txBufferIndex = 0;
+uint8_t TwoWire::txBufferLength = 0;
+
+uint8_t TwoWire::transmitting = 0;
+void (*TwoWire::user_onRequest)(void);
+void (*TwoWire::user_onReceive)(int);
+
+// Constructors ////////////////////////////////////////////////////////////////
+
+TwoWire::TwoWire()
+{
+}
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+void TwoWire::begin(void)
+{
+ // init buffer for reads
+ rxBuffer = (uint8_t*) calloc(BUFFER_LENGTH, sizeof(uint8_t));
+ rxBufferIndex = 0;
+ rxBufferLength = 0;
+
+ // init buffer for writes
+ txBuffer = (uint8_t*) calloc(BUFFER_LENGTH, sizeof(uint8_t));
+ txBufferIndex = 0;
+ txBufferLength = 0;
+
+ twi_init();
+}
+
+void TwoWire::begin(uint8_t address)
+{
+ twi_setAddress(address);
+ twi_attachSlaveTxEvent(onRequestService);
+ twi_attachSlaveRxEvent(onReceiveService);
+ begin();
+}
+
+void TwoWire::begin(int address)
+{
+ begin((uint8_t)address);
+}
+
+uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
+{
+ // clamp to buffer length
+ if(quantity > BUFFER_LENGTH){
+ quantity = BUFFER_LENGTH;
+ }
+ // perform blocking read into buffer
+ uint8_t read = twi_readFrom(address, rxBuffer, quantity);
+ // set rx buffer iterator vars
+ rxBufferIndex = 0;
+ rxBufferLength = read;
+
+ return read;
+}
+
+uint8_t TwoWire::requestFrom(int address, int quantity)
+{
+ return requestFrom((uint8_t)address, (uint8_t)quantity);
+}
+
+void TwoWire::beginTransmission(uint8_t address)
+{
+ // indicate that we are transmitting
+ transmitting = 1;
+ // set address of targeted slave
+ txAddress = address;
+ // reset tx buffer iterator vars
+ txBufferIndex = 0;
+ txBufferLength = 0;
+}
+
+void TwoWire::beginTransmission(int address)
+{
+ beginTransmission((uint8_t)address);
+}
+
+uint8_t TwoWire::endTransmission(void)
+{
+ // transmit buffer (blocking)
+ int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1);
+ // reset tx buffer iterator vars
+ txBufferIndex = 0;
+ txBufferLength = 0;
+ // indicate that we are done transmitting
+ transmitting = 0;
+ return ret;
+}
+
+// must be called in:
+// slave tx event callback
+// or after beginTransmission(address)
+void TwoWire::send(uint8_t data)
+{
+ if(transmitting){
+ // in master transmitter mode
+ // don't bother if buffer is full
+ if(txBufferLength >= BUFFER_LENGTH){
+ return;
+ }
+ // put byte in tx buffer
+ txBuffer[txBufferIndex] = data;
+ ++txBufferIndex;
+ // update amount in buffer
+ txBufferLength = txBufferIndex;
+ }else{
+ // in slave send mode
+ // reply to master
+ twi_transmit(&data, 1);
+ }
+}
+
+// must be called in:
+// slave tx event callback
+// or after beginTransmission(address)
+void TwoWire::send(uint8_t* data, uint8_t quantity)
+{
+ if(transmitting){
+ // in master transmitter mode
+ for(uint8_t i = 0; i < quantity; ++i){
+ send(data[i]);
+ }
+ }else{
+ // in slave send mode
+ // reply to master
+ twi_transmit(data, quantity);
+ }
+}
+
+// must be called in:
+// slave tx event callback
+// or after beginTransmission(address)
+void TwoWire::send(char* data)
+{
+ send((uint8_t*)data, strlen(data));
+}
+
+// must be called in:
+// slave tx event callback
+// or after beginTransmission(address)
+void TwoWire::send(int data)
+{
+ send((uint8_t)data);
+}
+
+// must be called in:
+// slave rx event callback
+// or after requestFrom(address, numBytes)
+uint8_t TwoWire::available(void)
+{
+ return rxBufferLength - rxBufferIndex;
+}
+
+// must be called in:
+// slave rx event callback
+// or after requestFrom(address, numBytes)
+uint8_t TwoWire::receive(void)
+{
+ // default to returning null char
+ // for people using with char strings
+ uint8_t value = '\0';
+
+ // get each successive byte on each call
+ if(rxBufferIndex < rxBufferLength){
+ value = rxBuffer[rxBufferIndex];
+ ++rxBufferIndex;
+ }
+
+ return value;
+}
+
+// behind the scenes function that is called when data is received
+void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
+{
+ // don't bother if user hasn't registered a callback
+ if(!user_onReceive){
+ return;
+ }
+ // don't bother if rx buffer is in use by a master requestFrom() op
+ // i know this drops data, but it allows for slight stupidity
+ // meaning, they may not have read all the master requestFrom() data yet
+ if(rxBufferIndex < rxBufferLength){
+ return;
+ }
+ // copy twi rx buffer into local read buffer
+ // this enables new reads to happen in parallel
+ for(uint8_t i = 0; i < numBytes; ++i){
+ rxBuffer[i] = inBytes[i];
+ }
+ // set rx iterator vars
+ rxBufferIndex = 0;
+ rxBufferLength = numBytes;
+ // alert user program
+ user_onReceive(numBytes);
+}
+
+// behind the scenes function that is called when data is requested
+void TwoWire::onRequestService(void)
+{
+ // don't bother if user hasn't registered a callback
+ if(!user_onRequest){
+ return;
+ }
+ // reset tx buffer iterator vars
+ // !!! this will kill any pending pre-master sendTo() activity
+ txBufferIndex = 0;
+ txBufferLength = 0;
+ // alert user program
+ user_onRequest();
+}
+
+// sets function called on slave write
+void TwoWire::onReceive( void (*function)(int) )
+{
+ user_onReceive = function;
+}
+
+// sets function called on slave read
+void TwoWire::onRequest( void (*function)(void) )
+{
+ user_onRequest = function;
+}
+
+// Preinstantiate Objects //////////////////////////////////////////////////////
+
+TwoWire Wire = TwoWire();
+
diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h
new file mode 100755
index 0000000..9e849d5
--- /dev/null
+++ b/libraries/Wire/Wire.h
@@ -0,0 +1,67 @@
+/*
+ TwoWire.h - TWI/I2C library for Arduino & Wiring
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef TwoWire_h
+#define TwoWire_h
+
+#include <inttypes.h>
+
+#define BUFFER_LENGTH 32
+
+class TwoWire
+{
+ private:
+ static uint8_t* rxBuffer;
+ static uint8_t rxBufferIndex;
+ static uint8_t rxBufferLength;
+
+ static uint8_t txAddress;
+ static uint8_t* txBuffer;
+ static uint8_t txBufferIndex;
+ static uint8_t txBufferLength;
+
+ static uint8_t transmitting;
+ static void (*user_onRequest)(void);
+ static void (*user_onReceive)(int);
+ static void onRequestService(void);
+ static void onReceiveService(uint8_t*, int);
+ public:
+ TwoWire();
+ void begin();
+ void begin(uint8_t);
+ void begin(int);
+ void beginTransmission(uint8_t);
+ void beginTransmission(int);
+ uint8_t endTransmission(void);
+ uint8_t requestFrom(uint8_t, uint8_t);
+ uint8_t requestFrom(int, int);
+ void send(uint8_t);
+ void send(uint8_t*, uint8_t);
+ void send(int);
+ void send(char*);
+ uint8_t available(void);
+ uint8_t receive(void);
+ void onReceive( void (*)(int) );
+ void onRequest( void (*)(void) );
+};
+
+extern TwoWire Wire;
+
+#endif
+
diff --git a/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.pde b/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.pde
new file mode 100755
index 0000000..c89b0f0
--- /dev/null
+++ b/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.pde
@@ -0,0 +1,84 @@
+// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder
+// by Nicholas Zambetti <http://www.zambetti.com>
+// and James Tichenor <http://www.jamestichenor.net>
+
+// Demonstrates use of the Wire library reading data from the
+// Devantech Utrasonic Rangers SFR08 and SFR10
+
+// Created 29 April 2006
+
+#include <Wire.h>
+
+void setup()
+{
+ Wire.begin(); // join i2c bus (address optional for master)
+ Serial.begin(9600); // start serial communication at 9600bps
+}
+
+int reading = 0;
+
+void loop()
+{
+ // step 1: instruct sensor to read echoes
+ Wire.beginTransmission(112); // transmit to device #112 (0x70)
+ // the address specified in the datasheet is 224 (0xE0)
+ // but i2c adressing uses the high 7 bits so it's 112
+ Wire.send(0x00); // sets register pointer to the command register (0x00)
+ Wire.send(0x50); // command sensor to measure in "inches" (0x50)
+ // use 0x51 for centimeters
+ // use 0x52 for ping microseconds
+ Wire.endTransmission(); // stop transmitting
+
+ // step 2: wait for readings to happen
+ delay(70); // datasheet suggests at least 65 milliseconds
+
+ // step 3: instruct sensor to return a particular echo reading
+ Wire.beginTransmission(112); // transmit to device #112
+ Wire.send(0x02); // sets register pointer to echo #1 register (0x02)
+ Wire.endTransmission(); // stop transmitting
+
+ // step 4: request reading from sensor
+ Wire.requestFrom(112, 2); // request 2 bytes from slave device #112
+
+ // step 5: receive reading from sensor
+ if(2 <= Wire.available()) // if two bytes were received
+ {
+ reading = Wire.receive(); // receive high byte (overwrites previous reading)
+ reading = reading << 8; // shift high byte to be high 8 bits
+ reading |= Wire.receive(); // receive low byte as lower 8 bits
+ Serial.println(reading); // print the reading
+ }
+
+ delay(250); // wait a bit since people have to read the output :)
+}
+
+
+/*
+
+// The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08)
+// usage: changeAddress(0x70, 0xE6);
+
+void changeAddress(byte oldAddress, byte newAddress)
+{
+ Wire.beginTransmission(oldAddress);
+ Wire.send(0x00);
+ Wire.send(0xA0);
+ Wire.endTransmission();
+
+ Wire.beginTransmission(oldAddress);
+ Wire.send(0x00);
+ Wire.send(0xAA);
+ Wire.endTransmission();
+
+ Wire.beginTransmission(oldAddress);
+ Wire.send(0x00);
+ Wire.send(0xA5);
+ Wire.endTransmission();
+
+ Wire.beginTransmission(oldAddress);
+ Wire.send(0x00);
+ Wire.send(newAddress);
+ Wire.endTransmission();
+}
+
+*/
diff --git a/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.pde b/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.pde
new file mode 100644
index 0000000..35ee5d6
--- /dev/null
+++ b/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.pde
@@ -0,0 +1,34 @@
+// I2C Digital Potentiometer
+// by Nicholas Zambetti <http://www.zambetti.com>
+// and Shawn Bonkowski <http://people.interaction-ivrea.it/s.bonkowski/>
+
+// Demonstrates use of the Wire library
+// Controls AD5171 digital potentiometer via I2C/TWI
+
+// Created 31 March 2006
+
+#include <Wire.h>
+
+void setup()
+{
+ Wire.begin(); // join i2c bus (address optional for master)
+}
+
+byte val = 0;
+
+void loop()
+{
+ Wire.beginTransmission(44); // transmit to device #44 (0x2c)
+ // device address is specified in datasheet
+ Wire.send(0x00); // sends instruction byte
+ Wire.send(val); // sends potentiometer value byte
+ Wire.endTransmission(); // stop transmitting
+
+ val++; // increment value
+ if(val == 64) // if reached 64th position (max)
+ {
+ val = 0; // start over from lowest value
+ }
+ delay(500);
+}
+
diff --git a/libraries/Wire/examples/master_reader/master_reader.pde b/libraries/Wire/examples/master_reader/master_reader.pde
new file mode 100644
index 0000000..1b139de
--- /dev/null
+++ b/libraries/Wire/examples/master_reader/master_reader.pde
@@ -0,0 +1,29 @@
+// Wire Master Reader
+// by Nicholas Zambetti <http://www.zambetti.com>
+
+// Demonstrates use of the Wire library
+// Reads data from an I2C/TWI slave device
+// Refer to the "Wire Slave Sender" example for use with this
+
+// Created 29 March 2006
+
+#include <Wire.h>
+
+void setup()
+{
+ Wire.begin(); // join i2c bus (address optional for master)
+ Serial.begin(9600); // start serial for output
+}
+
+void loop()
+{
+ Wire.requestFrom(2, 6); // request 6 bytes from slave device #2
+
+ while(Wire.available()) // slave may send less than requested
+ {
+ char c = Wire.receive(); // receive a byte as character
+ Serial.print(c); // print the character
+ }
+
+ delay(500);
+}
diff --git a/libraries/Wire/examples/master_writer/master_writer.pde b/libraries/Wire/examples/master_writer/master_writer.pde
new file mode 100644
index 0000000..d0ff9fa
--- /dev/null
+++ b/libraries/Wire/examples/master_writer/master_writer.pde
@@ -0,0 +1,28 @@
+// Wire Master Writer
+// by Nicholas Zambetti <http://www.zambetti.com>
+
+// Demonstrates use of the Wire library
+// Writes data to an I2C/TWI slave device
+// Refer to the "Wire Slave Receiver" example for use with this
+
+// Created 29 March 2006
+
+#include <Wire.h>
+
+void setup()
+{
+ Wire.begin(); // join i2c bus (address optional for master)
+}
+
+byte x = 0;
+
+void loop()
+{
+ Wire.beginTransmission(4); // transmit to device #4
+ Wire.send("x is "); // sends five bytes
+ Wire.send(x); // sends one byte
+ Wire.endTransmission(); // stop transmitting
+
+ x++;
+ delay(500);
+}
diff --git a/libraries/Wire/examples/slave_receiver/slave_receiver.pde b/libraries/Wire/examples/slave_receiver/slave_receiver.pde
new file mode 100644
index 0000000..53c86b5
--- /dev/null
+++ b/libraries/Wire/examples/slave_receiver/slave_receiver.pde
@@ -0,0 +1,35 @@
+// Wire Slave Receiver
+// by Nicholas Zambetti <http://www.zambetti.com>
+
+// Demonstrates use of the Wire library
+// Receives data as an I2C/TWI slave device
+// Refer to the "Wire Master Writer" example for use with this
+
+// Created 29 March 2006
+
+#include <Wire.h>
+
+void setup()
+{
+ Wire.begin(4); // join i2c bus with address #4
+ Wire.onReceive(receiveEvent); // register event
+ Serial.begin(9600); // start serial for output
+}
+
+void loop()
+{
+ delay(100);
+}
+
+// function that executes whenever data is received from master
+// this function is registered as an event, see setup()
+void receiveEvent(int howMany)
+{
+ while(1 < Wire.available()) // loop through all but the last
+ {
+ char c = Wire.receive(); // receive byte as a character
+ Serial.print(c); // print the character
+ }
+ int x = Wire.receive(); // receive byte as an integer
+ Serial.println(x); // print the integer
+}
diff --git a/libraries/Wire/examples/slave_sender/slave_sender.pde b/libraries/Wire/examples/slave_sender/slave_sender.pde
new file mode 100644
index 0000000..f500644
--- /dev/null
+++ b/libraries/Wire/examples/slave_sender/slave_sender.pde
@@ -0,0 +1,29 @@
+// Wire Slave Sender
+// by Nicholas Zambetti <http://www.zambetti.com>
+
+// Demonstrates use of the Wire library
+// Sends data as an I2C/TWI slave device
+// Refer to the "Wire Master Reader" example for use with this
+
+// Created 29 March 2006
+
+#include <Wire.h>
+
+void setup()
+{
+ Wire.begin(2); // join i2c bus with address #2
+ Wire.onRequest(requestEvent); // register event
+}
+
+void loop()
+{
+ delay(100);
+}
+
+// function that executes whenever data is requested by master
+// this function is registered as an event, see setup()
+void requestEvent()
+{
+ Wire.send("hello "); // respond with message of 6 bytes
+ // as expected by master
+}
diff --git a/libraries/Wire/keywords.txt b/libraries/Wire/keywords.txt
new file mode 100644
index 0000000..12f129b
--- /dev/null
+++ b/libraries/Wire/keywords.txt
@@ -0,0 +1,31 @@
+#######################################
+# Syntax Coloring Map For Wire
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+begin KEYWORD2
+beginTransmission KEYWORD2
+endTransmission KEYWORD2
+requestFrom KEYWORD2
+send KEYWORD2
+receive KEYWORD2
+onReceive KEYWORD2
+onRequest KEYWORD2
+
+#######################################
+# Instances (KEYWORD2)
+#######################################
+
+Wire KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
diff --git a/libraries/Wire/utility/twi.c b/libraries/Wire/utility/twi.c
new file mode 100644
index 0000000..82a25c0
--- /dev/null
+++ b/libraries/Wire/utility/twi.c
@@ -0,0 +1,474 @@
+/*
+ twi.c - TWI/I2C library for Wiring & Arduino
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <math.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <compat/twi.h>
+
+#ifndef cbi
+#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+#endif
+
+#ifndef sbi
+#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#endif
+
+#include "twi.h"
+
+static volatile uint8_t twi_state;
+static uint8_t twi_slarw;
+
+static void (*twi_onSlaveTransmit)(void);
+static void (*twi_onSlaveReceive)(uint8_t*, int);
+
+static uint8_t* twi_masterBuffer;
+static volatile uint8_t twi_masterBufferIndex;
+static uint8_t twi_masterBufferLength;
+
+static uint8_t* twi_txBuffer;
+static volatile uint8_t twi_txBufferIndex;
+static volatile uint8_t twi_txBufferLength;
+
+static uint8_t* twi_rxBuffer;
+static volatile uint8_t twi_rxBufferIndex;
+
+static volatile uint8_t twi_error;
+
+/*
+ * Function twi_init
+ * Desc readys twi pins and sets twi bitrate
+ * Input none
+ * Output none
+ */
+void twi_init(void)
+{
+ // initialize state
+ twi_state = TWI_READY;
+
+ #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
+ // activate internal pull-ups for twi
+ // as per note from atmega8 manual pg167
+ sbi(PORTC, 4);
+ sbi(PORTC, 5);
+ #else
+ // activate internal pull-ups for twi
+ // as per note from atmega128 manual pg204
+ sbi(PORTD, 0);
+ sbi(PORTD, 1);
+ #endif
+
+ // initialize twi prescaler and bit rate
+ cbi(TWSR, TWPS0);
+ cbi(TWSR, TWPS1);
+ TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;
+
+ /* twi bit rate formula from atmega128 manual pg 204
+ SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
+ note: TWBR should be 10 or higher for master mode
+ It is 72 for a 16mhz Wiring board with 100kHz TWI */
+
+ // enable twi module, acks, and twi interrupt
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
+
+ // allocate buffers
+ twi_masterBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));
+ twi_txBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));
+ twi_rxBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));
+}
+
+/*
+ * Function twi_slaveInit
+ * Desc sets slave address and enables interrupt
+ * Input none
+ * Output none
+ */
+void twi_setAddress(uint8_t address)
+{
+ // set twi slave address (skip over TWGCE bit)
+ TWAR = address << 1;
+}
+
+/*
+ * Function twi_readFrom
+ * Desc attempts to become twi bus master and read a
+ * series of bytes from a device on the bus
+ * Input address: 7bit i2c device address
+ * data: pointer to byte array
+ * length: number of bytes to read into array
+ * Output number of bytes read
+ */
+uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
+{
+ uint8_t i;
+
+ // ensure data will fit into buffer
+ if(TWI_BUFFER_LENGTH < length){
+ return 0;
+ }
+
+ // wait until twi is ready, become master receiver
+ while(TWI_READY != twi_state){
+ continue;
+ }
+ twi_state = TWI_MRX;
+ // reset error state (0xFF.. no error occured)
+ twi_error = 0xFF;
+
+ // initialize buffer iteration vars
+ twi_masterBufferIndex = 0;
+ twi_masterBufferLength = length;
+
+ // build sla+w, slave device address + w bit
+ twi_slarw = TW_READ;
+ twi_slarw |= address << 1;
+
+ // send start condition
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
+
+ // wait for read operation to complete
+ while(TWI_MRX == twi_state){
+ continue;
+ }
+
+ if (twi_masterBufferIndex < length)
+ length = twi_masterBufferIndex;
+
+ // copy twi buffer to data
+ for(i = 0; i < length; ++i){
+ data[i] = twi_masterBuffer[i];
+ }
+
+ return length;
+}
+
+/*
+ * Function twi_writeTo
+ * Desc attempts to become twi bus master and write a
+ * series of bytes to a device on the bus
+ * Input address: 7bit i2c device address
+ * data: pointer to byte array
+ * length: number of bytes in array
+ * wait: boolean indicating to wait for write or not
+ * Output 0 .. success
+ * 1 .. length to long for buffer
+ * 2 .. address send, NACK received
+ * 3 .. data send, NACK received
+ * 4 .. other twi error (lost bus arbitration, bus error, ..)
+ */
+uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)
+{
+ uint8_t i;
+
+ // ensure data will fit into buffer
+ if(TWI_BUFFER_LENGTH < length){
+ return 1;
+ }
+
+ // wait until twi is ready, become master transmitter
+ while(TWI_READY != twi_state){
+ continue;
+ }
+ twi_state = TWI_MTX;
+ // reset error state (0xFF.. no error occured)
+ twi_error = 0xFF;
+
+ // initialize buffer iteration vars
+ twi_masterBufferIndex = 0;
+ twi_masterBufferLength = length;
+
+ // copy data to twi buffer
+ for(i = 0; i < length; ++i){
+ twi_masterBuffer[i] = data[i];
+ }
+
+ // build sla+w, slave device address + w bit
+ twi_slarw = TW_WRITE;
+ twi_slarw |= address << 1;
+
+ // send start condition
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
+
+ // wait for write operation to complete
+ while(wait && (TWI_MTX == twi_state)){
+ continue;
+ }
+
+ if (twi_error == 0xFF)
+ return 0; // success
+ else if (twi_error == TW_MT_SLA_NACK)
+ return 2; // error: address send, nack received
+ else if (twi_error == TW_MT_DATA_NACK)
+ return 3; // error: data send, nack received
+ else
+ return 4; // other twi error
+}
+
+/*
+ * Function twi_transmit
+ * Desc fills slave tx buffer with data
+ * must be called in slave tx event callback
+ * Input data: pointer to byte array
+ * length: number of bytes in array
+ * Output 1 length too long for buffer
+ * 2 not slave transmitter
+ * 0 ok
+ */
+uint8_t twi_transmit(uint8_t* data, uint8_t length)
+{
+ uint8_t i;
+
+ // ensure data will fit into buffer
+ if(TWI_BUFFER_LENGTH < length){
+ return 1;
+ }
+
+ // ensure we are currently a slave transmitter
+ if(TWI_STX != twi_state){
+ return 2;
+ }
+
+ // set length and copy data into tx buffer
+ twi_txBufferLength = length;
+ for(i = 0; i < length; ++i){
+ twi_txBuffer[i] = data[i];
+ }
+
+ return 0;
+}
+
+/*
+ * Function twi_attachSlaveRxEvent
+ * Desc sets function called before a slave read operation
+ * Input function: callback function to use
+ * Output none
+ */
+void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) )
+{
+ twi_onSlaveReceive = function;
+}
+
+/*
+ * Function twi_attachSlaveTxEvent
+ * Desc sets function called before a slave write operation
+ * Input function: callback function to use
+ * Output none
+ */
+void twi_attachSlaveTxEvent( void (*function)(void) )
+{
+ twi_onSlaveTransmit = function;
+}
+
+/*
+ * Function twi_reply
+ * Desc sends byte or readys receive line
+ * Input ack: byte indicating to ack or to nack
+ * Output none
+ */
+void twi_reply(uint8_t ack)
+{
+ // transmit master read ready signal, with or without ack
+ if(ack){
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
+ }else{
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
+ }
+}
+
+/*
+ * Function twi_stop
+ * Desc relinquishes bus master status
+ * Input none
+ * Output none
+ */
+void twi_stop(void)
+{
+ // send stop condition
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
+
+ // wait for stop condition to be exectued on bus
+ // TWINT is not set after a stop condition!
+ while(TWCR & _BV(TWSTO)){
+ continue;
+ }
+
+ // update twi state
+ twi_state = TWI_READY;
+}
+
+/*
+ * Function twi_releaseBus
+ * Desc releases bus control
+ * Input none
+ * Output none
+ */
+void twi_releaseBus(void)
+{
+ // release bus
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
+
+ // update twi state
+ twi_state = TWI_READY;
+}
+
+SIGNAL(TWI_vect)
+{
+ switch(TW_STATUS){
+ // All Master
+ case TW_START: // sent start condition
+ case TW_REP_START: // sent repeated start condition
+ // copy device address and r/w bit to output register and ack
+ TWDR = twi_slarw;
+ twi_reply(1);
+ break;
+
+ // Master Transmitter
+ case TW_MT_SLA_ACK: // slave receiver acked address
+ case TW_MT_DATA_ACK: // slave receiver acked data
+ // if there is data to send, send it, otherwise stop
+ if(twi_masterBufferIndex < twi_masterBufferLength){
+ // copy data to output register and ack
+ TWDR = twi_masterBuffer[twi_masterBufferIndex++];
+ twi_reply(1);
+ }else{
+ twi_stop();
+ }
+ break;
+ case TW_MT_SLA_NACK: // address sent, nack received
+ twi_error = TW_MT_SLA_NACK;
+ twi_stop();
+ break;
+ case TW_MT_DATA_NACK: // data sent, nack received
+ twi_error = TW_MT_DATA_NACK;
+ twi_stop();
+ break;
+ case TW_MT_ARB_LOST: // lost bus arbitration
+ twi_error = TW_MT_ARB_LOST;
+ twi_releaseBus();
+ break;
+
+ // Master Receiver
+ case TW_MR_DATA_ACK: // data received, ack sent
+ // put byte into buffer
+ twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
+ case TW_MR_SLA_ACK: // address sent, ack received
+ // ack if more bytes are expected, otherwise nack
+ if(twi_masterBufferIndex < twi_masterBufferLength){
+ twi_reply(1);
+ }else{
+ twi_reply(0);
+ }
+ break;
+ case TW_MR_DATA_NACK: // data received, nack sent
+ // put final byte into buffer
+ twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
+ case TW_MR_SLA_NACK: // address sent, nack received
+ twi_stop();
+ break;
+ // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case
+
+ // Slave Receiver
+ case TW_SR_SLA_ACK: // addressed, returned ack
+ case TW_SR_GCALL_ACK: // addressed generally, returned ack
+ case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack
+ case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack
+ // enter slave receiver mode
+ twi_state = TWI_SRX;
+ // indicate that rx buffer can be overwritten and ack
+ twi_rxBufferIndex = 0;
+ twi_reply(1);
+ break;
+ case TW_SR_DATA_ACK: // data received, returned ack
+ case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
+ // if there is still room in the rx buffer
+ if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
+ // put byte in buffer and ack
+ twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
+ twi_reply(1);
+ }else{
+ // otherwise nack
+ twi_reply(0);
+ }
+ break;
+ case TW_SR_STOP: // stop or repeated start condition received
+ // put a null char after data if there's room
+ if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
+ twi_rxBuffer[twi_rxBufferIndex] = '\0';
+ }
+ // callback to user defined callback
+ twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
+ // ack future responses
+ twi_reply(1);
+ // leave slave receiver state
+ twi_state = TWI_READY;
+ break;
+ case TW_SR_DATA_NACK: // data received, returned nack
+ case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
+ // nack back at master
+ twi_reply(0);
+ break;
+
+ // Slave Transmitter
+ case TW_ST_SLA_ACK: // addressed, returned ack
+ case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
+ // enter slave transmitter mode
+ twi_state = TWI_STX;
+ // ready the tx buffer index for iteration
+ twi_txBufferIndex = 0;
+ // set tx buffer length to be zero, to verify if user changes it
+ twi_txBufferLength = 0;
+ // request for txBuffer to be filled and length to be set
+ // note: user must call twi_transmit(bytes, length) to do this
+ twi_onSlaveTransmit();
+ // if they didn't change buffer & length, initialize it
+ if(0 == twi_txBufferLength){
+ twi_txBufferLength = 1;
+ twi_txBuffer[0] = 0x00;
+ }
+ // transmit first byte from buffer, fall
+ case TW_ST_DATA_ACK: // byte sent, ack returned
+ // copy data to output register
+ TWDR = twi_txBuffer[twi_txBufferIndex++];
+ // if there is more to send, ack, otherwise nack
+ if(twi_txBufferIndex < twi_txBufferLength){
+ twi_reply(1);
+ }else{
+ twi_reply(0);
+ }
+ break;
+ case TW_ST_DATA_NACK: // received nack, we are done
+ case TW_ST_LAST_DATA: // received ack, but we are done already!
+ // ack future responses
+ twi_reply(1);
+ // leave slave receiver state
+ twi_state = TWI_READY;
+ break;
+
+ // All
+ case TW_NO_INFO: // no state information
+ break;
+ case TW_BUS_ERROR: // bus error, illegal stop/start
+ twi_error = TW_BUS_ERROR;
+ twi_stop();
+ break;
+ }
+}
+
diff --git a/libraries/Wire/utility/twi.h b/libraries/Wire/utility/twi.h
new file mode 100755
index 0000000..1258d8d
--- /dev/null
+++ b/libraries/Wire/utility/twi.h
@@ -0,0 +1,57 @@
+/*
+ twi.h - TWI/I2C library for Wiring & Arduino
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef twi_h
+#define twi_h
+
+ #include <inttypes.h>
+
+ //#define ATMEGA8
+
+ #ifndef CPU_FREQ
+ #define CPU_FREQ 16000000L
+ #endif
+
+ #ifndef TWI_FREQ
+ #define TWI_FREQ 100000L
+ #endif
+
+ #ifndef TWI_BUFFER_LENGTH
+ #define TWI_BUFFER_LENGTH 32
+ #endif
+
+ #define TWI_READY 0
+ #define TWI_MRX 1
+ #define TWI_MTX 2
+ #define TWI_SRX 3
+ #define TWI_STX 4
+
+ void twi_init(void);
+ void twi_setAddress(uint8_t);
+ uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);
+ uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);
+ uint8_t twi_transmit(uint8_t*, uint8_t);
+ void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
+ void twi_attachSlaveTxEvent( void (*)(void) );
+ void twi_reply(uint8_t);
+ void twi_stop(void);
+ void twi_releaseBus(void);
+
+#endif
+
diff --git a/programmers.txt b/programmers.txt
new file mode 100644
index 0000000..c3e4d9b
--- /dev/null
+++ b/programmers.txt
@@ -0,0 +1,15 @@
+avrisp.name=AVR ISP
+avrisp.communication=serial
+avrisp.protocol=stk500
+
+avrispmkii.name=AVRISP mkII
+avrispmkii.communication=usb
+avrispmkii.protocol=stk500v2
+
+usbtinyisp.name=USBtinyISP
+usbtinyisp.protocol=usbtiny
+
+parallel.name=Parallel Programmer
+parallel.protocol=dapa
+parallel.force=true
+# parallel.delay=200