mirror of
https://github.com/digistump/DigistumpArduino.git
synced 2025-04-28 07:39:02 -07:00
Compare commits
No commits in common. "master" and "v1.5.8C" have entirely different histories.
34
README.md
34
README.md
@ -1,23 +1,35 @@
|
|||||||
DigistumpArduino
|
DigistumpArduino
|
||||||
================
|
================
|
||||||
|
|
||||||
Files to add Digistump support (Digispark, Pro, DigiX) to Arduino 1.6.X (1.6.4+)
|
Files to add Digistump support (Digispark, Pro, DigiX) to Arduino 1.5.X (1.5.7+)
|
||||||
|
|
||||||
**These files are designed for install via the Arduino Boards Manager:**
|
|
||||||
|
|
||||||
Board manager URL: http://digistump.com/package_digistump_index.json
|
**Binary downloads of the bundled IDE can be found here:** https://github.com/digistump/DigistumpArduino/releases/tag/v1.5.8B
|
||||||
|
|
||||||
**Full Install Instructions:**
|
**To manually install:**
|
||||||
|
|
||||||
Digispark: http://digistump.com/wiki/digispark/tutorials/connecting
|
Place digistump folder inside the Arduino /hardware folder.
|
||||||
|
|
||||||
Digispark Pro: http://digistump.com/wiki/digispark/tutorials/connectingpro
|
|
||||||
|
|
||||||
DigiX: http://digistump.com/wiki/digix/tutorials/software
|
|
||||||
|
|
||||||
**To compile:**
|
**To compile:**
|
||||||
|
|
||||||
Micronucleus is the only executable in these packages that is pre-compiled:
|
To compile tools for other platforms or from scratch use:
|
||||||
|
|
||||||
|
Arduino 1.5.X
|
||||||
|
|
||||||
|
This repo.
|
||||||
|
|
||||||
Micronucleus: https://github.com/micronucleus/micronucleus/tree/80419704f68bf0783c5de63a6a4b9d89b45235c7
|
Micronucleus: https://github.com/micronucleus/micronucleus/tree/80419704f68bf0783c5de63a6a4b9d89b45235c7
|
||||||
Dependencies: libusb and possibly lib32stdc on linux - (on ubuntu get it by issuing: apt-get install lib32stdc++6)
|
Dependencies: libusb and possibly lib32stdc on linux - (on ubuntu get it by issuing: apt-get install lib32stdc++6)
|
||||||
|
|
||||||
|
AVR-Dummy: https://github.com/digistump/avr-dummy
|
||||||
|
|
||||||
|
- Download the lastest Arduino 1.5.X branch binaries or source (and compile per their instructions if necessary)
|
||||||
|
- Download this repo
|
||||||
|
- Download the Micronucleus source linked above
|
||||||
|
- Download the AVR-Dummy source above
|
||||||
|
- Compile the micronucleus commandline tool (commandline directory) and avr-dummy ("make all" for both) - which will produce executables named micronucleus and avrdude
|
||||||
|
- Copy the digistump folder from this repo into the hardware folder in your arduino directory.
|
||||||
|
- Copy micronucleus and avrdude executables to the hard/digistump/avr/tools folder in the arduino directory
|
||||||
|
- You're all set!
|
||||||
|
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
//This file allows the Digispark_Examples to appear in the File > Examples menu and fixes the Invalid library warning in Arduino IDE 1.6.6+
|
|
@ -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 <inttypes.h>
|
|
||||||
#include <avr/eeprom.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
/***
|
|
||||||
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
|
|
@ -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 <EEPROM.h>
|
|
||||||
|
|
||||||
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.
|
|
@ -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 <EEPROM.h>
|
|
||||||
|
|
||||||
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. **/ }
|
|
@ -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 <Arduino.h>
|
|
||||||
#include <EEPROM.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -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 <EEPROM.h>
|
|
||||||
|
|
||||||
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 */ }
|
|
@ -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 <EEPROM.h>
|
|
||||||
|
|
||||||
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(){}
|
|
@ -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 <EEPROM.h>
|
|
||||||
|
|
||||||
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 */ }
|
|
@ -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 <EEPROM.h>
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
@ -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 <EEPROM.h>
|
|
||||||
|
|
||||||
/** 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);
|
|
||||||
}
|
|
@ -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 <EEPROM.h>
|
|
||||||
|
|
||||||
/** 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);
|
|
||||||
}
|
|
@ -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)
|
|
||||||
#######################################
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
name=EEPROM
|
|
||||||
version=2.0
|
|
||||||
author=Arduino, Christopher Andrews
|
|
||||||
maintainer=Arduino <info@arduino.cc>
|
|
||||||
sentence=Enables reading and writing to the permanent board storage. For all Arduino boards BUT Arduino DUE.
|
|
||||||
paragraph=
|
|
||||||
url=http://www.arduino.cc/en/Reference/EEPROM
|
|
||||||
architectures=avr
|
|
||||||
|
|
@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
|
|
||||||
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
|
|
||||||
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
|
|
||||||
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (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<<INT0)
|
|
||||||
#define SPI_INT1_MASK (1<<INT1)
|
|
||||||
#define SPI_INT2_MASK (1<<INT2)
|
|
||||||
#define SPI_INT3_MASK (1<<INT3)
|
|
||||||
#define SPI_INT4_MASK (1<<INT6)
|
|
||||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
|
||||||
#define SPI_INT0_MASK (1<<INT0)
|
|
||||||
#define SPI_INT1_MASK (1<<INT1)
|
|
||||||
#define SPI_INT2_MASK (1<<INT2)
|
|
||||||
#define SPI_INT3_MASK (1<<INT3)
|
|
||||||
#define SPI_INT4_MASK (1<<INT4)
|
|
||||||
#define SPI_INT5_MASK (1<<INT5)
|
|
||||||
#define SPI_INT6_MASK (1<<INT6)
|
|
||||||
#define SPI_INT7_MASK (1<<INT7)
|
|
||||||
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
|
|
||||||
#define SPI_INT0_MASK (1<<INT4)
|
|
||||||
#define SPI_INT1_MASK (1<<INT5)
|
|
||||||
#define SPI_INT2_MASK (1<<INT0)
|
|
||||||
#define SPI_INT3_MASK (1<<INT1)
|
|
||||||
#define SPI_INT4_MASK (1<<INT2)
|
|
||||||
#define SPI_INT5_MASK (1<<INT3)
|
|
||||||
#define SPI_INT6_MASK (1<<INT6)
|
|
||||||
#define SPI_INT7_MASK (1<<INT7)
|
|
||||||
#else
|
|
||||||
#ifdef INT0
|
|
||||||
#define SPI_INT0_MASK (1<<INT0)
|
|
||||||
#endif
|
|
||||||
#ifdef INT1
|
|
||||||
#define SPI_INT1_MASK (1<<INT1)
|
|
||||||
#endif
|
|
||||||
#ifdef INT2
|
|
||||||
#define SPI_INT2_MASK (1<<INT2)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SPIClass::usingInterrupt(uint8_t interruptNumber)
|
|
||||||
{
|
|
||||||
uint8_t mask = 0;
|
|
||||||
uint8_t sreg = SREG;
|
|
||||||
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
|
|
||||||
switch (interruptNumber) {
|
|
||||||
#ifdef SPI_INT0_MASK
|
|
||||||
case 0: mask = SPI_INT0_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT1_MASK
|
|
||||||
case 1: mask = SPI_INT1_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT2_MASK
|
|
||||||
case 2: mask = SPI_INT2_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT3_MASK
|
|
||||||
case 3: mask = SPI_INT3_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT4_MASK
|
|
||||||
case 4: mask = SPI_INT4_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT5_MASK
|
|
||||||
case 5: mask = SPI_INT5_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT6_MASK
|
|
||||||
case 6: mask = SPI_INT6_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT7_MASK
|
|
||||||
case 7: mask = SPI_INT7_MASK; break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
interruptMode = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
interruptMask |= mask;
|
|
||||||
if (!interruptMode)
|
|
||||||
interruptMode = 1;
|
|
||||||
SREG = sreg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
|
|
||||||
{
|
|
||||||
// Once in mode 2 we can't go back to 0 without a proper reference count
|
|
||||||
if (interruptMode == 2)
|
|
||||||
return;
|
|
||||||
uint8_t mask = 0;
|
|
||||||
uint8_t sreg = SREG;
|
|
||||||
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
|
|
||||||
switch (interruptNumber) {
|
|
||||||
#ifdef SPI_INT0_MASK
|
|
||||||
case 0: mask = SPI_INT0_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT1_MASK
|
|
||||||
case 1: mask = SPI_INT1_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT2_MASK
|
|
||||||
case 2: mask = SPI_INT2_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT3_MASK
|
|
||||||
case 3: mask = SPI_INT3_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT4_MASK
|
|
||||||
case 4: mask = SPI_INT4_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT5_MASK
|
|
||||||
case 5: mask = SPI_INT5_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT6_MASK
|
|
||||||
case 6: mask = SPI_INT6_MASK; break;
|
|
||||||
#endif
|
|
||||||
#ifdef SPI_INT7_MASK
|
|
||||||
case 7: mask = SPI_INT7_MASK; break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
// this case can't be reached
|
|
||||||
}
|
|
||||||
interruptMask &= ~mask;
|
|
||||||
if (!interruptMask)
|
|
||||||
interruptMode = 0;
|
|
||||||
SREG = sreg;
|
|
||||||
}
|
|
@ -1,324 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
|
|
||||||
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
|
|
||||||
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
|
|
||||||
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (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 <Arduino.h>
|
|
||||||
|
|
||||||
// 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
|
|
@ -1,10 +0,0 @@
|
|||||||
name=SPI
|
|
||||||
version=1.0
|
|
||||||
author=Arduino
|
|
||||||
maintainer=Arduino <info@arduino.cc>
|
|
||||||
sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE.
|
|
||||||
paragraph=
|
|
||||||
category=Communication
|
|
||||||
url=http://www.arduino.cc/en/Reference/SPI
|
|
||||||
architectures=avr
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
TinyWireM
|
|
||||||
=========
|
|
||||||
|
|
||||||
ATtiny (e.g. Adafruit Trinket, Gemma) I2C library, adapted from BroHogan's code on Arduino Playground: http://playground.arduino.cc/Code/USIi2c
|
|
||||||
|
|
||||||
Minor changes for consistency with the Arduino 1.0 Wire library (e.g. uses write() instead of send()). Buffer size slightly increased for Adafruit_LEDBackpack use.
|
|
||||||
|
|
||||||
On the Trinket boards, pin #0 is SDA (I2C data), pin #2 is SCK (I2C clock).
|
|
@ -1,9 +0,0 @@
|
|||||||
name=TinyWireM
|
|
||||||
version=1.0.0
|
|
||||||
author=Adafruit
|
|
||||||
maintainer=Adafruit <info@adafruit.com>
|
|
||||||
sentence=I2C library for Trinket and Gemma, adapted from BroHogan's code on Arduino Playground
|
|
||||||
paragraph=I2C library for Trinket and Gemma, adapted from BroHogan's code on Arduino Playground
|
|
||||||
category=Signal Input/Output
|
|
||||||
url=https://github.com/adafruit/TinyWireM
|
|
||||||
architectures=*
|
|
@ -1,5 +0,0 @@
|
|||||||
micronucleusprog.name=Micronucleus
|
|
||||||
micronucleusprog.communication=usb
|
|
||||||
micronucleusprog.protocol=micronucleus
|
|
||||||
micronucleusprog.program.tool={runtime.tools.micronucleus.path}/micronucleus
|
|
||||||
micronucleusprog.program.extra_params=-Pusb
|
|
@ -1 +0,0 @@
|
|||||||
//This file allows the DigiXBetaBonus sketches to appear in the File > Examples menu and fixes the Invalid library warning in Arduino IDE 1.6.6+
|
|
@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
EEPROM.h - EEPROM library for the Digistump DigiX
|
|
||||||
|
|
||||||
This is mostly the merger of the stock Arduino EEPROM library, original
|
|
||||||
Copyright (c) 2006 David A. Mellis/Christopher Andrews 2015 (LGPL 2.1) with a
|
|
||||||
few functions from Dennis Schweer (Inglorious Engineer)'s Extensive TWI/I2C
|
|
||||||
EEPROM Library for 24LCxxx devices v0.4.1 (CC-BY-SA), as distributed with the
|
|
||||||
DigiX core.
|
|
||||||
|
|
||||||
Merging work by SukkoPera <software@sukkology.net>, 2016.
|
|
||||||
|
|
||||||
The basic idea is to create a library that is interface-compatible with
|
|
||||||
Arduino's stock library that is used on non-Due boards, to achieve
|
|
||||||
compatibility at source level, so that the usual EEPROM.write()/read()/get()
|
|
||||||
/put() calls can be used.
|
|
||||||
|
|
||||||
I'm not really sure of what license the resulting code should be released
|
|
||||||
under, so I'm leaving the LGPL 2.1, as most of the code here actually came
|
|
||||||
under that license, and the rest is pretty basic stuff, but let me know if I
|
|
||||||
should change that.
|
|
||||||
|
|
||||||
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 <inttypes.h>
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
static const int DIGIX_EEPROM_ADDR = 0x50;
|
|
||||||
|
|
||||||
static const int E2END = 0xFFF;
|
|
||||||
|
|
||||||
/***
|
|
||||||
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{
|
|
||||||
private:
|
|
||||||
void extEEPROMwrite(int EEPROM_addr, int addr, byte data)
|
|
||||||
{
|
|
||||||
Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM
|
|
||||||
Wire.write(highByte(addr)); // send high byte of address
|
|
||||||
Wire.write(lowByte(addr)); // send low byte of address
|
|
||||||
Wire.write((byte) data); // send data
|
|
||||||
Wire.endTransmission(true); // stop transmitting
|
|
||||||
delay(6); // wait for a successful write
|
|
||||||
}
|
|
||||||
|
|
||||||
byte extEEPROMread(int EEPROM_addr, int addr) const
|
|
||||||
{
|
|
||||||
Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM
|
|
||||||
Wire.write(highByte(addr)); // send high byte of address
|
|
||||||
Wire.write(lowByte(addr)); // send low byte of address
|
|
||||||
Wire.endTransmission(true); // stop transmitting
|
|
||||||
Wire.requestFrom(EEPROM_addr, 0x01, true); // request 1 byte form the device attached to EEPROM_addr
|
|
||||||
byte data_out = 64;
|
|
||||||
// read that byte
|
|
||||||
while(Wire.available() == 0) {} // wait for data
|
|
||||||
data_out = Wire.read(); //read single byte
|
|
||||||
return data_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
EERef( const int index )
|
|
||||||
: index( index ) {}
|
|
||||||
|
|
||||||
//Access/read members.
|
|
||||||
uint8_t operator*() const { return extEEPROMread( DIGIX_EEPROM_ADDR, 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 extEEPROMwrite( DIGIX_EEPROM_ADDR, 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{
|
|
||||||
boolean inited;
|
|
||||||
|
|
||||||
// c'tor
|
|
||||||
EEPROMClass () { inited = false; }
|
|
||||||
|
|
||||||
// Check if the i2c library was initialized, and do it if not.
|
|
||||||
// FIXME: What happens if the sketch has already called Wire.begin() on its
|
|
||||||
// own?
|
|
||||||
void checkInited () { if (!inited) { Wire.begin(); inited = true; } }
|
|
||||||
|
|
||||||
//Basic user access methods.
|
|
||||||
EERef operator[]( const int idx ) { return idx; }
|
|
||||||
uint8_t read( int idx ) { checkInited (); return EERef( idx ); }
|
|
||||||
void write( int idx, uint8_t val ) { checkInited (); (EERef( idx )) = val; }
|
|
||||||
void update( int idx, uint8_t val ) { checkInited (); 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 ){
|
|
||||||
checkInited ();
|
|
||||||
|
|
||||||
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 ){
|
|
||||||
checkInited ();
|
|
||||||
|
|
||||||
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
|
|
@ -62,46 +62,4 @@ digispark-pro64.build.core=pro
|
|||||||
digispark-pro64.build.variant=pro64buffer
|
digispark-pro64.build.variant=pro64buffer
|
||||||
digispark-pro64.upload.wait_for_upload_port = false
|
digispark-pro64.upload.wait_for_upload_port = false
|
||||||
digispark-pro64.upload.use_1200bps_touch = false
|
digispark-pro64.upload.use_1200bps_touch = false
|
||||||
digispark-pro64.upload.disable_flushing = false
|
digispark-pro64.upload.disable_flushing = false
|
||||||
|
|
||||||
digispark-tiny16.name=Digispark (16mhz - No USB)
|
|
||||||
digispark-tiny16.upload.using=micronucleusprog
|
|
||||||
digispark-tiny16.upload.protocol=usb
|
|
||||||
digispark-tiny16.upload.tool=micronucleus
|
|
||||||
digispark-tiny16.upload.maximum_size=6012
|
|
||||||
digispark-tiny16.build.mcu=attiny85
|
|
||||||
digispark-tiny16.build.f_cpu=16000000L
|
|
||||||
digispark-tiny16.build.board=AVR_DIGISPARK
|
|
||||||
digispark-tiny16.build.core=tiny
|
|
||||||
digispark-tiny16.build.variant=digispark
|
|
||||||
digispark-tiny16.upload.wait_for_upload_port = false
|
|
||||||
digispark-tiny16.upload.use_1200bps_touch = false
|
|
||||||
digispark-tiny16.upload.disable_flushing = false
|
|
||||||
|
|
||||||
digispark-tiny8.name=Digispark (8mhz - No USB)
|
|
||||||
digispark-tiny8.upload.using=micronucleusprog
|
|
||||||
digispark-tiny8.upload.protocol=usb
|
|
||||||
digispark-tiny8.upload.tool=micronucleus
|
|
||||||
digispark-tiny8.upload.maximum_size=6012
|
|
||||||
digispark-tiny8.build.mcu=attiny85
|
|
||||||
digispark-tiny8.build.f_cpu=8000000L
|
|
||||||
digispark-tiny8.build.board=AVR_DIGISPARK
|
|
||||||
digispark-tiny8.build.core=tiny
|
|
||||||
digispark-tiny8.build.variant=digispark
|
|
||||||
digispark-tiny8.upload.wait_for_upload_port = false
|
|
||||||
digispark-tiny8.upload.use_1200bps_touch = false
|
|
||||||
digispark-tiny8.upload.disable_flushing = false
|
|
||||||
|
|
||||||
digispark-tiny1.name=Digispark (1mhz - No USB)
|
|
||||||
digispark-tiny1.upload.using=micronucleusprog
|
|
||||||
digispark-tiny1.upload.protocol=usb
|
|
||||||
digispark-tiny1.upload.tool=micronucleus
|
|
||||||
digispark-tiny1.upload.maximum_size=6012
|
|
||||||
digispark-tiny1.build.mcu=attiny85
|
|
||||||
digispark-tiny1.build.f_cpu=1000000L
|
|
||||||
digispark-tiny1.build.board=AVR_DIGISPARK
|
|
||||||
digispark-tiny1.build.core=tiny
|
|
||||||
digispark-tiny1.build.variant=digispark
|
|
||||||
digispark-tiny1.upload.wait_for_upload_port = false
|
|
||||||
digispark-tiny1.upload.use_1200bps_touch = false
|
|
||||||
digispark-tiny1.upload.disable_flushing = false
|
|
@ -43,7 +43,6 @@ extern "C"{
|
|||||||
|
|
||||||
#define INPUT 0x0
|
#define INPUT 0x0
|
||||||
#define OUTPUT 0x1
|
#define OUTPUT 0x1
|
||||||
#define INPUT_PULLUP 0x2
|
|
||||||
|
|
||||||
#define true 0x1
|
#define true 0x1
|
||||||
#define false 0x0
|
#define false 0x0
|
@ -35,28 +35,21 @@ void pinMode(uint8_t pin, uint8_t mode)
|
|||||||
{
|
{
|
||||||
uint8_t bit = digitalPinToBitMask(pin);
|
uint8_t bit = digitalPinToBitMask(pin);
|
||||||
uint8_t port = digitalPinToPort(pin);
|
uint8_t port = digitalPinToPort(pin);
|
||||||
volatile uint8_t *reg, *out;
|
volatile uint8_t *reg;
|
||||||
|
|
||||||
if (port == NOT_A_PIN) return;
|
if (port == NOT_A_PIN) return;
|
||||||
|
|
||||||
// JWS: can I let the optimizer do this?
|
// JWS: can I let the optimizer do this?
|
||||||
reg = portModeRegister(port);
|
reg = portModeRegister(port);
|
||||||
out = portOutputRegister(port);
|
|
||||||
|
|
||||||
if (mode == INPUT) {
|
if (mode == INPUT) {
|
||||||
uint8_t oldSREG = SREG;
|
uint8_t oldSREG = SREG;
|
||||||
cli();
|
cli();
|
||||||
*reg &= ~bit;
|
*reg &= ~bit;
|
||||||
SREG = oldSREG;
|
SREG = oldSREG;
|
||||||
} else if (mode == INPUT_PULLUP) {
|
|
||||||
uint8_t oldSREG = SREG;
|
|
||||||
cli();
|
|
||||||
*reg &= ~bit;
|
|
||||||
*out |= bit;
|
|
||||||
SREG = oldSREG;
|
|
||||||
} else {
|
} else {
|
||||||
uint8_t oldSREG = SREG;
|
uint8_t oldSREG = SREG;
|
||||||
cli();
|
cli();
|
||||||
*reg |= bit;
|
*reg |= bit;
|
||||||
SREG = oldSREG;
|
SREG = oldSREG;
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user