From d73967a7695f152c7cd80b5dca339b06b1709eff Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Tue, 18 Oct 2016 16:28:32 -0500 Subject: [PATCH 01/13] lib: remove existing libraries and PinChangeInt submodule --- .gitmodules | 3 - hardware/bean/avr/libraries/EEPROM/EEPROM.h | 146 ----- hardware/bean/avr/libraries/EEPROM/README.md | 139 ----- .../examples/eeprom_clear/eeprom_clear.ino | 35 -- .../EEPROM/examples/eeprom_crc/eeprom_crc.ino | 50 -- .../EEPROM/examples/eeprom_get/eeprom_get.ino | 66 --- .../eeprom_iteration/eeprom_iteration.ino | 57 -- .../EEPROM/examples/eeprom_put/eeprom_put.ino | 56 -- .../examples/eeprom_read/eeprom_read.ino | 57 -- .../examples/eeprom_update/eeprom_update.ino | 69 --- .../examples/eeprom_write/eeprom_write.ino | 58 -- .../bean/avr/libraries/EEPROM/keywords.txt | 22 - .../avr/libraries/EEPROM/library.properties | 10 - hardware/bean/avr/libraries/PinChangeInt | 1 - hardware/bean/avr/libraries/SPI/SPI.cpp | 201 ------- hardware/bean/avr/libraries/SPI/SPI.h | 324 ----------- .../BarometricPressureSensor.ino | 143 ----- .../DigitalPotControl/DigitalPotControl.ino | 71 --- hardware/bean/avr/libraries/SPI/keywords.txt | 36 -- .../bean/avr/libraries/SPI/library.properties | 10 - .../SoftwareSerial/SoftwareSerial.cpp | 490 ---------------- .../libraries/SoftwareSerial/SoftwareSerial.h | 121 ---- .../SoftwareSerialExample.ino | 55 -- .../TwoPortReceive/TwoPortReceive.ino | 93 ---- .../avr/libraries/SoftwareSerial/keywords.txt | 30 - .../SoftwareSerial/library.properties | 10 - hardware/bean/avr/libraries/Wire/Wire.cpp | 303 ---------- hardware/bean/avr/libraries/Wire/Wire.h | 80 --- .../SFRRanger_reader/SFRRanger_reader.ino | 87 --- .../digital_potentiometer.ino | 39 -- .../examples/master_reader/master_reader.ino | 32 -- .../examples/master_writer/master_writer.ino | 31 -- .../slave_receiver/slave_receiver.ino | 38 -- .../examples/slave_sender/slave_sender.ino | 32 -- hardware/bean/avr/libraries/Wire/keywords.txt | 32 -- .../avr/libraries/Wire/library.properties | 10 - .../bean/avr/libraries/Wire/utility/twi.c | 527 ------------------ .../bean/avr/libraries/Wire/utility/twi.h | 53 -- 38 files changed, 3617 deletions(-) delete mode 100644 hardware/bean/avr/libraries/EEPROM/EEPROM.h delete mode 100644 hardware/bean/avr/libraries/EEPROM/README.md delete mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino delete mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino delete mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino delete mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino delete mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino delete mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino delete mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino delete mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino delete mode 100644 hardware/bean/avr/libraries/EEPROM/keywords.txt delete mode 100644 hardware/bean/avr/libraries/EEPROM/library.properties delete mode 160000 hardware/bean/avr/libraries/PinChangeInt delete mode 100644 hardware/bean/avr/libraries/SPI/SPI.cpp delete mode 100644 hardware/bean/avr/libraries/SPI/SPI.h delete mode 100644 hardware/bean/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino delete mode 100644 hardware/bean/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino delete mode 100644 hardware/bean/avr/libraries/SPI/keywords.txt delete mode 100644 hardware/bean/avr/libraries/SPI/library.properties delete mode 100644 hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.cpp delete mode 100644 hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.h delete mode 100644 hardware/bean/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino delete mode 100644 hardware/bean/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino delete mode 100644 hardware/bean/avr/libraries/SoftwareSerial/keywords.txt delete mode 100644 hardware/bean/avr/libraries/SoftwareSerial/library.properties delete mode 100644 hardware/bean/avr/libraries/Wire/Wire.cpp delete mode 100644 hardware/bean/avr/libraries/Wire/Wire.h delete mode 100644 hardware/bean/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino delete mode 100644 hardware/bean/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino delete mode 100644 hardware/bean/avr/libraries/Wire/examples/master_reader/master_reader.ino delete mode 100644 hardware/bean/avr/libraries/Wire/examples/master_writer/master_writer.ino delete mode 100644 hardware/bean/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino delete mode 100644 hardware/bean/avr/libraries/Wire/examples/slave_sender/slave_sender.ino delete mode 100644 hardware/bean/avr/libraries/Wire/keywords.txt delete mode 100644 hardware/bean/avr/libraries/Wire/library.properties delete mode 100644 hardware/bean/avr/libraries/Wire/utility/twi.c delete mode 100644 hardware/bean/avr/libraries/Wire/utility/twi.h diff --git a/.gitmodules b/.gitmodules index 9ae8f59..7c7835e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "hardware/bean/avr/cores/bean/applicationMessageHeaders"] path = hardware/bean/avr/cores/bean/applicationMessageHeaders url = https://bitbucket.org/punchthroughdesign/bean-application-message-definitions.git -[submodule "hardware/bean/avr/libraries/PinChangeInt"] - path = hardware/bean/avr/libraries/PinChangeInt - url = https://github.com/PunchThrough/PinChangeInt.git \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/EEPROM.h b/hardware/bean/avr/libraries/EEPROM/EEPROM.h deleted file mode 100644 index cde75db..0000000 --- a/hardware/bean/avr/libraries/EEPROM/EEPROM.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - EEPROM.h - EEPROM library - Original Copyright (c) 2006 David A. Mellis. All right reserved. - New version by Christopher Andrews 2015. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef EEPROM_h -#define EEPROM_h - -#include -#include -#include - -/*** - EERef class. - - This object references an EEPROM cell. - Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. - This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. -***/ - -struct EERef{ - - EERef( const int index ) - : index( index ) {} - - //Access/read members. - uint8_t operator*() const { return eeprom_read_byte( (uint8_t*) index ); } - operator const uint8_t() const { return **this; } - - //Assignment/write members. - EERef &operator=( const EERef &ref ) { return *this = *ref; } - EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_t*) index, in ), *this; } - EERef &operator +=( uint8_t in ) { return *this = **this + in; } - EERef &operator -=( uint8_t in ) { return *this = **this - in; } - EERef &operator *=( uint8_t in ) { return *this = **this * in; } - EERef &operator /=( uint8_t in ) { return *this = **this / in; } - EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; } - EERef &operator %=( uint8_t in ) { return *this = **this % in; } - EERef &operator &=( uint8_t in ) { return *this = **this & in; } - EERef &operator |=( uint8_t in ) { return *this = **this | in; } - EERef &operator <<=( uint8_t in ) { return *this = **this << in; } - EERef &operator >>=( uint8_t in ) { return *this = **this >> in; } - - EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; } - - /** Prefix increment/decrement **/ - EERef& operator++() { return *this += 1; } - EERef& operator--() { return *this -= 1; } - - /** Postfix increment/decrement **/ - uint8_t operator++ (int){ - uint8_t ret = **this; - return ++(*this), ret; - } - - uint8_t operator-- (int){ - uint8_t ret = **this; - return --(*this), ret; - } - - int index; //Index of current EEPROM cell. -}; - -/*** - EEPtr class. - - This object is a bidirectional pointer to EEPROM cells represented by EERef objects. - Just like a normal pointer type, this can be dereferenced and repositioned using - increment/decrement operators. -***/ - -struct EEPtr{ - - EEPtr( const int index ) - : index( index ) {} - - operator const int() const { return index; } - EEPtr &operator=( int in ) { return index = in, *this; } - - //Iterator functionality. - bool operator!=( const EEPtr &ptr ) { return index != ptr.index; } - EERef operator*() { return index; } - - /** Prefix & Postfix increment/decrement **/ - EEPtr& operator++() { return ++index, *this; } - EEPtr& operator--() { return --index, *this; } - EEPtr operator++ (int) { return index++; } - EEPtr operator-- (int) { return index--; } - - int index; //Index of current EEPROM cell. -}; - -/*** - EEPROMClass class. - - This object represents the entire EEPROM space. - It wraps the functionality of EEPtr and EERef into a basic interface. - This class is also 100% backwards compatible with earlier Arduino core releases. -***/ - -struct EEPROMClass{ - - //Basic user access methods. - EERef operator[]( const int idx ) { return idx; } - uint8_t read( int idx ) { return EERef( idx ); } - void write( int idx, uint8_t val ) { (EERef( idx )) = val; } - void update( int idx, uint8_t val ) { EERef( idx ).update( val ); } - - //STL and C++11 iteration capability. - EEPtr begin() { return 0x00; } - EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid. - uint16_t length() { return E2END + 1; } - - //Functionality to 'get' and 'put' objects to and from EEPROM. - template< typename T > T &get( int idx, T &t ){ - EEPtr e = idx; - uint8_t *ptr = (uint8_t*) &t; - for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e; - return t; - } - - template< typename T > const T &put( int idx, const T &t ){ - EEPtr e = idx; - const uint8_t *ptr = (const uint8_t*) &t; - for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ ); - return t; - } -}; - -static EEPROMClass EEPROM; -#endif \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/README.md b/hardware/bean/avr/libraries/EEPROM/README.md deleted file mode 100644 index a624136..0000000 --- a/hardware/bean/avr/libraries/EEPROM/README.md +++ /dev/null @@ -1,139 +0,0 @@ -## **EEPROM Library V2.0** for Arduino - -**Written by:** _Christopher Andrews_. - -### **What is the EEPROM library.** - -Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips. - -### **How to use it** -The EEPROM library is included in your IDE download. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch. - -```Arduino -#include - -void setup(){ - -} - -void loop(){ - -} - -``` - -The library provides a global variable named `EEPROM`, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below. - -You can view all the examples [here](examples/). - -### **Library functions** - -#### **`EEPROM.read( address )`** [[_example_]](examples/eeprom_read/eeprom_read.ino) - -This function allows you to read a single byte of data from the eeprom. -Its only parameter is an `int` which should be set to the address you wish to read. - -The function returns an `unsigned char` containing the value read. - -#### **`EEPROM.write( address, value )`** [[_example_]](examples/eeprom_write/eeprom_write.ino) - -The `write()` method allows you to write a single byte of data to the EEPROM. -Two parameters are needed. The first is an `int` containing the address that is to be written, and the second is a the data to be written (`unsigned char`). - -This function does not return any value. - -#### **`EEPROM.update( address, value )`** [[_example_]](examples/eeprom_update/eeprom_update.ino) - -This function is similar to `EEPROM.write()` however this method will only write data if the cell contents pointed to by `address` is different to `value`. This method can help prevent unnecessary wear on the EEPROM cells. - -This function does not return any value. - -#### **`EEPROM.get( address, object )`** [[_example_]](examples/eeprom_get/eeprom_get.ino) - -This function will retrieve any object from the EEPROM. -Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to read. - -This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. - -#### **`EEPROM.put( address, object )`** [[_example_]](examples/eeprom_put/eeprom_put.ino) - -This function will write any object to the EEPROM. -Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to write. - -This function uses the _update_ method to write its data, and therefore only rewrites changed cells. - -This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. - -#### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino) - -This operator allows using the identifier `EEPROM` like an array. -EEPROM cells can be read _and_ **_written_** directly using this method. - -This operator returns a reference to the EEPROM cell. - -```c++ -unsigned char val; - -//Read first EEPROM cell. -val = EEPROM[ 0 ]; - -//Write first EEPROM cell. -EEPROM[ 0 ] = val; - -//Compare contents -if( val == EEPROM[ 0 ] ){ - //Do something... -} -``` - -#### **`EEPROM.length()`** - -This function returns an `unsigned int` containing the number of cells in the EEPROM. - ---- - -### **Advanced features** - -This library uses a component based approach to provide its functionality. This means you can also use these components to design a customized approach. Two background classes are available for use: `EERef` & `EEPtr`. - -#### **`EERef` class** - -This object references an EEPROM cell. -Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. -This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. - -```C++ -EERef ref = EEPROM[ 10 ]; //Create a reference to 11th cell. - -ref = 4; //write to EEPROM cell. - -unsigned char val = ref; //Read referenced cell. -``` - -#### **`EEPtr` class** - -This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects. -Just like a normal pointer type, this type can be dereferenced and repositioned using -increment/decrement operators. - -```C++ -EEPtr ptr = 10; //Create a pointer to 11th cell. - -*ptr = 4; //dereference and write to EEPROM cell. - -unsigned char val = *ptr; //dereference and read. - -ptr++; //Move to next EEPROM cell. -``` - -#### **`EEPROM.begin()`** - -This function returns an `EEPtr` pointing to the first cell in the EEPROM. -This is useful for STL objects, custom iteration and C++11 style ranged for loops. - -#### **`EEPROM.end()`** - -This function returns an `EEPtr` pointing at the location after the last EEPROM cell. -Used with `begin()` to provide custom iteration. - -**Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell. diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino deleted file mode 100644 index 49eb5fe..0000000 --- a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino +++ /dev/null @@ -1,35 +0,0 @@ -/* - * EEPROM Clear - * - * Sets all of the bytes of the EEPROM to 0. - * Please see eeprom_iteration for a more in depth - * look at how to traverse the EEPROM. - * - * This example code is in the public domain. - */ - -#include - -void setup() -{ - - /*** - Iterate through each byte of the EEPROM storage. - - Larger AVR processors have larger EEPROM sizes, E.g: - - Arduno Duemilanove: 512b EEPROM storage. - - Arduino Uno: 1kb EEPROM storage. - - Arduino Mega: 4kb EEPROM storage. - - Rather than hard-coding the length, you should use the pre-provided length function. - This will make your code portable to all AVR processors. - ***/ - - for ( int i = 0 ; i < EEPROM.length() ; i++ ) - EEPROM.write(i, 0); - - // turn the LED on when we're done - digitalWrite(13, HIGH); -} - -void loop(){ /** Empty loop. **/ } diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino deleted file mode 100644 index 8461d56..0000000 --- a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino +++ /dev/null @@ -1,50 +0,0 @@ -/*** - Written by Christopher Andrews. - CRC algorithm generated by pycrc, MIT licence ( https://github.com/tpircher/pycrc ). - - A CRC is a simple way of checking whether data has changed or become corrupted. - This example calculates a CRC value directly on the EEPROM values. - The purpose of this example is to highlight how the EEPROM object can be used just like an array. -***/ - -#include -#include - -void setup(){ - - //Start serial - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } - - //Print length of data to run CRC on. - Serial.print( "EEPROM length: " ); - Serial.println( EEPROM.length() ); - - //Print the result of calling eeprom_crc() - Serial.print( "CRC32 of EEPROM data: 0x" ); - Serial.println( eeprom_crc(), HEX ); - Serial.print( "\n\nDone!" ); -} - -void loop(){ /* Empty loop */ } - -unsigned long eeprom_crc( void ){ - - const unsigned long crc_table[16] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, - 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, - 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - - unsigned long crc = ~0L; - - for( int index = 0 ; index < EEPROM.length() ; ++index ){ - crc = crc_table[( crc ^ EEPROM[index] ) & 0x0f] ^ (crc >> 4); - crc = crc_table[( crc ^ ( EEPROM[index] >> 4 )) & 0x0f] ^ (crc >> 4); - crc = ~crc; - } - return crc; -} \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino deleted file mode 100644 index 6620999..0000000 --- a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino +++ /dev/null @@ -1,66 +0,0 @@ -/*** - eeprom_get example. - - This shows how to use the EEPROM.get() method. - - To pre-set the EEPROM data, run the example sketch eeprom_put. - This sketch will run without it, however, the values shown - will be shown from what ever is already on the EEPROM. - - This may cause the serial object to print out a large string - of garbage if there is no null character inside one of the strings - loaded. - - Written by Christopher Andrews 2015 - Released under MIT licence. -***/ - -#include - -void setup(){ - - float f = 0.00f; //Variable to store data read from EEPROM. - int eeAddress = 0; //EEPROM address to start reading from - - Serial.begin( 9600 ); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } - Serial.print( "Read float from EEPROM: " ); - - //Get the float data from the EEPROM at position 'eeAddress' - EEPROM.get( eeAddress, f ); - Serial.println( f, 3 ); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float. - - /*** - As get also returns a reference to 'f', you can use it inline. - E.g: Serial.print( EEPROM.get( eeAddress, f ) ); - ***/ - - /*** - Get can be used with custom structures too. - I have separated this into an extra function. - ***/ - - secondTest(); //Run the next test. -} - -struct MyObject{ - float field1; - byte field2; - char name[10]; -}; - -void secondTest(){ - int eeAddress = sizeof(float); //Move address to the next byte after float 'f'. - - MyObject customVar; //Variable to store custom object read from EEPROM. - EEPROM.get( eeAddress, customVar ); - - Serial.println( "Read custom object from EEPROM: " ); - Serial.println( customVar.field1 ); - Serial.println( customVar.field2 ); - Serial.println( customVar.name ); -} - -void loop(){ /* Empty loop */ } \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino deleted file mode 100644 index 650c90a..0000000 --- a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino +++ /dev/null @@ -1,57 +0,0 @@ -/*** - eeprom_iteration example. - - A set of example snippets highlighting the - simplest methods for traversing the EEPROM. - - Running this sketch is not necessary, this is - simply highlighting certain programming methods. - - Written by Christopher Andrews 2015 - Released under MIT licence. -***/ - -#include - -void setup() { - - /*** - Iterate the EEPROM using a for loop. - ***/ - - for( int index = 0 ; index < EEPROM.length() ; index++ ){ - - //Add one to each cell in the EEPROM - EEPROM[ index ] += 1; - } - - /*** - Iterate the EEPROM using a while loop. - ***/ - - int index = 0; - - while( index < EEPROM.length() ){ - - //Add one to each cell in the EEPROM - EEPROM[ index ] += 1; - index++; - } - - /*** - Iterate the EEPROM using a do-while loop. - ***/ - - int idx = 0; //Used 'idx' to avoid name conflict with 'index' above. - - do{ - - //Add one to each cell in the EEPROM - EEPROM[ idx ] += 1; - idx++; - }while( idx < EEPROM.length() ); - - -} //End of setup function. - -void loop(){} \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino deleted file mode 100644 index 186cf95..0000000 --- a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino +++ /dev/null @@ -1,56 +0,0 @@ -/*** - eeprom_put example. - - This shows how to use the EEPROM.put() method. - Also, this sketch will pre-set the EEPROM data for the - example sketch eeprom_get. - - Note, unlike the single byte version EEPROM.write(), - the put method will use update semantics. As in a byte - will only be written to the EEPROM if the data is actually - different. - - Written by Christopher Andrews 2015 - Released under MIT licence. -***/ - -#include - -struct MyObject{ - float field1; - byte field2; - char name[10]; -}; - -void setup(){ - - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } - - float f = 123.456f; //Variable to store in EEPROM. - int eeAddress = 0; //Location we want the data to be put. - - - //One simple call, with the address first and the object second. - EEPROM.put( eeAddress, f ); - - Serial.println("Written float data type!"); - - /** Put is designed for use with custom structures also. **/ - - //Data to store. - MyObject customVar = { - 3.14f, - 65, - "Working!" - }; - - eeAddress += sizeof(float); //Move address to the next byte after float 'f'. - - EEPROM.put( eeAddress, customVar ); - Serial.print( "Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!" ); -} - -void loop(){ /* Empty loop */ } \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino deleted file mode 100644 index 68c4ffc..0000000 --- a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino +++ /dev/null @@ -1,57 +0,0 @@ -/* - * EEPROM Read - * - * Reads the value of each byte of the EEPROM and prints it - * to the computer. - * This example code is in the public domain. - */ - -#include - -// start reading from the first byte (address 0) of the EEPROM -int address = 0; -byte value; - -void setup() -{ - // initialize serial and wait for port to open: - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } -} - -void loop() -{ - // read a byte from the current address of the EEPROM - value = EEPROM.read(address); - - Serial.print(address); - Serial.print("\t"); - Serial.print(value, DEC); - Serial.println(); - - /*** - Advance to the next address, when at the end restart at the beginning. - - Larger AVR processors have larger EEPROM sizes, E.g: - - Arduno Duemilanove: 512b EEPROM storage. - - Arduino Uno: 1kb EEPROM storage. - - Arduino Mega: 4kb EEPROM storage. - - Rather than hard-coding the length, you should use the pre-provided length function. - This will make your code portable to all AVR processors. - ***/ - address = address + 1; - if(address == EEPROM.length()) - address = 0; - - /*** - As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an - EEPROM address is also doable by a bitwise and of the length - 1. - - ++address &= EEPROM.length() - 1; - ***/ - - delay(500); -} diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino deleted file mode 100644 index 831056f..0000000 --- a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino +++ /dev/null @@ -1,69 +0,0 @@ -/*** - EEPROM Update method - - Stores values read from analog input 0 into the EEPROM. - These values will stay in the EEPROM when the board is - turned off and may be retrieved later by another sketch. - - If a value has not changed in the EEPROM, it is not overwritten - which would reduce the life span of the EEPROM unnecessarily. - - Released using MIT licence. - ***/ - -#include - -/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ -int address = 0; - -void setup(){ /** EMpty setup **/ } - -void loop() -{ - /*** - need to divide by 4 because analog inputs range from - 0 to 1023 and each byte of the EEPROM can only hold a - value from 0 to 255. - ***/ - int val = analogRead(0) / 4; - - /*** - Update the particular EEPROM cell. - these values will remain there when the board is - turned off. - ***/ - EEPROM.update(address, val); - - /*** - The function EEPROM.update(address, val) is equivalent to the following: - - if( EEPROM.read(address) != val ){ - EEPROM.write(address, val); - } - ***/ - - - /*** - Advance to the next address, when at the end restart at the beginning. - - Larger AVR processors have larger EEPROM sizes, E.g: - - Arduno Duemilanove: 512b EEPROM storage. - - Arduino Uno: 1kb EEPROM storage. - - Arduino Mega: 4kb EEPROM storage. - - Rather than hard-coding the length, you should use the pre-provided length function. - This will make your code portable to all AVR processors. - ***/ - address = address + 1; - if(address == EEPROM.length()) - address = 0; - - /*** - As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an - EEPROM address is also doable by a bitwise and of the length - 1. - - ++address &= EEPROM.length() - 1; - ***/ - - delay(100); -} diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino deleted file mode 100644 index f07446c..0000000 --- a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino +++ /dev/null @@ -1,58 +0,0 @@ -/* - * EEPROM Write - * - * Stores values read from analog input 0 into the EEPROM. - * These values will stay in the EEPROM when the board is - * turned off and may be retrieved later by another sketch. - */ - -#include - -/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ -int addr = 0; - -void setup(){ /** Empty setup. **/} - -void loop() -{ - /*** - Need to divide by 4 because analog inputs range from - 0 to 1023 and each byte of the EEPROM can only hold a - value from 0 to 255. - ***/ - - int val = analogRead(0) / 4; - - /*** - Write the value to the appropriate byte of the EEPROM. - these values will remain there when the board is - turned off. - ***/ - - EEPROM.write(addr, val); - - /*** - Advance to the next address, when at the end restart at the beginning. - - Larger AVR processors have larger EEPROM sizes, E.g: - - Arduno Duemilanove: 512b EEPROM storage. - - Arduino Uno: 1kb EEPROM storage. - - Arduino Mega: 4kb EEPROM storage. - - Rather than hard-coding the length, you should use the pre-provided length function. - This will make your code portable to all AVR processors. - ***/ - addr = addr + 1; - if(addr == EEPROM.length()) - addr = 0; - - /*** - As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an - EEPROM address is also doable by a bitwise and of the length - 1. - - ++addr &= EEPROM.length() - 1; - ***/ - - - delay(100); -} diff --git a/hardware/bean/avr/libraries/EEPROM/keywords.txt b/hardware/bean/avr/libraries/EEPROM/keywords.txt deleted file mode 100644 index 2cabc0b..0000000 --- a/hardware/bean/avr/libraries/EEPROM/keywords.txt +++ /dev/null @@ -1,22 +0,0 @@ -####################################### -# Syntax Coloring Map For EEPROM -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -EEPROM KEYWORD1 -EERef KEYWORD1 -EEPtr KEYWORD2 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -update KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### - diff --git a/hardware/bean/avr/libraries/EEPROM/library.properties b/hardware/bean/avr/libraries/EEPROM/library.properties deleted file mode 100644 index 1160042..0000000 --- a/hardware/bean/avr/libraries/EEPROM/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=EEPROM -version=2.0 -author=Arduino, Christopher Andrews -maintainer=Arduino -sentence=Enables reading and writing to the permanent board storage. For all Arduino boards BUT Arduino DUE. -paragraph= -url=http://arduino.cc/en/Reference/EEPROM -architectures=avr -types=Arduino -category=Data Storage diff --git a/hardware/bean/avr/libraries/PinChangeInt b/hardware/bean/avr/libraries/PinChangeInt deleted file mode 160000 index ec745f8..0000000 --- a/hardware/bean/avr/libraries/PinChangeInt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ec745f854b2b807640341cf479f540bb8bb3fc2f diff --git a/hardware/bean/avr/libraries/SPI/SPI.cpp b/hardware/bean/avr/libraries/SPI/SPI.cpp deleted file mode 100644 index af14e07..0000000 --- a/hardware/bean/avr/libraries/SPI/SPI.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2010 by Cristian Maglie - * Copyright (c) 2014 by Paul Stoffregen (Transaction API) - * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) - * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) - * SPI Master library for arduino. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of either the GNU General Public License version 2 - * or the GNU Lesser General Public License version 2.1, both as - * published by the Free Software Foundation. - */ - -#include "SPI.h" - -SPIClass SPI; - -uint8_t SPIClass::initialized = 0; -uint8_t SPIClass::interruptMode = 0; -uint8_t SPIClass::interruptMask = 0; -uint8_t SPIClass::interruptSave = 0; -#ifdef SPI_TRANSACTION_MISMATCH_LED -uint8_t SPIClass::inTransactionFlag = 0; -#endif - -void SPIClass::begin() -{ - uint8_t sreg = SREG; - noInterrupts(); // Protect from a scheduler and prevent transactionBegin - if (!initialized) { - // Set SS to high so a connected chip will be "deselected" by default - uint8_t port = digitalPinToPort(SS); - uint8_t bit = digitalPinToBitMask(SS); - volatile uint8_t *reg = portModeRegister(port); - - // if the SS pin is not already configured as an output - // then set it high (to enable the internal pull-up resistor) - if(!(*reg & bit)){ - digitalWrite(SS, HIGH); - } - - // When the SS pin is set as OUTPUT, it can be used as - // a general purpose output port (it doesn't influence - // SPI operations). - pinMode(SS, OUTPUT); - - // Warning: if the SS pin ever becomes a LOW INPUT then SPI - // automatically switches to Slave, so the data direction of - // the SS pin MUST be kept as OUTPUT. - SPCR |= _BV(MSTR); - SPCR |= _BV(SPE); - - // Set direction register for SCK and MOSI pin. - // MISO pin automatically overrides to INPUT. - // By doing this AFTER enabling SPI, we avoid accidentally - // clocking in a single bit since the lines go directly - // from "input" to SPI control. - // http://code.google.com/p/arduino/issues/detail?id=888 - pinMode(SCK, OUTPUT); - pinMode(MOSI, OUTPUT); - } - initialized++; // reference count - SREG = sreg; -} - -void SPIClass::end() { - uint8_t sreg = SREG; - noInterrupts(); // Protect from a scheduler and prevent transactionBegin - // Decrease the reference counter - if (initialized) - initialized--; - // If there are no more references disable SPI - if (!initialized) { - SPCR &= ~_BV(SPE); - interruptMode = 0; - #ifdef SPI_TRANSACTION_MISMATCH_LED - inTransactionFlag = 0; - #endif - } - SREG = sreg; -} - -// mapping of interrupt numbers to bits within SPI_AVR_EIMSK -#if defined(__AVR_ATmega32U4__) - #define SPI_INT0_MASK (1< - * Copyright (c) 2014 by Paul Stoffregen (Transaction API) - * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) - * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) - * SPI Master library for arduino. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of either the GNU General Public License version 2 - * or the GNU Lesser General Public License version 2.1, both as - * published by the Free Software Foundation. - */ - -#ifndef _SPI_H_INCLUDED -#define _SPI_H_INCLUDED - -#include - -// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(), -// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode) -#define SPI_HAS_TRANSACTION 1 - -// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method -#define SPI_HAS_NOTUSINGINTERRUPT 1 - -// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version. -// This way when there is a bug fix you can check this define to alert users -// of your code if it uses better version of this library. -// This also implies everything that SPI_HAS_TRANSACTION as documented above is -// available too. -#define SPI_ATOMIC_VERSION 1 - -// Uncomment this line to add detection of mismatched begin/end transactions. -// A mismatch occurs if other libraries fail to use SPI.endTransaction() for -// each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn -// on if any mismatch is ever detected. -//#define SPI_TRANSACTION_MISMATCH_LED 5 - -#ifndef LSBFIRST -#define LSBFIRST 0 -#endif -#ifndef MSBFIRST -#define MSBFIRST 1 -#endif - -#define SPI_CLOCK_DIV4 0x00 -#define SPI_CLOCK_DIV16 0x01 -#define SPI_CLOCK_DIV64 0x02 -#define SPI_CLOCK_DIV128 0x03 -#define SPI_CLOCK_DIV2 0x04 -#define SPI_CLOCK_DIV8 0x05 -#define SPI_CLOCK_DIV32 0x06 - -#define SPI_MODE0 0x00 -#define SPI_MODE1 0x04 -#define SPI_MODE2 0x08 -#define SPI_MODE3 0x0C - -#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR -#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR -#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR - -// define SPI_AVR_EIMSK for AVR boards with external interrupt pins -#if defined(EIMSK) - #define SPI_AVR_EIMSK EIMSK -#elif defined(GICR) - #define SPI_AVR_EIMSK GICR -#elif defined(GIMSK) - #define SPI_AVR_EIMSK GIMSK -#endif - -class SPISettings { -public: - SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { - if (__builtin_constant_p(clock)) { - init_AlwaysInline(clock, bitOrder, dataMode); - } else { - init_MightInline(clock, bitOrder, dataMode); - } - } - SPISettings() { - init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); - } -private: - void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { - init_AlwaysInline(clock, bitOrder, dataMode); - } - void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) - __attribute__((__always_inline__)) { - // Clock settings are defined as follows. Note that this shows SPI2X - // inverted, so the bits form increasing numbers. Also note that - // fosc/64 appears twice - // SPR1 SPR0 ~SPI2X Freq - // 0 0 0 fosc/2 - // 0 0 1 fosc/4 - // 0 1 0 fosc/8 - // 0 1 1 fosc/16 - // 1 0 0 fosc/32 - // 1 0 1 fosc/64 - // 1 1 0 fosc/64 - // 1 1 1 fosc/128 - - // We find the fastest clock that is less than or equal to the - // given clock rate. The clock divider that results in clock_setting - // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the - // slowest (128 == 2 ^^ 7, so clock_div = 6). - uint8_t clockDiv; - - // When the clock is known at compiletime, use this if-then-else - // cascade, which the compiler knows how to completely optimize - // away. When clock is not known, use a loop instead, which generates - // shorter code. - if (__builtin_constant_p(clock)) { - if (clock >= F_CPU / 2) { - clockDiv = 0; - } else if (clock >= F_CPU / 4) { - clockDiv = 1; - } else if (clock >= F_CPU / 8) { - clockDiv = 2; - } else if (clock >= F_CPU / 16) { - clockDiv = 3; - } else if (clock >= F_CPU / 32) { - clockDiv = 4; - } else if (clock >= F_CPU / 64) { - clockDiv = 5; - } else { - clockDiv = 6; - } - } else { - uint32_t clockSetting = F_CPU / 2; - clockDiv = 0; - while (clockDiv < 6 && clock < clockSetting) { - clockSetting /= 2; - clockDiv++; - } - } - - // Compensate for the duplicate fosc/64 - if (clockDiv == 6) - clockDiv = 7; - - // Invert the SPI2X bit - clockDiv ^= 0x1; - - // Pack into the SPISettings class - spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) | - (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK); - spsr = clockDiv & SPI_2XCLOCK_MASK; - } - uint8_t spcr; - uint8_t spsr; - friend class SPIClass; -}; - - -class SPIClass { -public: - // Initialize the SPI library - static void begin(); - - // If SPI is used from within an interrupt, this function registers - // that interrupt with the SPI library, so beginTransaction() can - // prevent conflicts. The input interruptNumber is the number used - // with attachInterrupt. If SPI is used from a different interrupt - // (eg, a timer), interruptNumber should be 255. - static void usingInterrupt(uint8_t interruptNumber); - // And this does the opposite. - static void notUsingInterrupt(uint8_t interruptNumber); - // Note: the usingInterrupt and notUsingInterrupt functions should - // not to be called from ISR context or inside a transaction. - // For details see: - // https://github.com/arduino/Arduino/pull/2381 - // https://github.com/arduino/Arduino/pull/2449 - - // Before using SPI.transfer() or asserting chip select pins, - // this function is used to gain exclusive access to the SPI bus - // and configure the correct settings. - inline static void beginTransaction(SPISettings settings) { - if (interruptMode > 0) { - uint8_t sreg = SREG; - noInterrupts(); - - #ifdef SPI_AVR_EIMSK - if (interruptMode == 1) { - interruptSave = SPI_AVR_EIMSK; - SPI_AVR_EIMSK &= ~interruptMask; - SREG = sreg; - } else - #endif - { - interruptSave = sreg; - } - } - - #ifdef SPI_TRANSACTION_MISMATCH_LED - if (inTransactionFlag) { - pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT); - digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH); - } - inTransactionFlag = 1; - #endif - - SPCR = settings.spcr; - SPSR = settings.spsr; - } - - // Write to the SPI bus (MOSI pin) and also receive (MISO pin) - inline static uint8_t transfer(uint8_t data) { - SPDR = data; - /* - * The following NOP introduces a small delay that can prevent the wait - * loop form iterating when running at the maximum speed. This gives - * about 10% more speed, even if it seems counter-intuitive. At lower - * speeds it is unnoticed. - */ - asm volatile("nop"); - while (!(SPSR & _BV(SPIF))) ; // wait - return SPDR; - } - inline static uint16_t transfer16(uint16_t data) { - union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out; - in.val = data; - if (!(SPCR & _BV(DORD))) { - SPDR = in.msb; - asm volatile("nop"); // See transfer(uint8_t) function - while (!(SPSR & _BV(SPIF))) ; - out.msb = SPDR; - SPDR = in.lsb; - asm volatile("nop"); - while (!(SPSR & _BV(SPIF))) ; - out.lsb = SPDR; - } else { - SPDR = in.lsb; - asm volatile("nop"); - while (!(SPSR & _BV(SPIF))) ; - out.lsb = SPDR; - SPDR = in.msb; - asm volatile("nop"); - while (!(SPSR & _BV(SPIF))) ; - out.msb = SPDR; - } - return out.val; - } - inline static void transfer(void *buf, size_t count) { - if (count == 0) return; - uint8_t *p = (uint8_t *)buf; - SPDR = *p; - while (--count > 0) { - uint8_t out = *(p + 1); - while (!(SPSR & _BV(SPIF))) ; - uint8_t in = SPDR; - SPDR = out; - *p++ = in; - } - while (!(SPSR & _BV(SPIF))) ; - *p = SPDR; - } - // After performing a group of transfers and releasing the chip select - // signal, this function allows others to access the SPI bus - inline static void endTransaction(void) { - #ifdef SPI_TRANSACTION_MISMATCH_LED - if (!inTransactionFlag) { - pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT); - digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH); - } - inTransactionFlag = 0; - #endif - - if (interruptMode > 0) { - #ifdef SPI_AVR_EIMSK - uint8_t sreg = SREG; - #endif - noInterrupts(); - #ifdef SPI_AVR_EIMSK - if (interruptMode == 1) { - SPI_AVR_EIMSK = interruptSave; - SREG = sreg; - } else - #endif - { - SREG = interruptSave; - } - } - } - - // Disable the SPI bus - static void end(); - - // This function is deprecated. New applications should use - // beginTransaction() to configure SPI settings. - inline static void setBitOrder(uint8_t bitOrder) { - if (bitOrder == LSBFIRST) SPCR |= _BV(DORD); - else SPCR &= ~(_BV(DORD)); - } - // This function is deprecated. New applications should use - // beginTransaction() to configure SPI settings. - inline static void setDataMode(uint8_t dataMode) { - SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; - } - // This function is deprecated. New applications should use - // beginTransaction() to configure SPI settings. - inline static void setClockDivider(uint8_t clockDiv) { - SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK); - SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK); - } - // These undocumented functions should not be used. SPI.transfer() - // polls the hardware flag which is automatically cleared as the - // AVR responds to SPI's interrupt - inline static void attachInterrupt() { SPCR |= _BV(SPIE); } - inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); } - -private: - static uint8_t initialized; - static uint8_t interruptMode; // 0=none, 1=mask, 2=global - static uint8_t interruptMask; // which interrupts to mask - static uint8_t interruptSave; // temp storage, to restore state - #ifdef SPI_TRANSACTION_MISMATCH_LED - static uint8_t inTransactionFlag; - #endif -}; - -extern SPIClass SPI; - -#endif diff --git a/hardware/bean/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino b/hardware/bean/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino deleted file mode 100644 index 8104fcb..0000000 --- a/hardware/bean/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino +++ /dev/null @@ -1,143 +0,0 @@ -/* - SCP1000 Barometric Pressure Sensor Display - - Shows the output of a Barometric Pressure Sensor on a - Uses the SPI library. For details on the sensor, see: - http://www.sparkfun.com/commerce/product_info.php?products_id=8161 - http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ - - This sketch adapted from Nathan Seidle's SCP1000 example for PIC: - http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip - - Circuit: - SCP1000 sensor attached to pins 6, 7, 10 - 13: - DRDY: pin 6 - CSB: pin 7 - MOSI: pin 11 - MISO: pin 12 - SCK: pin 13 - - created 31 July 2010 - modified 14 August 2010 - by Tom Igoe - */ - -// the sensor communicates using SPI, so include the library: -#include - -//Sensor's memory register addresses: -const int PRESSURE = 0x1F; //3 most significant bits of pressure -const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure -const int TEMPERATURE = 0x21; //16 bit temperature reading -const byte READ = 0b11111100; // SCP1000's read command -const byte WRITE = 0b00000010; // SCP1000's write command - -// pins used for the connection with the sensor -// the other you need are controlled by the SPI library): -const int dataReadyPin = 6; -const int chipSelectPin = 7; - -void setup() { - Serial.begin(9600); - - // start the SPI library: - SPI.begin(); - - // initalize the data ready and chip select pins: - pinMode(dataReadyPin, INPUT); - pinMode(chipSelectPin, OUTPUT); - - //Configure SCP1000 for low noise configuration: - writeRegister(0x02, 0x2D); - writeRegister(0x01, 0x03); - writeRegister(0x03, 0x02); - // give the sensor time to set up: - delay(100); -} - -void loop() { - //Select High Resolution Mode - writeRegister(0x03, 0x0A); - - // don't do anything until the data ready pin is high: - if (digitalRead(dataReadyPin) == HIGH) { - //Read the temperature data - int tempData = readRegister(0x21, 2); - - // convert the temperature to celsius and display it: - float realTemp = (float)tempData / 20.0; - Serial.print("Temp[C]="); - Serial.print(realTemp); - - - //Read the pressure data highest 3 bits: - byte pressure_data_high = readRegister(0x1F, 1); - pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 - - //Read the pressure data lower 16 bits: - unsigned int pressure_data_low = readRegister(0x20, 2); - //combine the two parts into one 19-bit number: - long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4; - - // display the temperature: - Serial.println("\tPressure [Pa]=" + String(pressure)); - } -} - -//Read from or write to register from the SCP1000: -unsigned int readRegister(byte thisRegister, int bytesToRead ) { - byte inByte = 0; // incoming byte from the SPI - unsigned int result = 0; // result to return - Serial.print(thisRegister, BIN); - Serial.print("\t"); - // SCP1000 expects the register name in the upper 6 bits - // of the byte. So shift the bits left by two bits: - thisRegister = thisRegister << 2; - // now combine the address and the command into one byte - byte dataToSend = thisRegister & READ; - Serial.println(thisRegister, BIN); - // take the chip select low to select the device: - digitalWrite(chipSelectPin, LOW); - // send the device the register you want to read: - SPI.transfer(dataToSend); - // send a value of 0 to read the first byte returned: - result = SPI.transfer(0x00); - // decrement the number of bytes left to read: - bytesToRead--; - // if you still have another byte to read: - if (bytesToRead > 0) { - // shift the first byte left, then get the second byte: - result = result << 8; - inByte = SPI.transfer(0x00); - // combine the byte you just got with the previous one: - result = result | inByte; - // decrement the number of bytes left to read: - bytesToRead--; - } - // take the chip select high to de-select: - digitalWrite(chipSelectPin, HIGH); - // return the result: - return(result); -} - - -//Sends a write command to SCP1000 - -void writeRegister(byte thisRegister, byte thisValue) { - - // SCP1000 expects the register address in the upper 6 bits - // of the byte. So shift the bits left by two bits: - thisRegister = thisRegister << 2; - // now combine the register address and the command into one byte: - byte dataToSend = thisRegister | WRITE; - - // take the chip select low to select the device: - digitalWrite(chipSelectPin, LOW); - - SPI.transfer(dataToSend); //Send register location - SPI.transfer(thisValue); //Send value to record into register - - // take the chip select high to de-select: - digitalWrite(chipSelectPin, HIGH); -} - diff --git a/hardware/bean/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino b/hardware/bean/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino deleted file mode 100644 index b135a74..0000000 --- a/hardware/bean/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino +++ /dev/null @@ -1,71 +0,0 @@ -/* - Digital Pot Control - - This example controls an Analog Devices AD5206 digital potentiometer. - The AD5206 has 6 potentiometer channels. Each channel's pins are labeled - A - connect this to voltage - W - this is the pot's wiper, which changes when you set it - B - connect this to ground. - - The AD5206 is SPI-compatible,and to command it, you send two bytes, - one with the channel number (0 - 5) and one with the resistance value for the - channel (0 - 255). - - The circuit: - * All A pins of AD5206 connected to +5V - * All B pins of AD5206 connected to ground - * An LED and a 220-ohm resisor in series connected from each W pin to ground - * CS - to digital pin 10 (SS pin) - * SDI - to digital pin 11 (MOSI pin) - * CLK - to digital pin 13 (SCK pin) - - created 10 Aug 2010 - by Tom Igoe - - Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 - -*/ - - -// inslude the SPI library: -#include - - -// set pin 10 as the slave select for the digital pot: -const int slaveSelectPin = 10; - -void setup() { - // set the slaveSelectPin as an output: - pinMode (slaveSelectPin, OUTPUT); - // initialize SPI: - SPI.begin(); -} - -void loop() { - // go through the six channels of the digital pot: - for (int channel = 0; channel < 6; channel++) { - // change the resistance on this channel from min to max: - for (int level = 0; level < 255; level++) { - digitalPotWrite(channel, level); - delay(10); - } - // wait a second at the top: - delay(100); - // change the resistance on this channel from max to min: - for (int level = 0; level < 255; level++) { - digitalPotWrite(channel, 255 - level); - delay(10); - } - } - -} - -void digitalPotWrite(int address, int value) { - // take the SS pin low to select the chip: - digitalWrite(slaveSelectPin, LOW); - // send in the address and value via SPI: - SPI.transfer(address); - SPI.transfer(value); - // take the SS pin high to de-select the chip: - digitalWrite(slaveSelectPin, HIGH); -} diff --git a/hardware/bean/avr/libraries/SPI/keywords.txt b/hardware/bean/avr/libraries/SPI/keywords.txt deleted file mode 100644 index fa76165..0000000 --- a/hardware/bean/avr/libraries/SPI/keywords.txt +++ /dev/null @@ -1,36 +0,0 @@ -####################################### -# Syntax Coloring Map SPI -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -SPI KEYWORD1 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### -begin KEYWORD2 -end KEYWORD2 -transfer KEYWORD2 -setBitOrder KEYWORD2 -setDataMode KEYWORD2 -setClockDivider KEYWORD2 - - -####################################### -# Constants (LITERAL1) -####################################### -SPI_CLOCK_DIV4 LITERAL1 -SPI_CLOCK_DIV16 LITERAL1 -SPI_CLOCK_DIV64 LITERAL1 -SPI_CLOCK_DIV128 LITERAL1 -SPI_CLOCK_DIV2 LITERAL1 -SPI_CLOCK_DIV8 LITERAL1 -SPI_CLOCK_DIV32 LITERAL1 -SPI_CLOCK_DIV64 LITERAL1 -SPI_MODE0 LITERAL1 -SPI_MODE1 LITERAL1 -SPI_MODE2 LITERAL1 -SPI_MODE3 LITERAL1 \ No newline at end of file diff --git a/hardware/bean/avr/libraries/SPI/library.properties b/hardware/bean/avr/libraries/SPI/library.properties deleted file mode 100644 index d132fa9..0000000 --- a/hardware/bean/avr/libraries/SPI/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=SPI -version=1.0 -author=Arduino -maintainer=Arduino -sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE. -paragraph= -url=http://arduino.cc/en/Reference/SPI -architectures=avr -types=Arduino -category=Communication diff --git a/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.cpp b/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.cpp deleted file mode 100644 index b4e4529..0000000 --- a/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* -SoftwareSerial.cpp (formerly NewSoftSerial.cpp) - -Multi-instance software serial library for Arduino/Wiring --- Interrupt-driven receive and other improvements by ladyada - (http://ladyada.net) --- Tuning, circular buffer, derivation from class Print/Stream, - multi-instance support, porting to 8MHz processors, - various optimizations, PROGMEM delay tables, inverse logic and - direct port writing by Mikal Hart (http://www.arduiniana.org) --- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) --- 20MHz processor support by Garrett Mace (http://www.macetech.com) --- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.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 - -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 -#include -#include -#include -#include - -// -// Statics -// -SoftwareSerial *SoftwareSerial::active_object = 0; -char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF]; -volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0; -volatile uint8_t SoftwareSerial::_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 SoftwareSerial::tunedDelay(uint16_t delay) { - _delay_loop_2(delay); -} - -// This function sets the current object as the "listening" -// one and returns true if it replaces another -bool SoftwareSerial::listen() -{ - if (!_rx_delay_stopbit) - return false; - - if (active_object != this) - { - if (active_object) - active_object->stopListening(); - - _buffer_overflow = false; - _receive_buffer_head = _receive_buffer_tail = 0; - active_object = this; - - setRxIntMsk(true); - return true; - } - - return false; -} - -// Stop listening. Returns true if we were actually listening. -bool SoftwareSerial::stopListening() -{ - if (active_object == this) - { - setRxIntMsk(false); - active_object = NULL; - return true; - } - return false; -} - -// -// The receive routine called by the interrupt handler -// -void SoftwareSerial::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()) - { - // Disable further interrupts during reception, this prevents - // triggering another interrupt directly after we return, which can - // cause problems at higher baudrates. - setRxIntMsk(false); - - // 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=8; i > 0; --i) - { - tunedDelay(_rx_delay_intrabit); - d >>= 1; - DebugPulse(_DEBUG_PIN2, 1); - if (rx_pin_read()) - d |= 0x80; - } - - if (_inverse_logic) - d = ~d; - - // if buffer full, set the overflow flag and return - uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF; - if (next != _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 = next; - } - else - { - DebugPulse(_DEBUG_PIN1, 1); - _buffer_overflow = true; - } - - // skip the stop bit - tunedDelay(_rx_delay_stopbit); - DebugPulse(_DEBUG_PIN1, 1); - - // Re-enable interrupts when we're sure to be inside the stop bit - setRxIntMsk(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 -} - -uint8_t SoftwareSerial::rx_pin_read() -{ - return *_receivePortRegister & _receiveBitMask; -} - -// -// Interrupt handling -// - -/* static */ -inline void SoftwareSerial::handle_interrupt() -{ - if (active_object) - { - active_object->recv(); - } -} - -#if defined(PCINT0_vect) -ISR(PCINT0_vect) -{ - SoftwareSerial::handle_interrupt(); -} -#endif - -#if defined(PCINT1_vect) -ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect)); -#endif - -#if defined(PCINT2_vect) -ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect)); -#endif - -#if defined(PCINT3_vect) -ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect)); -#endif - -// -// Constructor -// -SoftwareSerial::SoftwareSerial(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 -// -SoftwareSerial::~SoftwareSerial() -{ - end(); -} - -void SoftwareSerial::setTX(uint8_t tx) -{ - // First write, then set output. If we do this the other way around, - // the pin would be output low for a short while before switching to - // output hihg. Now, it is input with pullup for a short while, which - // is fine. With inverse logic, either order is fine. - digitalWrite(tx, _inverse_logic ? LOW : HIGH); - pinMode(tx, OUTPUT); - _transmitBitMask = digitalPinToBitMask(tx); - uint8_t port = digitalPinToPort(tx); - _transmitPortRegister = portOutputRegister(port); -} - -void SoftwareSerial::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); -} - -uint16_t SoftwareSerial::subtract_cap(uint16_t num, uint16_t sub) { - if (num > sub) - return num - sub; - else - return 1; -} - -// -// Public methods -// - -void SoftwareSerial::begin(long speed) -{ - _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0; - - // Precalculate the various delays, in number of 4-cycle delays - uint16_t bit_delay = (F_CPU / speed) / 4; - - // 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit, - // 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits, - // 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit - // These are all close enough to just use 15 cycles, since the inter-bit - // timings are the most critical (deviations stack 8 times) - _tx_delay = subtract_cap(bit_delay, 15 / 4); - - // Only setup rx when we have a valid PCINT for this pin - if (digitalPinToPCICR(_receivePin)) { - #if GCC_VERSION > 40800 - // Timings counted from gcc 4.8.2 output. This works up to 115200 on - // 16Mhz and 57600 on 8Mhz. - // - // When the start bit occurs, there are 3 or 4 cycles before the - // interrupt flag is set, 4 cycles before the PC is set to the right - // interrupt vector address and the old PC is pushed on the stack, - // and then 75 cycles of instructions (including the RJMP in the - // ISR vector table) until the first delay. After the delay, there - // are 17 more cycles until the pin value is read (excluding the - // delay in the loop). - // We want to have a total delay of 1.5 bit time. Inside the loop, - // we already wait for 1 bit time - 23 cycles, so here we wait for - // 0.5 bit time - (71 + 18 - 22) cycles. - _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4); - - // There are 23 cycles in each loop iteration (excluding the delay) - _rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4); - - // There are 37 cycles from the last bit read to the start of - // stopbit delay and 11 cycles from the delay until the interrupt - // mask is enabled again (which _must_ happen during the stopbit). - // This delay aims at 3/4 of a bit time, meaning the end of the - // delay will be at 1/4th of the stopbit. This allows some extra - // time for ISR cleanup, which makes 115200 baud at 16Mhz work more - // reliably - _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4); - #else // Timings counted from gcc 4.3.2 output - // Note that this code is a _lot_ slower, mostly due to bad register - // allocation choices of gcc. This works up to 57600 on 16Mhz and - // 38400 on 8Mhz. - _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4); - _rx_delay_intrabit = subtract_cap(bit_delay, 11 / 4); - _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4); - #endif - - - // Enable the PCINT for the entire port here, but never disable it - // (others might also need it, so we disable the interrupt by using - // the per-pin PCMSK register). - *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin)); - // Precalculate the pcint mask register and value, so setRxIntMask - // can be used inside the ISR without costing too much time. - _pcint_maskreg = digitalPinToPCMSK(_receivePin); - _pcint_maskvalue = _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 - - listen(); -} - -void SoftwareSerial::setRxIntMsk(bool enable) -{ - if (enable) - *_pcint_maskreg |= _pcint_maskvalue; - else - *_pcint_maskreg &= ~_pcint_maskvalue; -} - -void SoftwareSerial::end() -{ - stopListening(); -} - - -// Read data from buffer -int SoftwareSerial::read() -{ - if (!isListening()) - return -1; - - // Empty buffer? - if (_receive_buffer_head == _receive_buffer_tail) - return -1; - - // Read from "head" - uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte - _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF; - return d; -} - -int SoftwareSerial::available() -{ - if (!isListening()) - return 0; - - return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF; -} - -size_t SoftwareSerial::write(uint8_t b) -{ - if (_tx_delay == 0) { - setWriteError(); - return 0; - } - - // By declaring these as local variables, the compiler will put them - // in registers _before_ disabling interrupts and entering the - // critical timing sections below, which makes it a lot easier to - // verify the cycle timings - volatile uint8_t *reg = _transmitPortRegister; - uint8_t reg_mask = _transmitBitMask; - uint8_t inv_mask = ~_transmitBitMask; - uint8_t oldSREG = SREG; - bool inv = _inverse_logic; - uint16_t delay = _tx_delay; - - if (inv) - b = ~b; - - cli(); // turn off interrupts for a clean txmit - - // Write the start bit - if (inv) - *reg |= reg_mask; - else - *reg &= inv_mask; - - tunedDelay(delay); - - // Write each of the 8 bits - for (uint8_t i = 8; i > 0; --i) - { - if (b & 1) // choose bit - *reg |= reg_mask; // send 1 - else - *reg &= inv_mask; // send 0 - - tunedDelay(delay); - b >>= 1; - } - - // restore pin to natural state - if (inv) - *reg &= inv_mask; - else - *reg |= reg_mask; - - SREG = oldSREG; // turn interrupts back on - tunedDelay(_tx_delay); - - return 1; -} - -void SoftwareSerial::flush() -{ - if (!isListening()) - return; - - uint8_t oldSREG = SREG; - cli(); - _receive_buffer_head = _receive_buffer_tail = 0; - SREG = oldSREG; -} - -int SoftwareSerial::peek() -{ - if (!isListening()) - return -1; - - // Empty buffer? - if (_receive_buffer_head == _receive_buffer_tail) - return -1; - - // Read from "head" - return _receive_buffer[_receive_buffer_head]; -} diff --git a/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.h b/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.h deleted file mode 100644 index 680e40d..0000000 --- a/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -SoftwareSerial.h (formerly NewSoftSerial.h) - -Multi-instance software serial library for Arduino/Wiring --- Interrupt-driven receive and other improvements by ladyada - (http://ladyada.net) --- Tuning, circular buffer, derivation from class Print/Stream, - multi-instance support, porting to 8MHz processors, - various optimizations, PROGMEM delay tables, inverse logic and - direct port writing by Mikal Hart (http://www.arduiniana.org) --- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) --- 20MHz processor support by Garrett Mace (http://www.macetech.com) --- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.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 - -The latest version of this library can always be found at -http://arduiniana.org. -*/ - -#ifndef SoftwareSerial_h -#define SoftwareSerial_h - -#include -#include - -/****************************************************************************** -* Definitions -******************************************************************************/ - -#define _SS_MAX_RX_BUFF 64 // RX buffer size -#ifndef GCC_VERSION -#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif - -class SoftwareSerial : public Stream -{ -private: - // per object data - uint8_t _receivePin; - uint8_t _receiveBitMask; - volatile uint8_t *_receivePortRegister; - uint8_t _transmitBitMask; - volatile uint8_t *_transmitPortRegister; - volatile uint8_t *_pcint_maskreg; - uint8_t _pcint_maskvalue; - - // Expressed as 4-cycle delays (must never be 0!) - 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[_SS_MAX_RX_BUFF]; - static volatile uint8_t _receive_buffer_tail; - static volatile uint8_t _receive_buffer_head; - static SoftwareSerial *active_object; - - // private methods - void recv() __attribute__((__always_inline__)); - uint8_t rx_pin_read(); - void tx_pin_write(uint8_t pin_state) __attribute__((__always_inline__)); - void setTX(uint8_t transmitPin); - void setRX(uint8_t receivePin); - void setRxIntMsk(bool enable) __attribute__((__always_inline__)); - - // Return num - sub, or 1 if the result would be < 1 - static uint16_t subtract_cap(uint16_t num, uint16_t sub); - - // private static method for timing - static inline void tunedDelay(uint16_t delay); - -public: - // public methods - SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false); - ~SoftwareSerial(); - void begin(long speed); - bool listen(); - void end(); - bool isListening() { return this == active_object; } - bool stopListening(); - bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; } - int peek(); - - virtual size_t write(uint8_t byte); - virtual int read(); - virtual int available(); - virtual void flush(); - operator bool() { return true; } - - using Print::write; - - // public only for easy access by interrupt handlers - static inline void handle_interrupt() __attribute__((__always_inline__)); -}; - -// Arduino 0012 workaround -#undef int -#undef char -#undef long -#undef byte -#undef float -#undef abs -#undef round - -#endif diff --git a/hardware/bean/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino b/hardware/bean/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino deleted file mode 100644 index f659133..0000000 --- a/hardware/bean/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino +++ /dev/null @@ -1,55 +0,0 @@ -/* - Software serial multple serial test - - Receives from the hardware serial, sends to software serial. - Receives from software serial, sends to hardware serial. - - The circuit: - * RX is digital pin 10 (connect to TX of other device) - * TX is digital pin 11 (connect to RX of other device) - - Note: - Not all pins on the Mega and Mega 2560 support change interrupts, - so only the following can be used for RX: - 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 - - Not all pins on the Leonardo support change interrupts, - so only the following can be used for RX: - 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). - - created back in the mists of time - modified 25 May 2012 - by Tom Igoe - based on Mikal Hart's example - - This example code is in the public domain. - - */ -#include - -SoftwareSerial mySerial(10, 11); // RX, TX - -void setup() -{ - // Open serial communications and wait for port to open: - Serial.begin(57600); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } - - - Serial.println("Goodnight moon!"); - - // set the data rate for the SoftwareSerial port - mySerial.begin(4800); - mySerial.println("Hello, world?"); -} - -void loop() // run over and over -{ - if (mySerial.available()) - Serial.write(mySerial.read()); - if (Serial.available()) - mySerial.write(Serial.read()); -} - diff --git a/hardware/bean/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino b/hardware/bean/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino deleted file mode 100644 index 95881a6..0000000 --- a/hardware/bean/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino +++ /dev/null @@ -1,93 +0,0 @@ -/* - Software serial multple serial test - - Receives from the two software serial ports, - sends to the hardware serial port. - - In order to listen on a software port, you call port.listen(). - When using two software serial ports, you have to switch ports - by listen()ing on each one in turn. Pick a logical time to switch - ports, like the end of an expected transmission, or when the - buffer is empty. This example switches ports when there is nothing - more to read from a port - - The circuit: - Two devices which communicate serially are needed. - * First serial device's TX attached to digital pin 2, RX to pin 3 - * Second serial device's TX attached to digital pin 4, RX to pin 5 - - Note: - Not all pins on the Mega and Mega 2560 support change interrupts, - so only the following can be used for RX: - 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 - - Not all pins on the Leonardo support change interrupts, - so only the following can be used for RX: - 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). - - created 18 Apr. 2011 - modified 25 May 2012 - by Tom Igoe - based on Mikal Hart's twoPortRXExample - - This example code is in the public domain. - - */ - -#include -// software serial #1: TX = digital pin 10, RX = digital pin 11 -SoftwareSerial portOne(10, 11); - -// software serial #2: TX = digital pin 8, RX = digital pin 9 -// on the Mega, use other pins instead, since 8 and 9 don't work on the Mega -SoftwareSerial portTwo(8, 9); - -void setup() -{ - // Open serial communications and wait for port to open: - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only - } - - - // Start each software serial port - portOne.begin(9600); - portTwo.begin(9600); -} - -void loop() -{ - // By default, the last intialized port is listening. - // when you want to listen on a port, explicitly select it: - portOne.listen(); - Serial.println("Data from port one:"); - // while there is data coming in, read it - // and send to the hardware serial port: - while (portOne.available() > 0) { - char inByte = portOne.read(); - Serial.write(inByte); - } - - // blank line to separate data from the two ports: - Serial.println(); - - // Now listen on the second port - portTwo.listen(); - // while there is data coming in, read it - // and send to the hardware serial port: - Serial.println("Data from port two:"); - while (portTwo.available() > 0) { - char inByte = portTwo.read(); - Serial.write(inByte); - } - - // blank line to separate data from the two ports: - Serial.println(); -} - - - - - - diff --git a/hardware/bean/avr/libraries/SoftwareSerial/keywords.txt b/hardware/bean/avr/libraries/SoftwareSerial/keywords.txt deleted file mode 100644 index aaea17c..0000000 --- a/hardware/bean/avr/libraries/SoftwareSerial/keywords.txt +++ /dev/null @@ -1,30 +0,0 @@ -####################################### -# Syntax Coloring Map for SoftwareSerial -# (formerly NewSoftSerial) -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -SoftwareSerial KEYWORD1 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -begin KEYWORD2 -end KEYWORD2 -read KEYWORD2 -write KEYWORD2 -available KEYWORD2 -isListening KEYWORD2 -overflow KEYWORD2 -flush KEYWORD2 -listen KEYWORD2 -peek KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### - diff --git a/hardware/bean/avr/libraries/SoftwareSerial/library.properties b/hardware/bean/avr/libraries/SoftwareSerial/library.properties deleted file mode 100644 index 463bf8a..0000000 --- a/hardware/bean/avr/libraries/SoftwareSerial/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=SoftwareSerial -version=1.0 -author=Arduino -maintainer=Arduino -sentence=Enables serial communication on digital pins. For all Arduino boards, BUT Arduino DUE. -paragraph= -url=http://arduino.cc/en/Reference/SoftwareSerial -architectures=avr -types=Arduino -category=Communication diff --git a/hardware/bean/avr/libraries/Wire/Wire.cpp b/hardware/bean/avr/libraries/Wire/Wire.cpp deleted file mode 100644 index 553add7..0000000 --- a/hardware/bean/avr/libraries/Wire/Wire.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* - 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 - - Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts -*/ - -extern "C" { - #include - #include - #include - #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); -} - -void TwoWire::setClock(uint32_t frequency) -{ - TWBR = ((F_CPU / frequency) - 16) / 2; -} - -uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) -{ - // clamp to buffer length - if(quantity > BUFFER_LENGTH){ - quantity = BUFFER_LENGTH; - } - // perform blocking read into buffer - uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop); - // set rx buffer iterator vars - rxBufferIndex = 0; - rxBufferLength = read; - - return read; -} - -uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) -{ - return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); -} - -uint8_t TwoWire::requestFrom(int address, int quantity) -{ - return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); -} - -uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) -{ - return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); -} - -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); -} - -// -// Originally, 'endTransmission' was an f(void) function. -// It has been modified to take one parameter indicating -// whether or not a STOP should be performed on the bus. -// Calling endTransmission(false) allows a sketch to -// perform a repeated start. -// -// WARNING: Nothing in the library keeps track of whether -// the bus tenure has been properly ended with a STOP. It -// is very possible to leave the bus in a hung state if -// no call to endTransmission(true) is made. Some I2C -// devices will behave oddly if they do not see a STOP. -// -uint8_t TwoWire::endTransmission(uint8_t sendStop) -{ - // transmit buffer (blocking) - int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop); - // reset tx buffer iterator vars - txBufferIndex = 0; - txBufferLength = 0; - // indicate that we are done transmitting - transmitting = 0; - return ret; -} - -// This provides backwards compatibility with the original -// definition, and expected behaviour, of endTransmission -// -uint8_t TwoWire::endTransmission(void) -{ - return endTransmission(true); -} - -// must be called in: -// slave tx event callback -// or after beginTransmission(address) -size_t TwoWire::write(uint8_t data) -{ - if(transmitting){ - // in master transmitter mode - // don't bother if buffer is full - if(txBufferLength >= BUFFER_LENGTH){ - setWriteError(); - return 0; - } - // 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); - } - return 1; -} - -// must be called in: -// slave tx event callback -// or after beginTransmission(address) -size_t TwoWire::write(const uint8_t *data, size_t quantity) -{ - if(transmitting){ - // in master transmitter mode - for(size_t i = 0; i < quantity; ++i){ - write(data[i]); - } - }else{ - // in slave send mode - // reply to master - twi_transmit(data, quantity); - } - return quantity; -} - -// must be called in: -// slave rx event callback -// or after requestFrom(address, numBytes) -int TwoWire::available(void) -{ - return rxBufferLength - rxBufferIndex; -} - -// must be called in: -// slave rx event callback -// or after requestFrom(address, numBytes) -int TwoWire::read(void) -{ - int value = -1; - - // get each successive byte on each call - if(rxBufferIndex < rxBufferLength){ - value = rxBuffer[rxBufferIndex]; - ++rxBufferIndex; - } - - return value; -} - -// must be called in: -// slave rx event callback -// or after requestFrom(address, numBytes) -int TwoWire::peek(void) -{ - int value = -1; - - if(rxBufferIndex < rxBufferLength){ - value = rxBuffer[rxBufferIndex]; - } - - return value; -} - -void TwoWire::flush(void) -{ - // XXX: to be implemented. -} - -// 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/hardware/bean/avr/libraries/Wire/Wire.h b/hardware/bean/avr/libraries/Wire/Wire.h deleted file mode 100644 index 732bdc3..0000000 --- a/hardware/bean/avr/libraries/Wire/Wire.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - 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 - - Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts -*/ - -#ifndef TwoWire_h -#define TwoWire_h - -#include -#include "Stream.h" - -#define BUFFER_LENGTH 32 - -class TwoWire : public Stream -{ - 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 setClock(uint32_t); - void beginTransmission(uint8_t); - void beginTransmission(int); - uint8_t endTransmission(void); - uint8_t endTransmission(uint8_t); - uint8_t requestFrom(uint8_t, uint8_t); - uint8_t requestFrom(uint8_t, uint8_t, uint8_t); - uint8_t requestFrom(int, int); - uint8_t requestFrom(int, int, int); - virtual size_t write(uint8_t); - virtual size_t write(const uint8_t *, size_t); - virtual int available(void); - virtual int read(void); - virtual int peek(void); - virtual void flush(void); - void onReceive( void (*)(int) ); - void onRequest( void (*)(void) ); - - 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; -}; - -extern TwoWire Wire; - -#endif - diff --git a/hardware/bean/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino b/hardware/bean/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino deleted file mode 100644 index d97a9e3..0000000 --- a/hardware/bean/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino +++ /dev/null @@ -1,87 +0,0 @@ -// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder -// by Nicholas Zambetti -// and James Tichenor - -// Demonstrates use of the Wire library reading data from the -// Devantech Utrasonic Rangers SFR08 and SFR10 - -// Created 29 April 2006 - -// This example code is in the public domain. - - -#include - -void setup() -{ - Wire.begin(); // join i2c bus (address optional for master) - Serial.begin(9600); // start serial communication at 9600bps -} - -int reading = 0; - -void loop() -{ - // step 1: instruct sensor to read echoes - Wire.beginTransmission(112); // transmit to device #112 (0x70) - // the address specified in the datasheet is 224 (0xE0) - // but i2c adressing uses the high 7 bits so it's 112 - Wire.write(byte(0x00)); // sets register pointer to the command register (0x00) - Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50) - // use 0x51 for centimeters - // use 0x52 for ping microseconds - Wire.endTransmission(); // stop transmitting - - // step 2: wait for readings to happen - delay(70); // datasheet suggests at least 65 milliseconds - - // step 3: instruct sensor to return a particular echo reading - Wire.beginTransmission(112); // transmit to device #112 - Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02) - Wire.endTransmission(); // stop transmitting - - // step 4: request reading from sensor - Wire.requestFrom(112, 2); // request 2 bytes from slave device #112 - - // step 5: receive reading from sensor - if (2 <= Wire.available()) // if two bytes were received - { - reading = Wire.read(); // receive high byte (overwrites previous reading) - reading = reading << 8; // shift high byte to be high 8 bits - reading |= Wire.read(); // receive low byte as lower 8 bits - Serial.println(reading); // print the reading - } - - delay(250); // wait a bit since people have to read the output :) -} - - -/* - -// The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08) -// usage: changeAddress(0x70, 0xE6); - -void changeAddress(byte oldAddress, byte newAddress) -{ - Wire.beginTransmission(oldAddress); - Wire.write(byte(0x00)); - Wire.write(byte(0xA0)); - Wire.endTransmission(); - - Wire.beginTransmission(oldAddress); - Wire.write(byte(0x00)); - Wire.write(byte(0xAA)); - Wire.endTransmission(); - - Wire.beginTransmission(oldAddress); - Wire.write(byte(0x00)); - Wire.write(byte(0xA5)); - Wire.endTransmission(); - - Wire.beginTransmission(oldAddress); - Wire.write(byte(0x00)); - Wire.write(newAddress); - Wire.endTransmission(); -} - -*/ diff --git a/hardware/bean/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino b/hardware/bean/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino deleted file mode 100644 index 4d1580a..0000000 --- a/hardware/bean/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino +++ /dev/null @@ -1,39 +0,0 @@ -// I2C Digital Potentiometer -// by Nicholas Zambetti -// and Shawn Bonkowski - -// Demonstrates use of the Wire library -// Controls AD5171 digital potentiometer via I2C/TWI - -// Created 31 March 2006 - -// This example code is in the public domain. - -// This example code is in the public domain. - - -#include - -void setup() -{ - Wire.begin(); // join i2c bus (address optional for master) -} - -byte val = 0; - -void loop() -{ - Wire.beginTransmission(44); // transmit to device #44 (0x2c) - // device address is specified in datasheet - Wire.write(byte(0x00)); // sends instruction byte - Wire.write(val); // sends potentiometer value byte - Wire.endTransmission(); // stop transmitting - - val++; // increment value - if (val == 64) // if reached 64th position (max) - { - val = 0; // start over from lowest value - } - delay(500); -} - diff --git a/hardware/bean/avr/libraries/Wire/examples/master_reader/master_reader.ino b/hardware/bean/avr/libraries/Wire/examples/master_reader/master_reader.ino deleted file mode 100644 index 74f0155..0000000 --- a/hardware/bean/avr/libraries/Wire/examples/master_reader/master_reader.ino +++ /dev/null @@ -1,32 +0,0 @@ -// Wire Master Reader -// by Nicholas Zambetti - -// Demonstrates use of the Wire library -// Reads data from an I2C/TWI slave device -// Refer to the "Wire Slave Sender" example for use with this - -// Created 29 March 2006 - -// This example code is in the public domain. - - -#include - -void setup() -{ - Wire.begin(); // join i2c bus (address optional for master) - Serial.begin(9600); // start serial for output -} - -void loop() -{ - Wire.requestFrom(2, 6); // request 6 bytes from slave device #2 - - while (Wire.available()) // slave may send less than requested - { - char c = Wire.read(); // receive a byte as character - Serial.print(c); // print the character - } - - delay(500); -} diff --git a/hardware/bean/avr/libraries/Wire/examples/master_writer/master_writer.ino b/hardware/bean/avr/libraries/Wire/examples/master_writer/master_writer.ino deleted file mode 100644 index 482e922..0000000 --- a/hardware/bean/avr/libraries/Wire/examples/master_writer/master_writer.ino +++ /dev/null @@ -1,31 +0,0 @@ -// Wire Master Writer -// by Nicholas Zambetti - -// Demonstrates use of the Wire library -// Writes data to an I2C/TWI slave device -// Refer to the "Wire Slave Receiver" example for use with this - -// Created 29 March 2006 - -// This example code is in the public domain. - - -#include - -void setup() -{ - Wire.begin(); // join i2c bus (address optional for master) -} - -byte x = 0; - -void loop() -{ - Wire.beginTransmission(4); // transmit to device #4 - Wire.write("x is "); // sends five bytes - Wire.write(x); // sends one byte - Wire.endTransmission(); // stop transmitting - - x++; - delay(500); -} diff --git a/hardware/bean/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino b/hardware/bean/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino deleted file mode 100644 index 15eff9a..0000000 --- a/hardware/bean/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino +++ /dev/null @@ -1,38 +0,0 @@ -// Wire Slave Receiver -// by Nicholas Zambetti - -// Demonstrates use of the Wire library -// Receives data as an I2C/TWI slave device -// Refer to the "Wire Master Writer" example for use with this - -// Created 29 March 2006 - -// This example code is in the public domain. - - -#include - -void setup() -{ - Wire.begin(4); // join i2c bus with address #4 - Wire.onReceive(receiveEvent); // register event - Serial.begin(9600); // start serial for output -} - -void loop() -{ - delay(100); -} - -// function that executes whenever data is received from master -// this function is registered as an event, see setup() -void receiveEvent(int howMany) -{ - while (1 < Wire.available()) // loop through all but the last - { - char c = Wire.read(); // receive byte as a character - Serial.print(c); // print the character - } - int x = Wire.read(); // receive byte as an integer - Serial.println(x); // print the integer -} diff --git a/hardware/bean/avr/libraries/Wire/examples/slave_sender/slave_sender.ino b/hardware/bean/avr/libraries/Wire/examples/slave_sender/slave_sender.ino deleted file mode 100644 index 4437ab1..0000000 --- a/hardware/bean/avr/libraries/Wire/examples/slave_sender/slave_sender.ino +++ /dev/null @@ -1,32 +0,0 @@ -// Wire Slave Sender -// by Nicholas Zambetti - -// Demonstrates use of the Wire library -// Sends data as an I2C/TWI slave device -// Refer to the "Wire Master Reader" example for use with this - -// Created 29 March 2006 - -// This example code is in the public domain. - - -#include - -void setup() -{ - Wire.begin(2); // join i2c bus with address #2 - Wire.onRequest(requestEvent); // register event -} - -void loop() -{ - delay(100); -} - -// function that executes whenever data is requested by master -// this function is registered as an event, see setup() -void requestEvent() -{ - Wire.write("hello "); // respond with message of 6 bytes - // as expected by master -} diff --git a/hardware/bean/avr/libraries/Wire/keywords.txt b/hardware/bean/avr/libraries/Wire/keywords.txt deleted file mode 100644 index ff31475..0000000 --- a/hardware/bean/avr/libraries/Wire/keywords.txt +++ /dev/null @@ -1,32 +0,0 @@ -####################################### -# Syntax Coloring Map For Wire -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -begin KEYWORD2 -setClock KEYWORD2 -beginTransmission KEYWORD2 -endTransmission KEYWORD2 -requestFrom KEYWORD2 -send KEYWORD2 -receive KEYWORD2 -onReceive KEYWORD2 -onRequest KEYWORD2 - -####################################### -# Instances (KEYWORD2) -####################################### - -Wire KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### - diff --git a/hardware/bean/avr/libraries/Wire/library.properties b/hardware/bean/avr/libraries/Wire/library.properties deleted file mode 100644 index 0f1e796..0000000 --- a/hardware/bean/avr/libraries/Wire/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Wire -version=1.0 -author=Arduino -maintainer=Arduino -sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. For all Arduino boards, BUT Arduino DUE. -paragraph= -url=http://arduino.cc/en/Reference/Wire -architectures=avr -types=Arduino -category=Communication diff --git a/hardware/bean/avr/libraries/Wire/utility/twi.c b/hardware/bean/avr/libraries/Wire/utility/twi.c deleted file mode 100644 index 201d7d1..0000000 --- a/hardware/bean/avr/libraries/Wire/utility/twi.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - 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 - - Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts -*/ - -#include -#include -#include -#include -#include -#include -#include "Arduino.h" // for digitalWrite - -#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 "pins_arduino.h" -#include "twi.h" - -static volatile uint8_t twi_state; -static volatile uint8_t twi_slarw; -static volatile uint8_t twi_sendStop; // should the transaction end with a stop -static volatile uint8_t twi_inRepStart; // in the middle of a repeated start - -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 volatile 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; - twi_sendStop = true; // default value - twi_inRepStart = false; - - // activate internal pullups for twi. - digitalWrite(SDA, 1); - digitalWrite(SCL, 1); - - // initialize twi prescaler and bit rate - cbi(TWSR, TWPS0); - cbi(TWSR, TWPS1); - TWBR = ((F_CPU / 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 - * sendStop: Boolean indicating whether to send a stop at the end - * Output number of bytes read - */ -uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) -{ - 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; - twi_sendStop = sendStop; - // 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; - - if (true == twi_inRepStart) { - // if we're in the repeated start state, then we've already sent the start, - // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. - // We need to remove ourselves from the repeated start state before we enable interrupts, - // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning - // up. Also, don't enable the START interrupt. There may be one pending from the - // repeated start that we sent outselves, and that would really confuse things. - twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR - TWDR = twi_slarw; - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START - } - else - // 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 - * sendStop: boolean indicating whether or not to send a stop at the end - * 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 sendStop) -{ - 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; - twi_sendStop = sendStop; - // 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; - - // if we're in a repeated start, then we've already sent the START - // in the ISR. Don't do it again. - // - if (true == twi_inRepStart) { - // if we're in the repeated start state, then we've already sent the start, - // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. - // We need to remove ourselves from the repeated start state before we enable interrupts, - // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning - // up. Also, don't enable the START interrupt. There may be one pending from the - // repeated start that we sent outselves, and that would really confuse things. - twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR - TWDR = twi_slarw; - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START - } - else - // send start condition - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs - - // 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(const 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; -} - -ISR(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{ - if (twi_sendStop) - twi_stop(); - else { - twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we - // avoid handling the interrupt until we're in the next transaction, - // at the point where we would normally issue the start. - TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; - twi_state = TWI_READY; - } - } - 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; - if (twi_sendStop) - twi_stop(); - else { - twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we - // avoid handling the interrupt until we're in the next transaction, - // at the point where we would normally issue the start. - TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; - twi_state = TWI_READY; - } - break; - 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/hardware/bean/avr/libraries/Wire/utility/twi.h b/hardware/bean/avr/libraries/Wire/utility/twi.h deleted file mode 100644 index 6526593..0000000 --- a/hardware/bean/avr/libraries/Wire/utility/twi.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - 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 - - //#define ATMEGA8 - - #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); - uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); - uint8_t twi_transmit(const 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 - From 941b1cf0cc5af5ef3b42550b6793a03e072f6029 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Tue, 18 Oct 2016 16:36:51 -0500 Subject: [PATCH 02/13] core: add #define IS_BEAN(0) to bean+/pins_arduino.h --- hardware/bean/avr/variants/bean+/pins_arduino.h | 15 ++++++++------- hardware/bean/avr/variants/bean/pins_arduino.h | 3 +-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hardware/bean/avr/variants/bean+/pins_arduino.h b/hardware/bean/avr/variants/bean+/pins_arduino.h index f718cf6..11c89d3 100644 --- a/hardware/bean/avr/variants/bean+/pins_arduino.h +++ b/hardware/bean/avr/variants/bean+/pins_arduino.h @@ -33,6 +33,8 @@ #define digitalPinHasPWM(p) ((p) == 2 || (p) == 5 || (p) == 6 || (p) == 7) +#define IS_BEAN (0) + static const uint8_t SS = 6; static const uint8_t MOSI = 7; static const uint8_t MISO = 8; @@ -128,19 +130,19 @@ const uint16_t PROGMEM port_to_input_PGM[] = { const uint8_t PROGMEM digital_pin_to_port_PGM[] = { PD, // D0 - PD, // D1 - PD, // D2 PWM - PD, // D3 - PB, // D4 + PD, // D1 + PD, // D2 PWM + PD, // D3 + PB, // D4 PB, // D5 PWM - PB, // D6 PWM + PB, // D6 PWM PB, // D7 PWM PB, // D8 PB, // D9 PC, // A0 PC, // A1 PC, // A2 - PC, // A3 + PC, // A3 PC, // A4 PC, // A5 PD, // CC_INTERRUPT @@ -188,4 +190,3 @@ const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { #endif // ARDUINO_MAIN #endif // Pins_Arduino_h - diff --git a/hardware/bean/avr/variants/bean/pins_arduino.h b/hardware/bean/avr/variants/bean/pins_arduino.h index 4addcbe..2e409c4 100644 --- a/hardware/bean/avr/variants/bean/pins_arduino.h +++ b/hardware/bean/avr/variants/bean/pins_arduino.h @@ -37,7 +37,7 @@ #define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) #endif - #define IS_BEAN (1) +#define IS_BEAN (1) static const uint8_t SS = 2; static const uint8_t MOSI = 3; @@ -204,4 +204,3 @@ const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { #endif // ARDUINO_MAIN #endif // Pins_Arduino_h - From 0d1cc6778180fb80a3c12c870ad47d5a9153a1b7 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Tue, 18 Oct 2016 20:52:01 -0500 Subject: [PATCH 03/13] lib: add bean-arduino-libraries as submodule --- .gitmodules | 3 +++ hardware/bean/avr/libraries | 1 + 2 files changed, 4 insertions(+) create mode 160000 hardware/bean/avr/libraries diff --git a/.gitmodules b/.gitmodules index 7c7835e..5a0a1b9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "hardware/bean/avr/cores/bean/applicationMessageHeaders"] path = hardware/bean/avr/cores/bean/applicationMessageHeaders url = https://bitbucket.org/punchthroughdesign/bean-application-message-definitions.git +[submodule "hardware/bean/avr/libraries"] + path = hardware/bean/avr/libraries + url = git@github.com:PunchThrough/bean-arduino-libraries.git diff --git a/hardware/bean/avr/libraries b/hardware/bean/avr/libraries new file mode 160000 index 0000000..af04b57 --- /dev/null +++ b/hardware/bean/avr/libraries @@ -0,0 +1 @@ +Subproject commit af04b57fed993827b9d269b85b36e89537ae5b90 From 57e0f632483a99330797ccfbb68ea1819debb0e7 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Wed, 19 Oct 2016 14:17:47 -0500 Subject: [PATCH 04/13] test: add test sketch that includes all libraries --- hardware/bean/avr/libraries | 2 +- resources/test_sketches/include_libraries.ino | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 resources/test_sketches/include_libraries.ino diff --git a/hardware/bean/avr/libraries b/hardware/bean/avr/libraries index af04b57..d6c0850 160000 --- a/hardware/bean/avr/libraries +++ b/hardware/bean/avr/libraries @@ -1 +1 @@ -Subproject commit af04b57fed993827b9d269b85b36e89537ae5b90 +Subproject commit d6c0850a8f2b000f82486ffc403a4579e3ff3f6e diff --git a/resources/test_sketches/include_libraries.ino b/resources/test_sketches/include_libraries.ino new file mode 100644 index 0000000..eb00bff --- /dev/null +++ b/resources/test_sketches/include_libraries.ino @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +void setup() +{ + // Nothing! +} + +void loop() +{ + Bean.sleep(1000); +} From f47623cf01642b4710d9dfe1b1b018bef3ab7970 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Wed, 19 Oct 2016 17:01:56 -0500 Subject: [PATCH 05/13] test: re-enable compile_all.py on circle --- circle.yml | 4 ++-- scripts/setup_platformio.sh | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/circle.yml b/circle.yml index dc9a52a..4ba4db9 100644 --- a/circle.yml +++ b/circle.yml @@ -24,12 +24,12 @@ dependencies: - sudo apt-get install doxygen - npm install # Don't install PlatformIO if it's already been set up; it takes forever - #- if [ ! -f "~/.platformio/appstate.json" ]; then scripts/setup_platformio.sh; fi + - if [ ! -f "~/.platformio/appstate.json" ]; then scripts/setup_platformio.sh; fi test: override: - scripts/lint_all.py --lint - #- scripts/compile_all.py + - scripts/compile_all.py post: - make docs - cp -R docs $CIRCLE_ARTIFACTS diff --git a/scripts/setup_platformio.sh b/scripts/setup_platformio.sh index d10e1b2..b988ea1 100755 --- a/scripts/setup_platformio.sh +++ b/scripts/setup_platformio.sh @@ -1,7 +1,6 @@ #!/bin/sh -# Installing PlatformIO with pip is kind of broken. Just use their install script. -python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" +pip install "platformio==2.3.5" platformio platforms install atmelavr # Add Punch Through boards definition @@ -15,5 +14,8 @@ platformio ci --board=uno || true # Add Punch Through core files # packages/framework-arduinoavr may not exist until the first compile happens, # so create the directory right away -mkdir -p /home/ubuntu/.platformio/packages/framework-arduinoavr/ +mkdir -p ~/.platformio/packages/framework-arduinoavr/ cp -rvf hardware/bean/avr/* ~/.platformio/packages/framework-arduinoavr/ + +# Install libraries +cp -rvf hardware/bean/avr/libraries/ ~/.platformio/lib/ From a65901024366cbc8649ade01efffc1ba7f44ae5e Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Wed, 19 Oct 2016 17:26:20 -0500 Subject: [PATCH 06/13] circle: upgrade setuptools before setting up pio --- circle.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/circle.yml b/circle.yml index 4ba4db9..21c909f 100644 --- a/circle.yml +++ b/circle.yml @@ -18,6 +18,7 @@ dependencies: cache_directories: - ~/.platformio override: + - pip install --upgrade pip setuptools virtualenv - pip install cpplint # Used for deployment - sudo apt-get update From fe84a633a7cb6c6cef775da52c1a6f7afc7b1d37 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Fri, 21 Oct 2016 14:51:02 -0500 Subject: [PATCH 07/13] lib: remove libraries submodule --- .gitmodules | 3 --- hardware/bean/avr/libraries | 1 - 2 files changed, 4 deletions(-) delete mode 160000 hardware/bean/avr/libraries diff --git a/.gitmodules b/.gitmodules index 5a0a1b9..7c7835e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "hardware/bean/avr/cores/bean/applicationMessageHeaders"] path = hardware/bean/avr/cores/bean/applicationMessageHeaders url = https://bitbucket.org/punchthroughdesign/bean-application-message-definitions.git -[submodule "hardware/bean/avr/libraries"] - path = hardware/bean/avr/libraries - url = git@github.com:PunchThrough/bean-arduino-libraries.git diff --git a/hardware/bean/avr/libraries b/hardware/bean/avr/libraries deleted file mode 160000 index d6c0850..0000000 --- a/hardware/bean/avr/libraries +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d6c0850a8f2b000f82486ffc403a4579e3ff3f6e From 40a56f224485c0f212cb13d47465ef820b30d1a4 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Fri, 21 Oct 2016 15:07:03 -0500 Subject: [PATCH 08/13] lib: add core libraries as non-submodule --- hardware/bean/avr/libraries/EEPROM/EEPROM.h | 146 ++++ hardware/bean/avr/libraries/EEPROM/README.md | 139 ++++ .../examples/eeprom_clear/eeprom_clear.ino | 35 + .../EEPROM/examples/eeprom_crc/eeprom_crc.ino | 50 ++ .../EEPROM/examples/eeprom_get/eeprom_get.ino | 66 ++ .../eeprom_iteration/eeprom_iteration.ino | 57 ++ .../EEPROM/examples/eeprom_put/eeprom_put.ino | 56 ++ .../examples/eeprom_read/eeprom_read.ino | 57 ++ .../examples/eeprom_update/eeprom_update.ino | 69 ++ .../examples/eeprom_write/eeprom_write.ino | 58 ++ .../bean/avr/libraries/EEPROM/keywords.txt | 22 + .../avr/libraries/EEPROM/library.properties | 10 + .../Examples/ByteBuffer/ByteBuffer.cpp | 324 +++++++++ .../Examples/ByteBuffer/ByteBuffer.h | 105 +++ .../PinChangeInt/Examples/GetPSTR/GetPSTR.h | 21 + .../PinChangeIntDebug/PinChangeIntDebug.ino | 187 +++++ .../PinChangeIntExample2560.ino | 108 +++ .../PinChangeIntExample328.ino | 96 +++ .../PinChangeIntSpeedTest.pde | 265 +++++++ .../PinChangeIntTest/PinChangeIntTest.ino | 355 ++++++++++ .../PinChangeIntTest2/PinChangeIntTest2.ino | 275 ++++++++ .../SimpleExample328/SimpleExample328.ino | 66 ++ .../bean/avr/libraries/PinChangeInt/LICENSE | 54 ++ .../bean/avr/libraries/PinChangeInt/NOTICE | 27 + .../avr/libraries/PinChangeInt/PinChangeInt.h | 652 ++++++++++++++++++ .../bean/avr/libraries/PinChangeInt/README | 110 +++ .../avr/libraries/PinChangeInt/RELEASE_NOTES | 436 ++++++++++++ .../libraries/PinChangeInt/Technical_Notes | 70 ++ .../avr/libraries/PinChangeInt/keywords.txt | 10 + hardware/bean/avr/libraries/SPI/SPI.cpp | 201 ++++++ hardware/bean/avr/libraries/SPI/SPI.h | 324 +++++++++ .../BarometricPressureSensor.ino | 143 ++++ .../DigitalPotControl/DigitalPotControl.ino | 71 ++ hardware/bean/avr/libraries/SPI/keywords.txt | 36 + .../bean/avr/libraries/SPI/library.properties | 10 + .../SoftwareSerial/SoftwareSerial.cpp | 490 +++++++++++++ .../libraries/SoftwareSerial/SoftwareSerial.h | 121 ++++ .../SoftwareSerialExample.ino | 55 ++ .../TwoPortReceive/TwoPortReceive.ino | 93 +++ .../avr/libraries/SoftwareSerial/keywords.txt | 30 + .../SoftwareSerial/library.properties | 10 + hardware/bean/avr/libraries/Wire/Wire.cpp | 303 ++++++++ hardware/bean/avr/libraries/Wire/Wire.h | 80 +++ .../SFRRanger_reader/SFRRanger_reader.ino | 87 +++ .../digital_potentiometer.ino | 39 ++ .../examples/master_reader/master_reader.ino | 32 + .../examples/master_writer/master_writer.ino | 31 + .../slave_receiver/slave_receiver.ino | 38 + .../examples/slave_sender/slave_sender.ino | 32 + hardware/bean/avr/libraries/Wire/keywords.txt | 32 + .../avr/libraries/Wire/library.properties | 10 + .../bean/avr/libraries/Wire/utility/twi.c | 527 ++++++++++++++ .../bean/avr/libraries/Wire/utility/twi.h | 53 ++ 53 files changed, 6774 insertions(+) create mode 100644 hardware/bean/avr/libraries/EEPROM/EEPROM.h create mode 100644 hardware/bean/avr/libraries/EEPROM/README.md create mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino create mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino create mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino create mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino create mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino create mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino create mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino create mode 100644 hardware/bean/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino create mode 100644 hardware/bean/avr/libraries/EEPROM/keywords.txt create mode 100644 hardware/bean/avr/libraries/EEPROM/library.properties create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.cpp create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/GetPSTR/GetPSTR.h create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntDebug/PinChangeIntDebug.ino create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntExample2560/PinChangeIntExample2560.ino create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntExample328/PinChangeIntExample328.ino create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntSpeedTest/PinChangeIntSpeedTest.pde create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntTest/PinChangeIntTest.ino create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntTest2/PinChangeIntTest2.ino create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Examples/SimpleExample328/SimpleExample328.ino create mode 100755 hardware/bean/avr/libraries/PinChangeInt/LICENSE create mode 100755 hardware/bean/avr/libraries/PinChangeInt/NOTICE create mode 100755 hardware/bean/avr/libraries/PinChangeInt/PinChangeInt.h create mode 100755 hardware/bean/avr/libraries/PinChangeInt/README create mode 100755 hardware/bean/avr/libraries/PinChangeInt/RELEASE_NOTES create mode 100755 hardware/bean/avr/libraries/PinChangeInt/Technical_Notes create mode 100755 hardware/bean/avr/libraries/PinChangeInt/keywords.txt create mode 100644 hardware/bean/avr/libraries/SPI/SPI.cpp create mode 100644 hardware/bean/avr/libraries/SPI/SPI.h create mode 100644 hardware/bean/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino create mode 100644 hardware/bean/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino create mode 100644 hardware/bean/avr/libraries/SPI/keywords.txt create mode 100644 hardware/bean/avr/libraries/SPI/library.properties create mode 100644 hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.cpp create mode 100644 hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.h create mode 100644 hardware/bean/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino create mode 100644 hardware/bean/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino create mode 100644 hardware/bean/avr/libraries/SoftwareSerial/keywords.txt create mode 100644 hardware/bean/avr/libraries/SoftwareSerial/library.properties create mode 100644 hardware/bean/avr/libraries/Wire/Wire.cpp create mode 100644 hardware/bean/avr/libraries/Wire/Wire.h create mode 100644 hardware/bean/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino create mode 100644 hardware/bean/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino create mode 100644 hardware/bean/avr/libraries/Wire/examples/master_reader/master_reader.ino create mode 100644 hardware/bean/avr/libraries/Wire/examples/master_writer/master_writer.ino create mode 100644 hardware/bean/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino create mode 100644 hardware/bean/avr/libraries/Wire/examples/slave_sender/slave_sender.ino create mode 100644 hardware/bean/avr/libraries/Wire/keywords.txt create mode 100644 hardware/bean/avr/libraries/Wire/library.properties create mode 100644 hardware/bean/avr/libraries/Wire/utility/twi.c create mode 100644 hardware/bean/avr/libraries/Wire/utility/twi.h diff --git a/hardware/bean/avr/libraries/EEPROM/EEPROM.h b/hardware/bean/avr/libraries/EEPROM/EEPROM.h new file mode 100644 index 0000000..cde75db --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/EEPROM.h @@ -0,0 +1,146 @@ +/* + EEPROM.h - EEPROM library + Original Copyright (c) 2006 David A. Mellis. All right reserved. + New version by Christopher Andrews 2015. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef EEPROM_h +#define EEPROM_h + +#include +#include +#include + +/*** + EERef class. + + This object references an EEPROM cell. + Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. + This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. +***/ + +struct EERef{ + + EERef( const int index ) + : index( index ) {} + + //Access/read members. + uint8_t operator*() const { return eeprom_read_byte( (uint8_t*) index ); } + operator const uint8_t() const { return **this; } + + //Assignment/write members. + EERef &operator=( const EERef &ref ) { return *this = *ref; } + EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_t*) index, in ), *this; } + EERef &operator +=( uint8_t in ) { return *this = **this + in; } + EERef &operator -=( uint8_t in ) { return *this = **this - in; } + EERef &operator *=( uint8_t in ) { return *this = **this * in; } + EERef &operator /=( uint8_t in ) { return *this = **this / in; } + EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; } + EERef &operator %=( uint8_t in ) { return *this = **this % in; } + EERef &operator &=( uint8_t in ) { return *this = **this & in; } + EERef &operator |=( uint8_t in ) { return *this = **this | in; } + EERef &operator <<=( uint8_t in ) { return *this = **this << in; } + EERef &operator >>=( uint8_t in ) { return *this = **this >> in; } + + EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; } + + /** Prefix increment/decrement **/ + EERef& operator++() { return *this += 1; } + EERef& operator--() { return *this -= 1; } + + /** Postfix increment/decrement **/ + uint8_t operator++ (int){ + uint8_t ret = **this; + return ++(*this), ret; + } + + uint8_t operator-- (int){ + uint8_t ret = **this; + return --(*this), ret; + } + + int index; //Index of current EEPROM cell. +}; + +/*** + EEPtr class. + + This object is a bidirectional pointer to EEPROM cells represented by EERef objects. + Just like a normal pointer type, this can be dereferenced and repositioned using + increment/decrement operators. +***/ + +struct EEPtr{ + + EEPtr( const int index ) + : index( index ) {} + + operator const int() const { return index; } + EEPtr &operator=( int in ) { return index = in, *this; } + + //Iterator functionality. + bool operator!=( const EEPtr &ptr ) { return index != ptr.index; } + EERef operator*() { return index; } + + /** Prefix & Postfix increment/decrement **/ + EEPtr& operator++() { return ++index, *this; } + EEPtr& operator--() { return --index, *this; } + EEPtr operator++ (int) { return index++; } + EEPtr operator-- (int) { return index--; } + + int index; //Index of current EEPROM cell. +}; + +/*** + EEPROMClass class. + + This object represents the entire EEPROM space. + It wraps the functionality of EEPtr and EERef into a basic interface. + This class is also 100% backwards compatible with earlier Arduino core releases. +***/ + +struct EEPROMClass{ + + //Basic user access methods. + EERef operator[]( const int idx ) { return idx; } + uint8_t read( int idx ) { return EERef( idx ); } + void write( int idx, uint8_t val ) { (EERef( idx )) = val; } + void update( int idx, uint8_t val ) { EERef( idx ).update( val ); } + + //STL and C++11 iteration capability. + EEPtr begin() { return 0x00; } + EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid. + uint16_t length() { return E2END + 1; } + + //Functionality to 'get' and 'put' objects to and from EEPROM. + template< typename T > T &get( int idx, T &t ){ + EEPtr e = idx; + uint8_t *ptr = (uint8_t*) &t; + for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e; + return t; + } + + template< typename T > const T &put( int idx, const T &t ){ + EEPtr e = idx; + const uint8_t *ptr = (const uint8_t*) &t; + for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ ); + return t; + } +}; + +static EEPROMClass EEPROM; +#endif \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/README.md b/hardware/bean/avr/libraries/EEPROM/README.md new file mode 100644 index 0000000..a624136 --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/README.md @@ -0,0 +1,139 @@ +## **EEPROM Library V2.0** for Arduino + +**Written by:** _Christopher Andrews_. + +### **What is the EEPROM library.** + +Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips. + +### **How to use it** +The EEPROM library is included in your IDE download. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch. + +```Arduino +#include + +void setup(){ + +} + +void loop(){ + +} + +``` + +The library provides a global variable named `EEPROM`, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below. + +You can view all the examples [here](examples/). + +### **Library functions** + +#### **`EEPROM.read( address )`** [[_example_]](examples/eeprom_read/eeprom_read.ino) + +This function allows you to read a single byte of data from the eeprom. +Its only parameter is an `int` which should be set to the address you wish to read. + +The function returns an `unsigned char` containing the value read. + +#### **`EEPROM.write( address, value )`** [[_example_]](examples/eeprom_write/eeprom_write.ino) + +The `write()` method allows you to write a single byte of data to the EEPROM. +Two parameters are needed. The first is an `int` containing the address that is to be written, and the second is a the data to be written (`unsigned char`). + +This function does not return any value. + +#### **`EEPROM.update( address, value )`** [[_example_]](examples/eeprom_update/eeprom_update.ino) + +This function is similar to `EEPROM.write()` however this method will only write data if the cell contents pointed to by `address` is different to `value`. This method can help prevent unnecessary wear on the EEPROM cells. + +This function does not return any value. + +#### **`EEPROM.get( address, object )`** [[_example_]](examples/eeprom_get/eeprom_get.ino) + +This function will retrieve any object from the EEPROM. +Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to read. + +This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. + +#### **`EEPROM.put( address, object )`** [[_example_]](examples/eeprom_put/eeprom_put.ino) + +This function will write any object to the EEPROM. +Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to write. + +This function uses the _update_ method to write its data, and therefore only rewrites changed cells. + +This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. + +#### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino) + +This operator allows using the identifier `EEPROM` like an array. +EEPROM cells can be read _and_ **_written_** directly using this method. + +This operator returns a reference to the EEPROM cell. + +```c++ +unsigned char val; + +//Read first EEPROM cell. +val = EEPROM[ 0 ]; + +//Write first EEPROM cell. +EEPROM[ 0 ] = val; + +//Compare contents +if( val == EEPROM[ 0 ] ){ + //Do something... +} +``` + +#### **`EEPROM.length()`** + +This function returns an `unsigned int` containing the number of cells in the EEPROM. + +--- + +### **Advanced features** + +This library uses a component based approach to provide its functionality. This means you can also use these components to design a customized approach. Two background classes are available for use: `EERef` & `EEPtr`. + +#### **`EERef` class** + +This object references an EEPROM cell. +Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. +This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. + +```C++ +EERef ref = EEPROM[ 10 ]; //Create a reference to 11th cell. + +ref = 4; //write to EEPROM cell. + +unsigned char val = ref; //Read referenced cell. +``` + +#### **`EEPtr` class** + +This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects. +Just like a normal pointer type, this type can be dereferenced and repositioned using +increment/decrement operators. + +```C++ +EEPtr ptr = 10; //Create a pointer to 11th cell. + +*ptr = 4; //dereference and write to EEPROM cell. + +unsigned char val = *ptr; //dereference and read. + +ptr++; //Move to next EEPROM cell. +``` + +#### **`EEPROM.begin()`** + +This function returns an `EEPtr` pointing to the first cell in the EEPROM. +This is useful for STL objects, custom iteration and C++11 style ranged for loops. + +#### **`EEPROM.end()`** + +This function returns an `EEPtr` pointing at the location after the last EEPROM cell. +Used with `begin()` to provide custom iteration. + +**Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell. diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino new file mode 100644 index 0000000..49eb5fe --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino @@ -0,0 +1,35 @@ +/* + * EEPROM Clear + * + * Sets all of the bytes of the EEPROM to 0. + * Please see eeprom_iteration for a more in depth + * look at how to traverse the EEPROM. + * + * This example code is in the public domain. + */ + +#include + +void setup() +{ + + /*** + Iterate through each byte of the EEPROM storage. + + Larger AVR processors have larger EEPROM sizes, E.g: + - Arduno Duemilanove: 512b EEPROM storage. + - Arduino Uno: 1kb EEPROM storage. + - Arduino Mega: 4kb EEPROM storage. + + Rather than hard-coding the length, you should use the pre-provided length function. + This will make your code portable to all AVR processors. + ***/ + + for ( int i = 0 ; i < EEPROM.length() ; i++ ) + EEPROM.write(i, 0); + + // turn the LED on when we're done + digitalWrite(13, HIGH); +} + +void loop(){ /** Empty loop. **/ } diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino new file mode 100644 index 0000000..8461d56 --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino @@ -0,0 +1,50 @@ +/*** + Written by Christopher Andrews. + CRC algorithm generated by pycrc, MIT licence ( https://github.com/tpircher/pycrc ). + + A CRC is a simple way of checking whether data has changed or become corrupted. + This example calculates a CRC value directly on the EEPROM values. + The purpose of this example is to highlight how the EEPROM object can be used just like an array. +***/ + +#include +#include + +void setup(){ + + //Start serial + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + //Print length of data to run CRC on. + Serial.print( "EEPROM length: " ); + Serial.println( EEPROM.length() ); + + //Print the result of calling eeprom_crc() + Serial.print( "CRC32 of EEPROM data: 0x" ); + Serial.println( eeprom_crc(), HEX ); + Serial.print( "\n\nDone!" ); +} + +void loop(){ /* Empty loop */ } + +unsigned long eeprom_crc( void ){ + + const unsigned long crc_table[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + + unsigned long crc = ~0L; + + for( int index = 0 ; index < EEPROM.length() ; ++index ){ + crc = crc_table[( crc ^ EEPROM[index] ) & 0x0f] ^ (crc >> 4); + crc = crc_table[( crc ^ ( EEPROM[index] >> 4 )) & 0x0f] ^ (crc >> 4); + crc = ~crc; + } + return crc; +} \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino new file mode 100644 index 0000000..6620999 --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino @@ -0,0 +1,66 @@ +/*** + eeprom_get example. + + This shows how to use the EEPROM.get() method. + + To pre-set the EEPROM data, run the example sketch eeprom_put. + This sketch will run without it, however, the values shown + will be shown from what ever is already on the EEPROM. + + This may cause the serial object to print out a large string + of garbage if there is no null character inside one of the strings + loaded. + + Written by Christopher Andrews 2015 + Released under MIT licence. +***/ + +#include + +void setup(){ + + float f = 0.00f; //Variable to store data read from EEPROM. + int eeAddress = 0; //EEPROM address to start reading from + + Serial.begin( 9600 ); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + Serial.print( "Read float from EEPROM: " ); + + //Get the float data from the EEPROM at position 'eeAddress' + EEPROM.get( eeAddress, f ); + Serial.println( f, 3 ); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float. + + /*** + As get also returns a reference to 'f', you can use it inline. + E.g: Serial.print( EEPROM.get( eeAddress, f ) ); + ***/ + + /*** + Get can be used with custom structures too. + I have separated this into an extra function. + ***/ + + secondTest(); //Run the next test. +} + +struct MyObject{ + float field1; + byte field2; + char name[10]; +}; + +void secondTest(){ + int eeAddress = sizeof(float); //Move address to the next byte after float 'f'. + + MyObject customVar; //Variable to store custom object read from EEPROM. + EEPROM.get( eeAddress, customVar ); + + Serial.println( "Read custom object from EEPROM: " ); + Serial.println( customVar.field1 ); + Serial.println( customVar.field2 ); + Serial.println( customVar.name ); +} + +void loop(){ /* Empty loop */ } \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino new file mode 100644 index 0000000..650c90a --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino @@ -0,0 +1,57 @@ +/*** + eeprom_iteration example. + + A set of example snippets highlighting the + simplest methods for traversing the EEPROM. + + Running this sketch is not necessary, this is + simply highlighting certain programming methods. + + Written by Christopher Andrews 2015 + Released under MIT licence. +***/ + +#include + +void setup() { + + /*** + Iterate the EEPROM using a for loop. + ***/ + + for( int index = 0 ; index < EEPROM.length() ; index++ ){ + + //Add one to each cell in the EEPROM + EEPROM[ index ] += 1; + } + + /*** + Iterate the EEPROM using a while loop. + ***/ + + int index = 0; + + while( index < EEPROM.length() ){ + + //Add one to each cell in the EEPROM + EEPROM[ index ] += 1; + index++; + } + + /*** + Iterate the EEPROM using a do-while loop. + ***/ + + int idx = 0; //Used 'idx' to avoid name conflict with 'index' above. + + do{ + + //Add one to each cell in the EEPROM + EEPROM[ idx ] += 1; + idx++; + }while( idx < EEPROM.length() ); + + +} //End of setup function. + +void loop(){} \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino new file mode 100644 index 0000000..186cf95 --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino @@ -0,0 +1,56 @@ +/*** + eeprom_put example. + + This shows how to use the EEPROM.put() method. + Also, this sketch will pre-set the EEPROM data for the + example sketch eeprom_get. + + Note, unlike the single byte version EEPROM.write(), + the put method will use update semantics. As in a byte + will only be written to the EEPROM if the data is actually + different. + + Written by Christopher Andrews 2015 + Released under MIT licence. +***/ + +#include + +struct MyObject{ + float field1; + byte field2; + char name[10]; +}; + +void setup(){ + + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + float f = 123.456f; //Variable to store in EEPROM. + int eeAddress = 0; //Location we want the data to be put. + + + //One simple call, with the address first and the object second. + EEPROM.put( eeAddress, f ); + + Serial.println("Written float data type!"); + + /** Put is designed for use with custom structures also. **/ + + //Data to store. + MyObject customVar = { + 3.14f, + 65, + "Working!" + }; + + eeAddress += sizeof(float); //Move address to the next byte after float 'f'. + + EEPROM.put( eeAddress, customVar ); + Serial.print( "Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!" ); +} + +void loop(){ /* Empty loop */ } \ No newline at end of file diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino new file mode 100644 index 0000000..68c4ffc --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino @@ -0,0 +1,57 @@ +/* + * EEPROM Read + * + * Reads the value of each byte of the EEPROM and prints it + * to the computer. + * This example code is in the public domain. + */ + +#include + +// start reading from the first byte (address 0) of the EEPROM +int address = 0; +byte value; + +void setup() +{ + // initialize serial and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } +} + +void loop() +{ + // read a byte from the current address of the EEPROM + value = EEPROM.read(address); + + Serial.print(address); + Serial.print("\t"); + Serial.print(value, DEC); + Serial.println(); + + /*** + Advance to the next address, when at the end restart at the beginning. + + Larger AVR processors have larger EEPROM sizes, E.g: + - Arduno Duemilanove: 512b EEPROM storage. + - Arduino Uno: 1kb EEPROM storage. + - Arduino Mega: 4kb EEPROM storage. + + Rather than hard-coding the length, you should use the pre-provided length function. + This will make your code portable to all AVR processors. + ***/ + address = address + 1; + if(address == EEPROM.length()) + address = 0; + + /*** + As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an + EEPROM address is also doable by a bitwise and of the length - 1. + + ++address &= EEPROM.length() - 1; + ***/ + + delay(500); +} diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino new file mode 100644 index 0000000..831056f --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino @@ -0,0 +1,69 @@ +/*** + EEPROM Update method + + Stores values read from analog input 0 into the EEPROM. + These values will stay in the EEPROM when the board is + turned off and may be retrieved later by another sketch. + + If a value has not changed in the EEPROM, it is not overwritten + which would reduce the life span of the EEPROM unnecessarily. + + Released using MIT licence. + ***/ + +#include + +/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ +int address = 0; + +void setup(){ /** EMpty setup **/ } + +void loop() +{ + /*** + need to divide by 4 because analog inputs range from + 0 to 1023 and each byte of the EEPROM can only hold a + value from 0 to 255. + ***/ + int val = analogRead(0) / 4; + + /*** + Update the particular EEPROM cell. + these values will remain there when the board is + turned off. + ***/ + EEPROM.update(address, val); + + /*** + The function EEPROM.update(address, val) is equivalent to the following: + + if( EEPROM.read(address) != val ){ + EEPROM.write(address, val); + } + ***/ + + + /*** + Advance to the next address, when at the end restart at the beginning. + + Larger AVR processors have larger EEPROM sizes, E.g: + - Arduno Duemilanove: 512b EEPROM storage. + - Arduino Uno: 1kb EEPROM storage. + - Arduino Mega: 4kb EEPROM storage. + + Rather than hard-coding the length, you should use the pre-provided length function. + This will make your code portable to all AVR processors. + ***/ + address = address + 1; + if(address == EEPROM.length()) + address = 0; + + /*** + As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an + EEPROM address is also doable by a bitwise and of the length - 1. + + ++address &= EEPROM.length() - 1; + ***/ + + delay(100); +} diff --git a/hardware/bean/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino new file mode 100644 index 0000000..f07446c --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino @@ -0,0 +1,58 @@ +/* + * EEPROM Write + * + * Stores values read from analog input 0 into the EEPROM. + * These values will stay in the EEPROM when the board is + * turned off and may be retrieved later by another sketch. + */ + +#include + +/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ +int addr = 0; + +void setup(){ /** Empty setup. **/} + +void loop() +{ + /*** + Need to divide by 4 because analog inputs range from + 0 to 1023 and each byte of the EEPROM can only hold a + value from 0 to 255. + ***/ + + int val = analogRead(0) / 4; + + /*** + Write the value to the appropriate byte of the EEPROM. + these values will remain there when the board is + turned off. + ***/ + + EEPROM.write(addr, val); + + /*** + Advance to the next address, when at the end restart at the beginning. + + Larger AVR processors have larger EEPROM sizes, E.g: + - Arduno Duemilanove: 512b EEPROM storage. + - Arduino Uno: 1kb EEPROM storage. + - Arduino Mega: 4kb EEPROM storage. + + Rather than hard-coding the length, you should use the pre-provided length function. + This will make your code portable to all AVR processors. + ***/ + addr = addr + 1; + if(addr == EEPROM.length()) + addr = 0; + + /*** + As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an + EEPROM address is also doable by a bitwise and of the length - 1. + + ++addr &= EEPROM.length() - 1; + ***/ + + + delay(100); +} diff --git a/hardware/bean/avr/libraries/EEPROM/keywords.txt b/hardware/bean/avr/libraries/EEPROM/keywords.txt new file mode 100644 index 0000000..2cabc0b --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/keywords.txt @@ -0,0 +1,22 @@ +####################################### +# Syntax Coloring Map For EEPROM +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +EEPROM KEYWORD1 +EERef KEYWORD1 +EEPtr KEYWORD2 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +update KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/hardware/bean/avr/libraries/EEPROM/library.properties b/hardware/bean/avr/libraries/EEPROM/library.properties new file mode 100644 index 0000000..1160042 --- /dev/null +++ b/hardware/bean/avr/libraries/EEPROM/library.properties @@ -0,0 +1,10 @@ +name=EEPROM +version=2.0 +author=Arduino, Christopher Andrews +maintainer=Arduino +sentence=Enables reading and writing to the permanent board storage. For all Arduino boards BUT Arduino DUE. +paragraph= +url=http://arduino.cc/en/Reference/EEPROM +architectures=avr +types=Arduino +category=Data Storage diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.cpp b/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.cpp new file mode 100755 index 0000000..154b706 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.cpp @@ -0,0 +1,324 @@ +/* + ByteBuffer.cpp - A circular buffer implementation for Arduino + Created by Sigurdur Orn, July 19, 2010. + siggi@mit.edu + Updated by GreyGnome (aka Mike Schwager) Mon Apr 8 21:11:15 CDT 2013 + Fixed putString() so it reenables inputs correctly. In the if (length == capacity) section, + it was missing this line: + SREG = oldSREG; // Restore register; reenables interrupts + Updated by GreyGnome (aka Mike Schwager) Thu Feb 23 17:25:14 CST 2012 + added the putString() method and the fillError variable. + added the checkError() and resetError() methods. The checkError() method resets the fillError variable + to false as a side effect. + added the ByteBuffer(unsigned int buf_size) constructor. + added the init() method, and had the constructor call it automagically. + Also made the capacity, position, length, and fillError variables volatile, for safe use by interrupts. + Mon Dec 3 07:55:04 CST 2012 + Added the putHex() and putDec() methods. + */ + +#include "ByteBuffer.h" + +void ByteBuffer::init(){ + ByteBuffer::init(DEFAULTBUFSIZE); +} + +void ByteBuffer::init(unsigned int buf_length){ + data = (byte*)malloc(sizeof(byte)*buf_length); + capacity = buf_length; + position = 0; + length = 0; + fillError=false; +} + +// Arduino 1.0: free() doesn't free. :-( This is a no-op as of 11/2012. +void ByteBuffer::deAllocate(){ + free(data); +} + +void ByteBuffer::clear(){ + position = 0; + length = 0; +} + +void ByteBuffer::resetError(){ + fillError=false; +} + +boolean ByteBuffer::checkError(){ + /* + if (fillError) { + Serial.print("E: checkError: length "); + Serial.println(length, DEC); + } + */ + + boolean result=fillError; + fillError=false; + return(result); +} + +int ByteBuffer::getSize(){ + return length; +} + +int ByteBuffer::getCapacity(){ + return capacity; +} + +byte ByteBuffer::peek(unsigned int index){ + byte b = data[(position+index)%capacity]; + return b; +} + +uint8_t 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 + //Serial.print("E: put: "); + //Serial.println(length, DEC); + fillError=true; + return 0; +} + + +uint8_t ByteBuffer::putString(const char *in) { + return(putString((char *) in)); +} + +uint8_t ByteBuffer::putString(char *in){ + uint8_t count=0; + char *inString; + + inString=in; + uint8_t oldSREG = SREG; cli(); + while(length <= capacity){ + if (length == capacity) { + fillError=true; + SREG = oldSREG; // Restore register; reenables interrupts + return count; + } + // save data byte at end of buffer + data[(position+length) % capacity] = *inString; + // increment the length + length++; + inString++; + count++; + if (*inString == 0) { + if (count==0) fillError=true; // Serial.println("E: putString"); }; + SREG = oldSREG; // Restore register; reenables interrupts + return count; + } + } + SREG = oldSREG; // Restore register; reenables interrupts + return count; +} + +uint8_t ByteBuffer::putInFront(byte in){ + uint8_t oldSREG = SREG; cli(); + 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++; + SREG = oldSREG; // Restore register; reenables interrupts + return 1; + } + // return failure + //Serial.println("E: putInFront"); + fillError=true; + SREG = oldSREG; // Restore register; reenables interrupts + return 0; +} + +// Returns 0 if length of data is 0. +byte ByteBuffer::get(){ + uint8_t oldSREG = SREG; cli(); + byte b = 0; + + if(length > 0){ + b = data[position]; + // move index down and decrement length + position = (position+1)%capacity; + length--; + } + SREG = oldSREG; // Restore register; reenables interrupts + return b; +} + +byte ByteBuffer::getFromBack(){ + byte b = 0; + if(length > 0){ + uint8_t oldSREG = SREG; cli(); + b = data[(position+length-1)%capacity]; + length--; + SREG = oldSREG; // Restore register; reenables interrupts + } + + return b; +} + +// +// Ints +// + +void ByteBuffer::putIntInFront(int in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); +} + +void 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; +} + +void ByteBuffer::putHex(uint8_t theByte) { + put('0'); put('x'); + uint8_t hinybble=theByte>>4; + uint8_t lonybble=theByte & 0x0F; + uint8_t addend=0; + if (hinybble >= 0x0a) addend=7; + put(hinybble+48+addend); + if (lonybble >= 0x0a) addend=7; + else addend=0; + put(lonybble+48+addend); +} + +void ByteBuffer::putDec(uint8_t number) { + uint8_t hundreds=0; + uint8_t tens=0; + uint8_t ones=0; + uint8_t tmp=number; + + while (tmp >= 100 ) { + hundreds++; + tmp-=100; + } + while (tmp >= 10 ) { + tens++; + tmp-=10; + } + ones=tmp; + hundreds+=48; tens+=48; ones+=48; + if (number >= 100) { put(hundreds); } + if (number >= 10) { put(tens); } + put(ones); +} + +void ByteBuffer::putDec(int8_t number) { + uint8_t absNumber=abs(number); + if (number < 0) put('-'); + putDec(absNumber); +} + +// +// Longs +// + +void ByteBuffer::putLongInFront(long in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); + putInFront(pointer[2]); + putInFront(pointer[3]); +} + +void 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 +// + +void ByteBuffer::putFloatInFront(float in){ + byte *pointer = (byte *)∈ + putInFront(pointer[0]); + putInFront(pointer[1]); + putInFront(pointer[2]); + putInFront(pointer[3]); +} + +void 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/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h b/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h new file mode 100755 index 0000000..3c276b6 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h @@ -0,0 +1,105 @@ +/* + ByteBuffer.h - A circular buffer implementation for Arduino + Created by Sigurdur Orn, July 19, 2010. siggi@mit.edu + Updated by GreyGnome (aka Mike Schwager) Thu Feb 23 17:25:14 CST 2012 + added the putString() method and the fillError variable. + added the checkError() and resetError() methods. The checkError() method resets the fillError variable + to false as a side effect. + added the ByteBuffer(unsigned int buf_size) constructor. + added the init() method, and had the constructor call it automagically. + protected certain sections of the code with cli()/sei() calls, for safe use by interrupts. + Also made the capacity, position, length, and fillError variables volatile, for safe use by interrupts. + */ + +#ifndef ByteBuffer_h +#define ByteBuffer_h + +#if defined(ARDUINO) && ARDUINO >= 100 + #include +#else + #include +#endif +//#include + +#define DEFAULTBUFSIZE 32 +class ByteBuffer +{ +public: + ByteBuffer() { + init(); + }; + ByteBuffer(unsigned int buf_size) { + init(buf_size); + }; + + // This method initializes the datastore of the buffer to a certain size. + void init(unsigned int buf_size); + + // This method initializes the datastore of the buffer to the default size. + void init(); + + // This method resets the buffer into an original state (with no data) + void clear(); + + // This method resets the fillError variable to false. + void resetError(); + + // This method tells you if your buffer overflowed at some time since the last + // check. The error state will be reset to false. + boolean checkError(); + + // This releases resources for this buffer, after this has been called the buffer should NOT be used + void deAllocate(); + + // Returns how much space is used in the buffer + 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 + // + uint8_t putInFront(byte in); + uint8_t put(byte in); + uint8_t putString(char *in); + + void putIntInFront(int in); + void putInt(int in); + + void putLongInFront(long in); + void putLong(long in); + + void putFloatInFront(float in); + void putFloat(float in); + + void putHex(uint8_t theByte); + + // + // 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; + + volatile unsigned int capacity; + volatile unsigned int position; + volatile unsigned int length; + volatile boolean fillError; +}; + +#endif diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/GetPSTR/GetPSTR.h b/hardware/bean/avr/libraries/PinChangeInt/Examples/GetPSTR/GetPSTR.h new file mode 100755 index 0000000..aaab06a --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/GetPSTR/GetPSTR.h @@ -0,0 +1,21 @@ +#ifndef INCLUDE_GETPSTR +#define INCLUDE_GETPSTR + +#if defined(ARDUINO) && ARDUINO >= 100 + #include +#else + #include "pins_arduino.h" + #include "WProgram.h" + #include "wiring.h" +#endif + +#define getPSTR(s) pgmStrToRAM(PSTR(s)) + +char *_pstr_to_print; +char *pgmStrToRAM(PROGMEM char *theString) { + free(_pstr_to_print); + _pstr_to_print=(char *) malloc(strlen_P(theString)); + strcpy_P(_pstr_to_print, theString); + return (_pstr_to_print); +} +#endif diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntDebug/PinChangeIntDebug.ino b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntDebug/PinChangeIntDebug.ino new file mode 100755 index 0000000..6b02a15 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntDebug/PinChangeIntDebug.ino @@ -0,0 +1,187 @@ +// PinChangeIntDebug +// version 1.0 Wed Jul 9 16:20:56 CDT 2014 +// Lean project for debugging. Don't expect a lot of commentary in here. This is for hacking. +// This code taken from Examples/PinChangeIntTest, so refer there for more information and commentary. + +#define PINMODE +#define FLASH +#include +#include +#include + +// This example demonstrates a configuration of 6 interrupting pins and 3 interrupt functions. +// A variety of interrupting pins have been chosen, so as to test all PORTs on the Arduino. +// The pins are as follows: +#define INTERRUPT_PIN1 2 // port D +#define INTERRUPT_PIN2 3 +#define INTERRUPT_PIN3 11 // Port B +#define INTERRUPT_PIN4 12 +#define INTERRUPT_PIN5 A3 // Port C, also can be given as "17" +#define INTERRUPT_PIN6 A4 + +uint8_t pins[6]={ INTERRUPT_PIN1, INTERRUPT_PIN2, INTERRUPT_PIN3, INTERRUPT_PIN4, INTERRUPT_PIN5, INTERRUPT_PIN6 }; +uint8_t ports[6]={ 0, 0, 0, 0, 0, 0 }; + +uint8_t latest_interrupted_pin; +uint8_t interrupt_count[20]={0}; // 20 possible arduino pins +uint8_t port; +uint8_t mode; + +ByteBuffer printBuffer(200); +char charArray[16]; +char numBuffer[5] = { 0, 0, 0, 0, 0 }; +uint8_t printFull=0; + +volatile boolean start=0; +volatile boolean initial=true; +long begintime=0; +long now=0; + +void smallIntToString(char *outString, int number) { + uint8_t thousands=0; + uint8_t hundreds=0; + uint8_t tens=0; + uint8_t ones=0; + + if (number > 9999) { + outString[0]='S'; outString[1]='I'; outString[2]='Z'; outString[3]='E'; outString[4]=0; + return; + } + while (number >= 1000 ) { + thousands++; + number-=1000; + } + while (number >= 100 ) { + hundreds++; + number-=100; + } + while (number >= 10 ) { + tens++; + number-=10; + } + ones=number; + ones+=48; + if (thousands > 0) { + thousands+=48; hundreds+=48; tens+=48; + outString[0]=thousands; outString[1]=hundreds; outString[2]=tens; + outString[3]=ones; outString[4]=0; + } + else if (hundreds > 0) { + hundreds+=48; tens+=48; + outString[0]=hundreds; outString[1]=tens; outString[2]=ones; outString[3]=0; + } + else if (tens > 0) { + tens+=48; + outString[0]=tens; outString[1]=ones; outString[2]=0; + } + else { outString[0]=ones; outString[1]=0; }; +} + +void showMode() { + switch (mode) { + case FALLING: + printBuffer.putString((char *) "-F-"); + break; + case RISING: + printBuffer.putString((char *) "+R+"); + break; + case CHANGE: + printBuffer.putString((char *) "*C*"); + break; + } +} + +void quicfunc0() { + latest_interrupted_pin=PCintPort::arduinoPin; + mode=PCintPort::pinmode; + showMode(); + if (start==1) { + interrupt_count[latest_interrupted_pin]++; + } + smallIntToString(numBuffer, latest_interrupted_pin); + printBuffer.putString((char *) "f0p"); printBuffer.putString(numBuffer); printBuffer.putString((char *) "-P"); + smallIntToString(numBuffer, digitalPinToPort(latest_interrupted_pin)); + printBuffer.putString(numBuffer); + printBuffer.putString((char *) "\n"); +}; + +#define MAXPINCOUNT 6 +void attachInterrupts() { + uint8_t i; + for (i=0; i < MAXPINCOUNT; i++) { + pinMode(pins[i], INPUT); digitalWrite(pins[i], HIGH); + ports[i]=digitalPinToPort(pins[i]); + PCintPort::attachInterrupt(pins[i], &quicfunc0, CHANGE); + } +} + +void detachInterrupts() { + uint8_t i; + for (i=0; i < MAXPINCOUNT; i++) { + PCintPort::detachInterrupt(pins[i]); + } +} + +uint8_t i; +bool interrupts_are_attached=false; +void setup() { + Serial.begin(115200); + delay(250); + Serial.println("Test"); + delay(250); + Serial.print("*---*"); + begintime=millis(); + attachInterrupts(); interrupts_are_attached=true; + Serial.println("NOTICE: Interrupts ATTACHED."); +} + +void loop() { + #define LOOPDELAY 2000 + now=millis(); + uint8_t count; + char outChar; + uint8_t pinState; + while ((outChar=(char)printBuffer.get()) != 0) Serial.print(outChar); + if ((now - begintime) > LOOPDELAY) { + Serial.print("."); + pinState=digitalRead(INTERRUPT_PIN1); + if (pinState == HIGH){ + Serial.print("H"); + } + else { Serial.print("L"); + } + if (printBuffer.checkError()) { + Serial.println("NOTICE: Some output lost due to filled buffer."); + } + for (i=0; i < 20; i++) { + if (interrupt_count[i] != 0) { + count=interrupt_count[i]; + interrupt_count[i]=0; + Serial.print("Count for pin "); + if (i < 14) { + Serial.print("D"); + Serial.print(i, DEC); + } else { + Serial.print("A"); + Serial.print(i-14, DEC); + } + Serial.print(" is "); + Serial.println(count, DEC); + } + } + begintime=millis(); + if (interrupts_are_attached) { + detachInterrupts(); interrupts_are_attached=false; + Serial.print("NOTICE: Interrupts DETACHED. Memory: "); + Serial.print(freeMemory(), DEC); + Serial.println(" bytes"); + } + else { + Serial.print("NOTICE: ATTACHING Interrupts. Memory: "); + Serial.print(freeMemory(), DEC); + Serial.println(" bytes"); + attachInterrupts(); interrupts_are_attached=true; + } + } +} + diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntExample2560/PinChangeIntExample2560.ino b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntExample2560/PinChangeIntExample2560.ino new file mode 100755 index 0000000..f09347b --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntExample2560/PinChangeIntExample2560.ino @@ -0,0 +1,108 @@ +// PinChangeIntExample2560 +// This only works for ATMega2560-based boards. +// See the Arduino and the chip documentation for more details. + +// See the Wiki at http://code.google.com/p/arduino-pinchangeint/wiki for more information. +// for vim editing: :set et ts=2 sts=2 sw=2 + +// This example demonstrates a configuration of 3 interrupting pins and 2 interrupt functions. +// The functions set the values of some global variables. All interrupts are serviced immediately, +// and the sketch can then query the values at our leisure. This makes loop timing non-critical. + +// The interrupt functions are a simple count of the number of times the pin was brought high. +// For 2 of the pins, the values are stored and retrieved from an array and they are reset after +// every read. For one of the pins ("MYPIN3"), there is a monotonically increasing count; that is, +// until the 8-bit value reaches 255. Then it will go back to 0. + +// For a more introductory sketch, see the SimpleExample328.ino sketch in the PinChangeInt +// library distribution. + +#include + +// PIN NAMING +// For the Analog Input pins used as digital input pins, you can call them 14, 15, 16, etc. +// or you can use A0, A1, A2, etc. (the Arduino code will properly recognize the symbolic names, +// for example, pinMode(A0, INPUT_PULLUP); + +// For Arduino MEGA (AT2560-based), besides the regular pins and the A (analog) pins, +// you have 4 more pins with defined names: +// SS = 53 +// MOSI = 51 +// MISO = 50 +// SCK = 52 + +// NOW CHOOSE PINS +#if ! ( defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || defined __AVR_ATmega1281__ || defined __AVR_ATmega2561__ || defined __AVR_ATmega640__ ) +#error "This sketch only works on chips in the ATmega2560 family." +#endif + +#define FIRST_ANALOG_PIN 54 +#define TOTAL_PINS 69 // But only 18 of them (not including RX0) are PinChangeInt-compatible + // Don't use RX0 (Arduino pin 0) in this program- it won't work this is the + // pin that Serial.print() uses! +// See the Arduino and the chip documentation for more details. +#define MYPIN1 SS +#define MYPIN2 SCK +#define MYPIN3 MOSI +#define PIN3TEXT "MOSI" // This will say what MYPIN3 is, on the serial monitor + +volatile uint8_t latest_interrupted_pin; +volatile uint8_t interrupt_count[TOTAL_PINS]={0}; // possible arduino pins +volatile uint8_t pin3Count=0; + +// Do not use any Serial.print() in this function. Serial.print() uses interrupts, and is not compatible +// with an interrupt routine...! +void quicfunc() { + latest_interrupted_pin=PCintPort::arduinoPin; + interrupt_count[latest_interrupted_pin]++; +}; + +// You can assign any number of functions to different pins. How cool is that? +void pin3func() { + pin3Count++; +} + +void setup() { + pinMode(MYPIN1, INPUT_PULLUP); + attachPinChangeInterrupt(MYPIN1, quicfunc, FALLING); // add more attachInterrupt code as required + pinMode(MYPIN2, INPUT_PULLUP); + attachPinChangeInterrupt(MYPIN2, quicfunc, FALLING); + pinMode(MYPIN3, INPUT_PULLUP); + attachPinChangeInterrupt(MYPIN3, pin3func, CHANGE); + Serial.begin(115200); + Serial.println("---------------------------------------"); +} + +uint8_t i; +uint8_t currentPIN3Count=0; +void loop() { + uint8_t count; + Serial.print("."); + delay(1000); // every second, + for (i=0; i < TOTAL_PINS; i++) { + if (interrupt_count[i] != 0) { // look at all the interrupted pins + count=interrupt_count[i]; // store its count since the last iteration + interrupt_count[i]=0; // and reset it to 0. + Serial.print("Count for pin "); + if (i == 50) { Serial.print("MISO"); } // then tell the user what it was, in a friendly way. + else if (i == 51) { Serial.print("MOSI"); } + else if (i == 52) { Serial.print("SCK"); } + else if (i == 53) { Serial.print("SS"); } + else if (i < FIRST_ANALOG_PIN) { + Serial.print("D"); + Serial.print(i, DEC); + } else { + Serial.print("A"); + Serial.print(i-FIRST_ANALOG_PIN, DEC); + } + Serial.print(" is "); + Serial.println(count, DEC); + } + } + if (currentPIN3Count != pin3Count) { // Print our monotonically increasing counter (no reset to 0) + Serial.print(PIN3TEXT); + Serial.print(" count update: "); Serial.print(pin3Count, DEC); Serial.println(); + currentPIN3Count=pin3Count; + } +} + diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntExample328/PinChangeIntExample328.ino b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntExample328/PinChangeIntExample328.ino new file mode 100755 index 0000000..d13e4c1 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntExample328/PinChangeIntExample328.ino @@ -0,0 +1,96 @@ +// PinChangeIntExample +// This only works for ATMega328-compatibles; ie, Leonardo is not covered here. +// See the Arduino and the chip documentation for more details. +// See the Wiki at http://code.google.com/p/arduino-pinchangeint/wiki for more information. + +// for vim editing: :set et ts=2 sts=2 sw=2 + +// This example demonstrates a configuration of 3 interrupting pins and 2 interrupt functions. +// The functions set the values of some global variables. All interrupts are serviced immediately, +// and the sketch can then query the values at our leisure. This makes loop timing non-critical. + +// The interrupt functions are a simple count of the number of times the pin was brought high. +// For 2 of the pins, the values are stored and retrieved from an array and they are reset after +// every read. For one of the pins ("MYPIN3"), there is a monotonically increasing count; that is, +// until the 8-bit value reaches 255. Then it will go back to 0. + +// For a more introductory sketch, see the SimpleExample328.ino sketch in the PinChangeInt +// library distribution. + +#include + +// Modify these at your leisure. +#define MYPIN1 A3 +#define MYPIN2 A4 +#define MYPIN3 A5 + +// Don't change these. +#define FIRST_ANALOG_PIN 14 +#define TOTAL_PINS 19 +// Notice that anything that gets modified inside an interrupt, that I wish to access +// outside the interrupt, is marked "volatile". That tells the compiler not to optimize +// them. +volatile uint8_t latest_interrupted_pin; +volatile uint8_t interrupt_count[TOTAL_PINS]={0}; // possible arduino pins +volatile uint8_t pin3Count=0; + +// Do not use any Serial.print() in interrupt subroutines. Serial.print() uses interrupts, +// and by default interrupts are off in interrupt subroutines. +// Here we update a counter corresponding to whichever pin interrupted. +void quicfunc0() { + interrupt_count[MYPIN1]++; +}; + +void quicfunc1() { + interrupt_count[MYPIN2]++; +}; + +// You can assign any number of functions to different pins. How cool is that? +// Here we have a global variable that we increment. We can access this variable outside the interrupt, +// and we know it will be valid because it was declared "volatile"- meaning, the compiler performs +// no optimizations on it. +void pin3func() { + pin3Count++; +} + +// Attach the interrupts in setup() +void setup() { + pinMode(MYPIN1, INPUT_PULLUP); + attachPinChangeInterrupt(MYPIN1, quicfunc0, RISING); + pinMode(MYPIN2, INPUT_PULLUP); + attachPinChangeInterrupt(MYPIN2, quicfunc1, RISING); + pinMode(MYPIN3, INPUT_PULLUP); + attachPinChangeInterrupt(MYPIN3, pin3func, CHANGE); // Any state change will trigger the interrupt. + Serial.begin(115200); + Serial.println("---------------------------------------"); +} + +uint8_t i; +uint8_t currentPIN3Count=0; + +void loop() { + uint8_t count; + Serial.print("."); + delay(1000); // every second, + for (i=0; i < TOTAL_PINS; i++) { + if (interrupt_count[i] != 0) { // look at all the interrupted pins + count=interrupt_count[i]; // store its count since the last iteration + interrupt_count[i]=0; // and reset it to 0 + Serial.print("Count for pin "); + if (i < FIRST_ANALOG_PIN) { // then tell the user what it was, in a friendly way + Serial.print("D"); + Serial.print(i, DEC); + } else { + Serial.print("A"); + Serial.print(i-FIRST_ANALOG_PIN, DEC); + } + Serial.print(" is "); + Serial.println(count, DEC); + } + } + if (currentPIN3Count != pin3Count) { // Print our monotonically increasing counter (no reset to 0). + Serial.print("Third pin count update: "); Serial.print(pin3Count, DEC); Serial.println(); + currentPIN3Count=pin3Count; + } +} + diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntSpeedTest/PinChangeIntSpeedTest.pde b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntSpeedTest/PinChangeIntSpeedTest.pde new file mode 100755 index 0000000..f0ac0f2 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntSpeedTest/PinChangeIntSpeedTest.pde @@ -0,0 +1,265 @@ +// PinChangeIntSpeedTest by GreyGnome aka Mike Schwager. Version numbers here refer to this sketch. +// Version 1.0 - initial version +// Version 1.1 - added code to test digitalRead() +// Version 1.2 - added new comments for the #define's for the NO_PORTx_PINCHANGES. +// Version 1.3 - includes cbiface.h with ooPinChangeInt, rather than cb.h +// Version 1.4 - testing version 2.10Beta with robtillaart's optimization +// Also added a #define/#undef INLINE_PCINTFUNC for inlining of the function called by the interrupt. +// Default: #undef for using the function as per usual. Changed PCIVERSION so that +// ooPinChangeInt starts at 1000 instead of 200. Modified the "Start" message to show "Start..", pause +// for 1 second, show "*\n" (where \n is a newline), pause for 1 second, then run the test. +// Version 1.4 - made this compatible with version 1.5 of PinChangeInt +// Version 1.5 - modified it to use #define OOPCIVERSION for ooPinChangeInt + +// This version number is for ooPinChangeInt +//#define OOPCIVERSION 1030 +#ifndef OOPCIVERSION +#define PCIVERSION 217 // 110 if using PinChangeInt-1.1, 120 for version 1.2 + // 1000 for ooPinChangeIntversion 1.00, 1001 for ooPinChangeInt version 1.01, etc. +#endif + +//-------- define these in your sketch, if applicable ---------------------------------------------------------- +// You can reduce the memory footprint of this handler by declaring that there will be no pin change interrupts +// on any one or two of the three ports. If only a single port remains, the handler will be declared inline +// reducing the size and latency of the handler. +#undef NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts +#undef NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts +// #define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts +// You can reduce the code size by 20-50 bytes, and you can speed up the interrupt routine +// slightly by declaring that you don't care if the static variables PCintPort::pinState and/or +// PCintPort::arduinoPin are set and made available to your interrupt routine. +// #define NO_PIN_STATE // to indicate that you don't need the pinState +// #define NO_PIN_NUMBER // to indicate that you don't need the arduinoPin +// if there is only one PCInt vector in use the code can be inlined +// reducing latency and code size +// define DISABLE_PCINT_MULTI_SERVICE below to limit the handler to servicing a single interrupt per invocation. +//#define DISABLE_PCINT_MULTI_SERVICE +//-------- define the above in your sketch, if applicable ------------------------------------------------------ +#if defined(OOPCIVERSION) + #define LIBRARYUNDERTEST "ooPinChangeInt" + #include + #if PCIVERSION == 1001 + #include + #else + #include + #endif +#else + #define LIBRARYUNDERTEST "PinChangeInt" + #include +#endif + +#define SERIALSTUFF // undef to take out all serial statements. Default: #define for measuring time. +#undef MEMTEST // undef to take out memory tests. Default: #undef for measuring time. +#undef INLINE_PCINTFUNC // define to inline the function called from the interrupt. This should have no effect, + // because the compiler will store the registers upon calling the interrupt routine, just + // like calling a function. Still, we test all assumptions. +//----------------------- +// NOTE: BECAUSE OF COLLISIONS in these libraries, you CANNOT have both libraries: PinChangeInt +// and ooPinChangeInt in the libraries directory at the same time. That said, under UNIX-y operating +// systems, it's easy to move the library directory to a name such as "PinChangeInt-1.3", which the +// Arduino will not recognize, and then create a symbolic link when you want to use a library. Such as: +// cd ~/Documents/Arduino/libaries +// mv PinChangeInt PinChangeInt-1.30 +// mv ooPinChangeInt ooPinChangeInt-1.00 +// ln -s PinChangeInt-1.30 PinChangeInt + +#undef FLASH // to flash LED on pin 13 during test + +#ifdef MEMTEST +#include +#endif + +#define TEST 6 + +#if TEST == 1 +#define PTEST 2 // pin to trigger interrupt. pins 0 and 1 are used +#define PLOW 2 // by Serial, so steer clear of them! +#define PHIGH 2 // Interrupts are attached to these pins + +#elif TEST == 2 // see the #if TEST == 2 || TEST == 3 code, below +#define PTEST 2 +#define PLOW 2 +#define PHIGH 2 // need to attachInterrupt to 5 in the code + +#elif TEST == 3 // see the #if TEST == 2 || TEST == 3 code, below +#define PTEST 5 +#define PLOW 2 +#define PHIGH 2 // need to attachInterrupt to 5 in the code + +#elif TEST == 4 +#define PTEST 2 +#define PLOW 2 +#define PHIGH 5 + +#elif TEST == 5 +#define PTEST 3 +#define PLOW 2 +#define PHIGH 5 + +#elif TEST == 6 +#define PTEST 4 +#define PLOW 2 +#define PHIGH 5 + +#elif TEST == 7 +#define PTEST 5 +#define PLOW 2 +#define PHIGH 5 +#endif + +uint8_t qf0; + +#ifdef INLINE_PCINTFUNC +#define INLINE_PCINTFUNC inline +#else +#define INLINE_PCINTFUNC +#endif +INLINE_PCINTFUNC void quicfunc(); +void quicfunc() { + qf0=TCNT0; +} + +#if defined(OOPCIVERSION) +class speedy : public CallBackInterface +{ + public: + uint8_t id; + static uint8_t var0; + speedy () { id=0; }; + speedy (uint8_t _i): id(_i) {}; + + void cbmethod() { + speedy::var0=TCNT0; + //Serial.print("Speedy method "); // debugging + //Serial.println(id, DEC); + }; +}; +uint8_t speedy::var0=0; +#endif + +volatile uint8_t *led_port; +volatile uint8_t *pinT_OP; +volatile uint8_t *pinT_IP; +uint8_t led_mask, not_led_mask; +uint8_t pinT_M, not_pinT_M; +volatile uint8_t pintest, pinIntLow, pinIntHigh; +uint8_t totalpins; +#if defined(OOPCIVERSION) +speedy speedster[8]={speedy(0), speedy(1), speedy(2), speedy(3), speedy(4), speedy(5), speedy(6), speedy(7) }; +#endif +#ifdef MEMTEST +int freemem; +#endif + +int i=0; + +#define PINLED 13 +void setup() +{ +#ifdef SERIALSTUFF + Serial.begin(115200); Serial.println("---------------------------------------"); +#endif // SERIALSTUFF + // set up ports for trigger + pinMode(0, OUTPUT); digitalWrite(0, HIGH); + pinMode(1, OUTPUT); digitalWrite(1, HIGH); + pinMode(2, OUTPUT); digitalWrite(2, HIGH); + pinMode(3, OUTPUT); digitalWrite(3, HIGH); + pinMode(4, OUTPUT); digitalWrite(4, HIGH); + pinMode(5, OUTPUT); digitalWrite(5, HIGH); + pinMode(6, OUTPUT); digitalWrite(6, HIGH); + pinMode(7, OUTPUT); digitalWrite(7, HIGH); +#ifdef FLASH + led_port=portOutputRegister(digitalPinToPort(PINLED)); + led_mask=digitalPinToBitMask(PINLED); + not_led_mask=led_mask^0xFF; + pinMode(PINLED, OUTPUT); digitalWrite(PINLED, LOW); +#endif + // ***************************************************************************** + // set up ports for output ************ PIN TO TEST IS GIVEN HERE ************** + // ***************************************************************************** + pintest=PTEST; + pinIntLow=PLOW; pinIntHigh=PHIGH; // Interrupts are attached to these pins + // ***************************************************************************** + // ***************************************************************************** + pinT_OP=portOutputRegister(digitalPinToPort(pintest)); // output port + pinT_IP=portInputRegister(digitalPinToPort(pintest)); // input port + pinT_M=digitalPinToBitMask(pintest); // mask + not_pinT_M=pinT_M^0xFF; // not-mask + *pinT_OP|=pinT_M; + for (i=pinIntLow; i <= pinIntHigh; i++) { +#if defined(OOPCIVERSION) + PCintPort::attachInterrupt(i, &speedster[i], CHANGE); // C++ technique; v1.3 or better +#endif +#if defined(PCIVERSION) + PCintPort::attachInterrupt((uint8_t) i, &quicfunc, CHANGE); // C technique; v1.2 or earlier +#endif + } +#if TEST == 2 || TEST == 3 + i=5; totalpins=2; +#if defined(OOPCIVERSION) + PCintPort::attachInterrupt(i, &speedster[i], CHANGE); // C++ technique; v1.3 or better +#endif +#if defined(PCIVERSION) + PCintPort::attachInterrupt(i, &quicfunc, CHANGE); // C technique; v1.2 or earlier +#endif +#else + totalpins=pinIntHigh - pinIntLow + 1; +#endif + i=0; +} // end setup() + +uint8_t k=0; +unsigned long milliStart, milliEnd, elapsed; +void loop() { + k=0; + *pinT_OP|=pinT_M; // pintest to 1 +#ifdef SERIALSTUFF + Serial.print(LIBRARYUNDERTEST); Serial.print(" "); + Serial.print("TEST: "); Serial.print(TEST, DEC); Serial.print(" "); +#ifndef MEMTEST + Serial.print("test pin mask: "); Serial.print(pinT_M, HEX); + Serial.print(". Total of "); Serial.print(totalpins, DEC); Serial.println(" pins enabled."); +#endif +#ifdef MEMTEST + freemem=freeMemory(); Serial.print("Free memory: "); Serial.println(freemem, DEC); +#endif +#endif + delay(1000); + Serial.print("Start.."); + delay(1000); Serial.print("*"); + #ifdef FLASH + *led_port|=led_mask; + #endif + milliStart=millis(); + while (k < 10) { + i=0; + while (i < 10000) { + *pinT_OP&=not_pinT_M; // pintest to 0 ****************************** 16.8 us + *pinT_OP|=pinT_M; // pintest to 1 ****************************** ...to get here + i++; + } + k++; + } + milliEnd=millis(); + #ifdef FLASH + *led_port&=not_led_mask; + #endif + elapsed=milliEnd-milliStart; + #ifndef MEMTEST + Serial.print(" Elapsed: "); + Serial.println(elapsed, DEC); + #endif + #ifdef SERIALSTUFF + Serial.print("Interrupted pin: "); + #if defined(OOPCIVERSION) + Serial.println(speedster[pintest].id, DEC); + #else + Serial.println(PCintPort::arduinoPin, DEC); + #endif +#ifdef MEMTEST + freemem=freeMemory(); Serial.print("END-Free memory: "); Serial.println(freemem, DEC); +#endif +#endif + delay(500); +} + diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntTest/PinChangeIntTest.ino b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntTest/PinChangeIntTest.ino new file mode 100755 index 0000000..2b550f4 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntTest/PinChangeIntTest.ino @@ -0,0 +1,355 @@ +// PinChangeIntTest +// +// See the Wiki at http://code.google.com/p/arduino-pinchangeint/wiki for more information. +// This sketch requires the ByteBuffer library, which is found in the PinChangeInt zipfile. +// for vim editing: :set et ts=2 sts=2 sw=2 +//-------- define these in your sketch, if applicable ---------------------------------------------------------- +//-------- This must go ahead of the #include statement -------------------------------------------------------- +// You can reduce the memory footprint of this handler by declaring that there will be no pin change interrupts +// on any one or two of the three ports. If only a single port remains, the handler will be declared inline +// reducing the size and latency of the handler. +// #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts +// #define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts +// #define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts +// You can reduce the code size by 20-50 bytes, and you can speed up the interrupt routine +// slightly by declaring that you don't care if the static variables PCintPort::pinState and/or +// PCintPort::arduinoPin are set and made available to your interrupt routine. +// #define NO_PIN_STATE // to indicate that you don't need the pinState +// #define NO_PIN_NUMBER // to indicate that you don't need the arduinoPin +// if there is only one PCInt vector in use the code can be inlined +// reducing latency and code size +// define DISABLE_PCINT_MULTI_SERVICE below to limit the handler to servicing a single interrupt per invocation. +// #define DISABLE_PCINT_MULTI_SERVICE +// The following is intended for testing purposes. If defined, then a variable PCintPort::pinMode can be read +// in your interrupt subroutine. It is not defined by default: +// #define PINMODE +//-------- define the above in your sketch, if applicable ------------------------------------------------------ +#define PINMODE +#define FLASH +#include +#include + +#define NEWLINE "\r\n" // Programs like "screen" in Linux don't return with a "\n" character. + +// This example demonstrates a configuration of 6 interrupting pins and 3 interrupt functions. +// A variety of interrupting pins have been chosen, so as to test all PORTs on the Arduino. +// The pins are as follows: +// quicfunc0 is attached to tPIN1-4. +// quicfunc1 is attached to tPIN5. +// quicfunc2 is attached to tPIN6. +// Pins tPIN1 and tPIN6 interrupt on FALLING. +// tPIN2 and tPIN4 interrupt on RISING. +// tPIN3 and tPIN5 interrupt on CHANGE. +// NOTE: +// For the Analog Input pins used as digital input pins, you can use numbers such as 14, 15, 16, etc. +// or you can use A0, A1, A2, etc. (the Arduino code comes with #define's for the Analog Input pin +// names and will properly recognize e.g., pinMode(A0, INPUT_PULLUP)); +#if defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || defined __AVR_ATmega1281__ || defined __AVR_ATmega2561__ || defined __AVR_ATmega640__ +#define tPIN1 14 // port J +#define tPIN2 15 +#define tPIN3 A8 // Port K +#define tPIN4 A12 +#define tPIN5 SS // Port B, also can be given as "57" +#define tPIN6 MOSI // This pin starts and stops the count +#else +// These only work for ATMega328-compatibles; ie, Leonardo is not covered here. +#define tPIN1 2 // port D +#define tPIN2 3 +#define tPIN3 11 // Port B +#define tPIN4 12 +#define tPIN5 A3 // Port C, also can be given as "17" +#define tPIN6 A4 // This pin starts and stops the count +#endif + +// HOW IT WORKS (ATmega328-specific; replace the references with the proper pins for the other chip types) +// The interrupt on Arduino pin A4 (tPIN6) will, when triggered, start the counting of interrupts. +// The array interrupt_count0[20] is updated in the interrupts; each cell keeps track of the number +// of interrupts on one of the 20 available interrupt pins on the Arduino. Every second in the main +// loop the array is scanned and registered interrupts are reported for all pins interrupted since +// the previous second. If no interrupts, the output is quiet. + +// tPIN6 is special. Not only does it start the counting of the interrups, but it turns on and off +// interrupts on pins 2, 11, and A3/17 (tPIN1, tPIN3, tPIN5). All pins start by interrupting, but after +// the count is turned on and then turned off, the 3 pins are detached from interrupts. +// Everytime thereafter when the count is turned off the 3 pins are detached. They are reattached +// when turned on. + +// Output is copied to a buffer, because we can't do a Serial.print() statement in an interrupt +// routine. The main loop checks for entries in the buffer and prints them if found. +// Output looks like this: +// -F- - an interrupt triggered by a falling signal occurred. +// +R+ - an interrupt triggered by a rising signal occurred. +// *C* - an interrupt triggered by a change in signal occurred. +// f#p#-P# - f# shows the interrupt subroutine that was called: 0, 1, or 2 +// - p# shows the pin number that triggered the interrupt +// - P# shows the port that this pin number is attached to. 2 is PORTB, 3 is PORTC, 4 is PORTD + +// HOW TO CONNECT +// Each pin gets a momentary contact switch connected to it. One side of the switch should connect +// to ground. The other side of the switch connects to the Arduino pin. For my purposes, I am using +// two rotary encoders. Each encoder contains 3 switches. But 6 regular pushbuttons would work, too. + +/* WHAT TO LOOK FOR + Output is sent to the serial line, so the Arduino IDE's serial terminal should be opened. + Upon startup, press tPINS1-5. You will see output like this: +-F-f0p2-P4 (counting off) +..*C*f0p11-P2 (counting off) ++R+f0p3-P4 (counting off) + This shows that + 1. an interrupt was triggered on a falling signal (*F*). It called (f0) function 0, which is quicfunc0. + The triggering pin was (p2) Arduuino pin 2, which is on (P4) Port 4 (PORTD). Counting of this interrupt is + off, so you will not see any output from the main loop. + 2. Two dots appeared. Dots came from iterations of loop(), so these 2 dots show that the two interrupts happened 2 seconds apart. + 3. an interrupt was triggered on a change in signal (*C*). It called quicfunc0, from Arduino pin 11, on Port 2 (PORTB). + The interrupt was not counted. + 4. an interrupt was triggered on a rising signal (+R+). It called quicfunc0, from Arduino pin 3, on Purt 4 (PORTD). + The pin should have started out at the high level, so likely the signal fell during onother interrupt, and now + the rise has been caught. + + Now press the button attached to tPIN6 (in our case, A4 or D18). You will see something like this: +-F-START! f2p18-P3 +.Count for pin A4 is 1 + This shows that + 1. The counting machanism (START!) was triggered by a folling signal (-F-) on pin 18 (p18) which is in Port 3 (P3) (which == PORTC) and + function f2 was called (f2). + 2. A dot appeared, which came from loop() because a second passed. + 3. The count for p18 or A4 was displayed. + + Now you will see messages for all the pins that you manipulate, for example: +*C*f0p11-P2 ++R+f0p3-P4 +*C*f0p11-P2 ++R+f0p3-P4 +*C*f0p11-P2 +.Count for pin D3 is 6 +Count for pin D11 is 9 +.+R+f0p3-P4 +-F-f0p2-P4 +.Count for pin D2 is 1 +Count for pin D3 is 1 + These codes reflect the interrupts, as described above. This output will take place until you press tPIN6: +-F-f2: STOP! Counting off. +Interrupt OFF on tPIN1 (2) tPIN3 (11) tPIN5 (17) + Then you will see output like this: +.....................+R+f0p12-P2 (counting off) +.+R+f0p12-P2 (counting off) ++R+f0p12-P2 (counting off) ++R+f0p12-P2 (counting off) + and tPIN1, tPIN3, and tPIN5 will not trigger interrupts. +*/ +// NOTES +// Output overwrites: +// It's possible during moderately fast interrupts to see your print output get garbled; eg, +// +R+f0p12-P2 (+R+f0p12-P2 (counting +R+f0p12-P2 (cou+R+f0p12-P+R+f0p12 +// This is because the print of the buffer takes place inside a while loop, and it can +// be interrupted and new data inserted into the buffer at a midpoint of the buffer's text. +// Just by spinning my rotary encoders I can readily generate over 200 interrupts per second +// on a pin, which is easily fast enough to overrun Serial output at 115,200 bps. +// The lesson here? ...Interrupts are tricky, and interrupt service routines should be fast. +// Just sayin'. + +// Pins: +// We want to use pins from each of ports B, C and D. So choose wisely. Ports are shown in +// this diagram of the ATmega328P chip. PD0 means "Port D, pin 0". PC3 means "Port C, Pin 3", +// PB2 means "Port B, pin 2" and so on. The corresponding Arduino pins are in parentheses. +// So PB2 is Arduino pin D 10, for example. +/* + +-\/-+ + PC6 1| |28 PC5 (AI 5) + (D 0) PD0 2| |27 PC4 (AI 4) + (D 1) PD1 3| |26 PC3 (AI 3) + (D 2) PD2 4| |25 PC2 (AI 2) + PWM+ (D 3) PD3 5| |24 PC1 (AI 1) + (D 4) PD4 6| |23 PC0 (AI 0) + VCC 7| |22 GND + GND 8| |21 AREF + PB6 9| |20 AVCC + PB7 10| |19 PB5 (D 13) + PWM+ (D 5) PD5 11| |18 PB4 (D 12) + PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM + (D 7) PD7 13| |16 PB2 (D 10) PWM + (D 8) PB0 14| |15 PB1 (D 9) PWM + +----+ +*/ + +uint8_t pins[6]={ tPIN1, tPIN2, tPIN3, tPIN4, tPIN5, tPIN6 }; +uint8_t ports[6]={ 0, 0, 0, 0, 0, 0 }; + +uint8_t latest_interrupted_pin; +uint8_t interrupt_count[20]={0}; // 20 possible arduino pins +uint8_t port; +uint8_t mode; + +ByteBuffer printBuffer(80); +char charArray[16]; +char numBuffer[4] = { 0, 0, 0, 0 }; +uint8_t printFull=0; + +volatile boolean start=0; +volatile boolean initial=true; +long begintime=0; +long now=0; + +void uint8ToString(char *outString, uint8_t number) { + uint8_t hundreds=0; + uint8_t tens=0; + uint8_t ones=0; + + while (number >= 100 ) { + hundreds++; + number-=100; + } + while (number >= 10 ) { + tens++; + number-=10; + } + ones=number; + ones+=48; + if (hundreds > 0) { hundreds+=48; tens+=48; outString[0]=hundreds; outString[1]=tens; outString[2]=ones; outString[3]=0; } + else if (tens > 0) { tens+=48; outString[0]=tens; outString[1]=ones; outString[2]=0; } + else { outString[0]=ones; outString[1]=0; }; +} + +void showMode() { + switch (mode) { + case FALLING: + printBuffer.putString((char *) "-F-"); + break; + case RISING: + printBuffer.putString((char *) "+R+"); + break; + case CHANGE: + printBuffer.putString((char *) "*C*"); + break; + } +} + +void quicfunc0() { + latest_interrupted_pin=PCintPort::arduinoPin; + mode=PCintPort::pinmode; + showMode(); + if (start==1) { + interrupt_count[latest_interrupted_pin]++; + } + uint8ToString(numBuffer, latest_interrupted_pin); + printBuffer.putString((char *) "f0p"); printBuffer.putString(numBuffer); printBuffer.putString((char *) "-P"); + uint8ToString(numBuffer, digitalPinToPort(latest_interrupted_pin)); + printBuffer.putString(numBuffer); + if (start !=1) printBuffer.putString((char *) " (counting off)"); + printBuffer.putString((char *) NEWLINE); +}; + +void quicfunc1() { + latest_interrupted_pin=PCintPort::arduinoPin; + mode=PCintPort::pinmode; + showMode(); + if (start==1) { + interrupt_count[latest_interrupted_pin]++; + } + uint8ToString(numBuffer, latest_interrupted_pin); + printBuffer.putString((char *) "f1p"); printBuffer.putString(numBuffer); printBuffer.putString((char *) "-P"); + uint8ToString(numBuffer, digitalPinToPort(latest_interrupted_pin)); + printBuffer.putString(numBuffer); + if (start !=1) printBuffer.putString((char *) " (counting off)"); + printBuffer.putString((char *) NEWLINE); +}; + +void quicfunc2() { + latest_interrupted_pin=PCintPort::arduinoPin; + mode=PCintPort::pinmode; + showMode(); + if (start == 1) { + printBuffer.putString((char *) "f2: STOP! Counting off.\n"); + printBuffer.putString((char *) "Interrupt OFF on tPIN1 ("); uint8ToString(numBuffer, tPIN1), printBuffer.putString(numBuffer); + printBuffer.putString((char *) ") tPIN3 (");uint8ToString(numBuffer, tPIN3), printBuffer.putString(numBuffer); + printBuffer.putString((char *) ") tPIN5 (");uint8ToString(numBuffer, tPIN5), printBuffer.putString(numBuffer); + printBuffer.putString((char *) ")"); + printBuffer.putString((char *) NEWLINE); + PCintPort::detachInterrupt(tPIN1); PCintPort::detachInterrupt(tPIN3); PCintPort::detachInterrupt(tPIN5); + start=0; + } else { + start=1; + interrupt_count[latest_interrupted_pin]++; + printBuffer.putString((char *) "START! f2p"); + uint8ToString(numBuffer, latest_interrupted_pin); + printBuffer.putString(numBuffer); printBuffer.putString((char *) "-P"); + uint8ToString(numBuffer, digitalPinToPort(latest_interrupted_pin)); + printBuffer.putString(numBuffer); printBuffer.putString((char *) NEWLINE); + if (! initial) { + PCintPort::attachInterrupt(tPIN1, &quicfunc0, FALLING); + PCintPort::attachInterrupt(tPIN3, &quicfunc0, CHANGE); + PCintPort::attachInterrupt(tPIN5, &quicfunc1, CHANGE); + } else { + initial=false; + } + } +}; + +uint8_t i; +void setup() { + Serial.begin(115200); + delay(250); + Serial.println("Test"); + for (i=0; i < 6; i++) { + pinMode(pins[i], INPUT_PULLUP); + ports[i]=digitalPinToPort(pins[i]); + switch (pins[i]) { + case tPIN1: + PCintPort::attachInterrupt(pins[i], &quicfunc0, FALLING); + break; + case tPIN3: + PCintPort::attachInterrupt(pins[i], &quicfunc0, CHANGE); + break; + case tPIN2: + case tPIN4: + PCintPort::attachInterrupt(pins[i], &quicfunc0, RISING); + break; + case tPIN5: + PCintPort::attachInterrupt(pins[i], &quicfunc1, CHANGE); + break; + case tPIN6: + attachPinChangeInterrupt(pins[i], quicfunc2, FALLING); // attachPinChangeInterrupt is a #define + break; + } + } + //Serial.println(printBuffer.getCapacity(), DEC); + //Serial.println("*---------------------------------------*"); + Serial.print("*---*"); + delay(250); + begintime=millis(); +} + +void loop() { + now=millis(); + uint8_t count; + char outChar; + // uint8_t bufsize; + //if (printBuffer.getSize() != 0) { Serial.print("SZ:"); Serial.println (printBuffer.getSize(), DEC); }; + //bufsize=printBuffer.getSize(); + //if (bufsize > 0) { Serial.print("S:"); Serial.println(bufsize); } + while ((outChar=(char)printBuffer.get()) != 0) Serial.print(outChar); + if ((now - begintime) > 1000) { + Serial.print("."); + if (printBuffer.checkError()) { + Serial.println("NOTICE: Some output lost due to filled buffer."); + } + for (i=0; i < 20; i++) { + if (interrupt_count[i] != 0) { + count=interrupt_count[i]; + interrupt_count[i]=0; + Serial.print("Count for pin "); + if (i < 14) { + Serial.print("D"); + Serial.print(i, DEC); + } else { + Serial.print("A"); + Serial.print(i-14, DEC); + } + Serial.print(" is "); + Serial.println(count, DEC); + } + } + begintime=millis(); + } +} + diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntTest2/PinChangeIntTest2.ino b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntTest2/PinChangeIntTest2.ino new file mode 100755 index 0000000..aec34c4 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/PinChangeIntTest2/PinChangeIntTest2.ino @@ -0,0 +1,275 @@ +//#define DISABLE_PCINT_MULTI_SERVICE +#define PINMODE +#define FLASH +#include +#include +#include + +// This example demonstrates a configuration of 6 interrupting pins and 3 interrupt functions. +// A variety of interrupting pins have been chosen, so as to test all PORTs on the Arduino. +// The pins are as follows: +#define tPIN1 2 // port D +#define tPIN2 3 +#define tPIN3 11 // Port B +#define tPIN4 12 +#define tPIN5 A3 // Port C, also can be given as "17" +#define tPIN6 A4 // starts and stops the count + +uint8_t pins[6]={ tPIN1, tPIN2, tPIN3, tPIN4, tPIN5, tPIN6 }; +uint8_t ports[6]={ 0, 0, 0, 0, 0, 0 }; + +uint8_t latest_interrupted_pin; +uint8_t interrupt_count[20]={0}; // 20 possible arduino pins +uint8_t port; +uint8_t mode; + +ByteBuffer printBuffer(200); +char charArray[16]; +char numBuffer[5] = { 0, 0, 0, 0, 0 }; +uint8_t printFull=0; + +volatile boolean start=0; +volatile boolean initial=true; +long begintime=0; +long now=0; + +void uint8ToHexString(char *outString, uint8_t theByte) { + outString[0]='0'; outString[1]='x'; + uint8_t hinybble=theByte>>4; + uint8_t lonybble=theByte & 0x0F; + if (hinybble < 0x0a) outString[2]=hinybble+48; + else outString[2]=hinybble+55; + if (lonybble < 0x0a) outString[3]=lonybble+48; + else outString[3]=lonybble+55; + outString[4]=0; +} + +void uint8ToString(char *outString, uint8_t number) { + uint8_t hundreds=0; + uint8_t tens=0; + uint8_t ones=0; + + while (number >= 100 ) { + hundreds++; + number-=100; + } + while (number >= 10 ) { + tens++; + number-=10; + } + ones=number; + ones+=48; + if (hundreds > 0) { hundreds+=48; tens+=48; outString[0]=hundreds; outString[1]=tens; outString[2]=ones; outString[3]=0; } + else if (tens > 0) { tens+=48; outString[0]=tens; outString[1]=ones; outString[2]=0; } + else { outString[0]=ones; outString[1]=0; }; +} + +void showMode() { + switch (mode) { + case FALLING: + printBuffer.putString(getPSTR("-F-")); + break; + case RISING: + printBuffer.putString(getPSTR("+R+")); + break; + case CHANGE: + printBuffer.putString(getPSTR("*C*")); + break; + } +} + +/* +void quicfunc0() { + latest_interrupted_pin=PCintPort::arduinoPin; + mode=PCintPort::pinmode; + showMode(); + if (start==1) { + interrupt_count[latest_interrupted_pin]++; + } + uint8ToString(numBuffer, latest_interrupted_pin); + printBuffer.putString((char *) "f0p"); printBuffer.putString(numBuffer); printBuffer.putString((char *) "-P"); + uint8ToString(numBuffer, digitalPinToPort(latest_interrupted_pin)); + printBuffer.putString(numBuffer); + if (start !=1) printBuffer.putString(getPSTR(" no count")); + printBuffer.putString((char *) "\n"); +}; + +void quicfunc1() { + latest_interrupted_pin=PCintPort::arduinoPin; + mode=PCintPort::pinmode; + showMode(); + if (start==1) { + interrupt_count[latest_interrupted_pin]++; + } + uint8ToString(numBuffer, latest_interrupted_pin); + printBuffer.putString(getPSTR("f1p")); printBuffer.putString(numBuffer); printBuffer.putString((char *) "-P"); + uint8ToString(numBuffer, digitalPinToPort(latest_interrupted_pin)); + printBuffer.putString(numBuffer); + if (start !=1) printBuffer.putString(getPSTR(" (counting off)")); + printBuffer.putString((char *) "\n"); +}; +*/ + +void quicfunc2() { + //*led_port|=led_mask; + //*led_port&=not_led_mask; // 2 micros to here (ie, 2 micros used to push registers and call subroutine) + latest_interrupted_pin=PCintPort::arduinoPin; + mode=PCintPort::pinmode; + showMode(); + *led_port|=led_mask; // 73 micros to get here from above. Used in "Rigol Timing Example" + *led_port&=not_led_mask; + //uint8ToString(numBuffer, PCintPort::s_count); printBuffer.putString(numBuffer); + *led_port|=led_mask; // 73 micros to get here from above. Second pulse in "Rigol Timing Example" + *led_port&=not_led_mask; + printBuffer.putString(getPSTR(" f2: P"));/* + uint8ToHexString(numBuffer, *portInputRegister(3)); printBuffer.putString(numBuffer);// C port + printBuffer.putString(getPSTR(" pin:")); uint8ToString(numBuffer, latest_interrupted_pin); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" c")); uint8ToHexString(numBuffer, PCintPort::curr); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" l")); uint8ToHexString(numBuffer, PCintPort::s_lastPinView); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" r")); uint8ToHexString(numBuffer, PCintPort::s_portRisingPins); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" f")); uint8ToHexString(numBuffer, PCintPort::s_portFallingPins); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" m")); uint8ToHexString(numBuffer, PCintPort::s_pmask); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" P")); printBuffer.put(PCintPort::s_PORT); printBuffer.putString("\r\n"); + printBuffer.putString(getPSTR("cp")); uint8ToHexString(numBuffer, PCintPort::s_changedPins); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" cXORlpv")); uint8ToHexString(numBuffer, PCintPort::s_currXORlastPinView); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" rp_nCurr")); uint8ToHexString(numBuffer, PCintPort::s_portRisingPins_nCurr); printBuffer.putString(numBuffer); + printBuffer.putString(getPSTR(" fp_nNCurr")); uint8ToHexString(numBuffer, PCintPort::s_portFallingPins_nNCurr); printBuffer.putString(numBuffer); + */printBuffer.putString("\r\n"); + if (PCintPort::pcint_multi > 0) { + printBuffer.putString("MULTI!\n"); PCintPort::pcint_multi=0; + } + if (PCintPort::PCIFRbug > 0) { printBuffer.putString("ERROR: BUG- PCIFR should be reset!"); PCintPort::PCIFRbug=0; } + //s_registers, if it existed, could be used to keep a running queue of the latest interrupts that have + //been serviced by the PCint(). But generally I don't think it's necessary for debugging at this point (famous last words?) + /*if (PCintPort::s_count > 2) { + for (uint8_t i=0; i < PCintPort::s_count; i++) { + uint8ToHexString(numBuffer, PCintPort::s_registers[i]); printBuffer.putString(numBuffer); printBuffer.putString(" "); + } + } + PCintPort::s_count=0;*/ + /* + if (start == 1) { + printBuffer.putString(getPSTR("STOP Count off\n")); + printBuffer.putString(getPSTR("Intr OFF: (")); uint8ToString(numBuffer, tPIN1), printBuffer.putString(numBuffer); + printBuffer.putString((char *) " "); uint8ToString(numBuffer, tPIN3), printBuffer.putString(numBuffer); + printBuffer.putString((char *) " "); uint8ToString(numBuffer, tPIN5), printBuffer.putString(numBuffer); + printBuffer.putString((char *) ")\n"); + PCintPort::detachInterrupt(tPIN1); PCintPort::detachInterrupt(tPIN3); PCintPort::detachInterrupt(tPIN5); + start=0; + } else { + start=1; + interrupt_count[latest_interrupted_pin]++; + printBuffer.putString(getPSTR("START! p")); + uint8ToString(numBuffer, latest_interrupted_pin); + printBuffer.putString(numBuffer); printBuffer.putString((char *) "-P"); + // MIKE put the REAL PORT HERE + uint8ToString(numBuffer, digitalPinToPort(latest_interrupted_pin)); + printBuffer.putString(numBuffer); printBuffer.putString((char *) "\n"); + if (! initial) { + PCintPort::attachInterrupt(tPIN1, &quicfunc0, FALLING); + PCintPort::attachInterrupt(tPIN3, &quicfunc0, CHANGE); + PCintPort::attachInterrupt(tPIN5, &quicfunc1, CHANGE); + } else { + initial=false; + } + }*/ +}; + +uint8_t i; +char hexBuffer[5]; +void setup() { + int8_t returncode=1; + Serial.begin(115200); + Serial.println("Test"); + delay(500); + for (i=5; i < 6; i++) { + pinMode(pins[i], INPUT); digitalWrite(pins[i], HIGH); + ports[i]=digitalPinToPort(pins[i]); + switch (pins[i]) { + /*case tPIN1: + #if PCINT_VERSION > 2100 + returncode=PCintPort::attachInterrupt(pins[i], &quicfunc0, FALLING); + #else + PCintPort::attachInterrupt(pins[i], &quicfunc0, FALLING); + #endif + Serial.println(getPSTR("FIRST FAILURE OK.")); + break; + case tPIN3: + #if PCINT_VERSION > 2100 + returncode=PCintPort::attachInterrupt(pins[i], &quicfunc0, CHANGE); + #else + PCintPort::attachInterrupt(pins[i], &quicfunc0, CHANGE); + #endif + break; + case tPIN2: + case tPIN4: + #if PCINT_VERSION > 2100 + returncode=PCintPort::attachInterrupt(pins[i], &quicfunc0, RISING); + #else + PCintPort::attachInterrupt(pins[i], &quicfunc0, RISING); + #endif + break; + case tPIN5: + #if PCINT_VERSION > 2100 + returncode=PCintPort::attachInterrupt(pins[i], &quicfunc1, CHANGE); + #else + PCintPort::attachInterrupt(pins[i], &quicfunc1, CHANGE); + #endif + break;*/ + case tPIN6: + #if PCINT_VERSION > 2100 + returncode=PCintPort::attachInterrupt(pins[i], &quicfunc2, FALLING); + #else + PCintPort::attachInterrupt(pins[i], &quicfunc2, FALLING); + #endif + break; + } + #if PCINT_VERSION > 2100 + Serial.print(getPSTR("setup(): Interrupt attach ")); + if (returncode != 1) Serial.print(getPSTR("unsuccessful ")); + else Serial.print(getPSTR("GOOD ")); + Serial.print(pins[i], DEC); + Serial.print(getPSTR(":pin, code: ")); Serial.println(returncode, DEC); + #endif + } + //Serial.println(printBuffer.getCapacity(), DEC); + //Serial.println("*---------------------------------------*"); + Serial.print("*---*"); + delay(250); + begintime=millis(); +} + +void loop() { + now=millis(); + uint8_t count; + char outChar; + // uint8_t bufsize; + //if (printBuffer.getSize() != 0) { Serial.print("SZ:"); Serial.println (printBuffer.getSize(), DEC); }; + //bufsize=printBuffer.getSize(); + //if (bufsize > 0) { Serial.print("S:"); Serial.println(bufsize); } + while ((outChar=(char)printBuffer.get()) != 0) Serial.print(outChar); + if ((now - begintime) > 1000) { + Serial.print("."); + if (printBuffer.checkError()) { + Serial.println(getPSTR("!Some output lost due to full buffer!")); + } + for (i=0; i < 20; i++) { + if (interrupt_count[i] != 0) { + count=interrupt_count[i]; + interrupt_count[i]=0; + Serial.print(getPSTR("Count for pin ")); + if (i < 14) { + Serial.print("D"); + Serial.print(i, DEC); + } else { + Serial.print("A"); + Serial.print(i-14, DEC); + } + Serial.print(" is "); + Serial.println(count, DEC); + } + } + begintime=millis(); + } +} + diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/SimpleExample328/SimpleExample328.ino b/hardware/bean/avr/libraries/PinChangeInt/Examples/SimpleExample328/SimpleExample328.ino new file mode 100755 index 0000000..d94b8b8 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/SimpleExample328/SimpleExample328.ino @@ -0,0 +1,66 @@ +// PinChangeInt SimpleExample sketch +// See the Wiki at http://code.google.com/p/arduino-pinchangeint/wiki for more information. + +// for vim editing: :set et ts=2 sts=2 sw=2 et + +// This example demonstrates the use of the PinChangeInt library on a single pin of your choice. +// This only works for ATMega328-compatibles; ie, Leonardo is not covered here. +// To use: + +// 1. You must be using a fairly recent version of the Arduino IDE software on your PC/Mac, +// that is, version 1.0.1 or later. Check Help->About Arduino in the IDE. + +// 2. Wire a simple switch to any Analog or Digital pin (known as ARDUINOPIN, defined below). +// Attach the other end to a GND pin. A "single pole single throw momentary contact" +// pushbutton switch is best for the best interrupting fun. + +// 3. When pressed, the switch will connect the pin to ground ("low", or "0") voltage, and interrupt the +// processor. Don't let it confuse you that a switch press means the pin's voltage goes to 0; it +// may seem more intuitive to apply a "1" or high voltage to the pin to represent "pressed". +// But the processor is perfectly happy that we've made "0" equal "Pressed". The reason we've done so +// is because we are using the "internal pullup resistor" feature of the processor... the chip gives +// us a free resistor on every pin! +// See http://arduino.cc/en/Tutorial/DigitalPins for a complete explanation. + +// 4. The interrupt is serviced immediately, and the ISR (Interrupt SubRoutine) sets the value of a global +// variable. The sketch can then query the value at its leisure. This makes loop timing non-critical. +// Open Tools->Serial Monitor in the IDE to see the results of your interrupts. + +// 5. See PinChangeIntExample328.ino (in the PinChangeInt distribution) for a more elaborate example. + +// 6. Create your own sketch using the PinChangeInt library! + +#include + +// Modify this at your leisure. +#define ARDUINOPIN A4 + +// Notice that values that get modified inside an interrupt, that I wish to access +// outside the interrupt, are marked "volatile". It tells the compiler not to optimize +// the variable. +volatile uint16_t interruptCount=0; // The count will go back to 0 after hitting 65535. + +// Do not use any Serial.print() in interrupt subroutines. Serial.print() uses interrupts, +// and by default interrupts are off in interrupt subroutines. Interrupt routines should also +// be as fast as possible. Here we just increment a counter. +void interruptFunction() { + interruptCount++; +} + +// Attach the interrupt in setup() +void setup() { + pinMode(ARDUINOPIN, INPUT_PULLUP); // Configure the pin as an input, and turn on the pullup resistor. + // See http://arduino.cc/en/Tutorial/DigitalPins + attachPinChangeInterrupt(ARDUINOPIN, interruptFunction, FALLING); + Serial.begin(115200); + Serial.println("---------------------------------------"); +} + +// In the loop, we just check to see where the interrupt count is at. The value gets updated by the +// interrupt routine. +void loop() { + delay(1000); // Every second, + Serial.print("Pin was interrupted: "); + Serial.print(interruptCount, DEC); // print the interrupt count. + Serial.println(" times so far."); +} diff --git a/hardware/bean/avr/libraries/PinChangeInt/LICENSE b/hardware/bean/avr/libraries/PinChangeInt/LICENSE new file mode 100755 index 0000000..31c692a --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/LICENSE @@ -0,0 +1,54 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + You must give any other recipients of the Work or Derivative Works a copy of this License; and + You must cause any modified files to carry prominent notices stating that You changed the files; and + You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/hardware/bean/avr/libraries/PinChangeInt/NOTICE b/hardware/bean/avr/libraries/PinChangeInt/NOTICE new file mode 100755 index 0000000..c8dcec1 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/NOTICE @@ -0,0 +1,27 @@ + NOTICE + PinChangeInt Arduino Library + Copyright 2008 Chris J. Kiick + Copyright 2009-2011 Lex Talionis + Copyright 2010-2014 Michael Schwager (aka "GreyGnome") + + This product includes software developed by Chris J. Kiick, Lex Talionis, + and Mike Schwager (aka, 'GreyGnome'). + + This library was inspired by and derived from Chris J. Kiick's PCInt Arduino + Playground example here: http://www.arduino.cc/playground/Main/PcInt + + Lex Talionis picked it up, refined it, and created a Google Code page for + it, found here: http://code.google.com/p/arduino-pinchangeint/ + + GreyGnome is the current maintainer, and would like to thank all those + Open Source coders, the Arduino makers and community, and especially Chris + and Lex for lighting the flame and showing the way! And a big thank you to + the users who have contributed comments and bug fixes along the way. + Without you this project would not have overcome some significant hurdles. + A more complete list can be found in the README file. + + A HUGE thanks to Jan Baeyens ("jantje"), who has graciously DONATED an + Arduino Mega ADK board to the PinChangeInt project!!! Wow, thanks Jan! + This makes the 2560-based Arduino Mega a first class supported platform- + I will be able to test it and verify that it works. + diff --git a/hardware/bean/avr/libraries/PinChangeInt/PinChangeInt.h b/hardware/bean/avr/libraries/PinChangeInt/PinChangeInt.h new file mode 100755 index 0000000..c088d4d --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/PinChangeInt.h @@ -0,0 +1,652 @@ +// This file is part of the PinChangeInt library for the Arduino. This library will work on any ATmega328-based +// or ATmega2560-based Arduino, as well as the Sanguino or Mioduino. + +// Most of the pins of an Arduino Uno use Pin Change Interrupts, and because of the way the ATmega interrupt +// system is designed it is difficult to trigger an Interrupt Service Request off of any single pin, and on +// any change of state (either rising, or falling, or both). The goal of this library is to make it easy for +// the programmer to attach an ISR so it will trigger on any change of state on any Pin Change Interrupt pin. + +// (NOTE TO SELF: Update the PCINT_VERSION define, below) ----------------- +#define PCINT_VERSION 2402 +/* +Copyright 2008 Chris J. Kiick +Copyright 2009-2011 Lex Talionis +Copyright 2010-2014 Michael Schwager (aka, "GreyGnome") + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * QUICKSTART + * + * For the beginners/lazy/busy/wreckless: + * To attach an interrupt to your Arduino Pin, calling your function "userFunc", and acting on + * the "mode", which is a change in the pin's state; either RISING or FALLING or CHANGE: + * attachPinChangeInterrupt(pin,userFunc,mode) + * Your function must not return any values and it cannot take any arguments (that is, its definition + * has to look like this: + * void userFunc() { + * ...your code here... + * } + * + * That's it. Everything else are details. + * + * If you need to exchange information to/from the interrupt, you can use global volatile variables. + * See the example for more information. + * + * You probably will not need to do this, but later in your sketch you can detach the interrupt: + * detachPinChangeInterrupt(pin) + * + * If you want to see what the *last* pin that triggered an interrupt was, you can get it this way: + * getInterruptedPin() + * Note: If you have multiple pins that are triggering interrupts and they are sufficiently fast, + * you will not be able to find all the pins that interrupted. +*/ + +// +// For the beginners +// +#define detachPinChangeInterrupt(pin) PCintPort::detachInterrupt(pin) +#define attachPinChangeInterrupt(pin,userFunc,mode) PCintPort::attachInterrupt(pin, &userFunc,mode) +#define getInterruptedPin() PCintPort::getArduinoPin() + +// We use 4-character tabstops, so IN VIM: :set ts=4 sw=4 sts=4 +// ...that's: ESCAPE key, colon key, then +// "s-e-t SPACE key t-s = 4 SPACE key s-w = 4 SPACE key s-t-s = 4" + +/* + * This is the PinChangeInt library for the Arduino. + This library provides an extension to the interrupt support for arduino by adding pin change + interrupts, giving a way for users to have interrupts drive off of any pin (ATmega328-based + Arduinos) and by the Port B, J, and K pins on the Arduino Mega and its ilk (see the README file). + + See the README for license, acknowledgments, and other details (especially concerning the Arduino MEGA). + + See google code project for latest, bugs and info http://code.google.com/p/arduino-pinchangeint/ + See github for the bleeding edge code: https://github.com/GreyGnome/PinChangeInt + For more information Refer to avr-gcc header files, arduino source and atmega datasheet. + + This library was inspired by and derived from Chris J. Kiick's PCInt Arduino Playground + example here: http://www.arduino.cc/playground/Main/PcInt + Nice job, Chris! +*/ + +//-------- define these in your sketch, if applicable ---------------------------------------------------------- +//-------- These must go in your sketch ahead of the #include statement ----------------------- +// You can reduce the memory footprint of this handler by declaring that there will be no pin change interrupts +// on any one or two of the three ports. If only a single port remains, the handler will be declared inline +// reducing the size and latency of the handler. +// #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts +// #define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts +// #define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts +// --- Mega support --- +// #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts +// #define NO_PORTJ_PINCHANGES // to indicate that port j will not be used for pin change interrupts +// #define NO_PORTK_PINCHANGES // to indicate that port k will not be used for pin change interrupts +// In the Mega, there is no Port C, no Port D. Instead, you get Port J and Port K. Port B remains. +// Port J, however, is practically useless because there is only 1 pin available for interrupts. Most +// of the Port J pins are not even connected to a header connection. // "Mega Support" notes +// --- Sanguino, Mioduino support --- +// #define NO_PORTA_PINCHANGES // to indicate that port a will not be used for pin change interrupts + +// You can reduce the code size by 20-50 bytes, and you can speed up the interrupt routine +// slightly by declaring that you don't care if the static variables PCintPort::pinState and/or +// PCintPort::arduinoPin are set and made available to your interrupt routine. +// #define NO_PIN_STATE // to indicate that you don't need the pinState +// #define NO_PIN_NUMBER // to indicate that you don't need the arduinoPin +// #define DISABLE_PCINT_MULTI_SERVICE // to limit the handler to servicing a single interrupt per invocation. +// #define GET_PCINT_VERSION // to enable the uint16_t getPCIintVersion () function. +// The following is intended for testing purposes. If defined, then a whole host of static variables can be read +// in your interrupt subroutine. It is not defined by default, and you DO NOT want to define this in +// Production code!: +// #define PINMODE +//-------- define the above in your sketch, if applicable ------------------------------------------------------ + +/* + VERSIONS found in moved to RELEASE_NOTES. + + See the README file for the License and more details. +*/ + +#ifndef PinChangeInt_h +#define PinChangeInt_h + +#include "stddef.h" + +// Maurice Beelen, nms277, Akesson Karlpetter, and Orly Andico +// sent in fixes to work with Arduino >= version 1.0 +#include +#include +#include // cbi and sbi defined here + +#undef DEBUG + +/* +* Theory: For the IO pins covered by Pin Change Interrupts +* (== all of them on the Atmega168/328, and a subset on the Atmega2560), +* the PCINT corresponding to the pin must be enabled and masked, and +* an ISR routine provided. Since PCINTs are per port, not per pin, the ISR +* must use some logic to actually implement a per-pin interrupt service. +*/ + +/* Pin to interrupt map, ATmega328: +* D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2 +* D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0 +* A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1 +*/ + +#undef INLINE_PCINT +#define INLINE_PCINT +// Thanks to cserveny...@gmail.com for MEGA support! +#if defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || defined __AVR_ATmega1281__ || defined __AVR_ATmega2561__ || defined __AVR_ATmega640__ + #define __USE_PORT_JK + // Mega does not have PORTA, C or D + #define NO_PORTA_PINCHANGES + #define NO_PORTC_PINCHANGES + #define NO_PORTD_PINCHANGES + #if ((defined(NO_PORTB_PINCHANGES) && defined(NO_PORTJ_PINCHANGES)) || \ + (defined(NO_PORTJ_PINCHANGES) && defined(NO_PORTK_PINCHANGES)) || \ + (defined(NO_PORTK_PINCHANGES) && defined(NO_PORTB_PINCHANGES))) + #define INLINE_PCINT inline + #endif +#else + #define NO_PORTJ_PINCHANGES + #define NO_PORTK_PINCHANGES + #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) + #ifndef NO_PORTA_PINCHANGES + #define __USE_PORT_A + #endif + #else + #define NO_PORTA_PINCHANGES + #endif + // if defined only D .OR. only C .OR. only B .OR. only A, then inline it + #if ( (defined(NO_PORTA_PINCHANGES) && defined(NO_PORTB_PINCHANGES) && defined(NO_PORTC_PINCHANGES)) || \ + (defined(NO_PORTA_PINCHANGES) && defined(NO_PORTB_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) || \ + (defined(NO_PORTA_PINCHANGES) && defined(NO_PORTC_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) || \ + (defined(NO_PORTB_PINCHANGES) && defined(NO_PORTC_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) ) + #define INLINE_PCINT inline + #endif +#endif + +// Provide drop in compatibility with Chris J. Kiick's PCInt project at +// http://www.arduino.cc/playground/Main/PcInt +#define PCdetachInterrupt(pin) PCintPort::detachInterrupt(pin) +#define PCattachInterrupt(pin,userFunc,mode) PCintPort::attachInterrupt(pin, userFunc,mode) +#define PCgetArduinoPin() PCintPort::getArduinoPin() + +typedef void (*PCIntvoidFuncPtr)(void); + +class PCintPort { +public: + // portB=PCintPort(2, 1,PCMSK1); + // index: portInputReg(*portInputRegister(index)), + // pcindex: PCICRbit(1 << pcindex) + // maskReg: portPCMask(maskReg) + PCintPort(int index,int pcindex, volatile uint8_t& maskReg) : + portInputReg(*portInputRegister(index)), + portPCMask(maskReg), + PCICRbit(1 << pcindex), + portRisingPins(0), + portFallingPins(0), + firstPin(NULL) +#ifdef PINMODE + ,intrCount(0) +#endif + { + #ifdef FLASH + ledsetup(); + #endif + } + volatile uint8_t& portInputReg; + static int8_t attachInterrupt(uint8_t pin, PCIntvoidFuncPtr userFunc, int mode); + static void detachInterrupt(uint8_t pin); + INLINE_PCINT void PCint(); + static volatile uint8_t curr; + #ifndef NO_PIN_NUMBER + static volatile uint8_t arduinoPin; + #endif + #ifndef NO_PIN_STATE + static volatile uint8_t pinState; + #endif + #ifdef PINMODE + static volatile uint8_t pinmode; + static volatile uint8_t s_portRisingPins; + static volatile uint8_t s_portFallingPins; + static volatile uint8_t s_lastPinView; + static volatile uint8_t s_pmask; + static volatile char s_PORT; + static volatile uint8_t s_changedPins; + static volatile uint8_t s_portRisingPins_nCurr; + static volatile uint8_t s_portFallingPins_nNCurr; + static volatile uint8_t s_currXORlastPinView; + volatile uint8_t intrCount; + static volatile uint8_t s_count; + static volatile uint8_t pcint_multi; + static volatile uint8_t PCIFRbug; + #endif + #ifdef FLASH + static void ledsetup(void); + #endif + +protected: + class PCintPin { + public: + PCintPin() : + PCintFunc((PCIntvoidFuncPtr)NULL), + mode(0) {} + PCIntvoidFuncPtr PCintFunc; + uint8_t mode; + uint8_t mask; + uint8_t arduinoPin; + PCintPin* next; + }; + void enable(PCintPin* pin, PCIntvoidFuncPtr userFunc, uint8_t mode); + int8_t addPin(uint8_t arduinoPin,PCIntvoidFuncPtr userFunc, uint8_t mode); + volatile uint8_t& portPCMask; + const uint8_t PCICRbit; + volatile uint8_t portRisingPins; + volatile uint8_t portFallingPins; + volatile uint8_t lastPinView; + PCintPin* firstPin; +}; + +#ifndef LIBCALL_PINCHANGEINT // LIBCALL_PINCHANGEINT *********************************************** +volatile uint8_t PCintPort::curr=0; +#ifndef NO_PIN_NUMBER +volatile uint8_t PCintPort::arduinoPin=0; +#endif +#ifndef NO_PIN_STATE +volatile uint8_t PCintPort::pinState=0; +#endif +#ifdef PINMODE +volatile uint8_t PCintPort::pinmode=0; +volatile uint8_t PCintPort::s_portRisingPins=0; +volatile uint8_t PCintPort::s_portFallingPins=0; +volatile uint8_t PCintPort::s_lastPinView=0; +volatile uint8_t PCintPort::s_pmask=0; +volatile char PCintPort::s_PORT='x'; +volatile uint8_t PCintPort::s_changedPins=0; +volatile uint8_t PCintPort::s_portRisingPins_nCurr=0; +volatile uint8_t PCintPort::s_portFallingPins_nNCurr=0; +volatile uint8_t PCintPort::s_currXORlastPinView=0; +volatile uint8_t PCintPort::s_count=0; +volatile uint8_t PCintPort::pcint_multi=0; +volatile uint8_t PCintPort::PCIFRbug=0; +#endif + +#ifdef FLASH +#define PINLED 13 +volatile uint8_t *led_port; +uint8_t led_mask; +uint8_t not_led_mask; +boolean ledsetup_run=false; +void PCintPort::ledsetup(void) { + if (! ledsetup_run) { + led_port=portOutputRegister(digitalPinToPort(PINLED)); + led_mask=digitalPinToBitMask(PINLED); + not_led_mask=led_mask^0xFF; + pinMode(PINLED, OUTPUT); digitalWrite(PINLED, LOW); + ledsetup_run=true; + } +}; +#endif + +// +// ATMEGA 644 +// +#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) // Sanguino, Mosquino uino bobino bonanafannafofino, me my momino... + +#ifndef NO_PORTA_PINCHANGES +PCintPort portA=PCintPort(1, 0,PCMSK0); // port PA==1 (from Arduino.h, Arduino version 1.0) +#endif +#ifndef NO_PORTB_PINCHANGES +PCintPort portB=PCintPort(2, 1,PCMSK1); // port PB==2 (from Arduino.h, Arduino version 1.0) +#endif +#ifndef NO_PORTC_PINCHANGES +PCintPort portC=PCintPort(3, 2,PCMSK2); // port PC==3 (also in pins_arduino.c, Arduino version 022) +#endif +#ifndef NO_PORTD_PINCHANGES +PCintPort portD=PCintPort(4, 3,PCMSK3); // port PD==4 +#endif + +#else // others + +#ifndef NO_PORTB_PINCHANGES +PCintPort portB=PCintPort(2, 0,PCMSK0); // port PB==2 (from Arduino.h, Arduino version 1.0) +#endif +#ifndef NO_PORTC_PINCHANGES // note: no PORTC on MEGA +PCintPort portC=PCintPort(3, 1,PCMSK1); // port PC==3 (also in pins_arduino.c, Arduino version 022) +#endif +#ifndef NO_PORTD_PINCHANGES // note: no PORTD on MEGA +PCintPort portD=PCintPort(4, 2,PCMSK2); // port PD==4 +#endif + +#endif // defined __AVR_ATmega644__ + +#ifdef __USE_PORT_JK +#ifndef NO_PORTJ_PINCHANGES +PCintPort portJ=PCintPort(10,1,PCMSK1); // port PJ==10 +#endif +#ifndef NO_PORTK_PINCHANGES +PCintPort portK=PCintPort(11,2,PCMSK2); // port PK==11 +#endif +#endif // USE_PORT_JK + +static PCintPort *lookupPortNumToPort( int portNum ) { + PCintPort *port = NULL; + + switch (portNum) { +#ifndef NO_PORTA_PINCHANGES + case 1: + port=&portA; + break; +#endif +#ifndef NO_PORTB_PINCHANGES + case 2: + port=&portB; + break; +#endif +#ifndef NO_PORTC_PINCHANGES + case 3: + port=&portC; + break; +#endif +#ifndef NO_PORTD_PINCHANGES + case 4: + port=&portD; + break; +#endif +#ifdef __USE_PORT_JK + +#ifndef NO_PORTJ_PINCHANGES + case 10: + port=&portJ; + break; +#endif + +#ifndef NO_PORTK_PINCHANGES + case 11: + port=&portK; + break; +#endif + +#endif // __USE_PORT_JK + } + + return port; +} + + +void PCintPort::enable(PCintPin* p, PCIntvoidFuncPtr userFunc, uint8_t mode) { + // Enable the pin for interrupts by adding to the PCMSKx register. + // ...The final steps; at this point the interrupt is enabled on this pin. + p->mode=mode; + p->PCintFunc=userFunc; +#ifndef NO_PORTJ_PINCHANGES + // A big shout out to jrhelbert for this fix! Thanks!!! + if ((p->arduinoPin == 14) || (p->arduinoPin == 15)) { + portPCMask |= (p->mask << 1); // PORTJ's PCMSK1 is a little odd... + } + else { + portPCMask |= p->mask; + } +#else + portPCMask |= p->mask; +#endif + if ((p->mode == RISING) || (p->mode == CHANGE)) portRisingPins |= p->mask; + if ((p->mode == FALLING) || (p->mode == CHANGE)) portFallingPins |= p->mask; + PCICR |= PCICRbit; +} + +int8_t PCintPort::addPin(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, uint8_t mode) +{ + PCintPin* tmp; + + tmp=firstPin; + // Add to linked list, starting with firstPin. If pin already exists, just enable. + if (firstPin != NULL) { + do { + if (tmp->arduinoPin == arduinoPin) { enable(tmp, userFunc, mode); return(0); } + if (tmp->next == NULL) break; + tmp=tmp->next; + } while (true); + } + + // Create pin p: fill in the data. + PCintPin* p=new PCintPin; + if (p == NULL) return(-1); + p->arduinoPin=arduinoPin; + p->mode = mode; + p->next=NULL; + p->mask = digitalPinToBitMask(arduinoPin); // the mask + + if (firstPin == NULL) firstPin=p; + else tmp->next=p; // NOTE that tmp cannot be NULL. + +#ifdef DEBUG + Serial.print("addPin. pin given: "); Serial.print(arduinoPin, DEC); + int addr = (int) p; + Serial.print(" instance addr: "); Serial.println(addr, HEX); + Serial.print("userFunc addr: "); Serial.println((int)p->PCintFunc, HEX); +#endif + + enable(p, userFunc, mode); +#ifdef DEBUG + Serial.print("addPin. pin given: "); Serial.print(arduinoPin, DEC), Serial.print (" pin stored: "); + int addr = (int) p; + Serial.print(" instance addr: "); Serial.println(addr, HEX); +#endif + return(1); +} + +/* + * attach an interrupt to a specific pin using pin change interrupts. + */ +int8_t PCintPort::attachInterrupt(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, int mode) +{ + PCintPort *port; + uint8_t portNum = digitalPinToPort(arduinoPin); + if ((portNum == NOT_A_PORT) || (userFunc == NULL)) return(-1); + + port=lookupPortNumToPort(portNum); + // Added by GreyGnome... must set the initial value of lastPinView for it to be correct on the 1st interrupt. + // ...but even then, how do you define "correct"? Ultimately, the user must specify (not provisioned for yet). + port->lastPinView=port->portInputReg; +#ifdef DEBUG + Serial.print("attachInterrupt- pin: "); Serial.println(arduinoPin, DEC); +#endif + // map pin to PCIR register + return(port->addPin(arduinoPin,userFunc,mode)); +} + +void PCintPort::detachInterrupt(uint8_t arduinoPin) +{ + PCintPort *port; + PCintPin* current; + uint8_t mask; + uint8_t portNum = digitalPinToPort(arduinoPin); + if (portNum == NOT_A_PORT) return; + port=lookupPortNumToPort(portNum); + mask=digitalPinToBitMask(arduinoPin); + current=port->firstPin; + while (current) { + if (current->mask == mask) { // found the target + uint8_t oldSREG = SREG; + cli(); // disable interrupts +#ifndef NO_PORTJ_PINCHANGES + // A big shout out to jrhelbert for this fix! Thanks!!! + if ((arduinoPin == 14) || (arduinoPin == 15)) { + port->portPCMask &= ~(mask << 1); // PORTJ's PCMSK1 is a little odd... + } + else { + port->portPCMask &= ~mask; // disable the mask entry. + } +#else + port->portPCMask &= ~mask; // disable the mask entry. +#endif + if (port->portPCMask == 0) PCICR &= ~(port->PCICRbit); + port->portRisingPins &= ~current->mask; port->portFallingPins &= ~current->mask; + // TODO: This is removed until we can add code that frees memory. + // Note that in the addPin() function, above, we do not define a new pin if it was + // once already defined. + // ... ... + // Link the previous' next to the found next. Then remove the found. + //if (prev != NULL) prev->next=current->next; // linked list skips over current. + //else firstPin=current->next; // at the first pin; save the new first pin + SREG = oldSREG; // Restore register; reenables interrupts + return; + } + current=current->next; + } +} + +// common code for isr handler. "port" is the PCINT number. +// there isn't really a good way to back-map ports and masks to pins. +void PCintPort::PCint() { + + #ifdef FLASH + if (*led_port & led_mask) *led_port&=not_led_mask; + else *led_port|=led_mask; + #endif + #ifndef DISABLE_PCINT_MULTI_SERVICE + uint8_t pcifr; + while (true) { + #endif + // get the pin states for the indicated port. + #ifdef PINMODE + PCintPort::s_lastPinView=lastPinView; + intrCount++; + PCintPort::s_count=intrCount; + #endif + uint8_t changedPins = (PCintPort::curr ^ lastPinView) & + ((portRisingPins & PCintPort::curr ) | ( portFallingPins & ~PCintPort::curr )); + + #ifdef PINMODE + PCintPort::s_currXORlastPinView=PCintPort::curr ^ lastPinView; + PCintPort::s_portRisingPins_nCurr=portRisingPins & PCintPort::curr; + PCintPort::s_portFallingPins_nNCurr=portFallingPins & ~PCintPort::curr; + #endif + lastPinView = PCintPort::curr; + + PCintPin* p = firstPin; + while (p) { + // Trigger interrupt if the bit is high and it's set to trigger on mode RISING or CHANGE + // Trigger interrupt if the bit is low and it's set to trigger on mode FALLING or CHANGE + if (p->mask & changedPins) { + #ifndef NO_PIN_STATE + PCintPort::pinState=PCintPort::curr & p->mask ? HIGH : LOW; + #endif + #ifndef NO_PIN_NUMBER + PCintPort::arduinoPin=p->arduinoPin; + #endif + #ifdef PINMODE + PCintPort::pinmode=p->mode; + PCintPort::s_portRisingPins=portRisingPins; + PCintPort::s_portFallingPins=portFallingPins; + PCintPort::s_pmask=p->mask; + PCintPort::s_changedPins=changedPins; + #endif + p->PCintFunc(); + } + p=p->next; + } + #ifndef DISABLE_PCINT_MULTI_SERVICE + pcifr = PCIFR & PCICRbit; + if (pcifr == 0) break; + PCIFR |= PCICRbit; + #ifdef PINMODE + PCintPort::pcint_multi++; + if (PCIFR & PCICRbit) PCintPort::PCIFRbug=1; // PCIFR & PCICRbit should ALWAYS be 0 here! + #endif + PCintPort::curr=portInputReg; + } + #endif +} + +#ifndef NO_PORTA_PINCHANGES +ISR(PCINT0_vect) { + #ifdef PINMODE + PCintPort::s_PORT='A'; + #endif + PCintPort::curr = portA.portInputReg; + portA.PCint(); +} +#define PORTBVECT PCINT1_vect +#define PORTCVECT PCINT2_vect +#define PORTDVECT PCINT3_vect +#else +#define PORTBVECT PCINT0_vect +#define PORTCVECT PCINT1_vect +#define PORTDVECT PCINT2_vect +#endif + +#ifndef NO_PORTB_PINCHANGES +ISR(PORTBVECT) { + #ifdef PINMODE + PCintPort::s_PORT='B'; + #endif + PCintPort::curr = portB.portInputReg; + portB.PCint(); +} +#endif + +#ifndef NO_PORTC_PINCHANGES +ISR(PORTCVECT) { + #ifdef PINMODE + PCintPort::s_PORT='C'; + #endif + PCintPort::curr = portC.portInputReg; + portC.PCint(); +} +#endif + +#ifndef NO_PORTD_PINCHANGES +ISR(PORTDVECT){ + #ifdef PINMODE + PCintPort::s_PORT='D'; + #endif + PCintPort::curr = portD.portInputReg; + portD.PCint(); +} +#endif + +#ifdef __USE_PORT_JK +#ifndef NO_PORTJ_PINCHANGES +ISR(PCINT1_vect) { + #ifdef PINMODE + PCintPort::s_PORT='J'; + #endif + PCintPort::curr = portJ.portInputReg; + portJ.PCint(); +} +#endif + +#ifndef NO_PORTK_PINCHANGES +ISR(PCINT2_vect){ + #ifdef PINMODE + PCintPort::s_PORT='K'; + #endif + PCintPort::curr = portK.portInputReg; + portK.PCint(); +} +#endif + +#endif // __USE_PORT_JK + +#ifdef GET_PCINT_VERSION +uint16_t getPCIntVersion () { + return ((uint16_t) PCINT_VERSION); +} +#endif // GET_PCINT_VERSION +#endif // #ifndef LIBCALL_PINCHANGEINT ************************************************************* +#endif // #ifndef PinChangeInt_h ******************************************************************* diff --git a/hardware/bean/avr/libraries/PinChangeInt/README b/hardware/bean/avr/libraries/PinChangeInt/README new file mode 100755 index 0000000..a80c3a8 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/README @@ -0,0 +1,110 @@ +---- README -------------------------------------------------------------------- + PinChangeInt README. Find instructions and more information at + https://github.com/GreyGnome/PinChangeInt/wiki + +NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +This library is deprecated as of April 3, 2015. This means that I will be +providing bug fixes for some time, but users are encouraged to migrate to +the EnableInterrupt library, at https://github.com/GreyGnome/EnableInterrupt . +It is faster and easier to use. Thank you. + + +---- DESCRIPTION --------------------------------------------------------------- +This is the PinChangeInt library for the Arduino. It provides an extension to +the interrupt support for ATmega328 and ATmega2560-based Arduinos, and some +ATmega32u4 and Sanguinos. It adds pin change interrupts, giving a way for users +to have interrupts drive off of any pin (ATmega328-based Arduinos), by the Port +B, J, and K pins on the Arduino Mega and its ilk, and on the appropriate ports +(including Port A) on the Sanguino and its ilk. Yun and Sanguino support are +weak, quite honestly, as I don't have either a Sanguino or a Yun. Theoretically +the library would work with a Leonardo but I have no reports regarding that +platform. The ATmega32u4 has port B (8 pins) pin change interrupts only. + +For more information refer to avr-gcc header files, Arduino source and Atmega +datasheet. + +This library was inspired by and derived from Chris J. Kiick's PCInt Arduino +Playground example here: http://playground.arduino.cc/Main/PcInt + +The following pins are usable PinChangeInt pins on the Mega (ATmega1280 and +ATmega2560-based Arduinos**): + +Arduino Arduino Arduino + Pin* PORT PCINT Pin PORT PCINT Pin PORT PCINT + A8 PK0 16 10 PB4 4 SS PB0 0 + A9 PK1 17 11 PB5 5 SCK PB1 1 + A10 PK2 18 12 PB6 6 MOSI PB2 2 + A11 PK3 19 13 PB7 7** MISO PB3 3 + A12 PK4 20 14 PJ1 10 + A13 PK5 21 15 PJ0 9 + A14 PK6 22 + A15 PK7 23 +...indeed, the ATmega2560 chip supports many more Pin Change Interrupt pins but +they are unavailable on the Arduino, unless you want to solder teeny tiny wires. + +* Note: Arduino Pin 0 is PE0 (PCINT8), which is RX0 and thus is not supported by +this library. It is the same pin the Arduino uses to upload sketches, and they +are connected to the FT232RL USB-to-Serial chip (ATmega16U2 on the R3). +** On the MegaADK, according to http://arduino.cc/en/Main/ArduinoBoardMegaADK: +"USB Host: MAX3421E. The MAX3421E comunicate with Arduino with the SPI bus. So +it uses the following pins: +Digital: 7 (RST), 50 (MISO), 51 (MOSI), 52 (SCK). NB: Please do not use Digital +pin 7 as input or output because is used in the comunication (sic) with +MAX3421E " + +---- LICENSE ------------------------------------------------------------------- +Licensed under the Apache2.0 license. See the source files for the license +boilerplate, the LICENSE file for the full text, and the NOTICE file which the +Apache2.0 license requires that you distribute with any code that you distribute +that uses this library. The copyright holders for this code are Chris J. Kiick, +Lex Talionis, and Michael Schwager. Chris and Lex have graciously agreed to the +Apache 2.0 license for this code, and beginning with version 2.40-rc1 this is +the license that applies. + +---- ACKNOWLEDGMENTS ----------------------------------------------------------- +This library was originally written by Chris J. Kiick, Robot builder and all +around geek, who said of it, + "Hi, Yeah, I wrote the original PCint library. It was a bit of a hack + and the new one has better features. I intended the code to be freely + usable. Didn't really think about a license. Feel free to use it in + your code: I hereby grant you permission." +Thanks, Chris! A hack? I dare say not, if I have taken this any further it's +merely by standing on the shoulders of giants. This library was the best +"tutorial" I found on Arduino Pin Change Interrupts and because of that I +decided to continue to maintain and (hopefully) improve it. We, the Arduino +community of robot builders and geeks, owe you a great debt of gratitude for +your hack- a hack in the finest sense. + +The library was then picked up by Lex Talionis, who created the Google Code +website. We all owe a debt of thanks to Lex, too, for all his hard work! He is +currently the other official maintainer of this code. + +Many thanks to all the contributors who have contributed bug fixes, code, and +suggestions to this project: + +John Boiles and Baziki (who added fixes to PcInt), Maurice Beelen, nms277, +Akesson Karlpetter, and Orly Andico for various fixes to this code, Rob Tillaart +for some excellent code reviews and nice optimizations, Andre' Franken for a +good bug report that kept me thinking, cserveny.tamas a special shout out for +providing the MEGA code to PinChangeInt, and Pat O'Brien for testing and +reporting on the Arduino Yun.- Thanks! + +A HUGE thanks to JRHelbert for fixing the PJ0 and PJ1 interrupt PCMSK1 issue on +the Mega... 06/2014 + +A HUGE thanks to Jan Baeyens ("jantje"), who has graciously DONATED an Arduino +Mega ADK to the PinChangeInt project!!! Wow, thanks Jan! This makes the +2560-based Arduino Mega a first class supported platform- I will be able to test +it and verify that it works. + +Finally, a shout out to Leonard Bernstein. I was inspired by him +(https://www.youtube.com/watch?feature=player_detailpage&v=R9g3Q-qvtss#t=1160) +from a Ted talk by Itay Talgam. None of the contributors, myself included, has +any interest in making money from this library and so I decided to free up the +code as much as possible for any purpose. ...But! You must give credit where +credit is due (it's not only a nice idea, it's the law- as in, the license +terms)! + +"If you love something, give it away." + +If apologize if I have forgotten anyone here. Please let me know if so. diff --git a/hardware/bean/avr/libraries/PinChangeInt/RELEASE_NOTES b/hardware/bean/avr/libraries/PinChangeInt/RELEASE_NOTES new file mode 100755 index 0000000..bff6bee --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/RELEASE_NOTES @@ -0,0 +1,436 @@ +****************************************************************************** + + PinChangeInt + ---- RELEASE NOTES --- +Version 2.40-rc2 Mon Jan 12 07:37:22 CST 2015 +Happy New Year! + +Cleaned up some code, and added the following #define's for ease-of-use: + +#define detachPinChangeInterrupt(pin) PCintPort::detachInterrupt(pin) +#define attachPinChangeInterrupt(pin,userFunc,mode) PCintPort::attachInterrupt(pin, &userFunc,mode) +#define getInterruptedPin() PCintPort::getArduinoPin() + +Cleaned up the README for better display on GitHub. + +Version 2.40-rc1 Fri Nov 7 07:26:36 CST 2014 +I'm going to the "-rcX" numbering format like the Linux kernel. That is, 2.40-rc1 is the first "release +candidate" on the way to a stable 2.40 release. + +Beginning with this release, only Arduino >= 1.00 is supported. The older Arduinos are left to the +dustbin of history... + +I have BIG news: Jan Baeyens ("jantje") has graciously DONATED an Arduino Mega ADK +to the PinChangeInt project!!! Wow, thanks Jan! This makes the 2560-based Arduino Mega +a first class supported platform- I will be able to test it and verify that it works. +I have done so in this release. + +To that end, The PinChangeIntExample has been modified to work properly with the Arduino Mega. +Thanks, Jan! + +And the BIG BIG BIG news: The library is now licensed under the Apache 2.0 License. I wanted to +free the code up for any use, and Chris J. Kiick and Lex Talionis graciously agreed. + +Version 2.32 Fri Oct 31 05:16:34 CDT 2014 +Argh! I should have done a "git status" prior to to tagging 2.31. Well, this makes 2.32. + +I had added an additional method to putString, so as to allow for a different signature and stop +the compiler from complaining: + +uint8_t ByteBuffer::putString(const char *in) { + return(putString((char *) in)); +} + +No other changes over 2.32 + +Version 2.31 Fri Oct 31 05:11:41 CDT 2014 +I forgot to update these release notes for version 2.30. And I didn't tag it. This is merely a +some housekeeping from 2.30. Here is what changed from version 2.21: + +In Examples/PinChangeIntTest/PinChangeIntTest.ino: + Whacked a nasty little bug in setup(), where my 'i' variable in the for + loop went until 'i < 7'. Should have been 'i < 6' all along. Grrr. + +In PinChangeInt.h: + Most significantly: Many thanks to JRHelbert for fixing the PJ0 and PJ1 + interrupt PCMSK1 issue on the Arduino Mega! This was a great coup, in my + humble opinion. Mega interrupt users are indebted to you, jrhelbert. + + Added PinChangeIntDebug.ino, which is a simplified PinChangeIntTest. My + head was spinning in PinChangeIntTest due to a nasty bug that I whacked, + so I wanted a simplified test file. + + +Version 2.21 (beta) Mon Apr 8 22:06:13 CDT 2013 +Fixed Examples/ByteBuffer/ByteBuffer.cpp. Bug in the PutString() method. Does not affect the behavior +of the library at all whatsoever, this was only used in the example code. + +Version 2.19 (beta) Tue Nov 20 07:33:37 CST 2012 +SANGUINO SUPPORT! ...And Mioduino! +...The ATmega644 chip is so cool, how can I not? 4 full ports of Pin Change Interrupt bliss! 32 i/o pins! 64k Flash! 4k RAM! Well I wish I had one. That said, Sanguino users, PLEASE send in your bug or bliss reports! Your interrupt-loving brethren and sistren are depending on you, so I can assure everyone that my changes work on that platform. Thanks. + +Modified the addPin() method to save 12 bytes; thanks again robtilllart! + if (firstPin != NULL) { + tmp=firstPin; + do { + if (tmp->arduinoPin == arduinoPin) { enable(tmp, userFunc, mode); return(0); } + if (tmp->next == NULL) break; + tmp=tmp->next; + } while (true); + } +Also changed the goto in the PCint() loop to be a while/break combination. No change to +code speed, but it looks better and passes the cleanliness "gut check". + +Includes PinChangeIntTest 1.5 sketch. + +...Ooops! Forgot the GetPSTR library, needed for the PinChangeIntTest code! Now it's included. +****************************************************************************** +Version 2.17 (beta) Sat Nov 17 09:46:50 CST 2012 +Another bugfix in the PCINT_MULTI_SERVICE section. I was using sbi(PCIFR, PCICRbit); +I didn't realize that was for I/O ports, and not ATmega registers. +But according to "deprecated.h", +"These macros became obsolete, as reading and writing IO ports can + be done by simply using the IO port name in an expression, and all + bit manipulation (including those on IO ports) can be done using + generic C bit manipulation operators." +So now I do: + PCIFR |= PCICRbit; +****************************************************************************** +Version 2.15 (beta) Sat Nov 17 01:17:44 CST 2012 +Fixed it so that attachInterrupt() will now follow your changes to the user function, +as well as the mode. detachInterrupt() still does not delete the PCintPin object but +at least you can detach and reattach at will, using different modes (RISING, FALLING, +CHANGE) and different functions as you wish. + +****************************************************************************** +Version 2.13 (beta) Mon Nov 12 09:33:06 CST 2012 +SIGNIFICANT BUGFIX release! Significant changes: +1. PCintPort::curr bug. Interrupts that occur rapidly will likely not get serviced properly by PCint(). +2. PCint() interrupt handler optimization. +3. PCIFR port bit set bug fix. +4. Many static variables added for debugging; used only when #define PINMODE is on. +5. detachInterrupt() no longer does a delete(), since that wasn't working anyway. When you detachInterrupt(), the PORT just disables interrupts for that pin; the PCintPin object remains in memory and in the linked list of pins (possibly slowing down your interrupts a couple of micros). You can reenable a detached interrupt- but you must do it within the PinChangeInt library (would anyone ever enable an interrupt on a pin, then disable it, then have need to reenable it but not using the library?). +6. attachInterrupt() now returns a uint8_t value: 1 on successful attach, 0 on successful attach but using an already-enabled pin, and -1 if the new() operator failed to create a PCintPin object. +Also, modified these release notes. + +Details: + +Uncovered a nasty bug, thanks to robtillaart on the Arduino Forums and Andre' Franken who posted to the PinChangeInt groups. This bug was introduced by me when I assigned PCintPort::curr early in the interrupt handler: +ISR(PCINT0_vect) { + PCintPort::curr = portB.portInputReg; + portB.PCint(); +} +Later, in the interrupt handler PCint(), we loop as long as PCIFR indicates a new interrupt wants to be triggered, provided DISABLE_PCINT_MULTI_SERVICE is not defined (it is not by default): +#ifndef DISABLE_PCINT_MULTI_SERVICE + pcifr = PCIFR & PCICRbit; + PCIFR = pcifr; // clear the interrupt if we will process it (no effect if bit is zero) +} while(pcifr); +#endif +...Well. Problem is, if a pin pops up and causes the PCIFR to change, we have to reread the port and look at how it is now! I wasn't doing that before, so if a new interrupt appeared while I was still servicing the old one, odd behavior would take place. For example, an interrupt would register but then the userFunc would not be called upon to service it. The code needs to be: + pcifr = PCIFR & PCICRbit; + PCIFR = pcifr; // clear the interrupt if we will process it (no effect if bit is zero) + PCintPort::curr=portInputReg; // ...Fixed in 2.11beta. +} while(pcifr); + +Also, made the interrupt handler even faster with an optimization from robtillaart to take out the checks for changed pins from the while() loop that steps through the pins: +uint8_t changedPins = (PCintPort::curr ^ lastPinView) & + ((portRisingPins & PCintPort::curr ) | ( portFallingPins & ~PCintPort::curr )); + +...This speedup is offset by more changes in the PCint() handler, which now looks like the following; there are two bug fixes: +---------------------------- +FIX 1: sbi(PCIFR, PCICRbit); +FIX 2: ...the aforementioned PCintPort::curr=portInputReg; +Here's the new code: +---------------------------- + #ifndef DISABLE_PCINT_MULTI_SERVICE + pcifr = PCIFR & PCICRbit; + if (pcifr) { + //if (PCIFR & PCICRbit) { // believe it or not, this adds .6 micros + sbi(PCIFR, PCICRbit); // This was a BUG: PCIFR = pcifr ...And here is the fix. + #ifdef PINMODE + PCintPort::pcint_multi++; + if (PCIFR & PCICRbit) PCintPort::PCIFRbug=1; // PCIFR & PCICRbit should ALWAYS be 0 here! + #endif + PCintPort::curr=portInputReg; // ...Fixed in 2.11beta. + goto loop; // A goto!!! Don't want to look at the portInputReg gratuitously, so the while() will not do. + } + #endif + +Also I added a lot of variables for debugging when PINMODE is defined, for routing out nasty bugs. I may need them in the future... :-( + +Finally, I am not putting newlines in this commentary so I can make it easier to paste online. + +****************************************************************************** +Version 2.11 (beta) Mon Nov 12 09:33:06 CST 2012 +See version 2.13 (beta) above. No change other than tidying up the release notes. +****************************************************************************** + Version 2.01 (beta) Thu Jun 28 12:35:48 CDT 2012 + ...Wow, Version 2! What? Why? + Modified the way that the pin is tested inside the interrupt subroutine (ISR) PCintPort::PCint(), + to make the interrupt quicker and slightly reduce the memory footprint. The interrupt's time is + reduced by 2 microseconds or about 7%. Instead of using the mode variable, two bitmasks are maintained + for each port. One bitmask contains all the pins that are configured to work on RISING signals, the other + on FALLING signals. A pin configured to work on CHANGE signals will appear in both bitmasks of the port. + Then, the test for a change goes like this: + if (thisChangedPin) { + if ((thisChangedPin & portRisingPins & PCintPort::curr ) || + (thisChangedPin & portFallingPins & ~PCintPort::curr )) { + where portRisingPins is the bitmask for the pins configured to interrupt on RISING signals, and + portFallingPins is the bitmask for the pins configured to interrupt on FALLING signals. Each port includes + these two bitmask variables. + + This is a significant change to some core functionality to the library, and it saves an appreciable amount + of time (2 out of 36 or so micros). Hence, the 2.00 designation. + + Tue Jun 26 12:42:20 CDT 2012 + I was officially given permission to use the PCint library: + + Re: PCint library + « Sent to: GreyGnome on: Today at 08:10:33 AM » + « You have forwarded or responded to this message. » + Quote Reply Remove + HI, + Yeah, I wrote the original PCint library. It was a bit of a hack and the new one has better features. + I intended the code to be freely usable. Didn't really think about a license. Feel free to use it in + your code: I hereby grant you permission. + + I'll investigate the MIT license, and see if it is appropriate. + Chris J. Kiick + Robot builder and all around geek. + + Version 1.81 (beta) Tue Jun 19 07:29:08 CDT 2012 + Created the getPCIntVersion function, and its associated GET_PCINT_VERSION preprocessor macro. The version + is a 16-bit int, therefore versions are represented as a 4-digit integer. 1810, then, is the first beta + release of 1.81x series. 1811 would be a bugfix of 1.810. 1820 would be the production release. + + Reversed the order of this list, so the most recent notes come first. + + Made some variables "volatile", because they are changed in the interrupt code. Thanks, Tony Cappellini! + + Added support for the Arduino Mega! Thanks to cserveny...@gmail.com! + NOTE: I don't have a Mega, so I rely on you to give me error (or working) reports! + To sum it up for the Mega: No Port C, no Port D. Instead, you get Port J and Port K. Port B remains. + Port J, however, is practically useless because there is only 1 pin available for interrupts. + Most of the Port J pins are not even connected to a header connector. Caveat Programmer. + + Created a function to report the version of this code. Put this #define ahead of the #include of this file, + in your sketch: + #define GET_PCINT_VERSION + Then you can call + uint16_t getPCIntVersion (); + and it will return a 16-bit integer representation of the version of this library. That is, version 1.73beta + will be reported as "1730". 1.74, then, will return "1740". And so on, for whatever version of the library + this happens to be. The odd number in the 10's position will indicate a beta version, as per usual, and the + number in the 1s place will indicate the beta revision (bugs may necessitate a 1.731, 1.732, etc.). + + Here are some of his notes based on his changes: + Mega and friends are using port B, J and K for interrupts. B is working without any modifications. + + J is mostly useless, because of the hardware UART. I was not able to get pin change notifications from + the TX pin (14), so only 15 left. All other (PORT J) pins are not connected on the Arduino boards. + + K controls Arduino pin A8-A15, working fine. + + 328/168 boards use C and D. So in case the lib is compiled with Mega target, the C and D will be + disabled. Also you cannot see port J/K with other targets. For J and K new flags introduced: + NO_PORTJ_PINCHANGES and NO_PORTK_PINCHANGES. + Maybe we should have PORTJ_PINCHANGES to enable PJ, because they will be most likely unused. + + Enjoy! + + Note: To remain consistent, I have not included PORTJ_PINCHANGES. All ports behave the same, + no matter how trivial those ports may seem... no surprises... + + Version 1.72 Wed Mar 14 18:57:55 CDT 2012 + Release. + + Version 1.71beta Sat Mar 10 12:57:05 CST 2012 + Code reordering: Starting in version 1.3 of this library, I put the code that enables + interrupts for the given pin, and the code that enables Pin Change Interrupts, ahead of actually + setting the user's function for the pin. Thus in the small interval between turning on the + interrupts and actually creating a valid link to an interrupt handler, it is possible to get an + interrupt. At that point the value of the pointer is 0, so this means that the Arduino + will start over again from memory location 0- just as if you'd pressed the reset button. Oops! + + I corrected it so the code now operates in the proper order. + (EDITORIAL NOTE: If you want to really learn something, teach it!) + + Minor code clean-up: All references to PCintPort::curr are now explicit. This changes the compiled + hex code not one whit. I just sleep better at night. + + Numbering: Changed the numbering scheme. Beta versions will end with an odd number in the hundredths + place- because they may be odd- and continue to be marked "beta". I'll just sleep better at night. :-) + + Version 1.70beta Mon Feb 27 07:20:42 CST 2012 + Happy Birthday to me! Happy Birthday tooooo meee! Happy Birthday, Dear Meeeeee-eeeee! + Happy Birthday to me! + + Yes, it is on this auspicious occasion of mine (and Elizabeth Taylor's [R.I.P.]) birthday that I + humbly submit to you, gracious Arduino PinChangeInt user, version 1.70beta of the PinChangeInt + library. I hope you enjoy it. + + New in this release: + The PinChangeIntTest sketch was created, which can be found in the Examples directory. It exercises: + * Two interrupting pins, one on each of the Arduino's PORTs. + * detachInterrupt() (and subsequent attachInterrupt()s). + Hopefully this will help avoid the embarrassing bugs that I have heretofore missed. + + As well, it has come to this author's (GreyGnome) attention that the Serial class in Arduino 1.0 + uses an interrupt that, if you attempt to print from an interrupt (which is what I was doing in my + tests) can easily lock up the Arduino. So I have taken SigurðurOrn's excellent ByteBuffer library + and modified it for my own nefarious purposes. (see http://siggiorn.com/?p=460). The zipfile + comes complete with the ByteBuffer library; see the ByteBuffer/ByteBuffer.h file for a list of + changes, and see the PinChangeIntTest sketch for a usage scenario. Now the (interrupt-less and) + relatively fast operation of filling a circular buffer is used in the interrupt routines. The buffer + is then printed from loop(). + + The library has been modified so it can be used in other libraries, such as my AdaEncoder library + (http://code.google.com/p/adaencoder/). When #include'd by another library you should #define + the LIBCALL_PINCHANGEINT macro. For example: + #ifndef PinChangeInt_h + #define LIBCALL_PINCHANGEINT + #include "../PinChangeInt/PinChangeInt.h" + #endif + This is necessary because the IDE compiles both your sketch and the .cpp file of your library, and + the .h file is included in both places. But since the .h file actually contains the code, any variable + or function definitions would occur twice and cause compilation errors- unless #ifdef'ed out. + + Version 1.6beta Fri Feb 10 08:48:35 CST 2012 + Set the value of the current register settings, first thing in each ISR; e.g., + ISR(PCINT0_vect) { + PCintPort::curr = portB.portInputReg; // version 1.6 + ... + ...instead of at the beginning of the PCintPort::PCint() static method. This means that the port is read + closer to the beginning of the interrupt, and may be slightly more accurate- only by a couple of microseconds, + really, but it's a cheap win. + + Fixed a bug- a BUG!- in the attachInterrupt() and detachInterrupt() methods. I didn't have breaks in my + switch statements! Augh! What am I, a (UNIX) shell programmer? ...Uh, generally, yes... + + Added the PINMODE define and the PCintPort::pinmode variable. + + Version 1.51 Sun Feb 5 23:28:02 CST 2012 + Crap, a bug! Changed line 392 from this: + PCintPort::pinState=curr & changedPins ? HIGH : LOW; + to this: + PCintPort::pinState=curr & p->mask ? HIGH : LOW; + Also added a few lines of (commented-out) debug code. + + Version 1.5 Thu Feb 2 18:09:49 CST 2012 + Added the PCintPort::pinState static variable to allow the programmer to query the state of the pin + at the time of interrupt. + Added two new #defines, NO_PIN_STATE and NO_PIN_NUMBER so as to reduce the code size by 20-50 bytes, + and to speed up the interrupt routine slightly by declaring that you don't care if the static variables + PCintPort::pinState and/or PCintPort::arduinoPin are set and made available to your interrupt routine. + // #define NO_PIN_STATE // to indicate that you don't need the pinState + // #define NO_PIN_NUMBER // to indicate that you don't need the arduinoPin + + Version 1.4 Tue Jan 10 09:41:14 CST 2012 + All the code has been moved into this .h file, so as to allow #define's to work from the user's + sketch. Thanks to Paul Stoffregen from pjrc.com for the inspiration! (Check out his website for + some nice [lots more memory] Arduino-like boards at really good prices. ...This has been an unsolicited + plug. Now back to our regular programming. ...Hehe, "programming", get it?) + + As a result, we no longer use the PinChangeIntConfig.h file. The user must #define things in his/her + sketch. Which is better anyway. + + Removed the pcIntPorts[] array, which created all the ports by default no matter what. Now, only + those ports (PCintPort objects) that you need will get created if you use the NO_PORTx_PINCHANGES #defines. + This saves flash memory, and actually we get a bit of a memory savings anyway even if all the ports are + left enabled. + + The attachInterrupt and detachInterrupt routines were modified to handle the new PCintPort objects. + + Version 1.3 Sat Dec 3 22:56:20 CST 2011 + Significant internal changes: + Tested and modified to work with Arduino 1.0. + + Modified to use the new() operator and symbolic links instead of creating a pre-populated + PCintPins[]. Renamed some variables to simplify or make their meaning more obvious (IMHO anyway). + Modified the PCintPort::PCint() code (ie, the interrupt code) to loop over a linked-list. For + those who love arrays, I have left some code in there that should work to loop over an array + instead. But it is commented out in the release version. + + For Arduino versions prior to 1.0: The new() operator requires the cppfix.h library, which is + included with this package. For Arduino 1.0 and above: new.h comes with the distribution, and + that is #included. + + Version 1.2 Sat Dec 3 Sat Dec 3 09:15:52 CST 2011 + Modified Thu Sep 8 07:33:17 CDT 2011 by GreyGnome. Fixes a bug with the initial port + value. Now it sets the initial value to be the state of the port at the time of + attachInterrupt(). The line is port.PCintLast=port.portInputReg; in attachInterrupt(). + See GreyGnome comment, below. + + Added the "arduinoPin" variable, so the user's function will know exactly which pin on + the Arduino was triggered. + + Version 1.1 Sat Dec 3 00:06:03 CST 2011 + ...updated to fix the "delPin" function as per "pekka"'s bug report. Thanks! + + ---- ^^^ VERSIONS ^^^ (NOTE TO SELF: Update the PCINT_VERSION define, below) ------------- + + See google code project for latest, bugs and info http://code.google.com/p/arduino-pinchangeint/ + For more information Refer to avr-gcc header files, arduino source and atmega datasheet. + + This library was inspired by and derived from "johnboiles" (it seems) + PCInt Arduino Playground example here: http://www.arduino.cc/playground/Main/PcInt + If you are the original author, please let us know at the google code page + + It provides an extension to the interrupt support for arduino by + adding pin change interrupts, giving a way for users to have + interrupts drive off of any pin. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +NOTES ================================================================================ + +Serial.print()---------------- + +Serial.print() does not work well inside interrupts. This is because it uses interrupts, +and while you are in an interrupt, interrupts are (by default) turned off. +Serial is declared in /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.h . +In the write() method in the .cpp file, for example it says: +... + // If the output buffer is full, there's nothing for it other than to + // wait for the interrupt handler to empty it a bit + // ???: return 0 here instead? + while (i == _tx_buffer->tail) + ; +... +And the ISR is further down in that file (this for the ATmega328 I believe): +ISR(USART_RX_vect) +... + +If a user wants to try to use Serial.print() inside an ISR, I believe it's possible +(by turning on interrupts inside the interrupt)... +but it would require them to be aware of any possible contention between the interrupts, +and the print ISRs. + + +Software Serial---------- +Also, the SoftwareSerial library defines ISRs for Pin Change Interrupt ports: + +ISR(PCINT0_vect) +{ + SoftwareSerial::handle_interrupt(); +} + +...It defines the interrupt on all ports, whether it's using them or not +(the library cannot know ahead of time if the user will be using a set of pins +or not). + +To ensure compatibility with the SoftwareSerial library, the user should comment +out the ports that they are NOT using with the SoftwareSerial library, in +/usr/share/arduino/libraries/SoftwareSerial/SoftwareSerial.cpp +and comment out the ports that they ARE using with this library in PinChangeInt.h diff --git a/hardware/bean/avr/libraries/PinChangeInt/Technical_Notes b/hardware/bean/avr/libraries/PinChangeInt/Technical_Notes new file mode 100755 index 0000000..9d48599 --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/Technical_Notes @@ -0,0 +1,70 @@ +The purpose of this library is to give the programmer the ability to add interrupts +with the easy of attachInterrupt, which looks like this: + attachInterrupt(interrupt, &function, MODE) +...the interrupt is a number which gets translated to the proper pin on the Arduino. For example, +Board int.0 int.1 int.2 int.3 int.4 int.5 +Uno, Ethernet 2 3 +Mega2560 2 3 21 20 19 18 +Leonardo 3 2 0 1 7 +Due (doesn't use interrupt numbers, it uses the pin numbers directly) + +The MODE is LOW, CHANGE, RISING, or FALLING. On the Due board, you also have HIGH. + + +The PinChangeInterrupt library does not work on the Due; it is not necessary. It is somewhat easier +to use than attachInterrupt() because you don't have to translate from an "Interrupt number" to a +pin number- you simply give it the pin that you want to Interrupt on: + + PCintPort::attachInterrupt(interrupt, &function, MODE) + +The MODE is LOW, CHANGE, RISING, or FALLING. On the Due board, you also have HIGH. + +To have an Interrupt: + +Global Interrupt flag must be enabled. +Set the I-bit in SREG. +In PCICR: bit 2 == PCIE2: set, enable pins PCINT[23:16], enable individual by PCMSK2 + bit 1 == PCIE1: set, enable PCINT[14:8], enable individual by PCMSK1 + bit 0 == PCIE0: set, enable PCINT[7:0], enable individual by PCMSK0 + +Pin Change Interrupts and Other Libraries ============================================================ + +Serial.print()---------------- + +Serial.print() does not work well inside interrupts. This is because it uses interrupts, +and while you are in an interrupt, interrupts are (by default) turned off. +Serial is declared in /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.h . +In the write() method in the .cpp file, for example it says: +... + // If the output buffer is full, there's nothing for it other than to + // wait for the interrupt handler to empty it a bit + // ???: return 0 here instead? + while (i == _tx_buffer->tail) + ; +... +And the ISR is further down in that file (this for the ATmega328 I believe): +ISR(USART_RX_vect) +... + +If a user wants to try to use Serial.print() inside an ISR, I believe it's possible +(by turning on interrupts inside the interrupt)... +but it would require them to be aware of any possible contention between the interrupts, +and the print ISRs. + + +Software Serial---------- +The SoftwareSerial library defines ISRs for Pin Change Interrupt ports: + +ISR(PCINT0_vect) +{ + SoftwareSerial::handle_interrupt(); +} + +...It defines the interrupt on all ports, whether it's using them or not +(the library cannot know ahead of time if the user will be using a set of pins +or not). + +To ensure compatibility with the SoftwareSerial library, the user should comment +out the ports that they are NOT using with the SoftwareSerial library, in +/usr/share/arduino/libraries/SoftwareSerial/SoftwareSerial.cpp +and comment out the ports that they ARE using with this library in PinChangeInt.h diff --git a/hardware/bean/avr/libraries/PinChangeInt/keywords.txt b/hardware/bean/avr/libraries/PinChangeInt/keywords.txt new file mode 100755 index 0000000..24e1cec --- /dev/null +++ b/hardware/bean/avr/libraries/PinChangeInt/keywords.txt @@ -0,0 +1,10 @@ +# LITERAL1 specifies constants + +# KEYWORD1 specifies datatypes and C/C++ keywords +pinState KEYWORD1 PinState +arduinoPin KEYWORD1 ArduinoPin +PCintPort KEYWORD1 PCInterruptPort + +# KEYWORD2 specifies methods and functions +attachInterrupt KEYWORD2 AttachInterrupt +detachInterrupt KEYWORD2 DetachInterrupt diff --git a/hardware/bean/avr/libraries/SPI/SPI.cpp b/hardware/bean/avr/libraries/SPI/SPI.cpp new file mode 100644 index 0000000..af14e07 --- /dev/null +++ b/hardware/bean/avr/libraries/SPI/SPI.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2010 by Cristian Maglie + * Copyright (c) 2014 by Paul Stoffregen (Transaction API) + * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) + * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) + * SPI Master library for arduino. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either the GNU General Public License version 2 + * or the GNU Lesser General Public License version 2.1, both as + * published by the Free Software Foundation. + */ + +#include "SPI.h" + +SPIClass SPI; + +uint8_t SPIClass::initialized = 0; +uint8_t SPIClass::interruptMode = 0; +uint8_t SPIClass::interruptMask = 0; +uint8_t SPIClass::interruptSave = 0; +#ifdef SPI_TRANSACTION_MISMATCH_LED +uint8_t SPIClass::inTransactionFlag = 0; +#endif + +void SPIClass::begin() +{ + uint8_t sreg = SREG; + noInterrupts(); // Protect from a scheduler and prevent transactionBegin + if (!initialized) { + // Set SS to high so a connected chip will be "deselected" by default + uint8_t port = digitalPinToPort(SS); + uint8_t bit = digitalPinToBitMask(SS); + volatile uint8_t *reg = portModeRegister(port); + + // if the SS pin is not already configured as an output + // then set it high (to enable the internal pull-up resistor) + if(!(*reg & bit)){ + digitalWrite(SS, HIGH); + } + + // When the SS pin is set as OUTPUT, it can be used as + // a general purpose output port (it doesn't influence + // SPI operations). + pinMode(SS, OUTPUT); + + // Warning: if the SS pin ever becomes a LOW INPUT then SPI + // automatically switches to Slave, so the data direction of + // the SS pin MUST be kept as OUTPUT. + SPCR |= _BV(MSTR); + SPCR |= _BV(SPE); + + // Set direction register for SCK and MOSI pin. + // MISO pin automatically overrides to INPUT. + // By doing this AFTER enabling SPI, we avoid accidentally + // clocking in a single bit since the lines go directly + // from "input" to SPI control. + // http://code.google.com/p/arduino/issues/detail?id=888 + pinMode(SCK, OUTPUT); + pinMode(MOSI, OUTPUT); + } + initialized++; // reference count + SREG = sreg; +} + +void SPIClass::end() { + uint8_t sreg = SREG; + noInterrupts(); // Protect from a scheduler and prevent transactionBegin + // Decrease the reference counter + if (initialized) + initialized--; + // If there are no more references disable SPI + if (!initialized) { + SPCR &= ~_BV(SPE); + interruptMode = 0; + #ifdef SPI_TRANSACTION_MISMATCH_LED + inTransactionFlag = 0; + #endif + } + SREG = sreg; +} + +// mapping of interrupt numbers to bits within SPI_AVR_EIMSK +#if defined(__AVR_ATmega32U4__) + #define SPI_INT0_MASK (1< + * Copyright (c) 2014 by Paul Stoffregen (Transaction API) + * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) + * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) + * SPI Master library for arduino. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either the GNU General Public License version 2 + * or the GNU Lesser General Public License version 2.1, both as + * published by the Free Software Foundation. + */ + +#ifndef _SPI_H_INCLUDED +#define _SPI_H_INCLUDED + +#include + +// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(), +// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode) +#define SPI_HAS_TRANSACTION 1 + +// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method +#define SPI_HAS_NOTUSINGINTERRUPT 1 + +// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version. +// This way when there is a bug fix you can check this define to alert users +// of your code if it uses better version of this library. +// This also implies everything that SPI_HAS_TRANSACTION as documented above is +// available too. +#define SPI_ATOMIC_VERSION 1 + +// Uncomment this line to add detection of mismatched begin/end transactions. +// A mismatch occurs if other libraries fail to use SPI.endTransaction() for +// each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn +// on if any mismatch is ever detected. +//#define SPI_TRANSACTION_MISMATCH_LED 5 + +#ifndef LSBFIRST +#define LSBFIRST 0 +#endif +#ifndef MSBFIRST +#define MSBFIRST 1 +#endif + +#define SPI_CLOCK_DIV4 0x00 +#define SPI_CLOCK_DIV16 0x01 +#define SPI_CLOCK_DIV64 0x02 +#define SPI_CLOCK_DIV128 0x03 +#define SPI_CLOCK_DIV2 0x04 +#define SPI_CLOCK_DIV8 0x05 +#define SPI_CLOCK_DIV32 0x06 + +#define SPI_MODE0 0x00 +#define SPI_MODE1 0x04 +#define SPI_MODE2 0x08 +#define SPI_MODE3 0x0C + +#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR +#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR +#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR + +// define SPI_AVR_EIMSK for AVR boards with external interrupt pins +#if defined(EIMSK) + #define SPI_AVR_EIMSK EIMSK +#elif defined(GICR) + #define SPI_AVR_EIMSK GICR +#elif defined(GIMSK) + #define SPI_AVR_EIMSK GIMSK +#endif + +class SPISettings { +public: + SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { + if (__builtin_constant_p(clock)) { + init_AlwaysInline(clock, bitOrder, dataMode); + } else { + init_MightInline(clock, bitOrder, dataMode); + } + } + SPISettings() { + init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); + } +private: + void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { + init_AlwaysInline(clock, bitOrder, dataMode); + } + void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) + __attribute__((__always_inline__)) { + // Clock settings are defined as follows. Note that this shows SPI2X + // inverted, so the bits form increasing numbers. Also note that + // fosc/64 appears twice + // SPR1 SPR0 ~SPI2X Freq + // 0 0 0 fosc/2 + // 0 0 1 fosc/4 + // 0 1 0 fosc/8 + // 0 1 1 fosc/16 + // 1 0 0 fosc/32 + // 1 0 1 fosc/64 + // 1 1 0 fosc/64 + // 1 1 1 fosc/128 + + // We find the fastest clock that is less than or equal to the + // given clock rate. The clock divider that results in clock_setting + // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the + // slowest (128 == 2 ^^ 7, so clock_div = 6). + uint8_t clockDiv; + + // When the clock is known at compiletime, use this if-then-else + // cascade, which the compiler knows how to completely optimize + // away. When clock is not known, use a loop instead, which generates + // shorter code. + if (__builtin_constant_p(clock)) { + if (clock >= F_CPU / 2) { + clockDiv = 0; + } else if (clock >= F_CPU / 4) { + clockDiv = 1; + } else if (clock >= F_CPU / 8) { + clockDiv = 2; + } else if (clock >= F_CPU / 16) { + clockDiv = 3; + } else if (clock >= F_CPU / 32) { + clockDiv = 4; + } else if (clock >= F_CPU / 64) { + clockDiv = 5; + } else { + clockDiv = 6; + } + } else { + uint32_t clockSetting = F_CPU / 2; + clockDiv = 0; + while (clockDiv < 6 && clock < clockSetting) { + clockSetting /= 2; + clockDiv++; + } + } + + // Compensate for the duplicate fosc/64 + if (clockDiv == 6) + clockDiv = 7; + + // Invert the SPI2X bit + clockDiv ^= 0x1; + + // Pack into the SPISettings class + spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) | + (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK); + spsr = clockDiv & SPI_2XCLOCK_MASK; + } + uint8_t spcr; + uint8_t spsr; + friend class SPIClass; +}; + + +class SPIClass { +public: + // Initialize the SPI library + static void begin(); + + // If SPI is used from within an interrupt, this function registers + // that interrupt with the SPI library, so beginTransaction() can + // prevent conflicts. The input interruptNumber is the number used + // with attachInterrupt. If SPI is used from a different interrupt + // (eg, a timer), interruptNumber should be 255. + static void usingInterrupt(uint8_t interruptNumber); + // And this does the opposite. + static void notUsingInterrupt(uint8_t interruptNumber); + // Note: the usingInterrupt and notUsingInterrupt functions should + // not to be called from ISR context or inside a transaction. + // For details see: + // https://github.com/arduino/Arduino/pull/2381 + // https://github.com/arduino/Arduino/pull/2449 + + // Before using SPI.transfer() or asserting chip select pins, + // this function is used to gain exclusive access to the SPI bus + // and configure the correct settings. + inline static void beginTransaction(SPISettings settings) { + if (interruptMode > 0) { + uint8_t sreg = SREG; + noInterrupts(); + + #ifdef SPI_AVR_EIMSK + if (interruptMode == 1) { + interruptSave = SPI_AVR_EIMSK; + SPI_AVR_EIMSK &= ~interruptMask; + SREG = sreg; + } else + #endif + { + interruptSave = sreg; + } + } + + #ifdef SPI_TRANSACTION_MISMATCH_LED + if (inTransactionFlag) { + pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT); + digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH); + } + inTransactionFlag = 1; + #endif + + SPCR = settings.spcr; + SPSR = settings.spsr; + } + + // Write to the SPI bus (MOSI pin) and also receive (MISO pin) + inline static uint8_t transfer(uint8_t data) { + SPDR = data; + /* + * The following NOP introduces a small delay that can prevent the wait + * loop form iterating when running at the maximum speed. This gives + * about 10% more speed, even if it seems counter-intuitive. At lower + * speeds it is unnoticed. + */ + asm volatile("nop"); + while (!(SPSR & _BV(SPIF))) ; // wait + return SPDR; + } + inline static uint16_t transfer16(uint16_t data) { + union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out; + in.val = data; + if (!(SPCR & _BV(DORD))) { + SPDR = in.msb; + asm volatile("nop"); // See transfer(uint8_t) function + while (!(SPSR & _BV(SPIF))) ; + out.msb = SPDR; + SPDR = in.lsb; + asm volatile("nop"); + while (!(SPSR & _BV(SPIF))) ; + out.lsb = SPDR; + } else { + SPDR = in.lsb; + asm volatile("nop"); + while (!(SPSR & _BV(SPIF))) ; + out.lsb = SPDR; + SPDR = in.msb; + asm volatile("nop"); + while (!(SPSR & _BV(SPIF))) ; + out.msb = SPDR; + } + return out.val; + } + inline static void transfer(void *buf, size_t count) { + if (count == 0) return; + uint8_t *p = (uint8_t *)buf; + SPDR = *p; + while (--count > 0) { + uint8_t out = *(p + 1); + while (!(SPSR & _BV(SPIF))) ; + uint8_t in = SPDR; + SPDR = out; + *p++ = in; + } + while (!(SPSR & _BV(SPIF))) ; + *p = SPDR; + } + // After performing a group of transfers and releasing the chip select + // signal, this function allows others to access the SPI bus + inline static void endTransaction(void) { + #ifdef SPI_TRANSACTION_MISMATCH_LED + if (!inTransactionFlag) { + pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT); + digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH); + } + inTransactionFlag = 0; + #endif + + if (interruptMode > 0) { + #ifdef SPI_AVR_EIMSK + uint8_t sreg = SREG; + #endif + noInterrupts(); + #ifdef SPI_AVR_EIMSK + if (interruptMode == 1) { + SPI_AVR_EIMSK = interruptSave; + SREG = sreg; + } else + #endif + { + SREG = interruptSave; + } + } + } + + // Disable the SPI bus + static void end(); + + // This function is deprecated. New applications should use + // beginTransaction() to configure SPI settings. + inline static void setBitOrder(uint8_t bitOrder) { + if (bitOrder == LSBFIRST) SPCR |= _BV(DORD); + else SPCR &= ~(_BV(DORD)); + } + // This function is deprecated. New applications should use + // beginTransaction() to configure SPI settings. + inline static void setDataMode(uint8_t dataMode) { + SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; + } + // This function is deprecated. New applications should use + // beginTransaction() to configure SPI settings. + inline static void setClockDivider(uint8_t clockDiv) { + SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK); + SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK); + } + // These undocumented functions should not be used. SPI.transfer() + // polls the hardware flag which is automatically cleared as the + // AVR responds to SPI's interrupt + inline static void attachInterrupt() { SPCR |= _BV(SPIE); } + inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); } + +private: + static uint8_t initialized; + static uint8_t interruptMode; // 0=none, 1=mask, 2=global + static uint8_t interruptMask; // which interrupts to mask + static uint8_t interruptSave; // temp storage, to restore state + #ifdef SPI_TRANSACTION_MISMATCH_LED + static uint8_t inTransactionFlag; + #endif +}; + +extern SPIClass SPI; + +#endif diff --git a/hardware/bean/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino b/hardware/bean/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino new file mode 100644 index 0000000..8104fcb --- /dev/null +++ b/hardware/bean/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino @@ -0,0 +1,143 @@ +/* + SCP1000 Barometric Pressure Sensor Display + + Shows the output of a Barometric Pressure Sensor on a + Uses the SPI library. For details on the sensor, see: + http://www.sparkfun.com/commerce/product_info.php?products_id=8161 + http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ + + This sketch adapted from Nathan Seidle's SCP1000 example for PIC: + http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip + + Circuit: + SCP1000 sensor attached to pins 6, 7, 10 - 13: + DRDY: pin 6 + CSB: pin 7 + MOSI: pin 11 + MISO: pin 12 + SCK: pin 13 + + created 31 July 2010 + modified 14 August 2010 + by Tom Igoe + */ + +// the sensor communicates using SPI, so include the library: +#include + +//Sensor's memory register addresses: +const int PRESSURE = 0x1F; //3 most significant bits of pressure +const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure +const int TEMPERATURE = 0x21; //16 bit temperature reading +const byte READ = 0b11111100; // SCP1000's read command +const byte WRITE = 0b00000010; // SCP1000's write command + +// pins used for the connection with the sensor +// the other you need are controlled by the SPI library): +const int dataReadyPin = 6; +const int chipSelectPin = 7; + +void setup() { + Serial.begin(9600); + + // start the SPI library: + SPI.begin(); + + // initalize the data ready and chip select pins: + pinMode(dataReadyPin, INPUT); + pinMode(chipSelectPin, OUTPUT); + + //Configure SCP1000 for low noise configuration: + writeRegister(0x02, 0x2D); + writeRegister(0x01, 0x03); + writeRegister(0x03, 0x02); + // give the sensor time to set up: + delay(100); +} + +void loop() { + //Select High Resolution Mode + writeRegister(0x03, 0x0A); + + // don't do anything until the data ready pin is high: + if (digitalRead(dataReadyPin) == HIGH) { + //Read the temperature data + int tempData = readRegister(0x21, 2); + + // convert the temperature to celsius and display it: + float realTemp = (float)tempData / 20.0; + Serial.print("Temp[C]="); + Serial.print(realTemp); + + + //Read the pressure data highest 3 bits: + byte pressure_data_high = readRegister(0x1F, 1); + pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 + + //Read the pressure data lower 16 bits: + unsigned int pressure_data_low = readRegister(0x20, 2); + //combine the two parts into one 19-bit number: + long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4; + + // display the temperature: + Serial.println("\tPressure [Pa]=" + String(pressure)); + } +} + +//Read from or write to register from the SCP1000: +unsigned int readRegister(byte thisRegister, int bytesToRead ) { + byte inByte = 0; // incoming byte from the SPI + unsigned int result = 0; // result to return + Serial.print(thisRegister, BIN); + Serial.print("\t"); + // SCP1000 expects the register name in the upper 6 bits + // of the byte. So shift the bits left by two bits: + thisRegister = thisRegister << 2; + // now combine the address and the command into one byte + byte dataToSend = thisRegister & READ; + Serial.println(thisRegister, BIN); + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + // send the device the register you want to read: + SPI.transfer(dataToSend); + // send a value of 0 to read the first byte returned: + result = SPI.transfer(0x00); + // decrement the number of bytes left to read: + bytesToRead--; + // if you still have another byte to read: + if (bytesToRead > 0) { + // shift the first byte left, then get the second byte: + result = result << 8; + inByte = SPI.transfer(0x00); + // combine the byte you just got with the previous one: + result = result | inByte; + // decrement the number of bytes left to read: + bytesToRead--; + } + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); + // return the result: + return(result); +} + + +//Sends a write command to SCP1000 + +void writeRegister(byte thisRegister, byte thisValue) { + + // SCP1000 expects the register address in the upper 6 bits + // of the byte. So shift the bits left by two bits: + thisRegister = thisRegister << 2; + // now combine the register address and the command into one byte: + byte dataToSend = thisRegister | WRITE; + + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + + SPI.transfer(dataToSend); //Send register location + SPI.transfer(thisValue); //Send value to record into register + + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); +} + diff --git a/hardware/bean/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino b/hardware/bean/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino new file mode 100644 index 0000000..b135a74 --- /dev/null +++ b/hardware/bean/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino @@ -0,0 +1,71 @@ +/* + Digital Pot Control + + This example controls an Analog Devices AD5206 digital potentiometer. + The AD5206 has 6 potentiometer channels. Each channel's pins are labeled + A - connect this to voltage + W - this is the pot's wiper, which changes when you set it + B - connect this to ground. + + The AD5206 is SPI-compatible,and to command it, you send two bytes, + one with the channel number (0 - 5) and one with the resistance value for the + channel (0 - 255). + + The circuit: + * All A pins of AD5206 connected to +5V + * All B pins of AD5206 connected to ground + * An LED and a 220-ohm resisor in series connected from each W pin to ground + * CS - to digital pin 10 (SS pin) + * SDI - to digital pin 11 (MOSI pin) + * CLK - to digital pin 13 (SCK pin) + + created 10 Aug 2010 + by Tom Igoe + + Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 + +*/ + + +// inslude the SPI library: +#include + + +// set pin 10 as the slave select for the digital pot: +const int slaveSelectPin = 10; + +void setup() { + // set the slaveSelectPin as an output: + pinMode (slaveSelectPin, OUTPUT); + // initialize SPI: + SPI.begin(); +} + +void loop() { + // go through the six channels of the digital pot: + for (int channel = 0; channel < 6; channel++) { + // change the resistance on this channel from min to max: + for (int level = 0; level < 255; level++) { + digitalPotWrite(channel, level); + delay(10); + } + // wait a second at the top: + delay(100); + // change the resistance on this channel from max to min: + for (int level = 0; level < 255; level++) { + digitalPotWrite(channel, 255 - level); + delay(10); + } + } + +} + +void digitalPotWrite(int address, int value) { + // take the SS pin low to select the chip: + digitalWrite(slaveSelectPin, LOW); + // send in the address and value via SPI: + SPI.transfer(address); + SPI.transfer(value); + // take the SS pin high to de-select the chip: + digitalWrite(slaveSelectPin, HIGH); +} diff --git a/hardware/bean/avr/libraries/SPI/keywords.txt b/hardware/bean/avr/libraries/SPI/keywords.txt new file mode 100644 index 0000000..fa76165 --- /dev/null +++ b/hardware/bean/avr/libraries/SPI/keywords.txt @@ -0,0 +1,36 @@ +####################################### +# Syntax Coloring Map SPI +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +SPI KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +end KEYWORD2 +transfer KEYWORD2 +setBitOrder KEYWORD2 +setDataMode KEYWORD2 +setClockDivider KEYWORD2 + + +####################################### +# Constants (LITERAL1) +####################################### +SPI_CLOCK_DIV4 LITERAL1 +SPI_CLOCK_DIV16 LITERAL1 +SPI_CLOCK_DIV64 LITERAL1 +SPI_CLOCK_DIV128 LITERAL1 +SPI_CLOCK_DIV2 LITERAL1 +SPI_CLOCK_DIV8 LITERAL1 +SPI_CLOCK_DIV32 LITERAL1 +SPI_CLOCK_DIV64 LITERAL1 +SPI_MODE0 LITERAL1 +SPI_MODE1 LITERAL1 +SPI_MODE2 LITERAL1 +SPI_MODE3 LITERAL1 \ No newline at end of file diff --git a/hardware/bean/avr/libraries/SPI/library.properties b/hardware/bean/avr/libraries/SPI/library.properties new file mode 100644 index 0000000..d132fa9 --- /dev/null +++ b/hardware/bean/avr/libraries/SPI/library.properties @@ -0,0 +1,10 @@ +name=SPI +version=1.0 +author=Arduino +maintainer=Arduino +sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE. +paragraph= +url=http://arduino.cc/en/Reference/SPI +architectures=avr +types=Arduino +category=Communication diff --git a/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.cpp b/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.cpp new file mode 100644 index 0000000..b4e4529 --- /dev/null +++ b/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.cpp @@ -0,0 +1,490 @@ +/* +SoftwareSerial.cpp (formerly NewSoftSerial.cpp) - +Multi-instance software serial library for Arduino/Wiring +-- Interrupt-driven receive and other improvements by ladyada + (http://ladyada.net) +-- Tuning, circular buffer, derivation from class Print/Stream, + multi-instance support, porting to 8MHz processors, + various optimizations, PROGMEM delay tables, inverse logic and + direct port writing by Mikal Hart (http://www.arduiniana.org) +-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) +-- 20MHz processor support by Garrett Mace (http://www.macetech.com) +-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.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 + +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 +#include +#include +#include +#include + +// +// Statics +// +SoftwareSerial *SoftwareSerial::active_object = 0; +char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF]; +volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0; +volatile uint8_t SoftwareSerial::_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 SoftwareSerial::tunedDelay(uint16_t delay) { + _delay_loop_2(delay); +} + +// This function sets the current object as the "listening" +// one and returns true if it replaces another +bool SoftwareSerial::listen() +{ + if (!_rx_delay_stopbit) + return false; + + if (active_object != this) + { + if (active_object) + active_object->stopListening(); + + _buffer_overflow = false; + _receive_buffer_head = _receive_buffer_tail = 0; + active_object = this; + + setRxIntMsk(true); + return true; + } + + return false; +} + +// Stop listening. Returns true if we were actually listening. +bool SoftwareSerial::stopListening() +{ + if (active_object == this) + { + setRxIntMsk(false); + active_object = NULL; + return true; + } + return false; +} + +// +// The receive routine called by the interrupt handler +// +void SoftwareSerial::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()) + { + // Disable further interrupts during reception, this prevents + // triggering another interrupt directly after we return, which can + // cause problems at higher baudrates. + setRxIntMsk(false); + + // 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=8; i > 0; --i) + { + tunedDelay(_rx_delay_intrabit); + d >>= 1; + DebugPulse(_DEBUG_PIN2, 1); + if (rx_pin_read()) + d |= 0x80; + } + + if (_inverse_logic) + d = ~d; + + // if buffer full, set the overflow flag and return + uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF; + if (next != _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 = next; + } + else + { + DebugPulse(_DEBUG_PIN1, 1); + _buffer_overflow = true; + } + + // skip the stop bit + tunedDelay(_rx_delay_stopbit); + DebugPulse(_DEBUG_PIN1, 1); + + // Re-enable interrupts when we're sure to be inside the stop bit + setRxIntMsk(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 +} + +uint8_t SoftwareSerial::rx_pin_read() +{ + return *_receivePortRegister & _receiveBitMask; +} + +// +// Interrupt handling +// + +/* static */ +inline void SoftwareSerial::handle_interrupt() +{ + if (active_object) + { + active_object->recv(); + } +} + +#if defined(PCINT0_vect) +ISR(PCINT0_vect) +{ + SoftwareSerial::handle_interrupt(); +} +#endif + +#if defined(PCINT1_vect) +ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect)); +#endif + +#if defined(PCINT2_vect) +ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect)); +#endif + +#if defined(PCINT3_vect) +ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect)); +#endif + +// +// Constructor +// +SoftwareSerial::SoftwareSerial(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 +// +SoftwareSerial::~SoftwareSerial() +{ + end(); +} + +void SoftwareSerial::setTX(uint8_t tx) +{ + // First write, then set output. If we do this the other way around, + // the pin would be output low for a short while before switching to + // output hihg. Now, it is input with pullup for a short while, which + // is fine. With inverse logic, either order is fine. + digitalWrite(tx, _inverse_logic ? LOW : HIGH); + pinMode(tx, OUTPUT); + _transmitBitMask = digitalPinToBitMask(tx); + uint8_t port = digitalPinToPort(tx); + _transmitPortRegister = portOutputRegister(port); +} + +void SoftwareSerial::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); +} + +uint16_t SoftwareSerial::subtract_cap(uint16_t num, uint16_t sub) { + if (num > sub) + return num - sub; + else + return 1; +} + +// +// Public methods +// + +void SoftwareSerial::begin(long speed) +{ + _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0; + + // Precalculate the various delays, in number of 4-cycle delays + uint16_t bit_delay = (F_CPU / speed) / 4; + + // 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit, + // 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits, + // 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit + // These are all close enough to just use 15 cycles, since the inter-bit + // timings are the most critical (deviations stack 8 times) + _tx_delay = subtract_cap(bit_delay, 15 / 4); + + // Only setup rx when we have a valid PCINT for this pin + if (digitalPinToPCICR(_receivePin)) { + #if GCC_VERSION > 40800 + // Timings counted from gcc 4.8.2 output. This works up to 115200 on + // 16Mhz and 57600 on 8Mhz. + // + // When the start bit occurs, there are 3 or 4 cycles before the + // interrupt flag is set, 4 cycles before the PC is set to the right + // interrupt vector address and the old PC is pushed on the stack, + // and then 75 cycles of instructions (including the RJMP in the + // ISR vector table) until the first delay. After the delay, there + // are 17 more cycles until the pin value is read (excluding the + // delay in the loop). + // We want to have a total delay of 1.5 bit time. Inside the loop, + // we already wait for 1 bit time - 23 cycles, so here we wait for + // 0.5 bit time - (71 + 18 - 22) cycles. + _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4); + + // There are 23 cycles in each loop iteration (excluding the delay) + _rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4); + + // There are 37 cycles from the last bit read to the start of + // stopbit delay and 11 cycles from the delay until the interrupt + // mask is enabled again (which _must_ happen during the stopbit). + // This delay aims at 3/4 of a bit time, meaning the end of the + // delay will be at 1/4th of the stopbit. This allows some extra + // time for ISR cleanup, which makes 115200 baud at 16Mhz work more + // reliably + _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4); + #else // Timings counted from gcc 4.3.2 output + // Note that this code is a _lot_ slower, mostly due to bad register + // allocation choices of gcc. This works up to 57600 on 16Mhz and + // 38400 on 8Mhz. + _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4); + _rx_delay_intrabit = subtract_cap(bit_delay, 11 / 4); + _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4); + #endif + + + // Enable the PCINT for the entire port here, but never disable it + // (others might also need it, so we disable the interrupt by using + // the per-pin PCMSK register). + *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin)); + // Precalculate the pcint mask register and value, so setRxIntMask + // can be used inside the ISR without costing too much time. + _pcint_maskreg = digitalPinToPCMSK(_receivePin); + _pcint_maskvalue = _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 + + listen(); +} + +void SoftwareSerial::setRxIntMsk(bool enable) +{ + if (enable) + *_pcint_maskreg |= _pcint_maskvalue; + else + *_pcint_maskreg &= ~_pcint_maskvalue; +} + +void SoftwareSerial::end() +{ + stopListening(); +} + + +// Read data from buffer +int SoftwareSerial::read() +{ + if (!isListening()) + return -1; + + // Empty buffer? + if (_receive_buffer_head == _receive_buffer_tail) + return -1; + + // Read from "head" + uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte + _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF; + return d; +} + +int SoftwareSerial::available() +{ + if (!isListening()) + return 0; + + return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF; +} + +size_t SoftwareSerial::write(uint8_t b) +{ + if (_tx_delay == 0) { + setWriteError(); + return 0; + } + + // By declaring these as local variables, the compiler will put them + // in registers _before_ disabling interrupts and entering the + // critical timing sections below, which makes it a lot easier to + // verify the cycle timings + volatile uint8_t *reg = _transmitPortRegister; + uint8_t reg_mask = _transmitBitMask; + uint8_t inv_mask = ~_transmitBitMask; + uint8_t oldSREG = SREG; + bool inv = _inverse_logic; + uint16_t delay = _tx_delay; + + if (inv) + b = ~b; + + cli(); // turn off interrupts for a clean txmit + + // Write the start bit + if (inv) + *reg |= reg_mask; + else + *reg &= inv_mask; + + tunedDelay(delay); + + // Write each of the 8 bits + for (uint8_t i = 8; i > 0; --i) + { + if (b & 1) // choose bit + *reg |= reg_mask; // send 1 + else + *reg &= inv_mask; // send 0 + + tunedDelay(delay); + b >>= 1; + } + + // restore pin to natural state + if (inv) + *reg &= inv_mask; + else + *reg |= reg_mask; + + SREG = oldSREG; // turn interrupts back on + tunedDelay(_tx_delay); + + return 1; +} + +void SoftwareSerial::flush() +{ + if (!isListening()) + return; + + uint8_t oldSREG = SREG; + cli(); + _receive_buffer_head = _receive_buffer_tail = 0; + SREG = oldSREG; +} + +int SoftwareSerial::peek() +{ + if (!isListening()) + return -1; + + // Empty buffer? + if (_receive_buffer_head == _receive_buffer_tail) + return -1; + + // Read from "head" + return _receive_buffer[_receive_buffer_head]; +} diff --git a/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.h b/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.h new file mode 100644 index 0000000..680e40d --- /dev/null +++ b/hardware/bean/avr/libraries/SoftwareSerial/SoftwareSerial.h @@ -0,0 +1,121 @@ +/* +SoftwareSerial.h (formerly NewSoftSerial.h) - +Multi-instance software serial library for Arduino/Wiring +-- Interrupt-driven receive and other improvements by ladyada + (http://ladyada.net) +-- Tuning, circular buffer, derivation from class Print/Stream, + multi-instance support, porting to 8MHz processors, + various optimizations, PROGMEM delay tables, inverse logic and + direct port writing by Mikal Hart (http://www.arduiniana.org) +-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) +-- 20MHz processor support by Garrett Mace (http://www.macetech.com) +-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.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 + +The latest version of this library can always be found at +http://arduiniana.org. +*/ + +#ifndef SoftwareSerial_h +#define SoftwareSerial_h + +#include +#include + +/****************************************************************************** +* Definitions +******************************************************************************/ + +#define _SS_MAX_RX_BUFF 64 // RX buffer size +#ifndef GCC_VERSION +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +class SoftwareSerial : public Stream +{ +private: + // per object data + uint8_t _receivePin; + uint8_t _receiveBitMask; + volatile uint8_t *_receivePortRegister; + uint8_t _transmitBitMask; + volatile uint8_t *_transmitPortRegister; + volatile uint8_t *_pcint_maskreg; + uint8_t _pcint_maskvalue; + + // Expressed as 4-cycle delays (must never be 0!) + 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[_SS_MAX_RX_BUFF]; + static volatile uint8_t _receive_buffer_tail; + static volatile uint8_t _receive_buffer_head; + static SoftwareSerial *active_object; + + // private methods + void recv() __attribute__((__always_inline__)); + uint8_t rx_pin_read(); + void tx_pin_write(uint8_t pin_state) __attribute__((__always_inline__)); + void setTX(uint8_t transmitPin); + void setRX(uint8_t receivePin); + void setRxIntMsk(bool enable) __attribute__((__always_inline__)); + + // Return num - sub, or 1 if the result would be < 1 + static uint16_t subtract_cap(uint16_t num, uint16_t sub); + + // private static method for timing + static inline void tunedDelay(uint16_t delay); + +public: + // public methods + SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false); + ~SoftwareSerial(); + void begin(long speed); + bool listen(); + void end(); + bool isListening() { return this == active_object; } + bool stopListening(); + bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; } + int peek(); + + virtual size_t write(uint8_t byte); + virtual int read(); + virtual int available(); + virtual void flush(); + operator bool() { return true; } + + using Print::write; + + // public only for easy access by interrupt handlers + static inline void handle_interrupt() __attribute__((__always_inline__)); +}; + +// Arduino 0012 workaround +#undef int +#undef char +#undef long +#undef byte +#undef float +#undef abs +#undef round + +#endif diff --git a/hardware/bean/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino b/hardware/bean/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino new file mode 100644 index 0000000..f659133 --- /dev/null +++ b/hardware/bean/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino @@ -0,0 +1,55 @@ +/* + Software serial multple serial test + + Receives from the hardware serial, sends to software serial. + Receives from software serial, sends to hardware serial. + + The circuit: + * RX is digital pin 10 (connect to TX of other device) + * TX is digital pin 11 (connect to RX of other device) + + Note: + Not all pins on the Mega and Mega 2560 support change interrupts, + so only the following can be used for RX: + 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 + + Not all pins on the Leonardo support change interrupts, + so only the following can be used for RX: + 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). + + created back in the mists of time + modified 25 May 2012 + by Tom Igoe + based on Mikal Hart's example + + This example code is in the public domain. + + */ +#include + +SoftwareSerial mySerial(10, 11); // RX, TX + +void setup() +{ + // Open serial communications and wait for port to open: + Serial.begin(57600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + Serial.println("Goodnight moon!"); + + // set the data rate for the SoftwareSerial port + mySerial.begin(4800); + mySerial.println("Hello, world?"); +} + +void loop() // run over and over +{ + if (mySerial.available()) + Serial.write(mySerial.read()); + if (Serial.available()) + mySerial.write(Serial.read()); +} + diff --git a/hardware/bean/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino b/hardware/bean/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino new file mode 100644 index 0000000..95881a6 --- /dev/null +++ b/hardware/bean/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino @@ -0,0 +1,93 @@ +/* + Software serial multple serial test + + Receives from the two software serial ports, + sends to the hardware serial port. + + In order to listen on a software port, you call port.listen(). + When using two software serial ports, you have to switch ports + by listen()ing on each one in turn. Pick a logical time to switch + ports, like the end of an expected transmission, or when the + buffer is empty. This example switches ports when there is nothing + more to read from a port + + The circuit: + Two devices which communicate serially are needed. + * First serial device's TX attached to digital pin 2, RX to pin 3 + * Second serial device's TX attached to digital pin 4, RX to pin 5 + + Note: + Not all pins on the Mega and Mega 2560 support change interrupts, + so only the following can be used for RX: + 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 + + Not all pins on the Leonardo support change interrupts, + so only the following can be used for RX: + 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). + + created 18 Apr. 2011 + modified 25 May 2012 + by Tom Igoe + based on Mikal Hart's twoPortRXExample + + This example code is in the public domain. + + */ + +#include +// software serial #1: TX = digital pin 10, RX = digital pin 11 +SoftwareSerial portOne(10, 11); + +// software serial #2: TX = digital pin 8, RX = digital pin 9 +// on the Mega, use other pins instead, since 8 and 9 don't work on the Mega +SoftwareSerial portTwo(8, 9); + +void setup() +{ + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + // Start each software serial port + portOne.begin(9600); + portTwo.begin(9600); +} + +void loop() +{ + // By default, the last intialized port is listening. + // when you want to listen on a port, explicitly select it: + portOne.listen(); + Serial.println("Data from port one:"); + // while there is data coming in, read it + // and send to the hardware serial port: + while (portOne.available() > 0) { + char inByte = portOne.read(); + Serial.write(inByte); + } + + // blank line to separate data from the two ports: + Serial.println(); + + // Now listen on the second port + portTwo.listen(); + // while there is data coming in, read it + // and send to the hardware serial port: + Serial.println("Data from port two:"); + while (portTwo.available() > 0) { + char inByte = portTwo.read(); + Serial.write(inByte); + } + + // blank line to separate data from the two ports: + Serial.println(); +} + + + + + + diff --git a/hardware/bean/avr/libraries/SoftwareSerial/keywords.txt b/hardware/bean/avr/libraries/SoftwareSerial/keywords.txt new file mode 100644 index 0000000..aaea17c --- /dev/null +++ b/hardware/bean/avr/libraries/SoftwareSerial/keywords.txt @@ -0,0 +1,30 @@ +####################################### +# Syntax Coloring Map for SoftwareSerial +# (formerly NewSoftSerial) +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +SoftwareSerial KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +end KEYWORD2 +read KEYWORD2 +write KEYWORD2 +available KEYWORD2 +isListening KEYWORD2 +overflow KEYWORD2 +flush KEYWORD2 +listen KEYWORD2 +peek KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/hardware/bean/avr/libraries/SoftwareSerial/library.properties b/hardware/bean/avr/libraries/SoftwareSerial/library.properties new file mode 100644 index 0000000..463bf8a --- /dev/null +++ b/hardware/bean/avr/libraries/SoftwareSerial/library.properties @@ -0,0 +1,10 @@ +name=SoftwareSerial +version=1.0 +author=Arduino +maintainer=Arduino +sentence=Enables serial communication on digital pins. For all Arduino boards, BUT Arduino DUE. +paragraph= +url=http://arduino.cc/en/Reference/SoftwareSerial +architectures=avr +types=Arduino +category=Communication diff --git a/hardware/bean/avr/libraries/Wire/Wire.cpp b/hardware/bean/avr/libraries/Wire/Wire.cpp new file mode 100644 index 0000000..553add7 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/Wire.cpp @@ -0,0 +1,303 @@ +/* + 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 + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts +*/ + +extern "C" { + #include + #include + #include + #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); +} + +void TwoWire::setClock(uint32_t frequency) +{ + TWBR = ((F_CPU / frequency) - 16) / 2; +} + +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) +{ + // clamp to buffer length + if(quantity > BUFFER_LENGTH){ + quantity = BUFFER_LENGTH; + } + // perform blocking read into buffer + uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop); + // set rx buffer iterator vars + rxBufferIndex = 0; + rxBufferLength = read; + + return read; +} + +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); +} + +uint8_t TwoWire::requestFrom(int address, int quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); +} + +uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); +} + +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); +} + +// +// Originally, 'endTransmission' was an f(void) function. +// It has been modified to take one parameter indicating +// whether or not a STOP should be performed on the bus. +// Calling endTransmission(false) allows a sketch to +// perform a repeated start. +// +// WARNING: Nothing in the library keeps track of whether +// the bus tenure has been properly ended with a STOP. It +// is very possible to leave the bus in a hung state if +// no call to endTransmission(true) is made. Some I2C +// devices will behave oddly if they do not see a STOP. +// +uint8_t TwoWire::endTransmission(uint8_t sendStop) +{ + // transmit buffer (blocking) + int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop); + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; + // indicate that we are done transmitting + transmitting = 0; + return ret; +} + +// This provides backwards compatibility with the original +// definition, and expected behaviour, of endTransmission +// +uint8_t TwoWire::endTransmission(void) +{ + return endTransmission(true); +} + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +size_t TwoWire::write(uint8_t data) +{ + if(transmitting){ + // in master transmitter mode + // don't bother if buffer is full + if(txBufferLength >= BUFFER_LENGTH){ + setWriteError(); + return 0; + } + // 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); + } + return 1; +} + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +size_t TwoWire::write(const uint8_t *data, size_t quantity) +{ + if(transmitting){ + // in master transmitter mode + for(size_t i = 0; i < quantity; ++i){ + write(data[i]); + } + }else{ + // in slave send mode + // reply to master + twi_transmit(data, quantity); + } + return quantity; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::available(void) +{ + return rxBufferLength - rxBufferIndex; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::read(void) +{ + int value = -1; + + // get each successive byte on each call + if(rxBufferIndex < rxBufferLength){ + value = rxBuffer[rxBufferIndex]; + ++rxBufferIndex; + } + + return value; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::peek(void) +{ + int value = -1; + + if(rxBufferIndex < rxBufferLength){ + value = rxBuffer[rxBufferIndex]; + } + + return value; +} + +void TwoWire::flush(void) +{ + // XXX: to be implemented. +} + +// 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/hardware/bean/avr/libraries/Wire/Wire.h b/hardware/bean/avr/libraries/Wire/Wire.h new file mode 100644 index 0000000..732bdc3 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/Wire.h @@ -0,0 +1,80 @@ +/* + 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 + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts +*/ + +#ifndef TwoWire_h +#define TwoWire_h + +#include +#include "Stream.h" + +#define BUFFER_LENGTH 32 + +class TwoWire : public Stream +{ + 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 setClock(uint32_t); + void beginTransmission(uint8_t); + void beginTransmission(int); + uint8_t endTransmission(void); + uint8_t endTransmission(uint8_t); + uint8_t requestFrom(uint8_t, uint8_t); + uint8_t requestFrom(uint8_t, uint8_t, uint8_t); + uint8_t requestFrom(int, int); + uint8_t requestFrom(int, int, int); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *, size_t); + virtual int available(void); + virtual int read(void); + virtual int peek(void); + virtual void flush(void); + void onReceive( void (*)(int) ); + void onRequest( void (*)(void) ); + + 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; +}; + +extern TwoWire Wire; + +#endif + diff --git a/hardware/bean/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino b/hardware/bean/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino new file mode 100644 index 0000000..d97a9e3 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino @@ -0,0 +1,87 @@ +// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder +// by Nicholas Zambetti +// and James Tichenor + +// Demonstrates use of the Wire library reading data from the +// Devantech Utrasonic Rangers SFR08 and SFR10 + +// Created 29 April 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) + Serial.begin(9600); // start serial communication at 9600bps +} + +int reading = 0; + +void loop() +{ + // step 1: instruct sensor to read echoes + Wire.beginTransmission(112); // transmit to device #112 (0x70) + // the address specified in the datasheet is 224 (0xE0) + // but i2c adressing uses the high 7 bits so it's 112 + Wire.write(byte(0x00)); // sets register pointer to the command register (0x00) + Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50) + // use 0x51 for centimeters + // use 0x52 for ping microseconds + Wire.endTransmission(); // stop transmitting + + // step 2: wait for readings to happen + delay(70); // datasheet suggests at least 65 milliseconds + + // step 3: instruct sensor to return a particular echo reading + Wire.beginTransmission(112); // transmit to device #112 + Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02) + Wire.endTransmission(); // stop transmitting + + // step 4: request reading from sensor + Wire.requestFrom(112, 2); // request 2 bytes from slave device #112 + + // step 5: receive reading from sensor + if (2 <= Wire.available()) // if two bytes were received + { + reading = Wire.read(); // receive high byte (overwrites previous reading) + reading = reading << 8; // shift high byte to be high 8 bits + reading |= Wire.read(); // receive low byte as lower 8 bits + Serial.println(reading); // print the reading + } + + delay(250); // wait a bit since people have to read the output :) +} + + +/* + +// The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08) +// usage: changeAddress(0x70, 0xE6); + +void changeAddress(byte oldAddress, byte newAddress) +{ + Wire.beginTransmission(oldAddress); + Wire.write(byte(0x00)); + Wire.write(byte(0xA0)); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.write(byte(0x00)); + Wire.write(byte(0xAA)); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.write(byte(0x00)); + Wire.write(byte(0xA5)); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.write(byte(0x00)); + Wire.write(newAddress); + Wire.endTransmission(); +} + +*/ diff --git a/hardware/bean/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino b/hardware/bean/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino new file mode 100644 index 0000000..4d1580a --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino @@ -0,0 +1,39 @@ +// I2C Digital Potentiometer +// by Nicholas Zambetti +// and Shawn Bonkowski + +// Demonstrates use of the Wire library +// Controls AD5171 digital potentiometer via I2C/TWI + +// Created 31 March 2006 + +// This example code is in the public domain. + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) +} + +byte val = 0; + +void loop() +{ + Wire.beginTransmission(44); // transmit to device #44 (0x2c) + // device address is specified in datasheet + Wire.write(byte(0x00)); // sends instruction byte + Wire.write(val); // sends potentiometer value byte + Wire.endTransmission(); // stop transmitting + + val++; // increment value + if (val == 64) // if reached 64th position (max) + { + val = 0; // start over from lowest value + } + delay(500); +} + diff --git a/hardware/bean/avr/libraries/Wire/examples/master_reader/master_reader.ino b/hardware/bean/avr/libraries/Wire/examples/master_reader/master_reader.ino new file mode 100644 index 0000000..74f0155 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/examples/master_reader/master_reader.ino @@ -0,0 +1,32 @@ +// Wire Master Reader +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Reads data from an I2C/TWI slave device +// Refer to the "Wire Slave Sender" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) + Serial.begin(9600); // start serial for output +} + +void loop() +{ + Wire.requestFrom(2, 6); // request 6 bytes from slave device #2 + + while (Wire.available()) // slave may send less than requested + { + char c = Wire.read(); // receive a byte as character + Serial.print(c); // print the character + } + + delay(500); +} diff --git a/hardware/bean/avr/libraries/Wire/examples/master_writer/master_writer.ino b/hardware/bean/avr/libraries/Wire/examples/master_writer/master_writer.ino new file mode 100644 index 0000000..482e922 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/examples/master_writer/master_writer.ino @@ -0,0 +1,31 @@ +// Wire Master Writer +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Writes data to an I2C/TWI slave device +// Refer to the "Wire Slave Receiver" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) +} + +byte x = 0; + +void loop() +{ + Wire.beginTransmission(4); // transmit to device #4 + Wire.write("x is "); // sends five bytes + Wire.write(x); // sends one byte + Wire.endTransmission(); // stop transmitting + + x++; + delay(500); +} diff --git a/hardware/bean/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino b/hardware/bean/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino new file mode 100644 index 0000000..15eff9a --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino @@ -0,0 +1,38 @@ +// Wire Slave Receiver +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Receives data as an I2C/TWI slave device +// Refer to the "Wire Master Writer" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(4); // join i2c bus with address #4 + Wire.onReceive(receiveEvent); // register event + Serial.begin(9600); // start serial for output +} + +void loop() +{ + delay(100); +} + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +void receiveEvent(int howMany) +{ + while (1 < Wire.available()) // loop through all but the last + { + char c = Wire.read(); // receive byte as a character + Serial.print(c); // print the character + } + int x = Wire.read(); // receive byte as an integer + Serial.println(x); // print the integer +} diff --git a/hardware/bean/avr/libraries/Wire/examples/slave_sender/slave_sender.ino b/hardware/bean/avr/libraries/Wire/examples/slave_sender/slave_sender.ino new file mode 100644 index 0000000..4437ab1 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/examples/slave_sender/slave_sender.ino @@ -0,0 +1,32 @@ +// Wire Slave Sender +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Sends data as an I2C/TWI slave device +// Refer to the "Wire Master Reader" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(2); // join i2c bus with address #2 + Wire.onRequest(requestEvent); // register event +} + +void loop() +{ + delay(100); +} + +// function that executes whenever data is requested by master +// this function is registered as an event, see setup() +void requestEvent() +{ + Wire.write("hello "); // respond with message of 6 bytes + // as expected by master +} diff --git a/hardware/bean/avr/libraries/Wire/keywords.txt b/hardware/bean/avr/libraries/Wire/keywords.txt new file mode 100644 index 0000000..ff31475 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/keywords.txt @@ -0,0 +1,32 @@ +####################################### +# Syntax Coloring Map For Wire +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +setClock KEYWORD2 +beginTransmission KEYWORD2 +endTransmission KEYWORD2 +requestFrom KEYWORD2 +send KEYWORD2 +receive KEYWORD2 +onReceive KEYWORD2 +onRequest KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +Wire KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/hardware/bean/avr/libraries/Wire/library.properties b/hardware/bean/avr/libraries/Wire/library.properties new file mode 100644 index 0000000..0f1e796 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/library.properties @@ -0,0 +1,10 @@ +name=Wire +version=1.0 +author=Arduino +maintainer=Arduino +sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. For all Arduino boards, BUT Arduino DUE. +paragraph= +url=http://arduino.cc/en/Reference/Wire +architectures=avr +types=Arduino +category=Communication diff --git a/hardware/bean/avr/libraries/Wire/utility/twi.c b/hardware/bean/avr/libraries/Wire/utility/twi.c new file mode 100644 index 0000000..201d7d1 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/utility/twi.c @@ -0,0 +1,527 @@ +/* + 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 + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts +*/ + +#include +#include +#include +#include +#include +#include +#include "Arduino.h" // for digitalWrite + +#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 "pins_arduino.h" +#include "twi.h" + +static volatile uint8_t twi_state; +static volatile uint8_t twi_slarw; +static volatile uint8_t twi_sendStop; // should the transaction end with a stop +static volatile uint8_t twi_inRepStart; // in the middle of a repeated start + +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 volatile 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; + twi_sendStop = true; // default value + twi_inRepStart = false; + + // activate internal pullups for twi. + digitalWrite(SDA, 1); + digitalWrite(SCL, 1); + + // initialize twi prescaler and bit rate + cbi(TWSR, TWPS0); + cbi(TWSR, TWPS1); + TWBR = ((F_CPU / 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 + * sendStop: Boolean indicating whether to send a stop at the end + * Output number of bytes read + */ +uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) +{ + 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; + twi_sendStop = sendStop; + // 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; + + if (true == twi_inRepStart) { + // if we're in the repeated start state, then we've already sent the start, + // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. + // We need to remove ourselves from the repeated start state before we enable interrupts, + // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning + // up. Also, don't enable the START interrupt. There may be one pending from the + // repeated start that we sent outselves, and that would really confuse things. + twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR + TWDR = twi_slarw; + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START + } + else + // 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 + * sendStop: boolean indicating whether or not to send a stop at the end + * 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 sendStop) +{ + 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; + twi_sendStop = sendStop; + // 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; + + // if we're in a repeated start, then we've already sent the START + // in the ISR. Don't do it again. + // + if (true == twi_inRepStart) { + // if we're in the repeated start state, then we've already sent the start, + // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. + // We need to remove ourselves from the repeated start state before we enable interrupts, + // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning + // up. Also, don't enable the START interrupt. There may be one pending from the + // repeated start that we sent outselves, and that would really confuse things. + twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR + TWDR = twi_slarw; + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START + } + else + // send start condition + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs + + // 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(const 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; +} + +ISR(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{ + if (twi_sendStop) + twi_stop(); + else { + twi_inRepStart = true; // we're gonna send the START + // don't enable the interrupt. We'll generate the start, but we + // avoid handling the interrupt until we're in the next transaction, + // at the point where we would normally issue the start. + TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; + twi_state = TWI_READY; + } + } + 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; + if (twi_sendStop) + twi_stop(); + else { + twi_inRepStart = true; // we're gonna send the START + // don't enable the interrupt. We'll generate the start, but we + // avoid handling the interrupt until we're in the next transaction, + // at the point where we would normally issue the start. + TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; + twi_state = TWI_READY; + } + break; + 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/hardware/bean/avr/libraries/Wire/utility/twi.h b/hardware/bean/avr/libraries/Wire/utility/twi.h new file mode 100644 index 0000000..6526593 --- /dev/null +++ b/hardware/bean/avr/libraries/Wire/utility/twi.h @@ -0,0 +1,53 @@ +/* + 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 + + //#define ATMEGA8 + + #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); + uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); + uint8_t twi_transmit(const 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 + From c86d30f00c553a8681d99b7848baeb88d655202e Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Fri, 21 Oct 2016 15:09:36 -0500 Subject: [PATCH 09/13] test: update include_libraries test sketch --- resources/test_sketches/include_libraries.ino | 7 ------- 1 file changed, 7 deletions(-) diff --git a/resources/test_sketches/include_libraries.ino b/resources/test_sketches/include_libraries.ino index eb00bff..9972e40 100644 --- a/resources/test_sketches/include_libraries.ino +++ b/resources/test_sketches/include_libraries.ino @@ -1,13 +1,6 @@ -#include -#include -#include #include -#include #include -#include -#include #include -#include #include #include From 4d42e8c5a1ceca55a7ae2a3592bec63448623780 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Sun, 23 Oct 2016 19:26:25 -0500 Subject: [PATCH 10/13] lib: fix example in PinChangeInt --- .../PinChangeInt/Examples/ByteBuffer/ByteBuffer.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h b/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h index 3c276b6..55ba30d 100755 --- a/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h +++ b/hardware/bean/avr/libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h @@ -1,3 +1,4 @@ + /* ByteBuffer.h - A circular buffer implementation for Arduino Created by Sigurdur Orn, July 19, 2010. siggi@mit.edu @@ -65,7 +66,9 @@ class ByteBuffer // uint8_t putInFront(byte in); uint8_t put(byte in); - uint8_t putString(char *in); + + uint8_t putString(const char *in); + uint8_t putString(char *in); void putIntInFront(int in); void putInt(int in); @@ -76,7 +79,10 @@ class ByteBuffer void putFloatInFront(float in); void putFloat(float in); - void putHex(uint8_t theByte); + void putHex(uint8_t); + + void putDec(uint8_t); + void putDec(int8_t); // // Get methods, either a regular get from front or from back From 3cc9f5d3558efee714cf43db3b90d6db832ec982 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Tue, 25 Oct 2016 14:33:49 -0500 Subject: [PATCH 11/13] fix: typo in ObserverAdvertisementInfo --- examples/observer/observer.ino | 2 +- hardware/bean/avr/cores/bean/Bean.cpp | 2 +- hardware/bean/avr/cores/bean/Bean.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/observer/observer.ino b/examples/observer/observer.ino index e42cfd2..9de1dbe 100644 --- a/examples/observer/observer.ino +++ b/examples/observer/observer.ino @@ -18,7 +18,7 @@ uint8_t expectedPacket[] = { void loop() { uint32_t start = millis(); - ObseverAdvertisementInfo info; + ObserverAdvertisementInfo info; int res = Bean.getObserverMessage(&info, 2000); if (res == 1) { Serial.print(info.eventType); diff --git a/hardware/bean/avr/cores/bean/Bean.cpp b/hardware/bean/avr/cores/bean/Bean.cpp index ad2a6a8..b67f4c7 100644 --- a/hardware/bean/avr/cores/bean/Bean.cpp +++ b/hardware/bean/avr/cores/bean/Bean.cpp @@ -561,7 +561,7 @@ void BeanClass::setCustomAdvertisement(uint8_t *buf, int len) { Serial.setCustomAdvertisement(buf, len); } -int BeanClass::getObserverMessage(ObseverAdvertisementInfo *message, +int BeanClass::getObserverMessage(ObserverAdvertisementInfo *message, unsigned long timeout) { return Serial.getObserverMessage(message, timeout); } diff --git a/hardware/bean/avr/cores/bean/Bean.h b/hardware/bean/avr/cores/bean/Bean.h index cbdbfc7..93fbd45 100644 --- a/hardware/bean/avr/cores/bean/Bean.h +++ b/hardware/bean/avr/cores/bean/Bean.h @@ -94,7 +94,7 @@ typedef ADV_SWITCH_ENABLED_T BluetoothServices; /** * Data returned by the observer role. */ -typedef OBSERVER_INFO_MESSAGE_T ObseverAdvertisementInfo; +typedef OBSERVER_INFO_MESSAGE_T ObserverAdvertisementInfo; class BeanClass { public: @@ -332,7 +332,7 @@ class BeanClass { * * @include observer/observer.ino */ - int getObserverMessage(ObseverAdvertisementInfo *message, unsigned long timeout); + int getObserverMessage(ObserverAdvertisementInfo *message, unsigned long timeout); ///@} From 2e3d0b2cab760b9c74b5cccadb577aaad3e97242 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Mon, 14 Nov 2016 16:46:44 -0600 Subject: [PATCH 12/13] changelog: add log for 2.0.0 and 2.0.1 --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..035a0c6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ +# 2.0.1 + +### Features + +* New macro `#IS_BEAN` - `0` for Bean+ and `1` for Bean + +### Fixes + +* Fixed typo `ObserverAdvertisementInfo` + +--- + +# 2.0.0 + +### Documentation + +* Vastly improve Doxygen code coverage. Used for doc generation at punchthrough.com/bean/reference. + +### Other + +* Build scripts and examples + +--- + +# < 2.0.0 + +See git history. From eec1ca64b6e33d8d82b36207fac04a4c2272d7e3 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Mon, 14 Nov 2016 16:52:46 -0600 Subject: [PATCH 13/13] changelog: update for 2.0.1 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 035a0c6..0c21ce6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ ### Fixes * Fixed typo `ObserverAdvertisementInfo` +* Fixed PlatformIO tests on Circle + +### Other + +* Removed PinChangeInt submodule, added as direct dependency +* New PlatformIO test that includes builtin libraries ---