Skip to content

Commit ed1436d

Browse files
authored
Merge pull request chipKIT32#351 from majenkotech/new-eeprom
Update EEPROM interface for new Arduino standard
2 parents ec0df50 + 47aa7b5 commit ed1436d

File tree

12 files changed

+558
-262
lines changed

12 files changed

+558
-262
lines changed

pic32/cores/pic32/avr/eeprom.h

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1-
#ifndef __EEPROM_H_
2-
#define __EEPROM_H_ 1
3-
4-
/* For AVR */
5-
#if defined(__AVR__)
6-
#include <avr/io.h>
7-
#endif
8-
9-
#endif /* __EEPROME_H_ */
1+
#ifndef __EEPROM_H_
2+
#define __EEPROM_H_ 1
3+
4+
/* For AVR */
5+
#if defined(__AVR__)
6+
#include <avr/io.h>
7+
#endif
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
14+
uint8_t eeprom_read_byte(uint8_t *index);
15+
void eeprom_write_byte(uint8_t *index, uint8_t in);
16+
17+
#ifdef __cplusplus
18+
}
19+
#endif
20+
21+
22+
#endif /* __EEPROME_H_ */

pic32/libraries/EEPROM/EEPROM.cpp

Lines changed: 0 additions & 78 deletions
This file was deleted.

pic32/libraries/EEPROM/EEPROM.h

Lines changed: 119 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
EEPROM.h - EEPROM library
3-
Copyright (c) 2006 David A. Mellis. All right reserved.
3+
Original Copyright (c) 2006 David A. Mellis. All right reserved.
4+
New version by Christopher Andrews 2015.
45
56
This library is free software; you can redistribute it and/or
67
modify it under the terms of the GNU Lesser General Public
@@ -21,19 +22,125 @@
2122
#define EEPROM_h
2223

2324
#include <inttypes.h>
25+
#include <avr/eeprom.h>
26+
#include <avr/io.h>
2427

25-
class EEPROMClass
26-
{
27-
public:
28-
EEPROMClass();
29-
void setMaxAddress(unsigned int value);
30-
unsigned int getMaxAddress();
31-
void clear();
32-
uint8_t read(unsigned int address);
33-
void write(unsigned int address, uint8_t value);
28+
/***
29+
EERef class.
30+
31+
This object references an EEPROM cell.
32+
Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
33+
This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
34+
***/
35+
36+
struct EERef{
37+
38+
EERef( const int index )
39+
: index( index ) {}
40+
41+
//Access/read members.
42+
uint8_t operator*() const { return eeprom_read_byte( (uint8_t*) index ); }
43+
operator const uint8_t() const { return **this; }
44+
45+
//Assignment/write members.
46+
EERef &operator=( const EERef &ref ) { return *this = *ref; }
47+
EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_t*) index, in ), *this; }
48+
EERef &operator +=( uint8_t in ) { return *this = **this + in; }
49+
EERef &operator -=( uint8_t in ) { return *this = **this - in; }
50+
EERef &operator *=( uint8_t in ) { return *this = **this * in; }
51+
EERef &operator /=( uint8_t in ) { return *this = **this / in; }
52+
EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; }
53+
EERef &operator %=( uint8_t in ) { return *this = **this % in; }
54+
EERef &operator &=( uint8_t in ) { return *this = **this & in; }
55+
EERef &operator |=( uint8_t in ) { return *this = **this | in; }
56+
EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
57+
EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
58+
59+
EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; }
60+
61+
/** Prefix increment/decrement **/
62+
EERef& operator++() { return *this += 1; }
63+
EERef& operator--() { return *this -= 1; }
64+
65+
/** Postfix increment/decrement **/
66+
uint8_t operator++ (int){
67+
uint8_t ret = **this;
68+
return ++(*this), ret;
69+
}
70+
71+
uint8_t operator-- (int){
72+
uint8_t ret = **this;
73+
return --(*this), ret;
74+
}
75+
76+
int index; //Index of current EEPROM cell.
3477
};
3578

36-
extern EEPROMClass EEPROM;
79+
/***
80+
EEPtr class.
81+
82+
This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
83+
Just like a normal pointer type, this can be dereferenced and repositioned using
84+
increment/decrement operators.
85+
***/
3786

38-
#endif
87+
struct EEPtr{
88+
89+
EEPtr( const int index )
90+
: index( index ) {}
91+
92+
operator const int() const { return index; }
93+
EEPtr &operator=( int in ) { return index = in, *this; }
94+
95+
//Iterator functionality.
96+
bool operator!=( const EEPtr &ptr ) { return index != ptr.index; }
97+
EERef operator*() { return index; }
98+
99+
/** Prefix & Postfix increment/decrement **/
100+
EEPtr& operator++() { return ++index, *this; }
101+
EEPtr& operator--() { return --index, *this; }
102+
EEPtr operator++ (int) { return index++; }
103+
EEPtr operator-- (int) { return index--; }
104+
105+
int index; //Index of current EEPROM cell.
106+
};
107+
108+
/***
109+
EEPROMClass class.
110+
111+
This object represents the entire EEPROM space.
112+
It wraps the functionality of EEPtr and EERef into a basic interface.
113+
This class is also 100% backwards compatible with earlier Arduino core releases.
114+
***/
115+
116+
struct EEPROMClass{
39117

118+
//Basic user access methods.
119+
EERef operator[]( const int idx ) { return idx; }
120+
uint8_t read( int idx ) { return EERef( idx ); }
121+
void write( int idx, uint8_t val ) { (EERef( idx )) = val; }
122+
void update( int idx, uint8_t val ) { EERef( idx ).update( val ); }
123+
124+
//STL and C++11 iteration capability.
125+
EEPtr begin() { return 0x00; }
126+
EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
127+
uint16_t length() { return E2END + 1; }
128+
129+
//Functionality to 'get' and 'put' objects to and from EEPROM.
130+
template< typename T > T &get( int idx, T &t ){
131+
EEPtr e = idx;
132+
uint8_t *ptr = (uint8_t*) &t;
133+
for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e;
134+
return t;
135+
}
136+
137+
template< typename T > const T &put( int idx, const T &t ){
138+
EEPtr e = idx;
139+
const uint8_t *ptr = (const uint8_t*) &t;
140+
for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ );
141+
return t;
142+
}
143+
};
144+
145+
static EEPROMClass EEPROM;
146+
#endif
Lines changed: 26 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,39 @@
11
/*
22
* EEPROM Clear
33
*
4-
* This sketch will erase the EEPROM memory. An erased
5-
* EEPROM has all of the bytes set to 0xFF (255 decimal).
4+
* Sets all of the bytes of the EEPROM to 0.
5+
* Please see eeprom_iteration for a more in depth
6+
* look at how to traverse the EEPROM.
67
*
7-
* Description
8-
* Unlike the AVR micrcontrollers used on the Arduino boards,
9-
* the PIC32 microcontrollers used on the chipKIT boards don't
10-
* have internal EEPROM memory. Instead, FLASH memory is used
11-
* to simulate EEPROM. There are two major differences between
12-
* FLASH and EEPROM. 1) EEPROM is byte erasable and rewritable.
13-
* With FLASH an entire page must be erased before any byte can
14-
* be rewritten. 2) FLASH can't be erased and rewritten as many
15-
* times as EEPROM. After a limited number of erase/write
16-
* cycles, the FLASH page will 'wear out', and additional
17-
* writes may not store the correct value. EEPROM can also
18-
* wear out, but it typically takes many more writes to wear
19-
* it out.
20-
* To address these issues, the chipKIT EEPROM library uses a
21-
* page of FLASH memory to simulate EEPROM.
22-
* The FLASH is used as content addressable memory. A 32-bit
23-
* word is used for each simulated EEPROM byte. The word stores
24-
* both the EEPROM address and the byte value. When a write is
25-
* performed, the page is searched for an unused location, when
26-
* one is found, the address/data is written to that word. When
27-
* reading, the page is searched for the address, and then the
28-
* value is returned. If a location is being rewritten, the old
29-
* location is marked as invalid and a new location written as
30-
* described above.
31-
* If there are no unused locations available in the page when a
32-
* write is being attempted, then the page must be erased before
33-
* the value can be written. The contents of the page is copied
34-
* to a memory buffer, the page erased, and then the old values
35-
* plus new value are written back to the FLASH page. This
36-
* method reduces the number of times that the page must be
37-
* erased and rewritten.
38-
* The PIC32 FLASH page size is 4K (4096) bytes, which allows for
39-
* simulation of up to 1K (1024) bytes of EEPROM.
40-
* There is a degenerate case, however, that can lead to rapid
41-
* wearout of the FLASH page being used. If all of the simulated
42-
* EEPROM locations have been written (i.e. all simulated EEPROM
43-
* addresses have been written to), then each additional write
44-
* results in the page being erased and rewritten, eliminating
45-
* the benefit of the wear leveling algorithm being used.
46-
* This library uses two methods to help reduce this problem.
47-
* The first is adding the clear() method. This method erases
48-
* the flash page, erasing all simulated EEPROM. If a sketch has
49-
* been run that uses a large amount of the simulated EEPROM,
50-
* clear() should be used when that EEPROM content is not longer
51-
* needed. This will reduce the number of values in the EEPROM
52-
* that need to be preserved, reducing the number of times that
53-
* the FLASH page will have to be erased and rewritten. The
54-
* second method used to reduce the liklihood of premature FLASH
55-
* wearout is to limit the default EEPROM memory size. By default
56-
* this library implements 512 bytes of simulated EEPROM. This
57-
* reserves at least half of the FLASH page to handle rewrites.
58-
* It is possible to increase the simulated EEPROM size if a
59-
* larger amount is needed. Two new methods have been added to
60-
* accomodate this. getMaxAddress returns the current size of
61-
* the simulated EEPROM. setMaxAddress allows setting it to
62-
* a different size up to 1024.
8+
* This example code is in the public domain.
639
*/
6410

6511
#include <EEPROM.h>
6612

67-
void setup()
68-
{
69-
// Clear entire eeprom
70-
EEPROM.clear();
71-
13+
void setup() {
14+
// initialize the LED pin as an output.
15+
pinMode(13, OUTPUT);
16+
17+
/***
18+
Iterate through each byte of the EEPROM storage.
19+
20+
Larger AVR processors have larger EEPROM sizes, E.g:
21+
- Arduno Duemilanove: 512b EEPROM storage.
22+
- Arduino Uno: 1kb EEPROM storage.
23+
- Arduino Mega: 4kb EEPROM storage.
24+
25+
Rather than hard-coding the length, you should use the pre-provided length function.
26+
This will make your code portable to all AVR processors.
27+
***/
28+
29+
for (int i = 0 ; i < EEPROM.length() ; i++) {
30+
EEPROM.write(i, 0);
31+
}
32+
7233
// turn the LED on when we're done
7334
digitalWrite(13, HIGH);
7435
}
7536

76-
void loop()
77-
{
37+
void loop() {
38+
/** Empty loop. **/
7839
}

0 commit comments

Comments
 (0)