]> Zhao Yanbai Git Server - acecode.git/commitdiff
...
authorAceVest <zhaoyanbai@126.com>
Mon, 18 Jun 2018 07:45:39 +0000 (15:45 +0800)
committerAceVest <zhaoyanbai@126.com>
Mon, 18 Jun 2018 07:45:39 +0000 (15:45 +0800)
15 files changed:
arduino/hardware/ace/avr/cores/avr/AceAvr.h
arduino/hardware/ace/avr/cores/avr/HardwareSerial.cpp [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/HardwareSerial.h [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/HardwareSerial0.cpp [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/HardwareSerial_private.h [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/PluggableUSB.h [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/Print.cpp [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/Print.h [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/Printable.h [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/Stream.cpp [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/Stream.h [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/WString.cpp [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/WString.h [new file with mode: 0644]
arduino/hardware/ace/avr/cores/avr/kernel.cpp
arduino/hardware/ace/avr/cores/avr/timer.cpp

index c2a676d844bf8e418140628315b69fa6ede168e6..9324addd7016b0d072a4f1c0ad070ada9034c90f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <stdint.h>
 #include <avr/pgmspace.h>
+#include <avr/interrupt.h>
 
 #define LOW  0
 #define HIGH 1
@@ -39,12 +40,25 @@ void acevest();
 #error "did not define F_CPU"
 #endif
 #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
+#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
+#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
+#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
+#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
+#define FRACT_MAX (1000 >> 3)
+
 
 #define cli()  __asm__ __volatile__ ("cli" ::: "memory")
 #define sei()  __asm__ __volatile__ ("sei" ::: "memory")
 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
 
 
+#ifndef cbi
+#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+#endif
+#ifndef sbi
+#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#endif
+
 const uint8_t PA = 1;
 const uint8_t PB = 2;
 const uint8_t PC = 3;
@@ -61,3 +75,8 @@ void set_digital_pin_mode(uint8_t pin, uint8_t mode);
 void digital_write(uint8_t pin, uint8_t val);
 void yield(void);
 
+unsigned long millis();
+
+
+typedef bool boolean;
+typedef uint8_t byte;
diff --git a/arduino/hardware/ace/avr/cores/avr/HardwareSerial.cpp b/arduino/hardware/ace/avr/cores/avr/HardwareSerial.cpp
new file mode 100644 (file)
index 0000000..5cd89e5
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+  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
+  Modified 28 September 2010 by Mark Sproul
+  Modified 14 August 2012 by Alarus
+  Modified 3 December 2013 by Matthijs Kooijman
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include "Arduino.h"
+
+#include "HardwareSerial.h"
+#include "HardwareSerial_private.h"
+
+// this next line disables the entire HardwareSerial.cpp, 
+// this is so I can support Attiny series and any other chip without a uart
+#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3)
+
+// SerialEvent functions are weak, so when the user doesn't define them,
+// the linker just sets their address to 0 (which is checked below).
+// The Serialx_available is just a wrapper around Serialx.available(),
+// but we can refer to it weakly so we don't pull in the entire
+// HardwareSerial instance if the user doesn't also refer to it.
+#if defined(HAVE_HWSERIAL0)
+  void serialEvent() __attribute__((weak));
+  bool Serial0_available() __attribute__((weak));
+#endif
+
+#if defined(HAVE_HWSERIAL1)
+  void serialEvent1() __attribute__((weak));
+  bool Serial1_available() __attribute__((weak));
+#endif
+
+#if defined(HAVE_HWSERIAL2)
+  void serialEvent2() __attribute__((weak));
+  bool Serial2_available() __attribute__((weak));
+#endif
+
+#if defined(HAVE_HWSERIAL3)
+  void serialEvent3() __attribute__((weak));
+  bool Serial3_available() __attribute__((weak));
+#endif
+
+void serialEventRun(void)
+{
+#if defined(HAVE_HWSERIAL0)
+  if (Serial0_available && serialEvent && Serial0_available()) serialEvent();
+#endif
+#if defined(HAVE_HWSERIAL1)
+  if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1();
+#endif
+#if defined(HAVE_HWSERIAL2)
+  if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2();
+#endif
+#if defined(HAVE_HWSERIAL3)
+  if (Serial3_available && serialEvent3 && Serial3_available()) serialEvent3();
+#endif
+}
+
+// Actual interrupt handlers //////////////////////////////////////////////////////////////
+
+void HardwareSerial::_tx_udr_empty_irq(void)
+{
+  // If interrupts are enabled, there must be more data in the output
+  // buffer. Send the next byte
+  unsigned char c = _tx_buffer[_tx_buffer_tail];
+  _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;
+
+  *_udr = c;
+
+  // clear the TXC bit -- "can be cleared by writing a one to its bit
+  // location". This makes sure flush() won't return until the bytes
+  // actually got written
+  sbi(*_ucsra, TXC0);
+
+  if (_tx_buffer_head == _tx_buffer_tail) {
+    // Buffer empty, so disable interrupts
+    cbi(*_ucsrb, UDRIE0);
+  }
+}
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+void HardwareSerial::begin(unsigned long baud, byte config)
+{
+  // Try u2x mode first
+  uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;
+  *_ucsra = 1 << U2X0;
+
+  // hardcoded exception for 57600 for compatibility with the bootloader
+  // shipped with the Duemilanove and previous boards and the firmware
+  // on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
+  // be > 4095, so switch back to non-u2x mode if the baud rate is too
+  // low.
+  if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
+  {
+    *_ucsra = 0;
+    baud_setting = (F_CPU / 8 / baud - 1) / 2;
+  }
+
+  // assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register)
+  *_ubrrh = baud_setting >> 8;
+  *_ubrrl = baud_setting;
+
+  _written = false;
+
+  //set the data bits, parity, and stop bits
+#if defined(__AVR_ATmega8__)
+  config |= 0x80; // select UCSRC register (shared with UBRRH)
+#endif
+  *_ucsrc = config;
+  
+  sbi(*_ucsrb, RXEN0);
+  sbi(*_ucsrb, TXEN0);
+  sbi(*_ucsrb, RXCIE0);
+  cbi(*_ucsrb, UDRIE0);
+}
+
+void HardwareSerial::end()
+{
+  // wait for transmission of outgoing data
+  flush();
+
+  cbi(*_ucsrb, RXEN0);
+  cbi(*_ucsrb, TXEN0);
+  cbi(*_ucsrb, RXCIE0);
+  cbi(*_ucsrb, UDRIE0);
+  
+  // clear any received data
+  _rx_buffer_head = _rx_buffer_tail;
+}
+
+int HardwareSerial::available(void)
+{
+  return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
+}
+
+int HardwareSerial::peek(void)
+{
+  if (_rx_buffer_head == _rx_buffer_tail) {
+    return -1;
+  } else {
+    return _rx_buffer[_rx_buffer_tail];
+  }
+}
+
+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[_rx_buffer_tail];
+    _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
+    return c;
+  }
+}
+
+int HardwareSerial::availableForWrite(void)
+{
+#if (SERIAL_TX_BUFFER_SIZE>256)
+  uint8_t oldSREG = SREG;
+  cli();
+#endif
+  tx_buffer_index_t head = _tx_buffer_head;
+  tx_buffer_index_t tail = _tx_buffer_tail;
+#if (SERIAL_TX_BUFFER_SIZE>256)
+  SREG = oldSREG;
+#endif
+  if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
+  return tail - head - 1;
+}
+
+void HardwareSerial::flush()
+{
+  // If we have never written a byte, no need to flush. This special
+  // case is needed since there is no way to force the TXC (transmit
+  // complete) bit to 1 during initialization
+  if (!_written)
+    return;
+
+  while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) {
+    if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0))
+       // Interrupts are globally disabled, but the DR empty
+       // interrupt should be enabled, so poll the DR empty flag to
+       // prevent deadlock
+       if (bit_is_set(*_ucsra, UDRE0))
+         _tx_udr_empty_irq();
+  }
+  // If we get here, nothing is queued anymore (DRIE is disabled) and
+  // the hardware finished tranmission (TXC is set).
+}
+
+size_t HardwareSerial::write(uint8_t c)
+{
+  _written = true;
+  // If the buffer and the data register is empty, just write the byte
+  // to the data register and be done. This shortcut helps
+  // significantly improve the effective datarate at high (>
+  // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
+  if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
+    *_udr = c;
+    sbi(*_ucsra, TXC0);
+    return 1;
+  }
+  tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
+       
+  // If the output buffer is full, there's nothing for it other than to 
+  // wait for the interrupt handler to empty it a bit
+  while (i == _tx_buffer_tail) {
+    if (bit_is_clear(SREG, SREG_I)) {
+      // Interrupts are disabled, so we'll have to poll the data
+      // register empty flag ourselves. If it is set, pretend an
+      // interrupt has happened and call the handler to free up
+      // space for us.
+      if(bit_is_set(*_ucsra, UDRE0))
+       _tx_udr_empty_irq();
+    } else {
+      // nop, the interrupt handler will free up space for us
+    }
+  }
+
+  _tx_buffer[_tx_buffer_head] = c;
+  _tx_buffer_head = i;
+       
+  sbi(*_ucsrb, UDRIE0);
+  
+  return 1;
+}
+
+#endif // whole file
diff --git a/arduino/hardware/ace/avr/cores/avr/HardwareSerial.h b/arduino/hardware/ace/avr/cores/avr/HardwareSerial.h
new file mode 100644 (file)
index 0000000..e6b8ef5
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+  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
+
+  Modified 28 September 2010 by Mark Sproul
+  Modified 14 August 2012 by Alarus
+  Modified 3 December 2013 by Matthijs Kooijman
+*/
+
+#ifndef HardwareSerial_h
+#define HardwareSerial_h
+
+#include <inttypes.h>
+
+#include "Stream.h"
+
+// Define constants and variables for buffering incoming serial data.  We're
+// using a ring buffer (I think), in which head is the index of the location
+// to which to write the next incoming character and tail is the index of the
+// location from which to read.
+// NOTE: a "power of 2" buffer size is reccomended to dramatically
+//       optimize all the modulo operations for ring buffers.
+// WARNING: When buffer sizes are increased to > 256, the buffer index
+// variables are automatically increased in size, but the extra
+// atomicity guards needed for that are not implemented. This will
+// often work, but occasionally a race condition can occur that makes
+// Serial behave erratically. See https://github.com/arduino/Arduino/issues/2405
+#if !defined(SERIAL_TX_BUFFER_SIZE)
+#if ((RAMEND - RAMSTART) < 1023)
+#define SERIAL_TX_BUFFER_SIZE 16
+#else
+#define SERIAL_TX_BUFFER_SIZE 64
+#endif
+#endif
+#if !defined(SERIAL_RX_BUFFER_SIZE)
+#if ((RAMEND - RAMSTART) < 1023)
+#define SERIAL_RX_BUFFER_SIZE 16
+#else
+#define SERIAL_RX_BUFFER_SIZE 64
+#endif
+#endif
+#if (SERIAL_TX_BUFFER_SIZE>256)
+typedef uint16_t tx_buffer_index_t;
+#else
+typedef uint8_t tx_buffer_index_t;
+#endif
+#if  (SERIAL_RX_BUFFER_SIZE>256)
+typedef uint16_t rx_buffer_index_t;
+#else
+typedef uint8_t rx_buffer_index_t;
+#endif
+
+// Define config for Serial.begin(baud, config);
+#define SERIAL_5N1 0x00
+#define SERIAL_6N1 0x02
+#define SERIAL_7N1 0x04
+#define SERIAL_8N1 0x06
+#define SERIAL_5N2 0x08
+#define SERIAL_6N2 0x0A
+#define SERIAL_7N2 0x0C
+#define SERIAL_8N2 0x0E
+#define SERIAL_5E1 0x20
+#define SERIAL_6E1 0x22
+#define SERIAL_7E1 0x24
+#define SERIAL_8E1 0x26
+#define SERIAL_5E2 0x28
+#define SERIAL_6E2 0x2A
+#define SERIAL_7E2 0x2C
+#define SERIAL_8E2 0x2E
+#define SERIAL_5O1 0x30
+#define SERIAL_6O1 0x32
+#define SERIAL_7O1 0x34
+#define SERIAL_8O1 0x36
+#define SERIAL_5O2 0x38
+#define SERIAL_6O2 0x3A
+#define SERIAL_7O2 0x3C
+#define SERIAL_8O2 0x3E
+
+class HardwareSerial : public Stream
+{
+  protected:
+    volatile uint8_t * const _ubrrh;
+    volatile uint8_t * const _ubrrl;
+    volatile uint8_t * const _ucsra;
+    volatile uint8_t * const _ucsrb;
+    volatile uint8_t * const _ucsrc;
+    volatile uint8_t * const _udr;
+    // Has any byte been written to the UART since begin()
+    bool _written;
+
+    volatile rx_buffer_index_t _rx_buffer_head;
+    volatile rx_buffer_index_t _rx_buffer_tail;
+    volatile tx_buffer_index_t _tx_buffer_head;
+    volatile tx_buffer_index_t _tx_buffer_tail;
+
+    // Don't put any members after these buffers, since only the first
+    // 32 bytes of this struct can be accessed quickly using the ldd
+    // instruction.
+    unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
+    unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
+
+  public:
+    inline HardwareSerial(
+      volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
+      volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
+      volatile uint8_t *ucsrc, volatile uint8_t *udr);
+    void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
+    void begin(unsigned long, uint8_t);
+    void end();
+    virtual int available(void);
+    virtual int peek(void);
+    virtual int read(void);
+    virtual int availableForWrite(void);
+    virtual void flush(void);
+    virtual size_t write(uint8_t);
+    inline size_t write(unsigned long n) { return write((uint8_t)n); }
+    inline size_t write(long n) { return write((uint8_t)n); }
+    inline size_t write(unsigned int n) { return write((uint8_t)n); }
+    inline size_t write(int n) { return write((uint8_t)n); }
+    using Print::write; // pull in write(str) and write(buf, size) from Print
+    operator bool() { return true; }
+
+    // Interrupt handlers - Not intended to be called externally
+    inline void _rx_complete_irq(void);
+    void _tx_udr_empty_irq(void);
+};
+
+#if defined(UBRRH) || defined(UBRR0H)
+  extern HardwareSerial Serial;
+  #define HAVE_HWSERIAL0
+#endif
+
+extern void serialEventRun(void) __attribute__((weak));
+
+#endif
diff --git a/arduino/hardware/ace/avr/cores/avr/HardwareSerial0.cpp b/arduino/hardware/ace/avr/cores/avr/HardwareSerial0.cpp
new file mode 100644 (file)
index 0000000..1146eeb
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+  HardwareSerial0.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
+  Modified 28 September 2010 by Mark Sproul
+  Modified 14 August 2012 by Alarus
+  Modified 3 December 2013 by Matthijs Kooijman
+*/
+
+#include "Arduino.h"
+#include "HardwareSerial.h"
+#include "HardwareSerial_private.h"
+
+// Each HardwareSerial is defined in its own file, sine the linker pulls
+// in the entire file when any element inside is used. --gc-sections can
+// additionally cause unused symbols to be dropped, but ISRs have the
+// "used" attribute so are never dropped and they keep the
+// HardwareSerial instance in as well. Putting each instance in its own
+// file prevents the linker from pulling in any unused instances in the
+// first place.
+
+#if defined(HAVE_HWSERIAL0)
+
+#if defined(USART_RX_vect)
+  ISR(USART_RX_vect)
+#elif defined(USART0_RX_vect)
+  ISR(USART0_RX_vect)
+#elif defined(USART_RXC_vect)
+  ISR(USART_RXC_vect) // ATmega8
+#else
+  #error "Don't know what the Data Received vector is called for Serial"
+#endif
+  {
+    Serial._rx_complete_irq();
+  }
+
+#if defined(UART0_UDRE_vect)
+ISR(UART0_UDRE_vect)
+#elif defined(UART_UDRE_vect)
+ISR(UART_UDRE_vect)
+#elif defined(USART0_UDRE_vect)
+ISR(USART0_UDRE_vect)
+#elif defined(USART_UDRE_vect)
+ISR(USART_UDRE_vect)
+#else
+  #error "Don't know what the Data Register Empty vector is called for Serial"
+#endif
+{
+  Serial._tx_udr_empty_irq();
+}
+
+#if defined(UBRRH) && defined(UBRRL)
+  HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);
+#else
+  HardwareSerial Serial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0);
+#endif
+
+// Function that can be weakly referenced by serialEventRun to prevent
+// pulling in this file if it's not otherwise used.
+bool Serial0_available() {
+  return Serial.available();
+}
+
+#endif // HAVE_HWSERIAL0
diff --git a/arduino/hardware/ace/avr/cores/avr/HardwareSerial_private.h b/arduino/hardware/ace/avr/cores/avr/HardwareSerial_private.h
new file mode 100644 (file)
index 0000000..259c3d1
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+  HardwareSerial_private.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
+
+  Modified 23 November 2006 by David A. Mellis
+  Modified 28 September 2010 by Mark Sproul
+  Modified 14 August 2012 by Alarus
+*/
+
+#include "AceAvr.h"
+
+// this next line disables the entire HardwareSerial.cpp, 
+// this is so I can support Attiny series and any other chip without a uart
+#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3)
+
+// Ensure that the various bit positions we use are available with a 0
+// postfix, so we can always use the values for UART0 for all UARTs. The
+// alternative, passing the various values for each UART to the
+// HardwareSerial constructor also works, but makes the code bigger and
+// slower.
+#if !defined(TXC0)
+#if defined(TXC)
+// Some chips like ATmega8 don't have UPE, only PE. The other bits are
+// named as expected.
+#if !defined(UPE) && defined(PE)
+#define UPE PE
+#endif
+// On ATmega8, the uart and its bits are not numbered, so there is no TXC0 etc.
+#define TXC0 TXC
+#define RXEN0 RXEN
+#define TXEN0 TXEN
+#define RXCIE0 RXCIE
+#define UDRIE0 UDRIE
+#define U2X0 U2X
+#define UPE0 UPE
+#define UDRE0 UDRE
+#elif defined(TXC1)
+// Some devices have uart1 but no uart0
+#define TXC0 TXC1
+#define RXEN0 RXEN1
+#define TXEN0 TXEN1
+#define RXCIE0 RXCIE1
+#define UDRIE0 UDRIE1
+#define U2X0 U2X1
+#define UPE0 UPE1
+#define UDRE0 UDRE1
+#else
+#error No UART found in HardwareSerial.cpp
+#endif
+#endif // !defined TXC0
+
+// Check at compiletime that it is really ok to use the bit positions of
+// UART0 for the other UARTs as well, in case these values ever get
+// changed for future hardware.
+#if defined(TXC1) && (TXC1 != TXC0 || RXEN1 != RXEN0 || RXCIE1 != RXCIE0 || \
+                     UDRIE1 != UDRIE0 || U2X1 != U2X0 || UPE1 != UPE0 || \
+                     UDRE1 != UDRE0)
+#error "Not all bit positions for UART1 are the same as for UART0"
+#endif
+#if defined(TXC2) && (TXC2 != TXC0 || RXEN2 != RXEN0 || RXCIE2 != RXCIE0 || \
+                     UDRIE2 != UDRIE0 || U2X2 != U2X0 || UPE2 != UPE0 || \
+                     UDRE2 != UDRE0)
+#error "Not all bit positions for UART2 are the same as for UART0"
+#endif
+#if defined(TXC3) && (TXC3 != TXC0 || RXEN3 != RXEN0 || RXCIE3 != RXCIE0 || \
+                     UDRIE3 != UDRIE0 || U3X3 != U3X0 || UPE3 != UPE0 || \
+                     UDRE3 != UDRE0)
+#error "Not all bit positions for UART3 are the same as for UART0"
+#endif
+
+// Constructors ////////////////////////////////////////////////////////////////
+
+HardwareSerial::HardwareSerial(
+  volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
+  volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
+  volatile uint8_t *ucsrc, volatile uint8_t *udr) :
+    _ubrrh(ubrrh), _ubrrl(ubrrl),
+    _ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc),
+    _udr(udr),
+    _rx_buffer_head(0), _rx_buffer_tail(0),
+    _tx_buffer_head(0), _tx_buffer_tail(0)
+{
+}
+
+// Actual interrupt handlers //////////////////////////////////////////////////////////////
+
+void HardwareSerial::_rx_complete_irq(void)
+{
+  if (bit_is_clear(*_ucsra, UPE0)) {
+    // No Parity error, read byte and store it in the buffer if there is
+    // room
+    unsigned char c = *_udr;
+    rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_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[_rx_buffer_head] = c;
+      _rx_buffer_head = i;
+    }
+  } else {
+    // Parity error, read byte but discard it
+    *_udr;
+  };
+}
+
+#endif // whole file
diff --git a/arduino/hardware/ace/avr/cores/avr/PluggableUSB.h b/arduino/hardware/ace/avr/cores/avr/PluggableUSB.h
new file mode 100644 (file)
index 0000000..507f0df
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+  PluggableUSB.h
+  Copyright (c) 2015 Arduino LLC
+
+  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 PUSB_h
+#define PUSB_h
+
+#include "USBAPI.h"
+#include <stdint.h>
+
+#if defined(USBCON)
+
+class PluggableUSBModule {
+public:
+  PluggableUSBModule(uint8_t numEps, uint8_t numIfs, uint8_t *epType) :
+    numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
+  { }
+
+protected:
+  virtual bool setup(USBSetup& setup) = 0;
+  virtual int getInterface(uint8_t* interfaceCount) = 0;
+  virtual int getDescriptor(USBSetup& setup) = 0;
+  virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; }
+
+  uint8_t pluggedInterface;
+  uint8_t pluggedEndpoint;
+
+  const uint8_t numEndpoints;
+  const uint8_t numInterfaces;
+  const uint8_t *endpointType;
+
+  PluggableUSBModule *next = NULL;
+
+  friend class PluggableUSB_;
+};
+
+class PluggableUSB_ {
+public:
+  PluggableUSB_();
+  bool plug(PluggableUSBModule *node);
+  int getInterface(uint8_t* interfaceCount);
+  int getDescriptor(USBSetup& setup);
+  bool setup(USBSetup& setup);
+  void getShortName(char *iSerialNum);
+
+private:
+  uint8_t lastIf;
+  uint8_t lastEp;
+  PluggableUSBModule* rootNode;
+};
+
+// Replacement for global singleton.
+// This function prevents static-initialization-order-fiasco
+// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
+PluggableUSB_& PluggableUSB();
+
+#endif
+
+#endif
diff --git a/arduino/hardware/ace/avr/cores/avr/Print.cpp b/arduino/hardware/ace/avr/cores/avr/Print.cpp
new file mode 100644 (file)
index 0000000..1e4c99a
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ 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
+ Modified 03 August 2015 by Chuck Todd
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "Arduino.h"
+
+#include "Print.h"
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+/* default implementation: may be overridden */
+size_t Print::write(const uint8_t *buffer, size_t size)
+{
+  size_t n = 0;
+  while (size--) {
+    if (write(*buffer++)) n++;
+    else break;
+  }
+  return n;
+}
+
+size_t Print::print(const __FlashStringHelper *ifsh)
+{
+  PGM_P p = reinterpret_cast<PGM_P>(ifsh);
+  size_t n = 0;
+  while (1) {
+    unsigned char c = pgm_read_byte(p++);
+    if (c == 0) break;
+    if (write(c)) n++;
+    else break;
+  }
+  return n;
+}
+
+size_t Print::print(const String &s)
+{
+  return write(s.c_str(), s.length());
+}
+
+size_t Print::print(const char str[])
+{
+  return write(str);
+}
+
+size_t Print::print(char c)
+{
+  return write(c);
+}
+
+size_t Print::print(unsigned char b, int base)
+{
+  return print((unsigned long) b, base);
+}
+
+size_t Print::print(int n, int base)
+{
+  return print((long) n, base);
+}
+
+size_t Print::print(unsigned int n, int base)
+{
+  return print((unsigned long) n, base);
+}
+
+size_t Print::print(long n, int base)
+{
+  if (base == 0) {
+    return write(n);
+  } else if (base == 10) {
+    if (n < 0) {
+      int t = print('-');
+      n = -n;
+      return printNumber(n, 10) + t;
+    }
+    return printNumber(n, 10);
+  } else {
+    return printNumber(n, base);
+  }
+}
+
+size_t Print::print(unsigned long n, int base)
+{
+  if (base == 0) return write(n);
+  else return printNumber(n, base);
+}
+
+size_t Print::print(double n, int digits)
+{
+  return printFloat(n, digits);
+}
+
+size_t Print::println(const __FlashStringHelper *ifsh)
+{
+  size_t n = print(ifsh);
+  n += println();
+  return n;
+}
+
+size_t Print::print(const Printable& x)
+{
+  return x.printTo(*this);
+}
+
+size_t Print::println(void)
+{
+  return write("\r\n");
+}
+
+size_t Print::println(const String &s)
+{
+  size_t n = print(s);
+  n += println();
+  return n;
+}
+
+size_t Print::println(const char c[])
+{
+  size_t n = print(c);
+  n += println();
+  return n;
+}
+
+size_t Print::println(char c)
+{
+  size_t n = print(c);
+  n += println();
+  return n;
+}
+
+size_t Print::println(unsigned char b, int base)
+{
+  size_t n = print(b, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(int num, int base)
+{
+  size_t n = print(num, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(unsigned int num, int base)
+{
+  size_t n = print(num, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(long num, int base)
+{
+  size_t n = print(num, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(unsigned long num, int base)
+{
+  size_t n = print(num, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(double num, int digits)
+{
+  size_t n = print(num, digits);
+  n += println();
+  return n;
+}
+
+size_t Print::println(const Printable& x)
+{
+  size_t n = print(x);
+  n += println();
+  return n;
+}
+
+// Private Methods /////////////////////////////////////////////////////////////
+
+size_t Print::printNumber(unsigned long n, uint8_t base)
+{
+  char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
+  char *str = &buf[sizeof(buf) - 1];
+
+  *str = '\0';
+
+  // prevent crash if called with base == 1
+  if (base < 2) base = 10;
+
+  do {
+    char c = n % base;
+    n /= base;
+
+    *--str = c < 10 ? c + '0' : c + 'A' - 10;
+  } while(n);
+
+  return write(str);
+}
+
+size_t Print::printFloat(double number, uint8_t digits) 
+{ 
+  size_t n = 0;
+  
+  if (isnan(number)) return print("nan");
+  if (isinf(number)) return print("inf");
+  if (number > 4294967040.0) return print ("ovf");  // constant determined empirically
+  if (number <-4294967040.0) return print ("ovf");  // constant determined empirically
+  
+  // Handle negative numbers
+  if (number < 0.0)
+  {
+     n += 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;
+  n += print(int_part);
+
+  // Print the decimal point, but only if there are digits beyond
+  if (digits > 0) {
+    n += print('.'); 
+  }
+
+  // Extract digits from the remainder one at a time
+  while (digits-- > 0)
+  {
+    remainder *= 10.0;
+    unsigned int toPrint = (unsigned int)(remainder);
+    n += print(toPrint);
+    remainder -= toPrint; 
+  } 
+  
+  return n;
+}
diff --git a/arduino/hardware/ace/avr/cores/avr/Print.h b/arduino/hardware/ace/avr/cores/avr/Print.h
new file mode 100644 (file)
index 0000000..058a2ab
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+  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
+
+#include "WString.h"
+#include "Printable.h"
+
+#define DEC 10
+#define HEX 16
+#define OCT 8
+#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar
+#undef BIN
+#endif
+#define BIN 2
+
+class Print
+{
+  private:
+    int write_error;
+    size_t printNumber(unsigned long, uint8_t);
+    size_t printFloat(double, uint8_t);
+  protected:
+    void setWriteError(int err = 1) { write_error = err; }
+  public:
+    Print() : write_error(0) {}
+  
+    int getWriteError() { return write_error; }
+    void clearWriteError() { setWriteError(0); }
+  
+    virtual size_t write(uint8_t) = 0;
+    size_t write(const char *str) {
+      if (str == NULL) return 0;
+      return write((const uint8_t *)str, strlen(str));
+    }
+    virtual size_t write(const uint8_t *buffer, size_t size);
+    size_t write(const char *buffer, size_t size) {
+      return write((const uint8_t *)buffer, size);
+    }
+
+    // default to zero, meaning "a single write may block"
+    // should be overriden by subclasses with buffering
+    virtual int availableForWrite() { return 0; }
+
+    size_t print(const __FlashStringHelper *);
+    size_t print(const String &);
+    size_t print(const char[]);
+    size_t print(char);
+    size_t print(unsigned char, int = DEC);
+    size_t print(int, int = DEC);
+    size_t print(unsigned int, int = DEC);
+    size_t print(long, int = DEC);
+    size_t print(unsigned long, int = DEC);
+    size_t print(double, int = 2);
+    size_t print(const Printable&);
+
+    size_t println(const __FlashStringHelper *);
+    size_t println(const String &s);
+    size_t println(const char[]);
+    size_t println(char);
+    size_t println(unsigned char, int = DEC);
+    size_t println(int, int = DEC);
+    size_t println(unsigned int, int = DEC);
+    size_t println(long, int = DEC);
+    size_t println(unsigned long, int = DEC);
+    size_t println(double, int = 2);
+    size_t println(const Printable&);
+    size_t println(void);
+
+    virtual void flush() { /* Empty implementation for backward compatibility */ }
+};
+
+#endif
diff --git a/arduino/hardware/ace/avr/cores/avr/Printable.h b/arduino/hardware/ace/avr/cores/avr/Printable.h
new file mode 100644 (file)
index 0000000..2a1b2e9
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+  Printable.h - Interface class that allows printing of complex types
+  Copyright (c) 2011 Adrian McEwen.  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 Printable_h
+#define Printable_h
+
+#include <stdlib.h>
+
+class Print;
+
+/** The Printable class provides a way for new classes to allow themselves to be printed.
+    By deriving from Printable and implementing the printTo method, it will then be possible
+    for users to print out instances of this class by passing them into the usual
+    Print::print and Print::println methods.
+*/
+
+class Printable
+{
+  public:
+    virtual size_t printTo(Print& p) const = 0;
+};
+
+#endif
+
diff --git a/arduino/hardware/ace/avr/cores/avr/Stream.cpp b/arduino/hardware/ace/avr/cores/avr/Stream.cpp
new file mode 100644 (file)
index 0000000..d284631
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ Stream.cpp - adds parsing methods to Stream class
+ 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
+
+ Created July 2011
+ parsing functions based on TextFinder library by Michael Margolis
+
+ findMulti/findUntil routines written by Jim Leonard/Xuth
+ */
+
+#include "Arduino.h"
+#include "Stream.h"
+
+#define PARSE_TIMEOUT 1000  // default number of milli-seconds to wait
+
+// protected method to read stream with timeout
+int Stream::timedRead()
+{
+  int c;
+  _startMillis = millis();
+  do {
+    c = read();
+    if (c >= 0) return c;
+  } while(millis() - _startMillis < _timeout);
+  return -1;     // -1 indicates timeout
+}
+
+// protected method to peek stream with timeout
+int Stream::timedPeek()
+{
+  int c;
+  _startMillis = millis();
+  do {
+    c = peek();
+    if (c >= 0) return c;
+  } while(millis() - _startMillis < _timeout);
+  return -1;     // -1 indicates timeout
+}
+
+// returns peek of the next digit in the stream or -1 if timeout
+// discards non-numeric characters
+int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
+{
+  int c;
+  while (1) {
+    c = timedPeek();
+
+    if( c < 0 ||
+        c == '-' ||
+        (c >= '0' && c <= '9') ||
+        (detectDecimal && c == '.')) return c;
+
+    switch( lookahead ){
+        case SKIP_NONE: return -1; // Fail code.
+        case SKIP_WHITESPACE:
+            switch( c ){
+                case ' ':
+                case '\t':
+                case '\r':
+                case '\n': break;
+                default: return -1; // Fail code.
+            }
+        case SKIP_ALL:
+            break;
+    }
+    read();  // discard non-numeric
+  }
+}
+
+// Public Methods
+//////////////////////////////////////////////////////////////
+
+void Stream::setTimeout(unsigned long timeout)  // sets the maximum number of milliseconds to wait
+{
+  _timeout = timeout;
+}
+
+ // find returns true if the target string is found
+bool  Stream::find(char *target)
+{
+  return findUntil(target, strlen(target), NULL, 0);
+}
+
+// reads data from the stream until the target string of given length is found
+// returns true if target string is found, false if timed out
+bool Stream::find(char *target, size_t length)
+{
+  return findUntil(target, length, NULL, 0);
+}
+
+// as find but search ends if the terminator string is found
+bool  Stream::findUntil(char *target, char *terminator)
+{
+  return findUntil(target, strlen(target), terminator, strlen(terminator));
+}
+
+// reads data from the stream until the target string of the given length is found
+// search terminated if the terminator string is found
+// returns true if target string is found, false if terminated or timed out
+bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
+{
+  if (terminator == NULL) {
+    MultiTarget t[1] = {{target, targetLen, 0}};
+    return findMulti(t, 1) == 0 ? true : false;
+  } else {
+    MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
+    return findMulti(t, 2) == 0 ? true : false;
+  }
+}
+
+// returns the first valid (long) integer value from the current position.
+// lookahead determines how parseInt looks ahead in the stream.
+// See LookaheadMode enumeration at the top of the file.
+// Lookahead is terminated by the first character that is not a valid part of an integer.
+// Once parsing commences, 'ignore' will be skipped in the stream.
+long Stream::parseInt(LookaheadMode lookahead, char ignore)
+{
+  bool isNegative = false;
+  long value = 0;
+  int c;
+
+  c = peekNextDigit(lookahead, false);
+  // ignore non numeric leading characters
+  if(c < 0)
+    return 0; // zero returned if timeout
+
+  do{
+    if(c == ignore)
+      ; // ignore this character
+    else if(c == '-')
+      isNegative = true;
+    else if(c >= '0' && c <= '9')        // is c a digit?
+      value = value * 10 + c - '0';
+    read();  // consume the character we got with peek
+    c = timedPeek();
+  }
+  while( (c >= '0' && c <= '9') || c == ignore );
+
+  if(isNegative)
+    value = -value;
+  return value;
+}
+
+// as parseInt but returns a floating point value
+float Stream::parseFloat(LookaheadMode lookahead, char ignore)
+{
+  bool isNegative = false;
+  bool isFraction = false;
+  long value = 0;
+  int c;
+  float fraction = 1.0;
+
+  c = peekNextDigit(lookahead, true);
+    // ignore non numeric leading characters
+  if(c < 0)
+    return 0; // zero returned if timeout
+
+  do{
+    if(c == ignore)
+      ; // ignore
+    else if(c == '-')
+      isNegative = true;
+    else if (c == '.')
+      isFraction = true;
+    else if(c >= '0' && c <= '9')  {      // is c a digit?
+      value = value * 10 + c - '0';
+      if(isFraction)
+         fraction *= 0.1;
+    }
+    read();  // consume the character we got with peek
+    c = timedPeek();
+  }
+  while( (c >= '0' && c <= '9')  || (c == '.' && !isFraction) || c == ignore );
+
+  if(isNegative)
+    value = -value;
+  if(isFraction)
+    return value * fraction;
+  else
+    return value;
+}
+
+// read characters from stream into buffer
+// terminates if length characters have been read, or timeout (see setTimeout)
+// returns the number of characters placed in the buffer
+// the buffer is NOT null terminated.
+//
+size_t Stream::readBytes(char *buffer, size_t length)
+{
+  size_t count = 0;
+  while (count < length) {
+    int c = timedRead();
+    if (c < 0) break;
+    *buffer++ = (char)c;
+    count++;
+  }
+  return count;
+}
+
+
+// as readBytes with terminator character
+// terminates if length characters have been read, timeout, or if the terminator character  detected
+// returns the number of characters placed in the buffer (0 means no valid data found)
+
+size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
+{
+  if (length < 1) return 0;
+  size_t index = 0;
+  while (index < length) {
+    int c = timedRead();
+    if (c < 0 || c == terminator) break;
+    *buffer++ = (char)c;
+    index++;
+  }
+  return index; // return number of characters, not including null terminator
+}
+
+String Stream::readString()
+{
+  String ret;
+  int c = timedRead();
+  while (c >= 0)
+  {
+    ret += (char)c;
+    c = timedRead();
+  }
+  return ret;
+}
+
+String Stream::readStringUntil(char terminator)
+{
+  String ret;
+  int c = timedRead();
+  while (c >= 0 && c != terminator)
+  {
+    ret += (char)c;
+    c = timedRead();
+  }
+  return ret;
+}
+
+int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
+  // any zero length target string automatically matches and would make
+  // a mess of the rest of the algorithm.
+  for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
+    if (t->len <= 0)
+      return t - targets;
+  }
+
+  while (1) {
+    int c = timedRead();
+    if (c < 0)
+      return -1;
+
+    for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
+      // the simple case is if we match, deal with that first.
+      if (c == t->str[t->index]) {
+        if (++t->index == t->len)
+          return t - targets;
+        else
+          continue;
+      }
+
+      // if not we need to walk back and see if we could have matched further
+      // down the stream (ie '1112' doesn't match the first position in '11112'
+      // but it will match the second position so we can't just reset the current
+      // index to 0 when we find a mismatch.
+      if (t->index == 0)
+        continue;
+
+      int origIndex = t->index;
+      do {
+        --t->index;
+        // first check if current char works against the new current index
+        if (c != t->str[t->index])
+          continue;
+
+        // if it's the only char then we're good, nothing more to check
+        if (t->index == 0) {
+          t->index++;
+          break;
+        }
+
+        // otherwise we need to check the rest of the found string
+        int diff = origIndex - t->index;
+        size_t i;
+        for (i = 0; i < t->index; ++i) {
+          if (t->str[i] != t->str[i + diff])
+            break;
+        }
+
+        // if we successfully got through the previous loop then our current
+        // index is good.
+        if (i == t->index) {
+          t->index++;
+          break;
+        }
+
+        // otherwise we just try the next index
+      } while (t->index);
+    }
+  }
+  // unreachable
+  return -1;
+}
diff --git a/arduino/hardware/ace/avr/cores/avr/Stream.h b/arduino/hardware/ace/avr/cores/avr/Stream.h
new file mode 100644 (file)
index 0000000..8e950c7
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+  Stream.h - base class for character-based streams.
+  Copyright (c) 2010 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
+
+  parsing functions based on TextFinder library by Michael Margolis
+*/
+
+#ifndef Stream_h
+#define Stream_h
+
+#include <inttypes.h>
+#include "Print.h"
+
+// compatability macros for testing
+/*
+#define   getInt()            parseInt()
+#define   getInt(ignore)    parseInt(ignore)
+#define   getFloat()          parseFloat()
+#define   getFloat(ignore)  parseFloat(ignore)
+#define   getString( pre_string, post_string, buffer, length)
+readBytesBetween( pre_string, terminator, buffer, length)
+*/
+
+// This enumeration provides the lookahead options for parseInt(), parseFloat()
+// The rules set out here are used until either the first valid character is found
+// or a time out occurs due to lack of input.
+enum LookaheadMode{
+    SKIP_ALL,       // All invalid characters are ignored.
+    SKIP_NONE,      // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
+    SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
+};
+
+#define NO_IGNORE_CHAR  '\x01' // a char not found in a valid ASCII numeric field
+
+class Stream : public Print
+{
+  protected:
+    unsigned long _timeout;      // number of milliseconds to wait for the next char before aborting timed read
+    unsigned long _startMillis;  // used for timeout measurement
+    int timedRead();    // read stream with timeout
+    int timedPeek();    // peek stream with timeout
+    int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
+
+  public:
+    virtual int available() = 0;
+    virtual int read() = 0;
+    virtual int peek() = 0;
+
+    Stream() {_timeout=1000;}
+
+// parsing methods
+
+  void setTimeout(unsigned long timeout);  // sets maximum milliseconds to wait for stream data, default is 1 second
+  unsigned long getTimeout(void) { return _timeout; }
+  
+  bool find(char *target);   // reads data from the stream until the target string is found
+  bool find(uint8_t *target) { return find ((char *)target); }
+  // returns true if target string is found, false if timed out (see setTimeout)
+
+  bool find(char *target, size_t length);   // reads data from the stream until the target string of given length is found
+  bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
+  // returns true if target string is found, false if timed out
+
+  bool find(char target) { return find (&target, 1); }
+
+  bool findUntil(char *target, char *terminator);   // as find but search ends if the terminator string is found
+  bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
+
+  bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen);   // as above but search ends if the terminate string is found
+  bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
+
+  long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
+  // returns the first valid (long) integer value from the current position.
+  // lookahead determines how parseInt looks ahead in the stream.
+  // See LookaheadMode enumeration at the top of the file.
+  // Lookahead is terminated by the first character that is not a valid part of an integer.
+  // Once parsing commences, 'ignore' will be skipped in the stream.
+
+  float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
+  // float version of parseInt
+
+  size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
+  size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
+  // terminates if length characters have been read or timeout (see setTimeout)
+  // returns the number of characters placed in the buffer (0 means no valid data found)
+
+  size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
+  size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
+  // terminates if length characters have been read, timeout, or if the terminator character  detected
+  // returns the number of characters placed in the buffer (0 means no valid data found)
+
+  // Arduino String functions to be added here
+  String readString();
+  String readStringUntil(char terminator);
+
+  protected:
+  long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
+  float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
+  // These overload exists for compatibility with any class that has derived
+  // Stream and used parseFloat/Int with a custom ignore character. To keep
+  // the public API simple, these overload remains protected.
+
+  struct MultiTarget {
+    const char *str;  // string you're searching for
+    size_t len;       // length of string you're searching for
+    size_t index;     // index used by the search routine.
+  };
+
+  // This allows you to search for an arbitrary number of strings.
+  // Returns index of the target that is found first or -1 if timeout occurs.
+  int findMulti(struct MultiTarget *targets, int tCount);
+};
+
+#undef NO_IGNORE_CHAR
+#endif
diff --git a/arduino/hardware/ace/avr/cores/avr/WString.cpp b/arduino/hardware/ace/avr/cores/avr/WString.cpp
new file mode 100644 (file)
index 0000000..f2572d6
--- /dev/null
@@ -0,0 +1,750 @@
+/*
+  WString.cpp - String library for Wiring & Arduino
+  ...mostly rewritten by Paul Stoffregen...
+  Copyright (c) 2009-10 Hernando Barragan.  All rights reserved.
+  Copyright 2011, Paul Stoffregen, paul@pjrc.com
+
+  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 "WString.h"
+
+/*********************************************/
+/*  Constructors                             */
+/*********************************************/
+
+String::String(const char *cstr)
+{
+       init();
+       if (cstr) copy(cstr, strlen(cstr));
+}
+
+String::String(const String &value)
+{
+       init();
+       *this = value;
+}
+
+String::String(const __FlashStringHelper *pstr)
+{
+       init();
+       *this = pstr;
+}
+
+#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+String::String(String &&rval)
+{
+       init();
+       move(rval);
+}
+String::String(StringSumHelper &&rval)
+{
+       init();
+       move(rval);
+}
+#endif
+
+String::String(char c)
+{
+       init();
+       char buf[2];
+       buf[0] = c;
+       buf[1] = 0;
+       *this = buf;
+}
+
+String::String(unsigned char value, unsigned char base)
+{
+       init();
+       char buf[1 + 8 * sizeof(unsigned char)];
+       utoa(value, buf, base);
+       *this = buf;
+}
+
+String::String(int value, unsigned char base)
+{
+       init();
+       char buf[2 + 8 * sizeof(int)];
+       itoa(value, buf, base);
+       *this = buf;
+}
+
+String::String(unsigned int value, unsigned char base)
+{
+       init();
+       char buf[1 + 8 * sizeof(unsigned int)];
+       utoa(value, buf, base);
+       *this = buf;
+}
+
+String::String(long value, unsigned char base)
+{
+       init();
+       char buf[2 + 8 * sizeof(long)];
+       ltoa(value, buf, base);
+       *this = buf;
+}
+
+String::String(unsigned long value, unsigned char base)
+{
+       init();
+       char buf[1 + 8 * sizeof(unsigned long)];
+       ultoa(value, buf, base);
+       *this = buf;
+}
+
+String::String(float value, unsigned char decimalPlaces)
+{
+       init();
+       char buf[33];
+       *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
+}
+
+String::String(double value, unsigned char decimalPlaces)
+{
+       init();
+       char buf[33];
+       *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
+}
+
+String::~String()
+{
+       free(buffer);
+}
+
+/*********************************************/
+/*  Memory Management                        */
+/*********************************************/
+
+inline void String::init(void)
+{
+       buffer = NULL;
+       capacity = 0;
+       len = 0;
+}
+
+void String::invalidate(void)
+{
+       if (buffer) free(buffer);
+       buffer = NULL;
+       capacity = len = 0;
+}
+
+unsigned char String::reserve(unsigned int size)
+{
+       if (buffer && capacity >= size) return 1;
+       if (changeBuffer(size)) {
+               if (len == 0) buffer[0] = 0;
+               return 1;
+       }
+       return 0;
+}
+
+unsigned char String::changeBuffer(unsigned int maxStrLen)
+{
+       char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
+       if (newbuffer) {
+               buffer = newbuffer;
+               capacity = maxStrLen;
+               return 1;
+       }
+       return 0;
+}
+
+/*********************************************/
+/*  Copy and Move                            */
+/*********************************************/
+
+String & String::copy(const char *cstr, unsigned int length)
+{
+       if (!reserve(length)) {
+               invalidate();
+               return *this;
+       }
+       len = length;
+       strcpy(buffer, cstr);
+       return *this;
+}
+
+String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
+{
+       if (!reserve(length)) {
+               invalidate();
+               return *this;
+       }
+       len = length;
+       strcpy_P(buffer, (PGM_P)pstr);
+       return *this;
+}
+
+#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+void String::move(String &rhs)
+{
+       if (buffer) {
+               if (rhs && capacity >= rhs.len) {
+                       strcpy(buffer, rhs.buffer);
+                       len = rhs.len;
+                       rhs.len = 0;
+                       return;
+               } else {
+                       free(buffer);
+               }
+       }
+       buffer = rhs.buffer;
+       capacity = rhs.capacity;
+       len = rhs.len;
+       rhs.buffer = NULL;
+       rhs.capacity = 0;
+       rhs.len = 0;
+}
+#endif
+
+String & String::operator = (const String &rhs)
+{
+       if (this == &rhs) return *this;
+       
+       if (rhs.buffer) copy(rhs.buffer, rhs.len);
+       else invalidate();
+       
+       return *this;
+}
+
+#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+String & String::operator = (String &&rval)
+{
+       if (this != &rval) move(rval);
+       return *this;
+}
+
+String & String::operator = (StringSumHelper &&rval)
+{
+       if (this != &rval) move(rval);
+       return *this;
+}
+#endif
+
+String & String::operator = (const char *cstr)
+{
+       if (cstr) copy(cstr, strlen(cstr));
+       else invalidate();
+       
+       return *this;
+}
+
+String & String::operator = (const __FlashStringHelper *pstr)
+{
+       if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
+       else invalidate();
+
+       return *this;
+}
+
+/*********************************************/
+/*  concat                                   */
+/*********************************************/
+
+unsigned char String::concat(const String &s)
+{
+       return concat(s.buffer, s.len);
+}
+
+unsigned char String::concat(const char *cstr, unsigned int length)
+{
+       unsigned int newlen = len + length;
+       if (!cstr) return 0;
+       if (length == 0) return 1;
+       if (!reserve(newlen)) return 0;
+       strcpy(buffer + len, cstr);
+       len = newlen;
+       return 1;
+}
+
+unsigned char String::concat(const char *cstr)
+{
+       if (!cstr) return 0;
+       return concat(cstr, strlen(cstr));
+}
+
+unsigned char String::concat(char c)
+{
+       char buf[2];
+       buf[0] = c;
+       buf[1] = 0;
+       return concat(buf, 1);
+}
+
+unsigned char String::concat(unsigned char num)
+{
+       char buf[1 + 3 * sizeof(unsigned char)];
+       itoa(num, buf, 10);
+       return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(int num)
+{
+       char buf[2 + 3 * sizeof(int)];
+       itoa(num, buf, 10);
+       return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(unsigned int num)
+{
+       char buf[1 + 3 * sizeof(unsigned int)];
+       utoa(num, buf, 10);
+       return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(long num)
+{
+       char buf[2 + 3 * sizeof(long)];
+       ltoa(num, buf, 10);
+       return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(unsigned long num)
+{
+       char buf[1 + 3 * sizeof(unsigned long)];
+       ultoa(num, buf, 10);
+       return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(float num)
+{
+       char buf[20];
+       char* string = dtostrf(num, 4, 2, buf);
+       return concat(string, strlen(string));
+}
+
+unsigned char String::concat(double num)
+{
+       char buf[20];
+       char* string = dtostrf(num, 4, 2, buf);
+       return concat(string, strlen(string));
+}
+
+unsigned char String::concat(const __FlashStringHelper * str)
+{
+       if (!str) return 0;
+       int length = strlen_P((const char *) str);
+       if (length == 0) return 1;
+       unsigned int newlen = len + length;
+       if (!reserve(newlen)) return 0;
+       strcpy_P(buffer + len, (const char *) str);
+       len = newlen;
+       return 1;
+}
+
+/*********************************************/
+/*  Concatenate                              */
+/*********************************************/
+
+StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, char c)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(c)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(num)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, int num)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(num)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(num)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, long num)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(num)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(num)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, float num)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(num)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, double num)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(num)) a.invalidate();
+       return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
+{
+       StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+       if (!a.concat(rhs))     a.invalidate();
+       return a;
+}
+
+/*********************************************/
+/*  Comparison                               */
+/*********************************************/
+
+int String::compareTo(const String &s) const
+{
+       if (!buffer || !s.buffer) {
+               if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
+               if (buffer && len > 0) return *(unsigned char *)buffer;
+               return 0;
+       }
+       return strcmp(buffer, s.buffer);
+}
+
+unsigned char String::equals(const String &s2) const
+{
+       return (len == s2.len && compareTo(s2) == 0);
+}
+
+unsigned char String::equals(const char *cstr) const
+{
+       if (len == 0) return (cstr == NULL || *cstr == 0);
+       if (cstr == NULL) return buffer[0] == 0;
+       return strcmp(buffer, cstr) == 0;
+}
+
+unsigned char String::operator<(const String &rhs) const
+{
+       return compareTo(rhs) < 0;
+}
+
+unsigned char String::operator>(const String &rhs) const
+{
+       return compareTo(rhs) > 0;
+}
+
+unsigned char String::operator<=(const String &rhs) const
+{
+       return compareTo(rhs) <= 0;
+}
+
+unsigned char String::operator>=(const String &rhs) const
+{
+       return compareTo(rhs) >= 0;
+}
+
+unsigned char String::equalsIgnoreCase( const String &s2 ) const
+{
+       if (this == &s2) return 1;
+       if (len != s2.len) return 0;
+       if (len == 0) return 1;
+       const char *p1 = buffer;
+       const char *p2 = s2.buffer;
+       while (*p1) {
+               if (tolower(*p1++) != tolower(*p2++)) return 0;
+       } 
+       return 1;
+}
+
+unsigned char String::startsWith( const String &s2 ) const
+{
+       if (len < s2.len) return 0;
+       return startsWith(s2, 0);
+}
+
+unsigned char String::startsWith( const String &s2, unsigned int offset ) const
+{
+       if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
+       return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
+}
+
+unsigned char String::endsWith( const String &s2 ) const
+{
+       if ( len < s2.len || !buffer || !s2.buffer) return 0;
+       return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
+}
+
+/*********************************************/
+/*  Character Access                         */
+/*********************************************/
+
+char String::charAt(unsigned int loc) const
+{
+       return operator[](loc);
+}
+
+void String::setCharAt(unsigned int loc, char c) 
+{
+       if (loc < len) buffer[loc] = c;
+}
+
+char & String::operator[](unsigned int index)
+{
+       static char dummy_writable_char;
+       if (index >= len || !buffer) {
+               dummy_writable_char = 0;
+               return dummy_writable_char;
+       }
+       return buffer[index];
+}
+
+char String::operator[]( unsigned int index ) const
+{
+       if (index >= len || !buffer) return 0;
+       return buffer[index];
+}
+
+void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
+{
+       if (!bufsize || !buf) return;
+       if (index >= len) {
+               buf[0] = 0;
+               return;
+       }
+       unsigned int n = bufsize - 1;
+       if (n > len - index) n = len - index;
+       strncpy((char *)buf, buffer + index, n);
+       buf[n] = 0;
+}
+
+/*********************************************/
+/*  Search                                   */
+/*********************************************/
+
+int String::indexOf(char c) const
+{
+       return indexOf(c, 0);
+}
+
+int String::indexOf( char ch, unsigned int fromIndex ) const
+{
+       if (fromIndex >= len) return -1;
+       const char* temp = strchr(buffer + fromIndex, ch);
+       if (temp == NULL) return -1;
+       return temp - buffer;
+}
+
+int String::indexOf(const String &s2) const
+{
+       return indexOf(s2, 0);
+}
+
+int String::indexOf(const String &s2, unsigned int fromIndex) const
+{
+       if (fromIndex >= len) return -1;
+       const char *found = strstr(buffer + fromIndex, s2.buffer);
+       if (found == NULL) return -1;
+       return found - buffer;
+}
+
+int String::lastIndexOf( char theChar ) const
+{
+       return lastIndexOf(theChar, len - 1);
+}
+
+int String::lastIndexOf(char ch, unsigned int fromIndex) const
+{
+       if (fromIndex >= len) return -1;
+       char tempchar = buffer[fromIndex + 1];
+       buffer[fromIndex + 1] = '\0';
+       char* temp = strrchr( buffer, ch );
+       buffer[fromIndex + 1] = tempchar;
+       if (temp == NULL) return -1;
+       return temp - buffer;
+}
+
+int String::lastIndexOf(const String &s2) const
+{
+       return lastIndexOf(s2, len - s2.len);
+}
+
+int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
+{
+       if (s2.len == 0 || len == 0 || s2.len > len) return -1;
+       if (fromIndex >= len) fromIndex = len - 1;
+       int found = -1;
+       for (char *p = buffer; p <= buffer + fromIndex; p++) {
+               p = strstr(p, s2.buffer);
+               if (!p) break;
+               if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
+       }
+       return found;
+}
+
+String String::substring(unsigned int left, unsigned int right) const
+{
+       if (left > right) {
+               unsigned int temp = right;
+               right = left;
+               left = temp;
+       }
+       String out;
+       if (left >= len) return out;
+       if (right > len) right = len;
+       char temp = buffer[right];  // save the replaced character
+       buffer[right] = '\0';   
+       out = buffer + left;  // pointer arithmetic
+       buffer[right] = temp;  //restore character
+       return out;
+}
+
+/*********************************************/
+/*  Modification                             */
+/*********************************************/
+
+void String::replace(char find, char replace)
+{
+       if (!buffer) return;
+       for (char *p = buffer; *p; p++) {
+               if (*p == find) *p = replace;
+       }
+}
+
+void String::replace(const String& find, const String& replace)
+{
+       if (len == 0 || find.len == 0) return;
+       int diff = replace.len - find.len;
+       char *readFrom = buffer;
+       char *foundAt;
+       if (diff == 0) {
+               while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
+                       memcpy(foundAt, replace.buffer, replace.len);
+                       readFrom = foundAt + replace.len;
+               }
+       } else if (diff < 0) {
+               char *writeTo = buffer;
+               while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
+                       unsigned int n = foundAt - readFrom;
+                       memcpy(writeTo, readFrom, n);
+                       writeTo += n;
+                       memcpy(writeTo, replace.buffer, replace.len);
+                       writeTo += replace.len;
+                       readFrom = foundAt + find.len;
+                       len += diff;
+               }
+               strcpy(writeTo, readFrom);
+       } else {
+               unsigned int size = len; // compute size needed for result
+               while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
+                       readFrom = foundAt + find.len;
+                       size += diff;
+               }
+               if (size == len) return;
+               if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
+               int index = len - 1;
+               while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
+                       readFrom = buffer + index + find.len;
+                       memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
+                       len += diff;
+                       buffer[len] = 0;
+                       memcpy(buffer + index, replace.buffer, replace.len);
+                       index--;
+               }
+       }
+}
+
+void String::remove(unsigned int index){
+       // Pass the biggest integer as the count. The remove method
+       // below will take care of truncating it at the end of the
+       // string.
+       remove(index, (unsigned int)-1);
+}
+
+void String::remove(unsigned int index, unsigned int count){
+       if (index >= len) { return; }
+       if (count <= 0) { return; }
+       if (count > len - index) { count = len - index; }
+       char *writeTo = buffer + index;
+       len = len - count;
+       strncpy(writeTo, buffer + index + count,len - index);
+       buffer[len] = 0;
+}
+
+void String::toLowerCase(void)
+{
+       if (!buffer) return;
+       for (char *p = buffer; *p; p++) {
+               *p = tolower(*p);
+       }
+}
+
+void String::toUpperCase(void)
+{
+       if (!buffer) return;
+       for (char *p = buffer; *p; p++) {
+               *p = toupper(*p);
+       }
+}
+
+void String::trim(void)
+{
+       if (!buffer || len == 0) return;
+       char *begin = buffer;
+       while (isspace(*begin)) begin++;
+       char *end = buffer + len - 1;
+       while (isspace(*end) && end >= begin) end--;
+       len = end + 1 - begin;
+       if (begin > buffer) memcpy(buffer, begin, len);
+       buffer[len] = 0;
+}
+
+/*********************************************/
+/*  Parsing / Conversion                     */
+/*********************************************/
+
+long String::toInt(void) const
+{
+       if (buffer) return atol(buffer);
+       return 0;
+}
+
+float String::toFloat(void) const
+{
+       return float(toDouble());
+}
+
+double String::toDouble(void) const
+{
+       if (buffer) return atof(buffer);
+       return 0;
+}
diff --git a/arduino/hardware/ace/avr/cores/avr/WString.h b/arduino/hardware/ace/avr/cores/avr/WString.h
new file mode 100644 (file)
index 0000000..77709c3
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+  WString.h - String library for Wiring & Arduino
+  ...mostly rewritten by Paul Stoffregen...
+  Copyright (c) 2009-10 Hernando Barragan.  All right reserved.
+  Copyright 2011, Paul Stoffregen, paul@pjrc.com
+
+  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 String_class_h
+#define String_class_h
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <avr/pgmspace.h>
+
+// When compiling programs with this class, the following gcc parameters
+// dramatically increase performance and memory (RAM) efficiency, typically
+// with little or no increase in code size.
+//     -felide-constructors
+//     -std=c++0x
+
+class __FlashStringHelper;
+#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
+
+// An inherited class for holding the result of a concatenation.  These
+// result objects are assumed to be writable by subsequent concatenations.
+class StringSumHelper;
+
+// The string class
+class String
+{
+       // use a function pointer to allow for "if (s)" without the
+       // complications of an operator bool(). for more information, see:
+       // http://www.artima.com/cppsource/safebool.html
+       typedef void (String::*StringIfHelperType)() const;
+       void StringIfHelper() const {}
+
+public:
+       // constructors
+       // creates a copy of the initial value.
+       // if the initial value is null or invalid, or if memory allocation
+       // fails, the string will be marked as invalid (i.e. "if (s)" will
+       // be false).
+       String(const char *cstr = "");
+       String(const String &str);
+       String(const __FlashStringHelper *str);
+       #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+       String(String &&rval);
+       String(StringSumHelper &&rval);
+       #endif
+       explicit String(char c);
+       explicit String(unsigned char, unsigned char base=10);
+       explicit String(int, unsigned char base=10);
+       explicit String(unsigned int, unsigned char base=10);
+       explicit String(long, unsigned char base=10);
+       explicit String(unsigned long, unsigned char base=10);
+       explicit String(float, unsigned char decimalPlaces=2);
+       explicit String(double, unsigned char decimalPlaces=2);
+       ~String(void);
+
+       // memory management
+       // return true on success, false on failure (in which case, the string
+       // is left unchanged).  reserve(0), if successful, will validate an
+       // invalid string (i.e., "if (s)" will be true afterwards)
+       unsigned char reserve(unsigned int size);
+       inline unsigned int length(void) const {return len;}
+
+       // creates a copy of the assigned value.  if the value is null or
+       // invalid, or if the memory allocation fails, the string will be
+       // marked as invalid ("if (s)" will be false).
+       String & operator = (const String &rhs);
+       String & operator = (const char *cstr);
+       String & operator = (const __FlashStringHelper *str);
+       #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+       String & operator = (String &&rval);
+       String & operator = (StringSumHelper &&rval);
+       #endif
+
+       // concatenate (works w/ built-in types)
+
+       // returns true on success, false on failure (in which case, the string
+       // is left unchanged).  if the argument is null or invalid, the
+       // concatenation is considered unsucessful.
+       unsigned char concat(const String &str);
+       unsigned char concat(const char *cstr);
+       unsigned char concat(char c);
+       unsigned char concat(unsigned char c);
+       unsigned char concat(int num);
+       unsigned char concat(unsigned int num);
+       unsigned char concat(long num);
+       unsigned char concat(unsigned long num);
+       unsigned char concat(float num);
+       unsigned char concat(double num);
+       unsigned char concat(const __FlashStringHelper * str);
+
+       // if there's not enough memory for the concatenated value, the string
+       // will be left unchanged (but this isn't signalled in any way)
+       String & operator += (const String &rhs)        {concat(rhs); return (*this);}
+       String & operator += (const char *cstr)         {concat(cstr); return (*this);}
+       String & operator += (char c)                   {concat(c); return (*this);}
+       String & operator += (unsigned char num)                {concat(num); return (*this);}
+       String & operator += (int num)                  {concat(num); return (*this);}
+       String & operator += (unsigned int num)         {concat(num); return (*this);}
+       String & operator += (long num)                 {concat(num); return (*this);}
+       String & operator += (unsigned long num)        {concat(num); return (*this);}
+       String & operator += (float num)                {concat(num); return (*this);}
+       String & operator += (double num)               {concat(num); return (*this);}
+       String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
+
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
+       friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
+
+       // comparison (only works w/ Strings and "strings")
+       operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
+       int compareTo(const String &s) const;
+       unsigned char equals(const String &s) const;
+       unsigned char equals(const char *cstr) const;
+       unsigned char operator == (const String &rhs) const {return equals(rhs);}
+       unsigned char operator == (const char *cstr) const {return equals(cstr);}
+       unsigned char operator != (const String &rhs) const {return !equals(rhs);}
+       unsigned char operator != (const char *cstr) const {return !equals(cstr);}
+       unsigned char operator <  (const String &rhs) const;
+       unsigned char operator >  (const String &rhs) const;
+       unsigned char operator <= (const String &rhs) const;
+       unsigned char operator >= (const String &rhs) const;
+       unsigned char equalsIgnoreCase(const String &s) const;
+       unsigned char startsWith( const String &prefix) const;
+       unsigned char startsWith(const String &prefix, unsigned int offset) const;
+       unsigned char endsWith(const String &suffix) const;
+
+       // character acccess
+       char charAt(unsigned int index) const;
+       void setCharAt(unsigned int index, char c);
+       char operator [] (unsigned int index) const;
+       char& operator [] (unsigned int index);
+       void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
+       void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
+               { getBytes((unsigned char *)buf, bufsize, index); }
+       const char* c_str() const { return buffer; }
+       char* begin() { return buffer; }
+       char* end() { return buffer + length(); }
+       const char* begin() const { return c_str(); }
+       const char* end() const { return c_str() + length(); }
+
+       // search
+       int indexOf( char ch ) const;
+       int indexOf( char ch, unsigned int fromIndex ) const;
+       int indexOf( const String &str ) const;
+       int indexOf( const String &str, unsigned int fromIndex ) const;
+       int lastIndexOf( char ch ) const;
+       int lastIndexOf( char ch, unsigned int fromIndex ) const;
+       int lastIndexOf( const String &str ) const;
+       int lastIndexOf( const String &str, unsigned int fromIndex ) const;
+       String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
+       String substring( unsigned int beginIndex, unsigned int endIndex ) const;
+
+       // modification
+       void replace(char find, char replace);
+       void replace(const String& find, const String& replace);
+       void remove(unsigned int index);
+       void remove(unsigned int index, unsigned int count);
+       void toLowerCase(void);
+       void toUpperCase(void);
+       void trim(void);
+
+       // parsing/conversion
+       long toInt(void) const;
+       float toFloat(void) const;
+       double toDouble(void) const;
+
+protected:
+       char *buffer;           // the actual char array
+       unsigned int capacity;  // the array length minus one (for the '\0')
+       unsigned int len;       // the String length (not counting the '\0')
+protected:
+       void init(void);
+       void invalidate(void);
+       unsigned char changeBuffer(unsigned int maxStrLen);
+       unsigned char concat(const char *cstr, unsigned int length);
+
+       // copy and move
+       String & copy(const char *cstr, unsigned int length);
+       String & copy(const __FlashStringHelper *pstr, unsigned int length);
+       #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+       void move(String &rhs);
+       #endif
+};
+
+class StringSumHelper : public String
+{
+public:
+       StringSumHelper(const String &s) : String(s) {}
+       StringSumHelper(const char *p) : String(p) {}
+       StringSumHelper(char c) : String(c) {}
+       StringSumHelper(unsigned char num) : String(num) {}
+       StringSumHelper(int num) : String(num) {}
+       StringSumHelper(unsigned int num) : String(num) {}
+       StringSumHelper(long num) : String(num) {}
+       StringSumHelper(unsigned long num) : String(num) {}
+       StringSumHelper(float num) : String(num) {}
+       StringSumHelper(double num) : String(num) {}
+};
+
+#endif  // __cplusplus
+#endif  // String_class_h
index 31875da46402d81864bfef5b6cec7504e94e7365..df4f042e11715160dca39d56525b521f8d3ce1ff 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <AceAvr.h>
 #include <kernel.h>
+#include <HardwareSerial.h>
 
 void delay(unsigned long ms);
 
@@ -26,6 +27,13 @@ void task_scheduler();
 
 uint8_t debug_task_stack[TASK_STACK_SIZE];
 void debug_task() {
+    Serial.begin(9600);
+
+    while(1) {
+        Serial.println("fuck");
+        task_delay(100);
+    }
+
     while(1) task_delay(1000);
     uint8_t pin = 12;
     set_digital_pin_mode(pin, OUTPUT);
index ac02f3aae6116ec16ccac657bb0a49a0075fbd62..b101177c681225b6b01b7ee777cadb0dd864e783 100644 (file)
 
 
 volatile unsigned long timer0_overflow_count = 0;
+volatile unsigned long timer0_millis = 0;
+static unsigned char timer0_fract = 0;
+
+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;
@@ -59,6 +75,19 @@ void init_timer0() {
 extern "C" void TIMER0_OVF_vect() __attribute__ ((signal,used, externally_visible));
 void TIMER0_OVF_vect()
 {
+    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++;
 }