diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java
index 7e2d3e378..33f1fc855 100644
--- a/app/src/processing/app/Editor.java
+++ b/app/src/processing/app/Editor.java
@@ -2292,7 +2292,6 @@ public class Editor extends JFrame implements RunnerListener {
public boolean serialPrompt() {
- populateSerialMenu();
int count = serialMenu.getItemCount();
Object[] names = new Object[count];
for (int i = 0; i < count; i++) {
@@ -2357,7 +2356,9 @@ public class Editor extends JFrame implements RunnerListener {
// error message will already be visible
}
} catch (SerialNotFoundException e) {
- if (serialPrompt()) run();
+ populateSerialMenu();
+ if (serialMenu.getItemCount() == 0) statusError(e);
+ else if (serialPrompt()) run();
else statusNotice("Upload canceled.");
} catch (RunnerException e) {
//statusError("Error during upload.");
@@ -2389,7 +2390,9 @@ public class Editor extends JFrame implements RunnerListener {
// error message will already be visible
}
} catch (SerialNotFoundException e) {
- if (serialPrompt()) run();
+ populateSerialMenu();
+ if (serialMenu.getItemCount() == 0) statusError(e);
+ else if (serialPrompt()) run();
else statusNotice("Upload canceled.");
} catch (RunnerException e) {
//statusError("Error during upload.");
diff --git a/build/build.xml b/build/build.xml
index 43433a5bb..1e5f0259b 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -198,6 +198,10 @@
+
+
+
+
@@ -218,7 +222,9 @@
-
+
+
+
@@ -402,6 +408,10 @@
+
+
+
+
diff --git a/build/create_reference.pl b/build/create_reference.pl
index d6601f08c..93427f1e2 100644
--- a/build/create_reference.pl
+++ b/build/create_reference.pl
@@ -20,11 +20,12 @@ my $guide = create_page('Guide_index.html', "$ARDUINO/Guide/HomePage");
my $faq = create_page('FAQ.html', "$ARDUINO/Main/FAQ");
my $env = create_page('environment.html', "$ARDUINO/Main/Environment");
-my $css = create_page('arduino.css', "$ARDUINO/pub/skins/arduino/arduino.css");
+my $css = create_page('arduinoUno.css', "$ARDUINO/pub/skins/arduinoUno/arduinoUno.css");
my $eeprom = create_page('EEPROM.html', "$ARDUINO/Reference/EEPROM");
my $stepper = create_page('Stepper.html', "$ARDUINO/Reference/Stepper");
my $softser = create_page('SoftwareSerial.html', "$ARDUINO/Reference/SoftwareSerial");
my $wire = create_page('Wire.html', "$ARDUINO/Reference/Wire");
+my $sd = create_page('SD.html', "$ARDUINO/Reference/SD");
my $servo = create_page('Servo.html', "$ARDUINO/Reference/Servo");
my $spi = create_page('SPI.html', "$ARDUINO/Reference/SPI");
my $lcd = create_page('LiquidCrystal.html', "$ARDUINO/Reference/LiquidCrystal");
@@ -38,6 +39,8 @@ create_linked_pages($eeprom, qr!$ARDUINO/Reference/(EEPROM\w+)!, '%%.ht
create_linked_pages($stepper, qr!$ARDUINO/Reference/(Stepper\w+)!, '%%.html');
create_linked_pages($wire, qr!$ARDUINO/Reference/(Wire\w+)!, '%%.html');
create_linked_pages($servo, qr!$ARDUINO/Reference/(Servo\w+)!, '%%.html');
+create_linked_pages($sd, qr!$ARDUINO/Reference/(SD\w+)!, '%%.html');
+create_linked_pages($sd, qr!$ARDUINO/Reference/(File\w+)!, '%%.html');
create_linked_pages($spi, qr!$ARDUINO/Reference/(SPI\w+)!, '%%.html');
create_linked_pages($lcd, qr!$ARDUINO/Reference/(LiquidCrystal\w+)!, '%%.html');
create_linked_pages($ethernet, qr!$ARDUINO/Reference/(Ethernet\w+)!, '%%.html');
@@ -104,7 +107,7 @@ sub localize_page {
$text =~ s!$ARDUINO/Serial/([^']*)!Serial_$1.html!xg;
# direct pages to the local style file
- $text =~ s!$ARDUINO/pub/skins/arduino/arduino.css!arduino.css!xg;
+ $text =~ s!$ARDUINO/pub/skins/arduinoUno/arduinoUno.css!arduinoUno.css!xg;
# change links to Main/FAQ to go to FAQ.html
$text =~ s!$ARDUINO/Main/FAQ!FAQ.html!xg;
diff --git a/build/fetch.sh b/build/fetch.sh
index 6272fca94..e75a0dcf4 100755
--- a/build/fetch.sh
+++ b/build/fetch.sh
@@ -12,6 +12,9 @@ mkdir reference || die 'unable to create reference directory'
cd reference
perl ../create_reference.pl || die 'unable to create local reference pages'
+mkdir img
+curl http://arduino.cc/en/pub/skins/arduinoUno/img/logo.png > img/logo.png
+
cd ..
zip -r shared/reference.zip reference || die 'unable to create reference.zip archive'
diff --git a/build/linux/dist/arduino b/build/linux/dist/arduino
index adce6b7fa..d371e768a 100755
--- a/build/linux/dist/arduino
+++ b/build/linux/dist/arduino
@@ -1,6 +1,6 @@
#!/bin/sh
-APPDIR="$(dirname -- "${0}")"
+APPDIR="$(dirname -- $(readlink -f -- "${0}") )"
cd $APPDIR
diff --git a/build/macosx/dist/eeprom.h b/build/macosx/dist/eeprom.h
new file mode 100644
index 000000000..61c38a727
--- /dev/null
+++ b/build/macosx/dist/eeprom.h
@@ -0,0 +1,442 @@
+/* Copyright (c) 2002, 2003, 2004, 2007 Marek Michalkiewicz
+ Copyright (c) 2005, 2006 Bjoern Haase
+ Copyright (c) 2008 Atmel Corporation
+ Copyright (c) 2008 Wouter van Gulik
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id: eeprom.h,v 1.21.2.6 2008/08/19 22:10:39 arcanum Exp $ */
+
+#ifndef _AVR_EEPROM_H_
+#define _AVR_EEPROM_H_ 1
+
+#include
+#include /* size_t */
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ATTR_PURE__
+# ifdef __DOXYGEN__
+# define __ATTR_PURE__
+# else
+# define __ATTR_PURE__ __attribute__((__pure__))
+# endif
+#endif
+
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+uint16_t __eerd_word (const uint16_t *, uint8_t (*)(const uint8_t *))
+ __ATTR_PURE__;
+uint32_t __eerd_dword (const uint32_t *, uint8_t (*)(const uint8_t *))
+ __ATTR_PURE__;
+void __eerd_block (void *, const void *, size_t, uint8_t (*)(const uint8_t *));
+
+void __eewr_word (uint16_t *, uint16_t, void (*)(uint8_t *, uint8_t));
+void __eewr_dword (uint32_t *, uint32_t, void (*)(uint8_t *, uint8_t));
+void __eewr_block (void *, const void *, size_t, void (*)(uint8_t *, uint8_t));
+#endif /* (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) ) */
+
+#if !E2END && !defined(__DOXYGEN__)
+# ifndef __COMPILING_AVR_LIBC__
+# warning "Device does not have EEPROM available."
+# endif
+ /* Omit below for chips without EEPROM. */
+
+#else
+
+/** \defgroup avr_eeprom : EEPROM handling
+ \code #include \endcode
+
+ This header file declares the interface to some simple library
+ routines suitable for handling the data EEPROM contained in the
+ AVR microcontrollers. The implementation uses a simple polled
+ mode interface. Applications that require interrupt-controlled
+ EEPROM access to ensure that no time will be wasted in spinloops
+ will have to deploy their own implementation.
+
+ \note All of the read/write functions first make sure the EEPROM
+ is ready to be accessed. Since this may cause long delays if a
+ write operation is still pending, time-critical applications
+ should first poll the EEPROM e. g. using eeprom_is_ready() before
+ attempting any actual I/O. But this functions are not wait until
+ SELFPRGEN in SPMCSR becomes zero. Do this manually, if your
+ softwate contains the Flash burning.
+
+ \note As these functions modify IO registers, they are known to be
+ non-reentrant. If any of these functions are used from both,
+ standard and interrupt context, the applications must ensure
+ proper protection (e.g. by disabling interrupts before accessing
+ them).
+
+ \note All write functions force erase_and_write programming mode.
+ */
+
+/** \def EEMEM
+ \ingroup avr_eeprom
+ Attribute expression causing a variable to be allocated within the
+ .eeprom section. */
+#define EEMEM __attribute__((section(".eeprom")))
+
+
+/* Register definitions */
+
+/* Check for aliases. */
+#if !defined(EEWE) && defined(EEPE)
+# define EEWE EEPE
+#endif
+
+#if !defined(EEMWE) && defined(EEMPE)
+# define EEMWE EEMPE
+#endif
+
+#if !defined(EECR) && defined(DEECR)
+/* AT86RF401 */
+# define EECR DEECR
+# define EEAR DEEAR
+# define EEARL DEEAR
+# define EEDR DEEDR
+# define EERE EER
+# define EEWE EEL
+# define EEMWE EEU
+#endif
+
+
+#if !defined(EECR) || !defined(EEDR) || !defined(EEARL)
+
+# if !defined(__EEPROM_REG_LOCATIONS__) \
+ && !defined(EEPROM_REG_LOCATIONS_OVERRIDE)
+ /* 6-byte string denoting where to find the EEPROM registers in memory
+ space. Adresses denoted in hex syntax with uppercase letters. Used
+ by the EEPROM subroutines.
+ First two letters: EECR address.
+ Second two letters: EEDR address.
+ Last two letters: EEAR address.
+ */
+# error "Unknown EEPROM register(s) location."
+# endif
+
+/* If needed, override the locations defined in the IO headers. */
+# ifdef EEPROM_REG_LOCATIONS_OVERRIDE
+# undef __EEPROM_REG_LOCATIONS__
+# define __EEPROM_REG_LOCATIONS__ EEPROM_REG_LOCATIONS_OVERRIDE
+# endif
+
+# define CONCAT1(a, b) CONCAT2(a, b)
+# define CONCAT2(a, b) a ## b
+# define HEXNR CONCAT1(0x, __EEPROM_REG_LOCATIONS__)
+
+# undef EECR
+# define EECR _SFR_IO8((HEXNR >> 16) & 0xFF)
+
+# undef EEDR
+# define EEDR _SFR_IO8((HEXNR >> 8) & 0xFF)
+
+# undef EEAR
+# define EEAR _SFR_IO8(HEXNR & 0xFF)
+
+# undef EEARH
+
+# undef EEARL
+# define EEARL EEAR
+
+#endif
+
+
+/** \def eeprom_is_ready
+ \ingroup avr_eeprom
+ \returns 1 if EEPROM is ready for a new read/write operation, 0 if not.
+ */
+#if defined(__DOXYGEN__)
+# define eeprom_is_ready()
+#elif defined(DEECR)
+# define eeprom_is_ready() bit_is_clear(DEECR, BSY)
+#else
+# define eeprom_is_ready() bit_is_clear(EECR, EEWE)
+#endif
+
+
+/** \def eeprom_busy_wait
+ \ingroup avr_eeprom
+ Loops until the eeprom is no longer busy.
+ \returns Nothing.
+ */
+#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
+
+
+/** \ingroup avr_eeprom
+ Read one byte from EEPROM address \a __p.
+ */
+__ATTR_PURE__ static __inline__ uint8_t eeprom_read_byte (const uint8_t *__p)
+{
+ do {} while (!eeprom_is_ready ());
+#if E2END <= 0xFF
+ EEARL = (uint8_t)__p;
+#else
+ EEAR = (uint16_t)__p;
+#endif
+ /* Use inline assembly below as some AVRs have problems with accessing
+ EECR with STS instructions. For example, see errata for ATmega64.
+ The code below also assumes that EECR and EEDR are in the I/O space.
+ */
+ uint8_t __result;
+ __asm__ __volatile__
+ (
+ "/* START EEPROM READ CRITICAL SECTION */ \n\t"
+ "sbi %1, %2 \n\t"
+ "in %0, %3 \n\t"
+ "/* END EEPROM READ CRITICAL SECTION */ \n\t"
+ : "=r" (__result)
+ : "i" (_SFR_IO_ADDR(EECR)),
+ "i" (EERE),
+ "i" (_SFR_IO_ADDR(EEDR))
+ );
+ return __result;
+}
+
+/** \ingroup avr_eeprom
+ Read one 16-bit word (little endian) from EEPROM address \a __p.
+ */
+__ATTR_PURE__ static __inline__ uint16_t eeprom_read_word (const uint16_t *__p)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ return __eerd_word (__p, eeprom_read_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ union
+ {
+ uint16_t word;
+ struct
+ {
+ uint8_t lo;
+ uint8_t hi;
+ } byte;
+ } x;
+
+ x.byte.lo = eeprom_read_byte ((const uint8_t *)__p);
+ x.byte.hi = eeprom_read_byte ((const uint8_t *)__p + 1);
+ return x.word;
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Read one 32-bit double word (little endian) from EEPROM address \a __p.
+ */
+__ATTR_PURE__ static __inline__
+uint32_t eeprom_read_dword (const uint32_t *__p)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ return __eerd_dword (__p, eeprom_read_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ union
+ {
+ uint32_t dword;
+ struct
+ {
+ uint8_t byte0;
+ uint8_t byte1;
+ uint8_t byte2;
+ uint8_t byte3;
+ } byte;
+ } x;
+
+ x.byte.byte0 = eeprom_read_byte ((const uint8_t *)__p);
+ x.byte.byte1 = eeprom_read_byte ((const uint8_t *)__p + 1);
+ x.byte.byte2 = eeprom_read_byte ((const uint8_t *)__p + 2);
+ x.byte.byte3 = eeprom_read_byte ((const uint8_t *)__p + 3);
+ return x.dword;
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Read a block of \a __n bytes from EEPROM address \a __src to SRAM
+ \a __dst.
+ */
+static __inline__ void
+eeprom_read_block (void *__dst, const void *__src, size_t __n)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ __eerd_block (__dst, __src, __n, eeprom_read_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ char *_myDstPtr;
+ char *_mySrcPtr;
+
+ _myDstPtr = (char *)__dst;
+ _mySrcPtr = (char *)__src;
+ while (__n--)
+ {
+ //* Jul 6, 2010 modifed by Mark Sproul to work with the 2560
+ // *(char *)__dst++ = eeprom_read_byte((const uint8_t *)__src++);
+ *_myDstPtr = eeprom_read_byte((const uint8_t *)_mySrcPtr);
+ _myDstPtr++;
+ _mySrcPtr++;
+ }
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Write a byte \a __value to EEPROM address \a __p.
+ */
+static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
+{
+ do {} while (!eeprom_is_ready ());
+
+#if defined(EEPM0) && defined(EEPM1)
+ EECR = 0; /* Set programming mode: erase and write. */
+#elif defined(EEPM0) || defined(EEPM1)
+# warning "Unknown EECR register, eeprom_write_byte() has become outdated."
+#endif
+
+#if E2END <= 0xFF
+ EEARL = (unsigned)__p;
+#else
+ EEAR = (unsigned)__p;
+#endif
+ EEDR = __value;
+
+ __asm__ __volatile__ (
+ "/* START EEPROM WRITE CRITICAL SECTION */\n\t"
+ "in r0, %[__sreg] \n\t"
+ "cli \n\t"
+ "sbi %[__eecr], %[__eemwe] \n\t"
+ "sbi %[__eecr], %[__eewe] \n\t"
+ "out %[__sreg], r0 \n\t"
+ "/* END EEPROM WRITE CRITICAL SECTION */"
+ :
+ : [__eecr] "i" (_SFR_IO_ADDR(EECR)),
+ [__sreg] "i" (_SFR_IO_ADDR(SREG)),
+ [__eemwe] "i" (EEMWE),
+ [__eewe] "i" (EEWE)
+ : "r0"
+ );
+}
+
+/** \ingroup avr_eeprom
+ Write a word \a __value to EEPROM address \a __p.
+ */
+static __inline__ void eeprom_write_word (uint16_t *__p, uint16_t __value)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ __eewr_word (__p, __value, eeprom_write_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ union
+ {
+ uint16_t word;
+ struct
+ {
+ uint8_t lo;
+ uint8_t hi;
+ } byte;
+ } x;
+
+ x.word = __value;
+ eeprom_write_byte ((uint8_t *)__p, x.byte.lo);
+ eeprom_write_byte ((uint8_t *)__p + 1, x.byte.hi);
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Write a 32-bit double word \a __value to EEPROM address \a __p.
+ */
+static __inline__ void eeprom_write_dword (uint32_t *__p, uint32_t __value)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ __eewr_dword (__p, __value, eeprom_write_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ union
+ {
+ uint32_t dword;
+ struct
+ {
+ uint8_t byte0;
+ uint8_t byte1;
+ uint8_t byte2;
+ uint8_t byte3;
+ } byte;
+ } x;
+
+ x.dword = __value;
+ eeprom_write_byte ((uint8_t *)__p, x.byte.byte0);
+ eeprom_write_byte ((uint8_t *)__p + 1, x.byte.byte1);
+ eeprom_write_byte ((uint8_t *)__p + 2, x.byte.byte2);
+ eeprom_write_byte ((uint8_t *)__p + 3, x.byte.byte3);
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Write a block of \a __n bytes to EEPROM address \a __dst from \a __src.
+ \note The argument order is mismatch with common functions like strcpy().
+ */
+static __inline__ void
+eeprom_write_block (const void *__src, void *__dst, size_t __n)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ __eewr_block (__dst, __src, __n, eeprom_write_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ uint8_t *_myDstPtr;
+ uint8_t *_mySrcPtr;
+
+ //* Jul 6, 2010 modifed by Mark Sproul to work with the 2560
+ _myDstPtr = (uint8_t *)__dst;
+ _mySrcPtr = (uint8_t *)__src;
+
+ while (__n--)
+ {
+ // eeprom_write_byte((uint8_t *)__dst++, *(uint8_t *)__src++);
+ eeprom_write_byte(_myDstPtr++, *_mySrcPtr++);
+ }
+#endif
+}
+
+/** \name IAR C compatibility defines */
+/*@{*/
+
+/** \def _EEPUT
+ \ingroup avr_eeprom
+ Write a byte to EEPROM. Compatibility define for IAR C. */
+#define _EEPUT(addr, val) eeprom_write_byte ((uint8_t *)(addr), (uint8_t)(val))
+
+/** \def _EEGET
+ \ingroup avr_eeprom
+ Read a byte from EEPROM. Compatibility define for IAR C. */
+#define _EEGET(var, addr) (var) = eeprom_read_byte ((const uint8_t *)(addr))
+
+/*@}*/
+
+#endif /* E2END || defined(__DOXYGEN__) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_AVR_EEPROM_H */
diff --git a/build/shared/reference.zip b/build/shared/reference.zip
index a0d3c5f24..960914d9c 100644
Binary files a/build/shared/reference.zip and b/build/shared/reference.zip differ
diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt
index 13d90b8a5..ae3950db9 100644
--- a/build/shared/revisions.txt
+++ b/build/shared/revisions.txt
@@ -1,4 +1,4 @@
-ARDUINO 0022
+ARDUINO 0022 - 2010.12.24
[core / libraries]
@@ -33,6 +33,9 @@ ARDUINO 0022
* Fixed SPI.setClockDivider() function.
http://code.google.com/p/arduino/issues/detail?id=365
+* Fixed EEPROM library on Mega 2560.
+ http://code.google.com/p/arduino/issues/detail?id=381
+
* Hardware serial receive interrupt optimization.
http://code.google.com/p/arduino/issues/detail?id=391
diff --git a/build/windows/eeprom.h b/build/windows/eeprom.h
new file mode 100644
index 000000000..61c38a727
--- /dev/null
+++ b/build/windows/eeprom.h
@@ -0,0 +1,442 @@
+/* Copyright (c) 2002, 2003, 2004, 2007 Marek Michalkiewicz
+ Copyright (c) 2005, 2006 Bjoern Haase
+ Copyright (c) 2008 Atmel Corporation
+ Copyright (c) 2008 Wouter van Gulik
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id: eeprom.h,v 1.21.2.6 2008/08/19 22:10:39 arcanum Exp $ */
+
+#ifndef _AVR_EEPROM_H_
+#define _AVR_EEPROM_H_ 1
+
+#include
+#include /* size_t */
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ATTR_PURE__
+# ifdef __DOXYGEN__
+# define __ATTR_PURE__
+# else
+# define __ATTR_PURE__ __attribute__((__pure__))
+# endif
+#endif
+
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+uint16_t __eerd_word (const uint16_t *, uint8_t (*)(const uint8_t *))
+ __ATTR_PURE__;
+uint32_t __eerd_dword (const uint32_t *, uint8_t (*)(const uint8_t *))
+ __ATTR_PURE__;
+void __eerd_block (void *, const void *, size_t, uint8_t (*)(const uint8_t *));
+
+void __eewr_word (uint16_t *, uint16_t, void (*)(uint8_t *, uint8_t));
+void __eewr_dword (uint32_t *, uint32_t, void (*)(uint8_t *, uint8_t));
+void __eewr_block (void *, const void *, size_t, void (*)(uint8_t *, uint8_t));
+#endif /* (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) ) */
+
+#if !E2END && !defined(__DOXYGEN__)
+# ifndef __COMPILING_AVR_LIBC__
+# warning "Device does not have EEPROM available."
+# endif
+ /* Omit below for chips without EEPROM. */
+
+#else
+
+/** \defgroup avr_eeprom : EEPROM handling
+ \code #include \endcode
+
+ This header file declares the interface to some simple library
+ routines suitable for handling the data EEPROM contained in the
+ AVR microcontrollers. The implementation uses a simple polled
+ mode interface. Applications that require interrupt-controlled
+ EEPROM access to ensure that no time will be wasted in spinloops
+ will have to deploy their own implementation.
+
+ \note All of the read/write functions first make sure the EEPROM
+ is ready to be accessed. Since this may cause long delays if a
+ write operation is still pending, time-critical applications
+ should first poll the EEPROM e. g. using eeprom_is_ready() before
+ attempting any actual I/O. But this functions are not wait until
+ SELFPRGEN in SPMCSR becomes zero. Do this manually, if your
+ softwate contains the Flash burning.
+
+ \note As these functions modify IO registers, they are known to be
+ non-reentrant. If any of these functions are used from both,
+ standard and interrupt context, the applications must ensure
+ proper protection (e.g. by disabling interrupts before accessing
+ them).
+
+ \note All write functions force erase_and_write programming mode.
+ */
+
+/** \def EEMEM
+ \ingroup avr_eeprom
+ Attribute expression causing a variable to be allocated within the
+ .eeprom section. */
+#define EEMEM __attribute__((section(".eeprom")))
+
+
+/* Register definitions */
+
+/* Check for aliases. */
+#if !defined(EEWE) && defined(EEPE)
+# define EEWE EEPE
+#endif
+
+#if !defined(EEMWE) && defined(EEMPE)
+# define EEMWE EEMPE
+#endif
+
+#if !defined(EECR) && defined(DEECR)
+/* AT86RF401 */
+# define EECR DEECR
+# define EEAR DEEAR
+# define EEARL DEEAR
+# define EEDR DEEDR
+# define EERE EER
+# define EEWE EEL
+# define EEMWE EEU
+#endif
+
+
+#if !defined(EECR) || !defined(EEDR) || !defined(EEARL)
+
+# if !defined(__EEPROM_REG_LOCATIONS__) \
+ && !defined(EEPROM_REG_LOCATIONS_OVERRIDE)
+ /* 6-byte string denoting where to find the EEPROM registers in memory
+ space. Adresses denoted in hex syntax with uppercase letters. Used
+ by the EEPROM subroutines.
+ First two letters: EECR address.
+ Second two letters: EEDR address.
+ Last two letters: EEAR address.
+ */
+# error "Unknown EEPROM register(s) location."
+# endif
+
+/* If needed, override the locations defined in the IO headers. */
+# ifdef EEPROM_REG_LOCATIONS_OVERRIDE
+# undef __EEPROM_REG_LOCATIONS__
+# define __EEPROM_REG_LOCATIONS__ EEPROM_REG_LOCATIONS_OVERRIDE
+# endif
+
+# define CONCAT1(a, b) CONCAT2(a, b)
+# define CONCAT2(a, b) a ## b
+# define HEXNR CONCAT1(0x, __EEPROM_REG_LOCATIONS__)
+
+# undef EECR
+# define EECR _SFR_IO8((HEXNR >> 16) & 0xFF)
+
+# undef EEDR
+# define EEDR _SFR_IO8((HEXNR >> 8) & 0xFF)
+
+# undef EEAR
+# define EEAR _SFR_IO8(HEXNR & 0xFF)
+
+# undef EEARH
+
+# undef EEARL
+# define EEARL EEAR
+
+#endif
+
+
+/** \def eeprom_is_ready
+ \ingroup avr_eeprom
+ \returns 1 if EEPROM is ready for a new read/write operation, 0 if not.
+ */
+#if defined(__DOXYGEN__)
+# define eeprom_is_ready()
+#elif defined(DEECR)
+# define eeprom_is_ready() bit_is_clear(DEECR, BSY)
+#else
+# define eeprom_is_ready() bit_is_clear(EECR, EEWE)
+#endif
+
+
+/** \def eeprom_busy_wait
+ \ingroup avr_eeprom
+ Loops until the eeprom is no longer busy.
+ \returns Nothing.
+ */
+#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
+
+
+/** \ingroup avr_eeprom
+ Read one byte from EEPROM address \a __p.
+ */
+__ATTR_PURE__ static __inline__ uint8_t eeprom_read_byte (const uint8_t *__p)
+{
+ do {} while (!eeprom_is_ready ());
+#if E2END <= 0xFF
+ EEARL = (uint8_t)__p;
+#else
+ EEAR = (uint16_t)__p;
+#endif
+ /* Use inline assembly below as some AVRs have problems with accessing
+ EECR with STS instructions. For example, see errata for ATmega64.
+ The code below also assumes that EECR and EEDR are in the I/O space.
+ */
+ uint8_t __result;
+ __asm__ __volatile__
+ (
+ "/* START EEPROM READ CRITICAL SECTION */ \n\t"
+ "sbi %1, %2 \n\t"
+ "in %0, %3 \n\t"
+ "/* END EEPROM READ CRITICAL SECTION */ \n\t"
+ : "=r" (__result)
+ : "i" (_SFR_IO_ADDR(EECR)),
+ "i" (EERE),
+ "i" (_SFR_IO_ADDR(EEDR))
+ );
+ return __result;
+}
+
+/** \ingroup avr_eeprom
+ Read one 16-bit word (little endian) from EEPROM address \a __p.
+ */
+__ATTR_PURE__ static __inline__ uint16_t eeprom_read_word (const uint16_t *__p)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ return __eerd_word (__p, eeprom_read_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ union
+ {
+ uint16_t word;
+ struct
+ {
+ uint8_t lo;
+ uint8_t hi;
+ } byte;
+ } x;
+
+ x.byte.lo = eeprom_read_byte ((const uint8_t *)__p);
+ x.byte.hi = eeprom_read_byte ((const uint8_t *)__p + 1);
+ return x.word;
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Read one 32-bit double word (little endian) from EEPROM address \a __p.
+ */
+__ATTR_PURE__ static __inline__
+uint32_t eeprom_read_dword (const uint32_t *__p)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ return __eerd_dword (__p, eeprom_read_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ union
+ {
+ uint32_t dword;
+ struct
+ {
+ uint8_t byte0;
+ uint8_t byte1;
+ uint8_t byte2;
+ uint8_t byte3;
+ } byte;
+ } x;
+
+ x.byte.byte0 = eeprom_read_byte ((const uint8_t *)__p);
+ x.byte.byte1 = eeprom_read_byte ((const uint8_t *)__p + 1);
+ x.byte.byte2 = eeprom_read_byte ((const uint8_t *)__p + 2);
+ x.byte.byte3 = eeprom_read_byte ((const uint8_t *)__p + 3);
+ return x.dword;
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Read a block of \a __n bytes from EEPROM address \a __src to SRAM
+ \a __dst.
+ */
+static __inline__ void
+eeprom_read_block (void *__dst, const void *__src, size_t __n)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ __eerd_block (__dst, __src, __n, eeprom_read_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ char *_myDstPtr;
+ char *_mySrcPtr;
+
+ _myDstPtr = (char *)__dst;
+ _mySrcPtr = (char *)__src;
+ while (__n--)
+ {
+ //* Jul 6, 2010 modifed by Mark Sproul to work with the 2560
+ // *(char *)__dst++ = eeprom_read_byte((const uint8_t *)__src++);
+ *_myDstPtr = eeprom_read_byte((const uint8_t *)_mySrcPtr);
+ _myDstPtr++;
+ _mySrcPtr++;
+ }
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Write a byte \a __value to EEPROM address \a __p.
+ */
+static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
+{
+ do {} while (!eeprom_is_ready ());
+
+#if defined(EEPM0) && defined(EEPM1)
+ EECR = 0; /* Set programming mode: erase and write. */
+#elif defined(EEPM0) || defined(EEPM1)
+# warning "Unknown EECR register, eeprom_write_byte() has become outdated."
+#endif
+
+#if E2END <= 0xFF
+ EEARL = (unsigned)__p;
+#else
+ EEAR = (unsigned)__p;
+#endif
+ EEDR = __value;
+
+ __asm__ __volatile__ (
+ "/* START EEPROM WRITE CRITICAL SECTION */\n\t"
+ "in r0, %[__sreg] \n\t"
+ "cli \n\t"
+ "sbi %[__eecr], %[__eemwe] \n\t"
+ "sbi %[__eecr], %[__eewe] \n\t"
+ "out %[__sreg], r0 \n\t"
+ "/* END EEPROM WRITE CRITICAL SECTION */"
+ :
+ : [__eecr] "i" (_SFR_IO_ADDR(EECR)),
+ [__sreg] "i" (_SFR_IO_ADDR(SREG)),
+ [__eemwe] "i" (EEMWE),
+ [__eewe] "i" (EEWE)
+ : "r0"
+ );
+}
+
+/** \ingroup avr_eeprom
+ Write a word \a __value to EEPROM address \a __p.
+ */
+static __inline__ void eeprom_write_word (uint16_t *__p, uint16_t __value)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ __eewr_word (__p, __value, eeprom_write_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ union
+ {
+ uint16_t word;
+ struct
+ {
+ uint8_t lo;
+ uint8_t hi;
+ } byte;
+ } x;
+
+ x.word = __value;
+ eeprom_write_byte ((uint8_t *)__p, x.byte.lo);
+ eeprom_write_byte ((uint8_t *)__p + 1, x.byte.hi);
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Write a 32-bit double word \a __value to EEPROM address \a __p.
+ */
+static __inline__ void eeprom_write_dword (uint32_t *__p, uint32_t __value)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ __eewr_dword (__p, __value, eeprom_write_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ union
+ {
+ uint32_t dword;
+ struct
+ {
+ uint8_t byte0;
+ uint8_t byte1;
+ uint8_t byte2;
+ uint8_t byte3;
+ } byte;
+ } x;
+
+ x.dword = __value;
+ eeprom_write_byte ((uint8_t *)__p, x.byte.byte0);
+ eeprom_write_byte ((uint8_t *)__p + 1, x.byte.byte1);
+ eeprom_write_byte ((uint8_t *)__p + 2, x.byte.byte2);
+ eeprom_write_byte ((uint8_t *)__p + 3, x.byte.byte3);
+#endif
+}
+
+/** \ingroup avr_eeprom
+ Write a block of \a __n bytes to EEPROM address \a __dst from \a __src.
+ \note The argument order is mismatch with common functions like strcpy().
+ */
+static __inline__ void
+eeprom_write_block (const void *__src, void *__dst, size_t __n)
+{
+#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
+ __eewr_block (__dst, __src, __n, eeprom_write_byte);
+#else
+ /* If ATmega256x device, do not call function. */
+ uint8_t *_myDstPtr;
+ uint8_t *_mySrcPtr;
+
+ //* Jul 6, 2010 modifed by Mark Sproul to work with the 2560
+ _myDstPtr = (uint8_t *)__dst;
+ _mySrcPtr = (uint8_t *)__src;
+
+ while (__n--)
+ {
+ // eeprom_write_byte((uint8_t *)__dst++, *(uint8_t *)__src++);
+ eeprom_write_byte(_myDstPtr++, *_mySrcPtr++);
+ }
+#endif
+}
+
+/** \name IAR C compatibility defines */
+/*@{*/
+
+/** \def _EEPUT
+ \ingroup avr_eeprom
+ Write a byte to EEPROM. Compatibility define for IAR C. */
+#define _EEPUT(addr, val) eeprom_write_byte ((uint8_t *)(addr), (uint8_t)(val))
+
+/** \def _EEGET
+ \ingroup avr_eeprom
+ Read a byte from EEPROM. Compatibility define for IAR C. */
+#define _EEGET(var, addr) (var) = eeprom_read_byte ((const uint8_t *)(addr))
+
+/*@}*/
+
+#endif /* E2END || defined(__DOXYGEN__) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_AVR_EEPROM_H */
diff --git a/libraries/ArduinoTestSuite/examples/ATS_SD_File/ATS_SD_File.pde b/libraries/ArduinoTestSuite/examples/ATS_SD_File/ATS_SD_File.pde
index 43cc454e9..fefd6b07d 100644
--- a/libraries/ArduinoTestSuite/examples/ATS_SD_File/ATS_SD_File.pde
+++ b/libraries/ArduinoTestSuite/examples/ATS_SD_File/ATS_SD_File.pde
@@ -15,21 +15,17 @@ void setup()
ATS_PrintTestStatus("SD.begin()", b = SD.begin(4));
if (!b) goto done;
- f = SD.open("test.txt", FILE_TRUNCATE);
+ SD.remove("test.txt");
+
+ f = SD.open("test.txt", FILE_WRITE);
ATS_PrintTestStatus("SD.open()", f);
if (!f) goto done;
- f.print("1234");
+ f.print("abc");
+ f.print("de");
f.close();
- f = SD.open("test.txt", FILE_TRUNCATE);
- ATS_PrintTestStatus("SD.open()", f);
- if (!f) goto done;
-
- f.print("abcde");
- f.close();
-
- f = SD.open("test.txt", FILE_APPEND);
+ f = SD.open("test.txt", FILE_WRITE);
ATS_PrintTestStatus("SD.open()", f);
if (!f) goto done;
@@ -70,8 +66,10 @@ void setup()
ATS_PrintTestStatus("read()", f.read() == -1);
f.close();
+
+ SD.remove("test2.txt");
- f = SD.open("test2.txt", FILE_TRUNCATE);
+ f = SD.open("test2.txt", FILE_WRITE);
ATS_PrintTestStatus("SD.open()", f);
if (!f) goto done;
diff --git a/libraries/ArduinoTestSuite/examples/ATS_SD_Files/ATS_SD_Files.pde b/libraries/ArduinoTestSuite/examples/ATS_SD_Files/ATS_SD_Files.pde
index 9036e5f53..c3804f4de 100644
--- a/libraries/ArduinoTestSuite/examples/ATS_SD_Files/ATS_SD_Files.pde
+++ b/libraries/ArduinoTestSuite/examples/ATS_SD_Files/ATS_SD_Files.pde
@@ -13,7 +13,7 @@ void setup()
if (!b) goto done;
ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf.txt"));
- ATS_PrintTestStatus("SD.open()", f = SD.open("asdf.txt", FILE_TRUNCATE)); f.close();
+ ATS_PrintTestStatus("SD.open()", f = SD.open("asdf.txt", FILE_WRITE)); f.close();
ATS_PrintTestStatus("SD.exists()", SD.exists("asdf.txt"));
ATS_PrintTestStatus("SD.exists()", SD.exists("/asdf.txt"));
ATS_PrintTestStatus("SD.remove()", SD.remove("asdf.txt"));
@@ -48,13 +48,13 @@ void setup()
ATS_PrintTestStatus("!SD.exists()", !SD.exists("x/y"));
ATS_PrintTestStatus("!SD.exists()", !SD.exists("x/y/z"));
- ATS_PrintTestStatus("!SD.open()", !(f = SD.open("asdf/asdf.txt", FILE_TRUNCATE))); f.close();
+ ATS_PrintTestStatus("!SD.open()", !(f = SD.open("asdf/asdf.txt", FILE_WRITE))); f.close();
ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf"));
ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf.txt"));
ATS_PrintTestStatus("!SD.exists()", !SD.exists("asdf/asdf.txt"));
ATS_PrintTestStatus("SD.mkdir()", SD.mkdir("asdf"));
ATS_PrintTestStatus("SD.exists()", SD.exists("asdf"));
- ATS_PrintTestStatus("SD.open()", f = SD.open("asdf/asdf.txt", FILE_TRUNCATE)); f.close();
+ ATS_PrintTestStatus("SD.open()", f = SD.open("asdf/asdf.txt", FILE_WRITE)); f.close();
ATS_PrintTestStatus("SD.exists()", SD.exists("asdf/asdf.txt"));
ATS_PrintTestStatus("!SD.rmdir()", !SD.rmdir("asdf"));
ATS_PrintTestStatus("SD.exists()", SD.exists("asdf"));
diff --git a/libraries/ArduinoTestSuite/examples/ATS_SD_Seek/ATS_SD_Seek.pde b/libraries/ArduinoTestSuite/examples/ATS_SD_Seek/ATS_SD_Seek.pde
new file mode 100644
index 000000000..5b0916ca7
--- /dev/null
+++ b/libraries/ArduinoTestSuite/examples/ATS_SD_Seek/ATS_SD_Seek.pde
@@ -0,0 +1,109 @@
+// Tests writing to and reading from a file, in particular the
+// the Stream implementation (e.g. read() and peek()).
+
+#include
+#include
+
+void setup()
+{
+ int startMemoryUsage = ATS_GetFreeMemory();
+ boolean b;
+ File f;
+
+ ATS_begin("Arduino", "SD Test");
+
+ ATS_PrintTestStatus("SD.begin()", b = SD.begin(4));
+ if (!b) goto done;
+
+ SD.remove("test.txt");
+
+ f = SD.open("test.txt", FILE_WRITE);
+ ATS_PrintTestStatus("SD.open()", f);
+ if (!f) goto done;
+
+ ATS_PrintTestStatus("initial position", f.position() == 0);
+ ATS_PrintTestStatus("initial size", f.size() == 0);
+
+ f.print("0123456789");
+
+ ATS_PrintTestStatus("position after writing", f.position() == 10);
+ ATS_PrintTestStatus("size after writing", f.size() == 10);
+
+ f.seek(0);
+
+ ATS_PrintTestStatus("size after seek", f.size() == 10);
+ ATS_PrintTestStatus("position after seek", f.position() == 0);
+
+ f.seek(7);
+
+ ATS_PrintTestStatus("position after seek", f.position() == 7);
+ ATS_PrintTestStatus("reading after seek", f.read() == '7');
+ ATS_PrintTestStatus("position after reading after seeking", f.position() == 8);
+ ATS_PrintTestStatus("reading after reading after seeking", f.read() == '8');
+
+ f.seek(3);
+
+ ATS_PrintTestStatus("position after seeking", f.position() == 3);
+ ATS_PrintTestStatus("peeking after seeking", f.peek() == '3');
+ ATS_PrintTestStatus("position after peeking after seeking", f.position() == 3);
+ ATS_PrintTestStatus("peeking after peeking after seeking", f.peek() == '3');
+ ATS_PrintTestStatus("position after peeking after seeking", f.position() == 3);
+ ATS_PrintTestStatus("peeking after peeking after seeking", f.read() == '3');
+ ATS_PrintTestStatus("position after peeking after seeking", f.position() == 4);
+
+ f.seek(1);
+
+ ATS_PrintTestStatus("position after seeking", f.position() == 1);
+ ATS_PrintTestStatus("peeking after seeking", f.peek() == '1');
+
+ f.seek(4);
+
+ ATS_PrintTestStatus("position after seeking", f.position() == 4);
+ ATS_PrintTestStatus("peeking after seeking", f.peek() == '4');
+
+ f.seek(7);
+
+ ATS_PrintTestStatus("position()", f.position() == 7);
+ ATS_PrintTestStatus("read()", f.read() == '7');
+
+ f.seek(0);
+ f.peek();
+ f.print("AB");
+
+ ATS_PrintTestStatus("position()", f.position() == 2);
+ ATS_PrintTestStatus("size()", f.size() == 10);
+ ATS_PrintTestStatus("read()", f.read() == '2');
+
+ f.seek(0);
+
+ ATS_PrintTestStatus("read()", f.read() == 'A');
+ ATS_PrintTestStatus("read()", f.read() == 'B');
+ ATS_PrintTestStatus("read()", f.read() == '2');
+
+ f.close();
+
+ f = SD.open("test.txt");
+ ATS_PrintTestStatus("SD.open()", f);
+ if (!f) goto done;
+
+ ATS_PrintTestStatus("position()", f.position() == 0);
+ ATS_PrintTestStatus("size()", f.size() == 10);
+ ATS_PrintTestStatus("peek()", f.peek() == 'A');
+ ATS_PrintTestStatus("read()", f.read() == 'A');
+
+ f.seek(4);
+
+ ATS_PrintTestStatus("position()", f.position() == 4);
+ ATS_PrintTestStatus("size()", f.size() == 10);
+ ATS_PrintTestStatus("peek()", f.peek() == '4');
+ ATS_PrintTestStatus("read()", f.read() == '4');
+
+ f.close();
+
+done:
+ ATS_ReportMemoryUsage(startMemoryUsage);
+ ATS_end();
+
+}
+
+void loop() {}
diff --git a/libraries/SD/File.cpp b/libraries/SD/File.cpp
index d09bd8f85..ded622c85 100644
--- a/libraries/SD/File.cpp
+++ b/libraries/SD/File.cpp
@@ -27,30 +27,35 @@ void File::write(const uint8_t *buf, size_t size) {
}
int File::peek() {
- if (SD.c != -1) return SD.c;
- SD.c = SD.file.read();
- return SD.c;
+ char c = SD.file.read();
+ if (c != -1) SD.file.seekCur(-1);
+ return c;
}
int File::read() {
- if (SD.c != -1) {
- int tmp = SD.c;
- SD.c = -1;
- return tmp;
- }
return SD.file.read();
}
int File::available() {
- if (SD.c != -1) return 1;
- SD.c = SD.file.read();
- return SD.c != -1;
+ return size() - position();
}
void File::flush() {
SD.file.sync();
}
+boolean File::seek(uint32_t pos) {
+ return SD.file.seekSet(pos);
+}
+
+uint32_t File::position() {
+ return SD.file.curPosition();
+}
+
+uint32_t File::size() {
+ return SD.file.fileSize();
+}
+
void File::close() {
SD.file.close();
}
diff --git a/libraries/SD/SD.cpp b/libraries/SD/SD.cpp
index 356a2986a..aca7468dd 100644
--- a/libraries/SD/SD.cpp
+++ b/libraries/SD/SD.cpp
@@ -297,7 +297,9 @@ boolean callback_openPath(SdFile& parentDir, char *filePathComponent,
if (isLastComponent) {
SDClass *p_SD = static_cast(object);
p_SD->file.open(parentDir, filePathComponent, p_SD->fileOpenMode);
- p_SD->c = -1;
+ if (p_SD->fileOpenMode == FILE_WRITE) {
+ p_SD->file.seekSet(p_SD->file.fileSize());
+ }
// TODO: Return file open result?
return false;
}
diff --git a/libraries/SD/SD.h b/libraries/SD/SD.h
index d013bcfc5..2c5c323a8 100644
--- a/libraries/SD/SD.h
+++ b/libraries/SD/SD.h
@@ -21,8 +21,7 @@
#include
#define FILE_READ O_READ
-#define FILE_TRUNCATE (O_WRITE | O_CREAT | O_TRUNC)
-#define FILE_APPEND (O_WRITE | O_CREAT | O_APPEND)
+#define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_SYNC)
class File : public Stream {
public:
@@ -33,6 +32,9 @@ public:
virtual int peek();
virtual int available();
virtual void flush();
+ boolean seek(uint32_t pos);
+ uint32_t position();
+ uint32_t size();
void close();
operator bool();
};
@@ -77,8 +79,6 @@ private:
// It shouldn't be set directly--it is set via the parameters to `open`.
int fileOpenMode;
- int c;
-
friend class File;
friend boolean callback_openPath(SdFile&, char *, boolean, void *);
};
diff --git a/libraries/SD/examples/Datalogger/Datalogger.pde b/libraries/SD/examples/Datalogger/Datalogger.pde
index fd946163f..73d81af7b 100644
--- a/libraries/SD/examples/Datalogger/Datalogger.pde
+++ b/libraries/SD/examples/Datalogger/Datalogger.pde
@@ -59,8 +59,9 @@ void loop()
}
}
- // open the file:
- File dataFile = SD.open("datalog.txt", FILE_APPEND);
+ // open the file. note that only one file can be open at a time,
+ // so you have to close this one before opening another.
+ File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
diff --git a/libraries/SD/examples/DumpFile/DumpFile.pde b/libraries/SD/examples/DumpFile/DumpFile.pde
new file mode 100644
index 000000000..961717fc9
--- /dev/null
+++ b/libraries/SD/examples/DumpFile/DumpFile.pde
@@ -0,0 +1,64 @@
+/*
+ SD card file dump
+
+ This example shows how to read a file from the SD card using the
+ SD library and send it over the serial port.
+
+ The circuit:
+ * SD card attached to SPI bus as follows:
+ ** MOSI - pin 11
+ ** MISO - pin 12
+ ** CLK - pin 13
+ ** CS - pin 4
+
+ created 22 December 2010
+
+ This example code is in the public domain.
+
+ */
+
+#include
+
+// On the Ethernet Shield, CS is pin 4. Note that even if it's not
+// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
+// 53 on the Mega) must be left as an output or the SD library
+// functions will not work.
+const int chipSelect = 4;
+
+void setup()
+{
+ Serial.begin(9600);
+ Serial.print("Initializing SD card...");
+ // make sure that the default chip select pin is set to
+ // output, even if you don't use it:
+ pinMode(10, OUTPUT);
+
+ // see if the card is present and can be initialized:
+ if (!SD.begin(chipSelect)) {
+ Serial.println("Card failed, or not present");
+ // don't do anything more:
+ return;
+ }
+ Serial.println("card initialized.");
+
+ // open the file. note that only one file can be open at a time,
+ // so you have to close this one before opening another.
+ File dataFile = SD.open("datalog.txt");
+
+ // if the file is available, write to it:
+ if (dataFile) {
+ while (dataFile.available()) {
+ Serial.write(dataFile.read());
+ }
+ dataFile.close();
+ }
+ // if the file isn't open, pop up an error:
+ else {
+ Serial.println("error opening datalog.txt");
+ }
+}
+
+void loop()
+{
+}
+
diff --git a/libraries/SD/examples/Files/Files.pde b/libraries/SD/examples/Files/Files.pde
index 5b6791f6b..5ed9fea4e 100644
--- a/libraries/SD/examples/Files/Files.pde
+++ b/libraries/SD/examples/Files/Files.pde
@@ -46,7 +46,7 @@ void setup()
// open a new file and immediately close it:
Serial.println("Creating example.txt...");
- myFile = SD.open("example.txt", FILE_TRUNCATE);
+ myFile = SD.open("example.txt", FILE_WRITE);
myFile.close();
// Check to see if the file exists:
diff --git a/libraries/SD/examples/ReadWrite/ReadWrite.pde b/libraries/SD/examples/ReadWrite/ReadWrite.pde
index 668fb0b6b..995721800 100644
--- a/libraries/SD/examples/ReadWrite/ReadWrite.pde
+++ b/libraries/SD/examples/ReadWrite/ReadWrite.pde
@@ -38,8 +38,9 @@ void setup()
}
Serial.println("initialization done.");
- // open a file:
- myFile = SD.open("test.txt", FILE_TRUNCATE);
+ // open the file. note that only one file can be open at a time,
+ // so you have to close this one before opening another.
+ myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
diff --git a/libraries/SD/keywords.txt b/libraries/SD/keywords.txt
index 232466ad0..419fe04d5 100644
--- a/libraries/SD/keywords.txt
+++ b/libraries/SD/keywords.txt
@@ -19,11 +19,12 @@ remove KEYWORD2
rmdir KEYWORD2
open KEYWORD2
close KEYWORD2
-
+seek KEYWORD2
+position KEYWORD2
+size KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
FILE_READ LITERAL1
-FILE_TRUNCATE LITERAL1
-FILE_APPEND LITERAL1
+FILE_WRITE LITERAL1