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