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