1+ /*
2+ Flash.h - An Arduino library for flash-based (ROM) data collections.
3+ Copyright (C) 2009-2012 Mikal Hart
4+ All rights reserved.
5+
6+ This library is free software; you can redistribute it and/or
7+ modify it under the terms of the GNU Lesser General Public
8+ License as published by the Free Software Foundation; either
9+ version 2.1 of the License, or (at your option) any later version.
10+
11+ This library is distributed in the hope that it will be useful,
12+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+ Lesser General Public License for more details.
15+
16+ You should have received a copy of the GNU Lesser General Public
17+ License along with this library; if not, write to the Free Software
18+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+ */
20+ #ifndef __FLASH_H__
21+ #define __FLASH_H__
22+
23+ #include < avr/pgmspace.h>
24+ #if ARDUINO >= 100
25+ #include " Arduino.h"
26+ #else
27+ #include " WProgram.h"
28+ #endif
29+
30+ #define FLASH_LIBRARY_VERSION 5
31+
32+ // Use these macros to define your flash-based data structures
33+ // Example: FLASH_STRING(str, "Four score and seven years ago");
34+ #define FLASH_STRING (name, value ) \
35+ static const char name##_flash[] PROGMEM = value; \
36+ _FLASH_STRING name (name##_flash);
37+
38+ // Example: FLASH_ARRAY(float, temperatures, 98.1, 98.5, 99.1, 102.1);
39+ #define FLASH_ARRAY (type, name, values... ) \
40+ static const type name##_flash[] PROGMEM = { values }; \
41+ _FLASH_ARRAY<type> name (name##_flash, sizeof (name##_flash) / sizeof(type));
42+
43+ // Example: FLASH_TABLE(uint8_t, fonts, 7, {ON, OFF, ON, ON, OFF, ON, OFF}, {OFF, ON, OFF, ON, OFF, ON, OFF});
44+ #define FLASH_TABLE (type, name, cols, values... ) \
45+ static const type name##_flash[][cols] PROGMEM = { values }; \
46+ _FLASH_TABLE<type> name ((const PROGMEM type *)name##_flash, sizeof (name##_flash) / sizeof (name##_flash[0 ]), cols);
47+
48+ // Example: FLASH_STRING_ARRAY(nums, PSTR("One"), PSTR("Two"), PSTR("Three"), PSTR("Four"), PSTR("Five"));
49+ #define FLASH_STRING_ARRAY (name, values... ) \
50+ const PROGMEM char *name##_arr[] = { values }; \
51+ _FLASH_STRING_ARRAY name (name##_arr, sizeof (name##_arr) / sizeof(name##_arr[0 ]));
52+
53+ #ifndef ARDUINO_CORE_PRINTABLE_SUPPORT
54+ class _Printable
55+ {
56+ public:
57+ virtual void print (Print &stream) const = 0;
58+ };
59+ #endif
60+
61+ #if ARDUINO < 100
62+ // Inline ROM strings. Example: Serial << F("Hello, big world!");
63+ #define F (str ) (_FLASH_STRING(PSTR(str)).Printable())
64+ #endif
65+
66+ /* _FLASH_STRING class. Use the FLASH_STRING() macro to create these, or use inline F() macro. */
67+ class _FLASH_STRING : public _Printable
68+ {
69+ public:
70+ _FLASH_STRING (const prog_char *arr);
71+
72+ size_t length () const
73+ { return strlen_P (_arr); }
74+
75+ char *copy (char *to, size_t size = -1 , size_t offset = 0 ) const
76+ {
77+ return size == -1 ?
78+ strcpy_P (to, _arr + offset) : strncpy_P (to, _arr + offset, size);
79+ }
80+
81+ const prog_char *access () const
82+ { return _arr; }
83+
84+ const _Printable &Printable () const
85+ { return *this ; }
86+
87+ char operator [](int index) const
88+ { return static_cast <char >(pgm_read_byte (_arr + index)); }
89+
90+ void print (Print &stream) const ;
91+
92+ private:
93+ const prog_char *_arr;
94+ };
95+
96+ /* _FLASH_ARRAY template class. Use the FLASH_ARRAY() macro to create these. */
97+ template <class T >
98+ class _FLASH_ARRAY : public _Printable
99+ {
100+ typedef T PROGMEM _DataType;
101+
102+ public:
103+ _FLASH_ARRAY (const _DataType *arr, size_t count) : _arr(arr), _size(count)
104+ { }
105+
106+ size_t count () const
107+ { return _size; }
108+
109+ const _DataType *access () const
110+ { return _arr; }
111+
112+ T operator [](int index) const
113+ {
114+ uint32_t val = 0 ;
115+ if (sizeof (T) == 1 )
116+ val = pgm_read_byte (_arr + index);
117+ else if (sizeof (T) == 2 )
118+ val = pgm_read_word (_arr + index);
119+ else if (sizeof (T) == 4 )
120+ val = pgm_read_dword (_arr + index);
121+ return *reinterpret_cast <T *>(&val);
122+ }
123+
124+ void print (Print &stream) const
125+ {
126+ for (size_t i=0 ; i<_size; ++i)
127+ {
128+ stream.print ((*this )[i]);
129+ if (i < _size - 1 )
130+ stream.print (" ," );
131+ }
132+ }
133+
134+ private:
135+ const _DataType *_arr;
136+ size_t _size;
137+ };
138+
139+ /* _FLASH_TABLE template class. Use the FLASH_TABLE() macro to create these. */
140+ template <class T >
141+ class _FLASH_TABLE : public _Printable
142+ {
143+ typedef T PROGMEM _DataType;
144+
145+ public:
146+ _FLASH_TABLE (const _DataType *arr, size_t rows, size_t cols) : _arr(arr), _rows(rows), _cols(cols)
147+ { }
148+
149+ size_t rows () const
150+ { return _rows; }
151+
152+ size_t cols () const
153+ { return _cols; }
154+
155+ const _DataType *access ()
156+ { return _arr; }
157+
158+ _FLASH_ARRAY<T> operator [](int index) const
159+ {
160+ _FLASH_ARRAY<T> row (_arr + index * _cols, _cols);
161+ return row;
162+ }
163+
164+ void print (Print &stream) const
165+ {
166+ for (int i=0 ; i<_rows; ++i)
167+ {
168+ _FLASH_ARRAY<T> row (_arr + i * _cols, _cols);
169+ row.print (stream);
170+ stream.println ();
171+ }
172+ }
173+
174+ private:
175+ const _DataType *_arr;
176+ size_t _rows, _cols;
177+ };
178+
179+ /* _FLASH_STRING_ARRAY class. Use the FLASH_STRING_ARRAY() macro to create these. */
180+ class _FLASH_STRING_ARRAY : public _Printable
181+ {
182+ public:
183+ _FLASH_STRING_ARRAY (const prog_char **arr, size_t count) : _arr(arr), _size(count)
184+ { }
185+
186+ size_t count () const
187+ { return _size; }
188+
189+ _FLASH_STRING operator [](int index) const
190+ { return _FLASH_STRING (_arr[index]); }
191+
192+ void print (Print &stream) const
193+ {
194+ for (size_t i=0 ; i<_size; ++i)
195+ {
196+ _FLASH_STRING str (_arr[i]);
197+ str.print (stream);
198+ stream.println ();
199+ }
200+ }
201+
202+ private:
203+ const prog_char **_arr;
204+ size_t _size;
205+ };
206+
207+ #ifndef ARDUINO_STREAMING
208+ #define ARDUINO_STREAMING
209+
210+ template <class T >
211+ inline Print &operator <<(Print &stream, T arg)
212+ { stream.print (arg); return stream; }
213+
214+ #endif
215+
216+ inline Print &operator <<(Print &stream, const _Printable &printable)
217+ { printable.print (stream); return stream; }
218+
219+ inline Print &operator <<(Print &stream, const _FLASH_STRING &printable)
220+ { printable.print (stream); return stream; }
221+
222+ template <class T >
223+ inline Print &operator <<(Print &stream, const _FLASH_ARRAY<T> &printable)
224+ { printable.print (stream); return stream; }
225+
226+ template <class T >
227+ inline Print &operator <<(Print &stream, const _FLASH_TABLE<T> &printable)
228+ { printable.print (stream); return stream; }
229+
230+ inline Print &operator <<(Print &stream, const _FLASH_STRING_ARRAY &printable)
231+ { printable.print (stream); return stream; }
232+
233+ #endif // def __FLASH_H__
0 commit comments