diff options
Diffstat (limited to 'arduino_libs_0022')
26 files changed, 2987 insertions, 0 deletions
diff --git a/arduino_libs_0022/ArduinoSerialManager.zip b/arduino_libs_0022/ArduinoSerialManager.zip Binary files differnew file mode 100644 index 0000000..7693b72 --- /dev/null +++ b/arduino_libs_0022/ArduinoSerialManager.zip diff --git a/arduino_libs_0022/ByteBuffer/.svn/all-wcprops b/arduino_libs_0022/ByteBuffer/.svn/all-wcprops new file mode 100755 index 0000000..de5c62d --- /dev/null +++ b/arduino_libs_0022/ByteBuffer/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 55 +/r/prg/!svn/ver/5368/trunk/arduino/libraries/ByteBuffer +END +ByteBuffer.h +K 25 +svn:wc:ra_dav:version-url +V 68 +/r/prg/!svn/ver/5368/trunk/arduino/libraries/ByteBuffer/ByteBuffer.h +END +ByteBuffer.cpp +K 25 +svn:wc:ra_dav:version-url +V 70 +/r/prg/!svn/ver/5812/trunk/arduino/libraries/ByteBuffer/ByteBuffer.cpp +END diff --git a/arduino_libs_0022/ByteBuffer/.svn/entries b/arduino_libs_0022/ByteBuffer/.svn/entries new file mode 100755 index 0000000..4c4a628 --- /dev/null +++ b/arduino_libs_0022/ByteBuffer/.svn/entries @@ -0,0 +1,120 @@ +10 + +dir +5368 +https://svn.media.mit.edu/r/prg/trunk/arduino/libraries/ByteBuffer +https://svn.media.mit.edu/r/prg + + + +2010-07-20T00:54:42.918731Z +5368 +siggi + + + + + + + + + + + + + + +bd000cc4-1869-4481-ad02-c3af97ea9c83 + +ByteBuffer.h +file + + + + +2010-07-19T22:27:55.000000Z +3b6d84df8e69905675772beb574cce67 +2010-07-20T00:54:42.918731Z +5368 +siggi + + + + + + + + + + + + + + + + + + + + + +844 + +SerialPacketHandler.cpp +file +5810 + + + + + + + + + + + + + + + + + + + +deleted + +ByteBuffer.cpp +file +5812 + + + +2010-09-02T16:31:44.000000Z +d95900d573ac73c8ccf95b384f8ec258 +2010-09-02T18:42:42.362483Z +5812 +siggi + + + + + + + + + + + + + + + + + + + + + +3483 + diff --git a/arduino_libs_0022/ByteBuffer/.svn/text-base/ByteBuffer.cpp.svn-base b/arduino_libs_0022/ByteBuffer/.svn/text-base/ByteBuffer.cpp.svn-base new file mode 100755 index 0000000..b91a586 --- /dev/null +++ b/arduino_libs_0022/ByteBuffer/.svn/text-base/ByteBuffer.cpp.svn-base @@ -0,0 +1,205 @@ +/* + ByteBuffer.cpp - A circular buffer implementation for Arduino + Created by Sigurdur Orn, July 19, 2010. + */ + +#include "WProgram.h" +#include "ByteBuffer.h" + + +ByteBuffer::ByteBuffer(){ + +} + +void ByteBuffer::init(unsigned int buf_length){ + data = (byte*)malloc(sizeof(byte)*buf_length); + float_bytes = (byte*)malloc(sizeof(byte)*8); + capacity = buf_length; + position = 0; + length = 0; +} + +void ByteBuffer::clear(){ + position = 0; + length = 0; +} + +int ByteBuffer::getSize(){ + return length; +} + +int ByteBuffer::getCapacity(){ + return capacity; +} + +byte ByteBuffer::peek(unsigned int index){ + byte b = data[(position+index)%capacity]; + return b; +} + +int ByteBuffer::put(byte in){ + if(length < capacity){ + // save data byte at end of buffer + data[(position+length) % capacity] = in; + // increment the length + length++; + return 1; + } + // return failure + return 0; +} + +int ByteBuffer::putInFront(byte in){ + if(length < capacity){ + // save data byte at end of buffer + if( position == 0 ) + position = capacity-1; + else + position = (position-1)%capacity; + data[position] = in; + // increment the length + length++; + return 1; + } + // return failure + return 0; +} + +byte ByteBuffer::get(){ + byte b = 0; + if(length > 0){ + b = data[position]; + // move index down and decrement length + position = (position+1)%capacity; + length--; + } + + return b; +} + +byte ByteBuffer::getFromBack(){ + byte b = 0; + if(length > 0){ + b = data[(position+length-1)%capacity]; + length--; + } + + return b; +} + +// +// Ints +// + +int ByteBuffer::putIntInFront(int in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); +} + +int ByteBuffer::putInt(int in){ + byte *pointer = (byte *)∈ + put(pointer[1]); + put(pointer[0]); +} + + +int ByteBuffer::getInt(){ + int ret; + byte *pointer = (byte *)&ret; + pointer[1] = get(); + pointer[0] = get(); + return ret; +} + +int ByteBuffer::getIntFromBack(){ + int ret; + byte *pointer = (byte *)&ret; + pointer[0] = getFromBack(); + pointer[1] = getFromBack(); + return ret; +} + +// +// Longs +// + +int ByteBuffer::putLongInFront(long in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); + putInFront(pointer[2]); + putInFront(pointer[3]); +} + +int ByteBuffer::putLong(long in){ + byte *pointer = (byte *)∈ + put(pointer[3]); + put(pointer[2]); + put(pointer[1]); + put(pointer[0]); +} + + +long ByteBuffer::getLong(){ + long ret; + byte *pointer = (byte *)&ret; + pointer[3] = get(); + pointer[2] = get(); + pointer[1] = get(); + pointer[0] = get(); + return ret; +} + +long ByteBuffer::getLongFromBack(){ + long ret; + byte *pointer = (byte *)&ret; + pointer[0] = getFromBack(); + pointer[1] = getFromBack(); + pointer[2] = getFromBack(); + pointer[3] = getFromBack(); + return ret; +} + + +// +// Floats +// + +int ByteBuffer::putFloatInFront(float in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); + putInFront(pointer[2]); + putInFront(pointer[3]); +} + +int ByteBuffer::putFloat(float in){ + byte *pointer = (byte *)∈ + put(pointer[3]); + put(pointer[2]); + put(pointer[1]); + put(pointer[0]); +} + +float ByteBuffer::getFloat(){ + float ret; + byte *pointer = (byte *)&ret; + pointer[3] = get(); + pointer[2] = get(); + pointer[1] = get(); + pointer[0] = get(); + return ret; +} + +float ByteBuffer::getFloatFromBack(){ + float ret; + byte *pointer = (byte *)&ret; + pointer[0] = getFromBack(); + pointer[1] = getFromBack(); + pointer[2] = getFromBack(); + pointer[3] = getFromBack(); + return ret; +} + + diff --git a/arduino_libs_0022/ByteBuffer/.svn/text-base/ByteBuffer.h.svn-base b/arduino_libs_0022/ByteBuffer/.svn/text-base/ByteBuffer.h.svn-base new file mode 100755 index 0000000..b100c2f --- /dev/null +++ b/arduino_libs_0022/ByteBuffer/.svn/text-base/ByteBuffer.h.svn-base @@ -0,0 +1,57 @@ +/* + ByteBuffer.h - A circular buffer implementation for Arduino + Created by Sigurdur Orn, July 19, 2010. + */ +#ifndef ByteBuffer_h +#define ByteBuffer_h + +#include "WProgram.h" + +class ByteBuffer +{ +public: + ByteBuffer(); + + void init(unsigned int buf_size); + + void clear(); + int getSize(); + int getCapacity(); + + int putInFront(byte in); + int put(byte in); + + byte get(); + byte getFromBack(); + + byte peek(unsigned int index); + + int putIntInFront(int in); + int putInt(int in); + + int putLongInFront(long in); + int putLong(long in); + + int getInt(); + int getIntFromBack(); + + long getLong(); + long getLongFromBack(); + + int putFloatInFront(float in); + int putFloat(float in); + + float getFloat(); + float getFloatFromBack(); + +private: + byte* data; + byte* float_bytes; + + unsigned int capacity; + unsigned int position; + unsigned int length; +}; + +#endif + diff --git a/arduino_libs_0022/ByteBuffer/ByteBuffer.cpp b/arduino_libs_0022/ByteBuffer/ByteBuffer.cpp new file mode 100755 index 0000000..b151cef --- /dev/null +++ b/arduino_libs_0022/ByteBuffer/ByteBuffer.cpp @@ -0,0 +1,212 @@ +/* + ByteBuffer.cpp - A circular buffer implementation for Arduino + Created by Sigurdur Orn, July 19, 2010. + siggi@mit.edu + */ + +#include <util/atomic.h> +#include "WProgram.h" +#include "ByteBuffer.h" + + +ByteBuffer::ByteBuffer(){ + +} + +void ByteBuffer::init(unsigned int buf_length){ + data = (byte*)malloc(sizeof(byte)*buf_length); + capacity = buf_length; + position = 0; + length = 0; +} + +void ByteBuffer::deAllocate(){ + free(data); +} + +void ByteBuffer::clear(){ + position = 0; + length = 0; +} + +int ByteBuffer::getSize(){ + return length; +} + +int ByteBuffer::getCapacity(){ + return capacity; +} + +byte ByteBuffer::peek(unsigned int index){ + byte b = data[(position+index)%capacity]; + return b; +} + +int ByteBuffer::put(byte in){ + if(length < capacity){ + // save data byte at end of buffer + data[(position+length) % capacity] = in; + // increment the length + length++; + return 1; + } + // return failure + return 0; +} + +int ByteBuffer::putInFront(byte in){ + if(length < capacity){ + // save data byte at end of buffer + if( position == 0 ) + position = capacity-1; + else + position = (position-1)%capacity; + data[position] = in; + // increment the length + length++; + return 1; + } + // return failure + return 0; +} + +byte ByteBuffer::get(){ + byte b = 0; + + + if(length > 0){ + b = data[position]; + // move index down and decrement length + position = (position+1)%capacity; + length--; + } + + return b; +} + +byte ByteBuffer::getFromBack(){ + byte b = 0; + if(length > 0){ + b = data[(position+length-1)%capacity]; + length--; + } + + return b; +} + +// +// Ints +// + +int ByteBuffer::putIntInFront(int in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); +} + +int ByteBuffer::putInt(int in){ + byte *pointer = (byte *)∈ + put(pointer[1]); + put(pointer[0]); +} + + +int ByteBuffer::getInt(){ + int ret; + byte *pointer = (byte *)&ret; + pointer[1] = get(); + pointer[0] = get(); + return ret; +} + +int ByteBuffer::getIntFromBack(){ + int ret; + byte *pointer = (byte *)&ret; + pointer[0] = getFromBack(); + pointer[1] = getFromBack(); + return ret; +} + +// +// Longs +// + +int ByteBuffer::putLongInFront(long in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); + putInFront(pointer[2]); + putInFront(pointer[3]); +} + +int ByteBuffer::putLong(long in){ + byte *pointer = (byte *)∈ + put(pointer[3]); + put(pointer[2]); + put(pointer[1]); + put(pointer[0]); +} + + +long ByteBuffer::getLong(){ + long ret; + byte *pointer = (byte *)&ret; + pointer[3] = get(); + pointer[2] = get(); + pointer[1] = get(); + pointer[0] = get(); + return ret; +} + +long ByteBuffer::getLongFromBack(){ + long ret; + byte *pointer = (byte *)&ret; + pointer[0] = getFromBack(); + pointer[1] = getFromBack(); + pointer[2] = getFromBack(); + pointer[3] = getFromBack(); + return ret; +} + + +// +// Floats +// + +int ByteBuffer::putFloatInFront(float in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); + putInFront(pointer[2]); + putInFront(pointer[3]); +} + +int ByteBuffer::putFloat(float in){ + byte *pointer = (byte *)∈ + put(pointer[3]); + put(pointer[2]); + put(pointer[1]); + put(pointer[0]); +} + +float ByteBuffer::getFloat(){ + float ret; + byte *pointer = (byte *)&ret; + pointer[3] = get(); + pointer[2] = get(); + pointer[1] = get(); + pointer[0] = get(); + return ret; +} + +float ByteBuffer::getFloatFromBack(){ + float ret; + byte *pointer = (byte *)&ret; + pointer[0] = getFromBack(); + pointer[1] = getFromBack(); + pointer[2] = getFromBack(); + pointer[3] = getFromBack(); + return ret; +} + + diff --git a/arduino_libs_0022/ByteBuffer/ByteBuffer.h b/arduino_libs_0022/ByteBuffer/ByteBuffer.h new file mode 100755 index 0000000..f6b4e48 --- /dev/null +++ b/arduino_libs_0022/ByteBuffer/ByteBuffer.h @@ -0,0 +1,74 @@ +/* + ByteBuffer.h - A circular buffer implementation for Arduino + Created by Sigurdur Orn, July 19, 2010. + siggi@mit.edu + */ + +#ifndef ByteBuffer_h +#define ByteBuffer_h + +#include "WProgram.h" + +class ByteBuffer +{ +public: + ByteBuffer(); + + // This method initializes the datastore of the buffer to a certain sizem the buffer should NOT be used before this call is made + void init(unsigned int buf_size); + + // This method resets the buffer into an original state (with no data) + void clear(); + + // This releases resources for this buffer, after this has been called the buffer should NOT be used + void deAllocate(); + + // Returns how much space is left in the buffer for more data + int getSize(); + + // Returns the maximum capacity of the buffer + int getCapacity(); + + // This method returns the byte that is located at index in the buffer but doesn't modify the buffer like the get methods (doesn't remove the retured byte from the buffer) + byte peek(unsigned int index); + + // + // Put methods, either a regular put in back or put in front + // + int putInFront(byte in); + int put(byte in); + + int putIntInFront(int in); + int putInt(int in); + + int putLongInFront(long in); + int putLong(long in); + + int putFloatInFront(float in); + int putFloat(float in); + + // + // Get methods, either a regular get from front or from back + // + byte get(); + byte getFromBack(); + + int getInt(); + int getIntFromBack(); + + long getLong(); + long getLongFromBack(); + + float getFloat(); + float getFloatFromBack(); + +private: + byte* data; + + unsigned int capacity; + unsigned int position; + unsigned int length; +}; + +#endif + diff --git a/arduino_libs_0022/NewSoftSerial/Examples/NewSoftSerialTest/NewSoftSerialTest.pde b/arduino_libs_0022/NewSoftSerial/Examples/NewSoftSerialTest/NewSoftSerialTest.pde new file mode 100644 index 0000000..0d9e815 --- /dev/null +++ b/arduino_libs_0022/NewSoftSerial/Examples/NewSoftSerialTest/NewSoftSerialTest.pde @@ -0,0 +1,25 @@ +
+#include <NewSoftSerial.h>
+
+NewSoftSerial mySerial(2, 3);
+
+void setup()
+{
+ Serial.begin(57600);
+ Serial.println("Goodnight moon!");
+
+ // set the data rate for the NewSoftSerial port
+ mySerial.begin(4800);
+ mySerial.println("Hello, world?");
+}
+
+void loop() // run over and over again
+{
+
+ if (mySerial.available()) {
+ Serial.print((char)mySerial.read());
+ }
+ if (Serial.available()) {
+ mySerial.print((char)Serial.read());
+ }
+}
diff --git a/arduino_libs_0022/NewSoftSerial/Examples/TwoNSSTest/TwoNSSTest.pde b/arduino_libs_0022/NewSoftSerial/Examples/TwoNSSTest/TwoNSSTest.pde new file mode 100644 index 0000000..73aa991 --- /dev/null +++ b/arduino_libs_0022/NewSoftSerial/Examples/TwoNSSTest/TwoNSSTest.pde @@ -0,0 +1,33 @@ +#include <NewSoftSerial.h>
+
+NewSoftSerial nss(2, 3);
+NewSoftSerial nss2(4, 5);
+
+void setup()
+{
+ nss2.begin(4800);
+ nss.begin(4800);
+ Serial.begin(115200);
+}
+
+void loop()
+{
+ // Every 10 seconds switch from
+ // one serial GPS device to the other
+ if ((millis() / 10000) % 2 == 0)
+ {
+ if (nss.available())
+ {
+ Serial.print(nss.read(), BYTE);
+ }
+ }
+
+ else
+ {
+ if (nss2.available())
+ {
+ Serial.print(nss2.read(), BYTE);
+ }
+ }
+}
+
diff --git a/arduino_libs_0022/NewSoftSerial/NewSoftSerial.cpp b/arduino_libs_0022/NewSoftSerial/NewSoftSerial.cpp new file mode 100644 index 0000000..463ab01 --- /dev/null +++ b/arduino_libs_0022/NewSoftSerial/NewSoftSerial.cpp @@ -0,0 +1,539 @@ +/*
+NewSoftSerial.cpp - Multi-instance software serial library
+Copyright (c) 2006 David A. Mellis. All rights reserved.
+-- Interrupt-driven receive and other improvements by ladyada
+-- Tuning, circular buffer, derivation from class Print,
+ multi-instance support, porting to 8MHz processors,
+ various optimizations, PROGMEM delay tables, inverse logic and
+ direct port writing by Mikal Hart
+
+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
+
+The latest version of this library can always be found at
+http://arduiniana.org.
+*/
+
+// When set, _DEBUG co-opts pins 11 and 13 for debugging with an
+// oscilloscope or logic analyzer. Beware: it also slightly modifies
+// the bit times, so don't rely on it too much at high baud rates
+#define _DEBUG 0
+#define _DEBUG_PIN1 11
+#define _DEBUG_PIN2 13
+//
+// Includes
+//
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include "WConstants.h"
+#include "pins_arduino.h"
+#include "NewSoftSerial.h"
+
+// Abstractions for maximum portability between processors
+// These are macros to associate pins to pin change interrupts
+#if !defined(digitalPinToPCICR) // Courtesy Paul Stoffregen
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
+#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)NULL))
+#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
+#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)NULL))))
+#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))
+#else
+#define digitalPinToPCICR(p) ((uint8_t *)NULL)
+#define digitalPinToPCICRbit(p) 0
+#define digitalPinToPCMSK(p) ((uint8_t *)NULL)
+#define digitalPinToPCMSKbit(p) 0
+#endif
+#endif
+
+//
+// Lookup table
+//
+typedef struct _DELAY_TABLE
+{
+ long baud;
+ unsigned short rx_delay_centering;
+ unsigned short rx_delay_intrabit;
+ unsigned short rx_delay_stopbit;
+ unsigned short tx_delay;
+} DELAY_TABLE;
+
+#if F_CPU == 16000000
+
+static const DELAY_TABLE PROGMEM table[] =
+{
+ // baud rxcenter rxintra rxstop tx
+ { 115200, 1, 17, 17, 12, },
+ { 57600, 10, 37, 37, 33, },
+ { 38400, 25, 57, 57, 54, },
+ { 31250, 31, 70, 70, 68, },
+ { 28800, 34, 77, 77, 74, },
+ { 19200, 54, 117, 117, 114, },
+ { 14400, 74, 156, 156, 153, },
+ { 9600, 114, 236, 236, 233, },
+ { 4800, 233, 474, 474, 471, },
+ { 2400, 471, 950, 950, 947, },
+ { 1200, 947, 1902, 1902, 1899, },
+ { 300, 3804, 7617, 7617, 7614, },
+};
+
+const int XMIT_START_ADJUSTMENT = 5;
+
+#elif F_CPU == 8000000
+
+static const DELAY_TABLE table[] PROGMEM =
+{
+ // baud rxcenter rxintra rxstop tx
+ { 115200, 1, 5, 5, 3, },
+ { 57600, 1, 15, 15, 13, },
+ { 38400, 2, 25, 26, 23, },
+ { 31250, 7, 32, 33, 29, },
+ { 28800, 11, 35, 35, 32, },
+ { 19200, 20, 55, 55, 52, },
+ { 14400, 30, 75, 75, 72, },
+ { 9600, 50, 114, 114, 112, },
+ { 4800, 110, 233, 233, 230, },
+ { 2400, 229, 472, 472, 469, },
+ { 1200, 467, 948, 948, 945, },
+ { 300, 1895, 3805, 3805, 3802, },
+};
+
+const int XMIT_START_ADJUSTMENT = 4;
+
+#elif F_CPU == 20000000
+
+// 20MHz support courtesy of the good people at macegr.com.
+// Thanks, Garrett!
+
+static const DELAY_TABLE PROGMEM table[] =
+{
+ // baud rxcenter rxintra rxstop tx
+ { 115200, 3, 21, 21, 18, },
+ { 57600, 20, 43, 43, 41, },
+ { 38400, 37, 73, 73, 70, },
+ { 31250, 45, 89, 89, 88, },
+ { 28800, 46, 98, 98, 95, },
+ { 19200, 71, 148, 148, 145, },
+ { 14400, 96, 197, 197, 194, },
+ { 9600, 146, 297, 297, 294, },
+ { 4800, 296, 595, 595, 592, },
+ { 2400, 592, 1189, 1189, 1186, },
+ { 1200, 1187, 2379, 2379, 2376, },
+ { 300, 4759, 9523, 9523, 9520, },
+};
+
+const int XMIT_START_ADJUSTMENT = 6;
+
+#else
+
+#error This version of NewSoftSerial supports only 20, 16 and 8MHz processors
+
+#endif
+
+//
+// Statics
+//
+NewSoftSerial *NewSoftSerial::active_object = 0;
+char NewSoftSerial::_receive_buffer[_NewSS_MAX_RX_BUFF];
+volatile uint8_t NewSoftSerial::_receive_buffer_tail = 0;
+volatile uint8_t NewSoftSerial::_receive_buffer_head = 0;
+
+//
+// Debugging
+//
+// This function generates a brief pulse
+// for debugging or measuring on an oscilloscope.
+inline void DebugPulse(uint8_t pin, uint8_t count)
+{
+#if _DEBUG
+ volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
+
+ uint8_t val = *pport;
+ while (count--)
+ {
+ *pport = val | digitalPinToBitMask(pin);
+ *pport = val;
+ }
+#endif
+}
+
+//
+// Private methods
+//
+
+/* static */
+inline void NewSoftSerial::tunedDelay(uint16_t delay) {
+ uint8_t tmp=0;
+
+ asm volatile("sbiw %0, 0x01 \n\t"
+ "ldi %1, 0xFF \n\t"
+ "cpi %A0, 0xFF \n\t"
+ "cpc %B0, %1 \n\t"
+ "brne .-10 \n\t"
+ : "+r" (delay), "+a" (tmp)
+ : "0" (delay)
+ );
+}
+
+// This function sets the current object as the "active"
+// one and returns true if it replaces another
+bool NewSoftSerial::activate(void)
+{
+ if (active_object != this)
+ {
+ _buffer_overflow = false;
+ uint8_t oldSREG = SREG;
+ cli();
+ _receive_buffer_head = _receive_buffer_tail = 0;
+ active_object = this;
+ SREG = oldSREG;
+ return true;
+ }
+
+ return false;
+}
+
+//
+// The receive routine called by the interrupt handler
+//
+void NewSoftSerial::recv()
+{
+
+#if GCC_VERSION < 40302
+// Work-around for avr-gcc 4.3.0 OSX version bug
+// Preserve the registers that the compiler misses
+// (courtesy of Arduino forum user *etracer*)
+ asm volatile(
+ "push r18 \n\t"
+ "push r19 \n\t"
+ "push r20 \n\t"
+ "push r21 \n\t"
+ "push r22 \n\t"
+ "push r23 \n\t"
+ "push r26 \n\t"
+ "push r27 \n\t"
+ ::);
+#endif
+
+ uint8_t d = 0;
+
+ // If RX line is high, then we don't see any start bit
+ // so interrupt is probably not for us
+ if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
+ {
+ // Wait approximately 1/2 of a bit width to "center" the sample
+ tunedDelay(_rx_delay_centering);
+ DebugPulse(_DEBUG_PIN2, 1);
+
+ // Read each of the 8 bits
+ for (uint8_t i=0x1; i; i <<= 1)
+ {
+ tunedDelay(_rx_delay_intrabit);
+ DebugPulse(_DEBUG_PIN2, 1);
+ uint8_t noti = ~i;
+ if (rx_pin_read())
+ d |= i;
+ else // else clause added to ensure function timing is ~balanced
+ d &= noti;
+ }
+
+ // skip the stop bit
+ tunedDelay(_rx_delay_stopbit);
+ DebugPulse(_DEBUG_PIN2, 1);
+
+ if (_inverse_logic)
+ d = ~d;
+
+ // if buffer full, set the overflow flag and return
+ if ((_receive_buffer_tail + 1) % _NewSS_MAX_RX_BUFF != _receive_buffer_head)
+ {
+ // save new data in buffer: tail points to where byte goes
+ _receive_buffer[_receive_buffer_tail] = d; // save new byte
+ _receive_buffer_tail = (_receive_buffer_tail + 1) % _NewSS_MAX_RX_BUFF;
+ }
+ else
+ {
+#if _DEBUG // for scope: pulse pin as overflow indictator
+ DebugPulse(_DEBUG_PIN1, 1);
+#endif
+ _buffer_overflow = true;
+ }
+ }
+
+#if GCC_VERSION < 40302
+// Work-around for avr-gcc 4.3.0 OSX version bug
+// Restore the registers that the compiler misses
+ asm volatile(
+ "pop r27 \n\t"
+ "pop r26 \n\t"
+ "pop r23 \n\t"
+ "pop r22 \n\t"
+ "pop r21 \n\t"
+ "pop r20 \n\t"
+ "pop r19 \n\t"
+ "pop r18 \n\t"
+ ::);
+#endif
+}
+
+void NewSoftSerial::tx_pin_write(uint8_t pin_state)
+{
+ if (pin_state == LOW)
+ *_transmitPortRegister &= ~_transmitBitMask;
+ else
+ *_transmitPortRegister |= _transmitBitMask;
+}
+
+uint8_t NewSoftSerial::rx_pin_read()
+{
+ return *_receivePortRegister & _receiveBitMask;
+}
+
+//
+// Interrupt handling
+//
+
+/* static */
+inline void NewSoftSerial::handle_interrupt()
+{
+ if (active_object)
+ {
+ active_object->recv();
+ }
+}
+
+#if defined(PCINT0_vect)
+ISR(PCINT0_vect)
+{
+ NewSoftSerial::handle_interrupt();
+}
+#endif
+
+#if defined(PCINT1_vect)
+ISR(PCINT1_vect)
+{
+ NewSoftSerial::handle_interrupt();
+}
+#endif
+
+#if defined(PCINT2_vect)
+ISR(PCINT2_vect)
+{
+ NewSoftSerial::handle_interrupt();
+}
+#endif
+
+#if defined(PCINT3_vect)
+ISR(PCINT3_vect)
+{
+ NewSoftSerial::handle_interrupt();
+}
+#endif
+
+//
+// Constructor
+//
+NewSoftSerial::NewSoftSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
+ _rx_delay_centering(0),
+ _rx_delay_intrabit(0),
+ _rx_delay_stopbit(0),
+ _tx_delay(0),
+ _buffer_overflow(false),
+ _inverse_logic(inverse_logic)
+{
+ setTX(transmitPin);
+ setRX(receivePin);
+}
+
+//
+// Destructor
+//
+NewSoftSerial::~NewSoftSerial()
+{
+ end();
+}
+
+void NewSoftSerial::setTX(uint8_t tx)
+{
+ pinMode(tx, OUTPUT);
+ digitalWrite(tx, HIGH);
+ _transmitBitMask = digitalPinToBitMask(tx);
+ uint8_t port = digitalPinToPort(tx);
+ _transmitPortRegister = portOutputRegister(port);
+}
+
+void NewSoftSerial::setRX(uint8_t rx)
+{
+ pinMode(rx, INPUT);
+ if (!_inverse_logic)
+ digitalWrite(rx, HIGH); // pullup for normal logic!
+ _receivePin = rx;
+ _receiveBitMask = digitalPinToBitMask(rx);
+ uint8_t port = digitalPinToPort(rx);
+ _receivePortRegister = portInputRegister(port);
+}
+
+//
+// Public methods
+//
+
+void NewSoftSerial::begin(long speed)
+{
+ _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
+
+ for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
+ {
+ long baud = pgm_read_dword(&table[i].baud);
+ if (baud == speed)
+ {
+ _rx_delay_centering = pgm_read_word(&table[i].rx_delay_centering);
+ _rx_delay_intrabit = pgm_read_word(&table[i].rx_delay_intrabit);
+ _rx_delay_stopbit = pgm_read_word(&table[i].rx_delay_stopbit);
+ _tx_delay = pgm_read_word(&table[i].tx_delay);
+ break;
+ }
+ }
+
+ // Set up RX interrupts, but only if we have a valid RX baud rate
+ if (_rx_delay_stopbit)
+ {
+ if (digitalPinToPCICR(_receivePin))
+ {
+ *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
+ *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
+ }
+ tunedDelay(_tx_delay); // if we were low this establishes the end
+ }
+
+#if _DEBUG
+ pinMode(_DEBUG_PIN1, OUTPUT);
+ pinMode(_DEBUG_PIN2, OUTPUT);
+#endif
+
+ activate();
+}
+
+void NewSoftSerial::end()
+{
+ if (digitalPinToPCMSK(_receivePin))
+ *digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
+}
+
+
+// Read data from buffer
+int NewSoftSerial::read(void)
+{
+ uint8_t d;
+
+ // A newly activated object never has any rx data
+ if (activate())
+ return -1;
+
+ // Empty buffer?
+ if (_receive_buffer_head == _receive_buffer_tail)
+ return -1;
+
+ // Read from "head"
+ d = _receive_buffer[_receive_buffer_head]; // grab next byte
+ _receive_buffer_head = (_receive_buffer_head + 1) % _NewSS_MAX_RX_BUFF;
+ return d;
+}
+
+uint8_t NewSoftSerial::available(void)
+{
+ // A newly activated object never has any rx data
+ if (activate())
+ return 0;
+
+ return (_receive_buffer_tail + _NewSS_MAX_RX_BUFF - _receive_buffer_head) % _NewSS_MAX_RX_BUFF;
+}
+
+void NewSoftSerial::write(uint8_t b)
+{
+ if (_tx_delay == 0)
+ return;
+
+ activate();
+
+ uint8_t oldSREG = SREG;
+ cli(); // turn off interrupts for a clean txmit
+
+ // Write the start bit
+ tx_pin_write(_inverse_logic ? HIGH : LOW);
+ tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
+
+ // Write each of the 8 bits
+ if (_inverse_logic)
+ {
+ for (byte mask = 0x01; mask; mask <<= 1)
+ {
+ if (b & mask) // choose bit
+ tx_pin_write(LOW); // send 1
+ else
+ tx_pin_write(HIGH); // send 0
+
+ tunedDelay(_tx_delay);
+ }
+
+ tx_pin_write(LOW); // restore pin to natural state
+ }
+ else
+ {
+ for (byte mask = 0x01; mask; mask <<= 1)
+ {
+ if (b & mask) // choose bit
+ tx_pin_write(HIGH); // send 1
+ else
+ tx_pin_write(LOW); // send 0
+
+ tunedDelay(_tx_delay);
+ }
+
+ tx_pin_write(HIGH); // restore pin to natural state
+ }
+
+ SREG = oldSREG; // turn interrupts back on
+ tunedDelay(_tx_delay);
+}
+
+#if !defined(cbi)
+#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#endif
+
+void NewSoftSerial::enable_timer0(bool enable)
+{
+ if (enable)
+#if defined(__AVR_ATmega8__)
+ sbi(TIMSK, TOIE0);
+#else
+ sbi(TIMSK0, TOIE0);
+#endif
+ else
+#if defined(__AVR_ATmega8__)
+ cbi(TIMSK, TOIE0);
+#else
+ cbi(TIMSK0, TOIE0);
+#endif
+}
+
+void NewSoftSerial::flush()
+{
+ if (active_object == this)
+ {
+ uint8_t oldSREG = SREG;
+ cli();
+ _receive_buffer_head = _receive_buffer_tail = 0;
+ SREG = oldSREG;
+ }
+}
diff --git a/arduino_libs_0022/NewSoftSerial/NewSoftSerial.h b/arduino_libs_0022/NewSoftSerial/NewSoftSerial.h new file mode 100644 index 0000000..1e39201 --- /dev/null +++ b/arduino_libs_0022/NewSoftSerial/NewSoftSerial.h @@ -0,0 +1,107 @@ +/*
+NewSoftSerial.h - Multi-instance software serial library
+Copyright (c) 2006 David A. Mellis. All rights reserved.
+-- Interrupt-driven receive and other improvements by ladyada
+-- Tuning, circular buffer, derivation from class Print,
+ multi-instance support, porting to 8MHz processors,
+ various optimizations, PROGMEM delay tables, inverse logic and
+ direct port writing by Mikal Hart
+
+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
+
+The latest version of this library can always be found at
+http://arduiniana.org.
+*/
+
+#ifndef NewSoftSerial_h
+#define NewSoftSerial_h
+
+#include <inttypes.h>
+#include "Print.h"
+
+/******************************************************************************
+* Definitions
+******************************************************************************/
+
+#define _NewSS_MAX_RX_BUFF 64 // RX buffer size
+#define _NewSS_VERSION 10 // software version of this library
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
+class NewSoftSerial : public Print
+{
+private:
+ // per object data
+ uint8_t _receivePin;
+ uint8_t _receiveBitMask;
+ volatile uint8_t *_receivePortRegister;
+ uint8_t _transmitBitMask;
+ volatile uint8_t *_transmitPortRegister;
+
+ uint16_t _rx_delay_centering;
+ uint16_t _rx_delay_intrabit;
+ uint16_t _rx_delay_stopbit;
+ uint16_t _tx_delay;
+
+ uint16_t _buffer_overflow:1;
+ uint16_t _inverse_logic:1;
+
+ // static data
+ static char _receive_buffer[_NewSS_MAX_RX_BUFF];
+ static volatile uint8_t _receive_buffer_tail;
+ static volatile uint8_t _receive_buffer_head;
+ static NewSoftSerial *active_object;
+
+ // private methods
+ void recv();
+ bool activate();
+ virtual void write(uint8_t byte);
+ uint8_t rx_pin_read();
+ void tx_pin_write(uint8_t pin_state);
+ void setTX(uint8_t transmitPin);
+ void setRX(uint8_t receivePin);
+
+ // private static method for timing
+ static inline void tunedDelay(uint16_t delay);
+
+public:
+ // public methods
+ NewSoftSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
+ ~NewSoftSerial();
+ void begin(long speed);
+ void end();
+ int read();
+ uint8_t available(void);
+ bool active() { return this == active_object; }
+ bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
+ static int library_version() { return _NewSS_VERSION; }
+ static void enable_timer0(bool enable);
+ void flush();
+
+ // public only for easy access by interrupt handlers
+ static inline void handle_interrupt();
+};
+
+// Arduino 0012 workaround
+#undef int
+#undef char
+#undef long
+#undef byte
+#undef float
+#undef abs
+#undef round
+
+#endif
diff --git a/arduino_libs_0022/NewSoftSerial/keywords.txt b/arduino_libs_0022/NewSoftSerial/keywords.txt new file mode 100644 index 0000000..0a39bea --- /dev/null +++ b/arduino_libs_0022/NewSoftSerial/keywords.txt @@ -0,0 +1,30 @@ +####################################### +# Syntax Coloring Map for NewSoftSerial +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +NewSoftSerial KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +setTX KEYWORD2 +setRX KEYWORD2 +begin KEYWORD2 +end KEYWORD2 +read KEYWORD2 +available KEYWORD2 +active KEYWORD2 +overflow KEYWORD2 +library_version KEYWORD2 +enable_timer0 KEYWORD2 +flush KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/arduino_libs_0022/SerialManager/.DS_Store b/arduino_libs_0022/SerialManager/.DS_Store Binary files differnew file mode 100755 index 0000000..5008ddf --- /dev/null +++ b/arduino_libs_0022/SerialManager/.DS_Store diff --git a/arduino_libs_0022/SerialManager/.svn/all-wcprops b/arduino_libs_0022/SerialManager/.svn/all-wcprops new file mode 100755 index 0000000..e920984 --- /dev/null +++ b/arduino_libs_0022/SerialManager/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 58 +/r/prg/!svn/ver/5369/trunk/arduino/libraries/SerialManager +END +SerialManager.h +K 25 +svn:wc:ra_dav:version-url +V 74 +/r/prg/!svn/ver/5812/trunk/arduino/libraries/SerialManager/SerialManager.h +END +SerialManager.cpp +K 25 +svn:wc:ra_dav:version-url +V 76 +/r/prg/!svn/ver/5812/trunk/arduino/libraries/SerialManager/SerialManager.cpp +END diff --git a/arduino_libs_0022/SerialManager/.svn/entries b/arduino_libs_0022/SerialManager/.svn/entries new file mode 100755 index 0000000..a965507 --- /dev/null +++ b/arduino_libs_0022/SerialManager/.svn/entries @@ -0,0 +1,144 @@ +10 + +dir +5369 +https://svn.media.mit.edu/r/prg/trunk/arduino/libraries/SerialManager +https://svn.media.mit.edu/r/prg + + + +2010-07-20T00:55:06.830758Z +5369 +siggi + + + + + + + + + + + + + + +bd000cc4-1869-4481-ad02-c3af97ea9c83 + +SerialManager.h +file +5812 + + + +2010-09-02T16:01:59.000000Z +81120736a5f09269c146fab073728dcf +2010-09-02T18:42:42.362483Z +5812 +siggi + + + + + + + + + + + + + + + + + + + + + +1242 + +SerialPacketHandler.cpp +file +5812 + + + + + + + + + + + + + + + + + + + +deleted + +SerialManager.cpp +file +5812 + + + +2010-09-02T16:02:09.000000Z +d7812d43c015d22e6970f3b8884d9b37 +2010-09-02T18:42:42.362483Z +5812 +siggi + + + + + + + + + + + + + + + + + + + + + +4793 + +SerialPacketHandler.h +file +5812 + + + + + + + + + + + + + + + + + + + +deleted + diff --git a/arduino_libs_0022/SerialManager/.svn/text-base/SerialManager.cpp.svn-base b/arduino_libs_0022/SerialManager/.svn/text-base/SerialManager.cpp.svn-base new file mode 100755 index 0000000..ed06dbc --- /dev/null +++ b/arduino_libs_0022/SerialManager/.svn/text-base/SerialManager.cpp.svn-base @@ -0,0 +1,197 @@ +/* + SerialManager.cpp - Library for doing packetized serial comm with Arduinos. + Created by Sigurdur Orn, May 23, 2010. + */ + +#include "WProgram.h" +#include "SerialManager.h" +#include "ByteBuffer.h" + + +SerialManager::SerialManager(unsigned int in_buf_size, unsigned int out_buf_size){ + serial_in_checksum = 0; + + incoming_buffer = (ByteBuffer*)malloc(sizeof(ByteBuffer)); + outgoing_buffer = (ByteBuffer*)malloc(sizeof(ByteBuffer)); + temp_buffer = (ByteBuffer*)malloc(sizeof(ByteBuffer)); + + incoming_buffer->init(in_buf_size); + outgoing_buffer->init(out_buf_size); + temp_buffer->init(10); + + byte1 = 0; + byte2 = 0; + byte3 = 0; + byte4 = 0; + + handlePacketFunction = 0; +} + +void SerialManager::init(int serial_port, int baud_rate){ + _serial_port = serial_port; + + if( serial_port == 0) + Serial.begin(baud_rate); +#if defined(__AVR_ATmega1280__) + else if( serial_port == 1) + Serial1.begin(baud_rate); + else if( serial_port == 2) + Serial2.begin(baud_rate); + else if( serial_port == 3) + Serial3.begin(baud_rate); +#endif +} + + + +bool SerialManager::isBusySending(){ + return ( outgoing_buffer->getSize() > 0 ); +} + +// Sends a single byte +int SerialManager::sendSerialByte(byte b){ + return outgoing_buffer->put(b); +} + +// Sends a packet with a header and a checksum +int SerialManager::sendSerialPacket(ByteBuffer* packet_buffer){ + // Copy buffer and calc checksum + byte checksum = 0; + while( packet_buffer->getSize() > 0 ){ + byte b = packet_buffer->get(); + outgoing_buffer->put(b); + checksum += b; + } + + outgoing_buffer->put( checksum ); + outgoing_buffer->put( 1 ); + outgoing_buffer->put( 2 ); + outgoing_buffer->put( 3 ); + outgoing_buffer->put( 4 ); + + return 0; +} + +// Sends a raw packet with no header or checksum +int SerialManager::sendRawSerial(ByteBuffer* packet_buffer){ + while( packet_buffer->getSize() > 0 ){ + byte b = packet_buffer->get(); + outgoing_buffer->put(b); + } + + return 0; +} + +void SerialManager::update(){ + + // If we have received stuff + if( _serial_port == 0 ){ + while( Serial.available() != 0 ) { + byte incoming = Serial.read(); + handleIncomingByte(incoming); + } + } + +#if defined(__AVR_ATmega1280__) + else if( _serial_port == 1 ){ + while( Serial1.available() != 0 ) { + byte incoming = Serial1.read(); + handleIncomingByte(incoming); + } + } + else if( _serial_port == 2 ){ + while( Serial2.available() != 0 ) { + byte incoming = Serial2.read(); + handleIncomingByte(incoming); + } + } + else if( _serial_port == 3 ){ + while( Serial3.available() != 0 ) { + byte incoming = Serial3.read(); + handleIncomingByte(incoming); + } + } +#endif + + + // If we should be sending stuff + if( outgoing_buffer->getSize() > 0 ){ + // If serial port not currently busy + if( _serial_port == 0 ) + if(((UCSRA) & (1 << UDRE)) ) Serial.write( outgoing_buffer->get() ); + +#if defined(__AVR_ATmega1280__) + else if( _serial_port == 1 ) + if(((UCSRA1) & (1 << UDRE1)) ) Serial1.write( outgoing_buffer->get() ); + else if( _serial_port == 2 ) + if(((UCSRA2) & (1 << UDRE2)) ) Serial2.write( outgoing_buffer->get() ); + else if( _serial_port == 3 ) + if(((UCSRA3) & (1 << UDRE3)) ) Serial3.write( outgoing_buffer->get() ); +#endif + } +} + +void SerialManager::setPacketHandler(void (*packetHandlerFunction)(ByteBuffer*)){ + handlePacketFunction = packetHandlerFunction; +} + + +void SerialManager::handleIncomingByte(byte incoming){ + + // If buffer overflows then reset (we could do something smarter here) +// if( incoming_buffer->getSize() == incoming_buffer->getCapacity() ){ +// incoming_buffer->clear(); +// } + + incoming_buffer->put( incoming ); + serial_in_checksum += incoming; + + byte1 = byte2; + byte2 = byte3; + byte3 = byte4; + byte4 = incoming; + + // If we have a full packet ready + if( byte1==1 && byte2==2 && byte3==3 && byte4==4 ){ + // Remove header from buffer + incoming_buffer->getFromBack(); + incoming_buffer->getFromBack(); + incoming_buffer->getFromBack(); + incoming_buffer->getFromBack(); + + byte checksum_received = incoming_buffer->getFromBack(); + + // Remove the whole header from the calculated checksum + serial_in_checksum -= checksum_received + 10; + + // If checksums don't match, then do something () + if( checksum_received != serial_in_checksum ){ + temp_buffer->clear(); + temp_buffer->put(123); + temp_buffer->put(234); + temp_buffer->put( checksum_received ); + temp_buffer->put( serial_in_checksum ); + sendSerialPacket(temp_buffer); + } + + // We have a successful packet + else{ + + if( handlePacketFunction != 0 ) + handlePacketFunction(incoming_buffer); + else + handlePacketDefault(incoming_buffer); + } + + // Clear variables + incoming_buffer->clear(); + serial_in_checksum = 0; + } + +} + +void SerialManager::handlePacketDefault(ByteBuffer* packet){ + // We could do something here like send the data to the host again for debug + // Or just do nothing + return; +} diff --git a/arduino_libs_0022/SerialManager/.svn/text-base/SerialManager.h.svn-base b/arduino_libs_0022/SerialManager/.svn/text-base/SerialManager.h.svn-base new file mode 100755 index 0000000..dcbdba6 --- /dev/null +++ b/arduino_libs_0022/SerialManager/.svn/text-base/SerialManager.h.svn-base @@ -0,0 +1,63 @@ +/* + SerialManager.h - Library for doing packetized serial comm with Arduinos. + Created by Sigurdur Orn, May 23, 2010. + */ +#ifndef SerialManager_h +#define SerialManager_h + +#include "ByteBuffer.h" +#include "WProgram.h" + +typedef void (*voidFuncPtr)(ByteBuffer*); + +#if defined(__AVR_ATmega8__) + #define UCSRA UCSRA + #define UDRE UDRE +#else + #define UCSRA UCSR0A + #define UDRE UDRE0 +#endif + +#if defined(__AVR_ATmega1280__) + #define UCSRA1 UCSR1A + #define UDRE1 UDRE1 + #define UCSRA2 UCSR2A + #define UDRE2 UDRE2 + #define UCSRA3 UCSR3A + #define UDRE3 UDRE3 +#endif + + +class SerialManager +{ +public: + SerialManager(unsigned int in_buf_size, unsigned int out_buf_size); + void init(int serial_port, int baud_rate); + void setPacketHandler(void (*rx_func)(ByteBuffer*)); + + void update(); + bool isBusySending(); + + int sendSerialByte(byte b); + int sendSerialPacket(ByteBuffer* packet); + int sendRawSerial(ByteBuffer* packet); + +private: + void handleIncomingByte(byte incoming); + void handlePacketDefault(ByteBuffer* packet); + + voidFuncPtr handlePacketFunction; + + byte _serial_port; + ByteBuffer* incoming_buffer; + ByteBuffer* outgoing_buffer; + ByteBuffer* temp_buffer; + byte serial_in_checksum; + byte byte1; + byte byte2; + byte byte3; + byte byte4; +}; + +#endif + diff --git a/arduino_libs_0022/SerialManager/SerialManager.cpp b/arduino_libs_0022/SerialManager/SerialManager.cpp new file mode 100755 index 0000000..2e2d306 --- /dev/null +++ b/arduino_libs_0022/SerialManager/SerialManager.cpp @@ -0,0 +1,193 @@ +/* + SerialManager.cpp - Library for doing packetized serial comm with Arduinos. + Created by Sigurdur Orn, May 23, 2010. + siggi@mit.edu + */ + +#include "WProgram.h" +#include "SerialManager.h" +#include "ByteBuffer.h" + + +SerialManager::SerialManager(unsigned int in_buf_size, unsigned int out_buf_size){ + serial_in_checksum = 0; + + incoming_buffer = (ByteBuffer*)malloc(sizeof(ByteBuffer)); + outgoing_buffer = (ByteBuffer*)malloc(sizeof(ByteBuffer)); + temp_buffer = (ByteBuffer*)malloc(sizeof(ByteBuffer)); + + incoming_buffer->init(in_buf_size); + outgoing_buffer->init(out_buf_size); + temp_buffer->init(10); + + byte1 = 0; + byte2 = 0; + byte3 = 0; + byte4 = 0; + + handlePacketFunction = 0; +} + +void SerialManager::init(int serial_port, int baud_rate){ + _serial_port = serial_port; + + if( serial_port == 0) + Serial.begin(baud_rate); +#if defined(__AVR_ATmega1280__) + else if( serial_port == 1) + Serial1.begin(baud_rate); + else if( serial_port == 2) + Serial2.begin(baud_rate); + else if( serial_port == 3) + Serial3.begin(baud_rate); +#endif +} + + + +bool SerialManager::isBusySending(){ + return ( outgoing_buffer->getSize() > 0 ); +} + +// Sends a single byte +int SerialManager::sendSerialByte(byte b){ + return outgoing_buffer->put(b); +} + +// Sends a packet with a header and a checksum +int SerialManager::sendSerialPacket(ByteBuffer* packet_buffer){ + // Copy buffer and calc checksum + byte checksum = 0; + while( packet_buffer->getSize() > 0 ){ + byte b = packet_buffer->get(); + outgoing_buffer->put(b); + checksum += b; + } + + outgoing_buffer->put( checksum ); + outgoing_buffer->put( 1 ); + outgoing_buffer->put( 2 ); + outgoing_buffer->put( 3 ); + outgoing_buffer->put( 4 ); + + return 0; +} + +// Sends a raw packet with no header or checksum +int SerialManager::sendRawSerial(ByteBuffer* packet_buffer){ + while( packet_buffer->getSize() > 0 ){ + byte b = packet_buffer->get(); + outgoing_buffer->put(b); + } + + return 0; +} + +void SerialManager::update(){ + + // If we have received stuff + if( _serial_port == 0 ){ + while( Serial.available() != 0 ) { + byte incoming = Serial.read(); + handleIncomingByte(incoming); + } + } + +#if defined(__AVR_ATmega1280__) + else if( _serial_port == 1 ){ + while( Serial1.available() != 0 ) { + byte incoming = Serial1.read(); + handleIncomingByte(incoming); + } + } + else if( _serial_port == 2 ){ + while( Serial2.available() != 0 ) { + byte incoming = Serial2.read(); + handleIncomingByte(incoming); + } + } + else if( _serial_port == 3 ){ + while( Serial3.available() != 0 ) { + byte incoming = Serial3.read(); + handleIncomingByte(incoming); + } + } +#endif + + + // If we should be sending stuff + if( outgoing_buffer->getSize() > 0 ){ + // If serial port not currently busy + if( _serial_port == 0 ) + if(((UCSRA) & (1 << UDRE)) ) Serial.write( outgoing_buffer->get() ); + +#if defined(__AVR_ATmega1280__) + else if( _serial_port == 1 ) + if(((UCSR1A) & (1 << UDRE1)) ) Serial1.write( outgoing_buffer->get() ); + else if( _serial_port == 2 ) + if(((UCSR2A) & (1 << UDRE2)) ) Serial2.write( outgoing_buffer->get() ); + else if( _serial_port == 3 ) + if(((UCSR3A) & (1 << UDRE3)) ) Serial3.write( outgoing_buffer->get() ); +#endif + } +} + +void SerialManager::setPacketHandler(void (*packetHandlerFunction)(ByteBuffer*)){ + handlePacketFunction = packetHandlerFunction; +} + + +void SerialManager::handleIncomingByte(byte incoming){ + + // If buffer overflows then reset (we could do something smarter here) + if( incoming_buffer->getSize() == incoming_buffer->getCapacity() ){ + incoming_buffer->clear(); + } + + incoming_buffer->put( incoming ); + serial_in_checksum += incoming; + + byte1 = byte2; + byte2 = byte3; + byte3 = byte4; + byte4 = incoming; + + // If we have a full packet ready + if( byte1==1 && byte2==2 && byte3==3 && byte4==4 ){ + // Remove header from buffer + incoming_buffer->getFromBack(); + incoming_buffer->getFromBack(); + incoming_buffer->getFromBack(); + incoming_buffer->getFromBack(); + + byte checksum_received = incoming_buffer->getFromBack(); + + // Remove the whole header from the calculated checksum + serial_in_checksum -= checksum_received + 10; + + // If checksums don't match, then do something () + if( checksum_received != serial_in_checksum ){ + ; // We could do something about this here + } + + // We have a successful packet + else{ + + if( handlePacketFunction != 0 ) + handlePacketFunction(incoming_buffer); + else + handlePacketDefault(incoming_buffer); + } + + // Clear variables + incoming_buffer->clear(); + serial_in_checksum = 0; + } + +} + +void SerialManager::handlePacketDefault(ByteBuffer* packet){ + // We could do something here like send the data to the host again for debug + // Or just do nothing + return; +} diff --git a/arduino_libs_0022/SerialManager/SerialManager.h b/arduino_libs_0022/SerialManager/SerialManager.h new file mode 100755 index 0000000..f1474c5 --- /dev/null +++ b/arduino_libs_0022/SerialManager/SerialManager.h @@ -0,0 +1,62 @@ +/* + SerialManager.h - Library for doing packetized serial comm with Arduinos. + Created by Sigurdur Orn, May 23, 2010. + siggi@mit.edu + */ + +#ifndef SerialManager_h +#define SerialManager_h + +#include "ByteBuffer.h" +#include "WProgram.h" + +typedef void (*voidFuncPtr)(ByteBuffer*); + +#if defined(__AVR_ATmega8__) + #define UCSRA UCSRA + #define UDRE UDRE +#else + #define UCSRA UCSR0A + #define UDRE UDRE0 +#endif + +#if defined(__AVR_ATmega1280__) + #define UCSRA1 UCSR1A + #define UCSRA2 UCSR2A + #define UCSRA3 UCSR3A +#endif + + +class SerialManager +{ +public: + SerialManager(unsigned int in_buf_size, unsigned int out_buf_size); + void init(int serial_port, int baud_rate); + void setPacketHandler(void (*rx_func)(ByteBuffer*)); + + void update(); + bool isBusySending(); + + int sendSerialByte(byte b); + int sendSerialPacket(ByteBuffer* packet); + int sendRawSerial(ByteBuffer* packet); + +private: + void handleIncomingByte(byte incoming); + void handlePacketDefault(ByteBuffer* packet); + + voidFuncPtr handlePacketFunction; + + byte _serial_port; + ByteBuffer* incoming_buffer; + ByteBuffer* outgoing_buffer; + ByteBuffer* temp_buffer; + byte serial_in_checksum; + byte byte1; + byte byte2; + byte byte3; + byte byte4; +}; + +#endif + diff --git a/arduino_libs_0022/Wire/Wire.cpp b/arduino_libs_0022/Wire/Wire.cpp new file mode 100644 index 0000000..849439b --- /dev/null +++ b/arduino_libs_0022/Wire/Wire.cpp @@ -0,0 +1,261 @@ +/* + TwoWire.cpp - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +extern "C" { + #include <stdlib.h> + #include <string.h> + #include <inttypes.h> + #include "twi.h" +} + +#include "Wire.h" + +// Initialize Class Variables ////////////////////////////////////////////////// + +uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; +uint8_t TwoWire::rxBufferIndex = 0; +uint8_t TwoWire::rxBufferLength = 0; + +uint8_t TwoWire::txAddress = 0; +uint8_t TwoWire::txBuffer[BUFFER_LENGTH]; +uint8_t TwoWire::txBufferIndex = 0; +uint8_t TwoWire::txBufferLength = 0; + +uint8_t TwoWire::transmitting = 0; +void (*TwoWire::user_onRequest)(void); +void (*TwoWire::user_onReceive)(int); + +// Constructors //////////////////////////////////////////////////////////////// + +TwoWire::TwoWire() +{ +} + +// Public Methods ////////////////////////////////////////////////////////////// + +void TwoWire::begin(void) +{ + rxBufferIndex = 0; + rxBufferLength = 0; + + txBufferIndex = 0; + txBufferLength = 0; + + twi_init(); +} + +void TwoWire::begin(uint8_t address) +{ + twi_setAddress(address); + twi_attachSlaveTxEvent(onRequestService); + twi_attachSlaveRxEvent(onReceiveService); + begin(); +} + +void TwoWire::begin(int address) +{ + begin((uint8_t)address); +} + +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) +{ + // clamp to buffer length + if(quantity > BUFFER_LENGTH){ + quantity = BUFFER_LENGTH; + } + // perform blocking read into buffer + uint8_t read = twi_readFrom(address, rxBuffer, quantity); + // set rx buffer iterator vars + rxBufferIndex = 0; + rxBufferLength = read; + + return read; +} + +uint8_t TwoWire::requestFrom(int address, int quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity); +} + +void TwoWire::beginTransmission(uint8_t address) +{ + // indicate that we are transmitting + transmitting = 1; + // set address of targeted slave + txAddress = address; + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; +} + +void TwoWire::beginTransmission(int address) +{ + beginTransmission((uint8_t)address); +} + +uint8_t TwoWire::endTransmission(void) +{ + // transmit buffer (blocking) + int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1); + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; + // indicate that we are done transmitting + transmitting = 0; + return ret; +} + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +void TwoWire::send(uint8_t data) +{ + if(transmitting){ + // in master transmitter mode + // don't bother if buffer is full + if(txBufferLength >= BUFFER_LENGTH){ + return; + } + // put byte in tx buffer + txBuffer[txBufferIndex] = data; + ++txBufferIndex; + // update amount in buffer + txBufferLength = txBufferIndex; + }else{ + // in slave send mode + // reply to master + twi_transmit(&data, 1); + } +} + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +void TwoWire::send(uint8_t* data, uint8_t quantity) +{ + if(transmitting){ + // in master transmitter mode + for(uint8_t i = 0; i < quantity; ++i){ + send(data[i]); + } + }else{ + // in slave send mode + // reply to master + twi_transmit(data, quantity); + } +} + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +void TwoWire::send(char* data) +{ + send((uint8_t*)data, strlen(data)); +} + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +void TwoWire::send(int data) +{ + send((uint8_t)data); +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +uint8_t TwoWire::available(void) +{ + return rxBufferLength - rxBufferIndex; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +uint8_t TwoWire::receive(void) +{ + // default to returning null char + // for people using with char strings + uint8_t value = '\0'; + + // get each successive byte on each call + if(rxBufferIndex < rxBufferLength){ + value = rxBuffer[rxBufferIndex]; + ++rxBufferIndex; + } + + return value; +} + +// behind the scenes function that is called when data is received +void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) +{ + // don't bother if user hasn't registered a callback + if(!user_onReceive){ + return; + } + // don't bother if rx buffer is in use by a master requestFrom() op + // i know this drops data, but it allows for slight stupidity + // meaning, they may not have read all the master requestFrom() data yet + if(rxBufferIndex < rxBufferLength){ + return; + } + // copy twi rx buffer into local read buffer + // this enables new reads to happen in parallel + for(uint8_t i = 0; i < numBytes; ++i){ + rxBuffer[i] = inBytes[i]; + } + // set rx iterator vars + rxBufferIndex = 0; + rxBufferLength = numBytes; + // alert user program + user_onReceive(numBytes); +} + +// behind the scenes function that is called when data is requested +void TwoWire::onRequestService(void) +{ + // don't bother if user hasn't registered a callback + if(!user_onRequest){ + return; + } + // reset tx buffer iterator vars + // !!! this will kill any pending pre-master sendTo() activity + txBufferIndex = 0; + txBufferLength = 0; + // alert user program + user_onRequest(); +} + +// sets function called on slave write +void TwoWire::onReceive( void (*function)(int) ) +{ + user_onReceive = function; +} + +// sets function called on slave read +void TwoWire::onRequest( void (*function)(void) ) +{ + user_onRequest = function; +} + +// Preinstantiate Objects ////////////////////////////////////////////////////// + +TwoWire Wire = TwoWire(); + diff --git a/arduino_libs_0022/Wire/Wire.h b/arduino_libs_0022/Wire/Wire.h new file mode 100644 index 0000000..a6c29c4 --- /dev/null +++ b/arduino_libs_0022/Wire/Wire.h @@ -0,0 +1,67 @@ +/* + TwoWire.h - TWI/I2C library for Arduino & Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef TwoWire_h +#define TwoWire_h + +#include <inttypes.h> + +#define BUFFER_LENGTH 32 + +class TwoWire +{ + private: + static uint8_t rxBuffer[]; + static uint8_t rxBufferIndex; + static uint8_t rxBufferLength; + + static uint8_t txAddress; + static uint8_t txBuffer[]; + static uint8_t txBufferIndex; + static uint8_t txBufferLength; + + static uint8_t transmitting; + static void (*user_onRequest)(void); + static void (*user_onReceive)(int); + static void onRequestService(void); + static void onReceiveService(uint8_t*, int); + public: + TwoWire(); + void begin(); + void begin(uint8_t); + void begin(int); + void beginTransmission(uint8_t); + void beginTransmission(int); + uint8_t endTransmission(void); + uint8_t requestFrom(uint8_t, uint8_t); + uint8_t requestFrom(int, int); + void send(uint8_t); + void send(uint8_t*, uint8_t); + void send(int); + void send(char*); + uint8_t available(void); + uint8_t receive(void); + void onReceive( void (*)(int) ); + void onRequest( void (*)(void) ); +}; + +extern TwoWire Wire; + +#endif + diff --git a/arduino_libs_0022/Wire/keywords.txt b/arduino_libs_0022/Wire/keywords.txt new file mode 100644 index 0000000..12f129b --- /dev/null +++ b/arduino_libs_0022/Wire/keywords.txt @@ -0,0 +1,31 @@ +####################################### +# Syntax Coloring Map For Wire +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +beginTransmission KEYWORD2 +endTransmission KEYWORD2 +requestFrom KEYWORD2 +send KEYWORD2 +receive KEYWORD2 +onReceive KEYWORD2 +onRequest KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +Wire KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/arduino_libs_0022/Wire/utility/twi.c b/arduino_libs_0022/Wire/utility/twi.c new file mode 100644 index 0000000..236878c --- /dev/null +++ b/arduino_libs_0022/Wire/utility/twi.c @@ -0,0 +1,476 @@ +/* + twi.c - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include <math.h> +#include <stdlib.h> +#include <inttypes.h> +#include <avr/io.h> +#include <avr/interrupt.h> +#include <compat/twi.h> + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif + +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#include "twi.h" + +static volatile uint8_t twi_state; +static uint8_t twi_slarw; + +static void (*twi_onSlaveTransmit)(void); +static void (*twi_onSlaveReceive)(uint8_t*, int); + +static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_masterBufferIndex; +static uint8_t twi_masterBufferLength; + +static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_txBufferIndex; +static volatile uint8_t twi_txBufferLength; + +static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_rxBufferIndex; + +static volatile uint8_t twi_error; + +/* + * Function twi_init + * Desc readys twi pins and sets twi bitrate + * Input none + * Output none + */ +void twi_init(void) +{ + // initialize state + twi_state = TWI_READY; + + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) + // activate internal pull-ups for twi + // as per note from atmega8 manual pg167 + sbi(PORTC, 4); + sbi(PORTC, 5); + #else + // activate internal pull-ups for twi + // as per note from atmega128 manual pg204 + sbi(PORTD, 0); + sbi(PORTD, 1); + #endif + + // initialize twi prescaler and bit rate + cbi(TWSR, TWPS0); + cbi(TWSR, TWPS1); + TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) + note: TWBR should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ + + // enable twi module, acks, and twi interrupt + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); +} + +/* + * Function twi_slaveInit + * Desc sets slave address and enables interrupt + * Input none + * Output none + */ +void twi_setAddress(uint8_t address) +{ + // set twi slave address (skip over TWGCE bit) + TWAR = address << 1; +} + +/* + * Function twi_readFrom + * Desc attempts to become twi bus master and read a + * series of bytes from a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes to read into array + * Output number of bytes read + */ +uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 0; + } + + // wait until twi is ready, become master receiver + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MRX; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length-1; // This is not intuitive, read on... + // On receive, the previously configured ACK/NACK setting is transmitted in + // response to the received byte before the interrupt is signalled. + // Therefor we must actually set NACK when the _next_ to last byte is + // received, causing that NACK to be sent in response to receiving the last + // expected byte of data. + + // build sla+w, slave device address + w bit + twi_slarw = TW_READ; + twi_slarw |= address << 1; + + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + + // wait for read operation to complete + while(TWI_MRX == twi_state){ + continue; + } + + if (twi_masterBufferIndex < length) + length = twi_masterBufferIndex; + + // copy twi buffer to data + for(i = 0; i < length; ++i){ + data[i] = twi_masterBuffer[i]; + } + + return length; +} + +/* + * Function twi_writeTo + * Desc attempts to become twi bus master and write a + * series of bytes to a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes in array + * wait: boolean indicating to wait for write or not + * Output 0 .. success + * 1 .. length to long for buffer + * 2 .. address send, NACK received + * 3 .. data send, NACK received + * 4 .. other twi error (lost bus arbitration, bus error, ..) + */ +uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // wait until twi is ready, become master transmitter + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MTX; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length; + + // copy data to twi buffer + for(i = 0; i < length; ++i){ + twi_masterBuffer[i] = data[i]; + } + + // build sla+w, slave device address + w bit + twi_slarw = TW_WRITE; + twi_slarw |= address << 1; + + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + + // wait for write operation to complete + while(wait && (TWI_MTX == twi_state)){ + continue; + } + + if (twi_error == 0xFF) + return 0; // success + else if (twi_error == TW_MT_SLA_NACK) + return 2; // error: address send, nack received + else if (twi_error == TW_MT_DATA_NACK) + return 3; // error: data send, nack received + else + return 4; // other twi error +} + +/* + * Function twi_transmit + * Desc fills slave tx buffer with data + * must be called in slave tx event callback + * Input data: pointer to byte array + * length: number of bytes in array + * Output 1 length too long for buffer + * 2 not slave transmitter + * 0 ok + */ +uint8_t twi_transmit(uint8_t* data, uint8_t length) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // ensure we are currently a slave transmitter + if(TWI_STX != twi_state){ + return 2; + } + + // set length and copy data into tx buffer + twi_txBufferLength = length; + for(i = 0; i < length; ++i){ + twi_txBuffer[i] = data[i]; + } + + return 0; +} + +/* + * Function twi_attachSlaveRxEvent + * Desc sets function called before a slave read operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) +{ + twi_onSlaveReceive = function; +} + +/* + * Function twi_attachSlaveTxEvent + * Desc sets function called before a slave write operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveTxEvent( void (*function)(void) ) +{ + twi_onSlaveTransmit = function; +} + +/* + * Function twi_reply + * Desc sends byte or readys receive line + * Input ack: byte indicating to ack or to nack + * Output none + */ +void twi_reply(uint8_t ack) +{ + // transmit master read ready signal, with or without ack + if(ack){ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); + }else{ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); + } +} + +/* + * Function twi_stop + * Desc relinquishes bus master status + * Input none + * Output none + */ +void twi_stop(void) +{ + // send stop condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); + + // wait for stop condition to be exectued on bus + // TWINT is not set after a stop condition! + while(TWCR & _BV(TWSTO)){ + continue; + } + + // update twi state + twi_state = TWI_READY; +} + +/* + * Function twi_releaseBus + * Desc releases bus control + * Input none + * Output none + */ +void twi_releaseBus(void) +{ + // release bus + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); + + // update twi state + twi_state = TWI_READY; +} + +SIGNAL(TWI_vect) +{ + switch(TW_STATUS){ + // All Master + case TW_START: // sent start condition + case TW_REP_START: // sent repeated start condition + // copy device address and r/w bit to output register and ack + TWDR = twi_slarw; + twi_reply(1); + break; + + // Master Transmitter + case TW_MT_SLA_ACK: // slave receiver acked address + case TW_MT_DATA_ACK: // slave receiver acked data + // if there is data to send, send it, otherwise stop + if(twi_masterBufferIndex < twi_masterBufferLength){ + // copy data to output register and ack + TWDR = twi_masterBuffer[twi_masterBufferIndex++]; + twi_reply(1); + }else{ + twi_stop(); + } + break; + case TW_MT_SLA_NACK: // address sent, nack received + twi_error = TW_MT_SLA_NACK; + twi_stop(); + break; + case TW_MT_DATA_NACK: // data sent, nack received + twi_error = TW_MT_DATA_NACK; + twi_stop(); + break; + case TW_MT_ARB_LOST: // lost bus arbitration + twi_error = TW_MT_ARB_LOST; + twi_releaseBus(); + break; + + // Master Receiver + case TW_MR_DATA_ACK: // data received, ack sent + // put byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + case TW_MR_SLA_ACK: // address sent, ack received + // ack if more bytes are expected, otherwise nack + if(twi_masterBufferIndex < twi_masterBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_MR_DATA_NACK: // data received, nack sent + // put final byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + case TW_MR_SLA_NACK: // address sent, nack received + twi_stop(); + break; + // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case + + // Slave Receiver + case TW_SR_SLA_ACK: // addressed, returned ack + case TW_SR_GCALL_ACK: // addressed generally, returned ack + case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack + case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack + // enter slave receiver mode + twi_state = TWI_SRX; + // indicate that rx buffer can be overwritten and ack + twi_rxBufferIndex = 0; + twi_reply(1); + break; + case TW_SR_DATA_ACK: // data received, returned ack + case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack + // if there is still room in the rx buffer + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + // put byte in buffer and ack + twi_rxBuffer[twi_rxBufferIndex++] = TWDR; + twi_reply(1); + }else{ + // otherwise nack + twi_reply(0); + } + break; + case TW_SR_STOP: // stop or repeated start condition received + // put a null char after data if there's room + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + twi_rxBuffer[twi_rxBufferIndex] = '\0'; + } + // sends ack and stops interface for clock stretching + twi_stop(); + // callback to user defined callback + twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); + // since we submit rx buffer to "wire" library, we can reset it + twi_rxBufferIndex = 0; + // ack future responses and leave slave receiver state + twi_releaseBus(); + break; + case TW_SR_DATA_NACK: // data received, returned nack + case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack + // nack back at master + twi_reply(0); + break; + + // Slave Transmitter + case TW_ST_SLA_ACK: // addressed, returned ack + case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack + // enter slave transmitter mode + twi_state = TWI_STX; + // ready the tx buffer index for iteration + twi_txBufferIndex = 0; + // set tx buffer length to be zero, to verify if user changes it + twi_txBufferLength = 0; + // request for txBuffer to be filled and length to be set + // note: user must call twi_transmit(bytes, length) to do this + twi_onSlaveTransmit(); + // if they didn't change buffer & length, initialize it + if(0 == twi_txBufferLength){ + twi_txBufferLength = 1; + twi_txBuffer[0] = 0x00; + } + // transmit first byte from buffer, fall + case TW_ST_DATA_ACK: // byte sent, ack returned + // copy data to output register + TWDR = twi_txBuffer[twi_txBufferIndex++]; + // if there is more to send, ack, otherwise nack + if(twi_txBufferIndex < twi_txBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_ST_DATA_NACK: // received nack, we are done + case TW_ST_LAST_DATA: // received ack, but we are done already! + // ack future responses + twi_reply(1); + // leave slave receiver state + twi_state = TWI_READY; + break; + + // All + case TW_NO_INFO: // no state information + break; + case TW_BUS_ERROR: // bus error, illegal stop/start + twi_error = TW_BUS_ERROR; + twi_stop(); + break; + } +} + diff --git a/arduino_libs_0022/Wire/utility/twi.h b/arduino_libs_0022/Wire/utility/twi.h new file mode 100644 index 0000000..1258d8d --- /dev/null +++ b/arduino_libs_0022/Wire/utility/twi.h @@ -0,0 +1,57 @@ +/* + twi.h - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef twi_h +#define twi_h + + #include <inttypes.h> + + //#define ATMEGA8 + + #ifndef CPU_FREQ + #define CPU_FREQ 16000000L + #endif + + #ifndef TWI_FREQ + #define TWI_FREQ 100000L + #endif + + #ifndef TWI_BUFFER_LENGTH + #define TWI_BUFFER_LENGTH 32 + #endif + + #define TWI_READY 0 + #define TWI_MRX 1 + #define TWI_MTX 2 + #define TWI_SRX 3 + #define TWI_STX 4 + + void twi_init(void); + void twi_setAddress(uint8_t); + uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t); + uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t); + uint8_t twi_transmit(uint8_t*, uint8_t); + void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); + void twi_attachSlaveTxEvent( void (*)(void) ); + void twi_reply(uint8_t); + void twi_stop(void); + void twi_releaseBus(void); + +#endif + diff --git a/arduino_libs_0022/core0022_2560.a b/arduino_libs_0022/core0022_2560.a Binary files differnew file mode 100644 index 0000000..39936f0 --- /dev/null +++ b/arduino_libs_0022/core0022_2560.a diff --git a/arduino_libs_0022/core0022_328p.a b/arduino_libs_0022/core0022_328p.a Binary files differnew file mode 100644 index 0000000..0141d8c --- /dev/null +++ b/arduino_libs_0022/core0022_328p.a |
