Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1702 | - | 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. |
2 | |||
3 | This software may be distributed and modified under the terms of the GNU |
||
4 | General Public License version 2 (GPL2) as published by the Free Software |
||
5 | Foundation and appearing in the file GPL2.TXT included in the packaging of |
||
6 | this file. Please note that GPL2 Section 2[b] requires that all works based |
||
7 | on this software must also be made publicly available under the terms of |
||
8 | the GPL2 ("Copyleft"). |
||
9 | |||
10 | Contact information |
||
11 | ------------------- |
||
12 | |||
13 | Circuits At Home, LTD |
||
14 | Web : http://www.circuitsathome.com |
||
15 | e-mail : support@circuitsathome.com |
||
16 | */ |
||
17 | #if !defined(__VALUELIST_H__) |
||
18 | #define __VALUELIST_H__ |
||
19 | |||
20 | #include <avr/eeprom.h> |
||
21 | #include "WProgram.h" |
||
22 | |||
23 | |||
24 | template <class ValueType, const uint8_t TitleSize> |
||
25 | struct ValueTitle |
||
26 | { |
||
27 | ValueType value; |
||
28 | const char title[TitleSize]; |
||
29 | }; |
||
30 | |||
31 | template <class ValueType, const uint16_t ListSize> |
||
32 | class ValueList |
||
33 | { |
||
34 | public: |
||
35 | uint16_t listSize; |
||
36 | ValueType valueList[ListSize]; |
||
37 | ValueType currentValue; |
||
38 | |||
39 | ValueType GetNext() |
||
40 | { |
||
41 | for (uint16_t i=0; i<listSize; i++) |
||
42 | if (valueList[i] == currentValue) |
||
43 | return ((i+1 < listSize) ? valueList[i+1] : currentValue); |
||
44 | |||
45 | return currentValue; |
||
46 | }; |
||
47 | |||
48 | ValueType GetPrev() |
||
49 | { |
||
50 | for (uint16_t i=0; i<listSize; i++) |
||
51 | if (valueList[i] == currentValue) |
||
52 | return ((i-1 >= 0) ? valueList[i-1] : currentValue); |
||
53 | |||
54 | return currentValue; |
||
55 | }; |
||
56 | }; |
||
57 | |||
58 | |||
59 | |||
60 | template <class ValueType, const uint8_t TitleSize> |
||
61 | const char* FindTitle(uint8_t size, const ValueTitle<ValueType, TitleSize> *p, ValueType val) |
||
62 | { |
||
63 | for (int i=0; i<size; i++) |
||
64 | { |
||
65 | if (pgm_read_byte(&(p[i].value)) == val) |
||
66 | return (const char*)p[i].title; |
||
67 | } |
||
68 | return PSTR("N/A"); |
||
69 | } |
||
70 | |||
71 | |||
72 | class EEPROMByteList |
||
73 | { |
||
74 | const uint16_t listOffset; |
||
75 | const uint8_t maxListSize; |
||
76 | uint8_t listSize; |
||
77 | |||
78 | uint16_t GetValueAddress(uint8_t val) |
||
79 | { |
||
80 | uint16_t tail = listOffset+listSize+2; |
||
81 | |||
82 | for (uint16_t i=listOffset+1; i<tail; i++) |
||
83 | if (eeprom_read_byte((uint8_t*)i) == val) |
||
84 | return i; |
||
85 | |||
86 | return 0xffff; |
||
87 | }; |
||
88 | |||
89 | public: |
||
90 | EEPROMByteList(uint16_t list_offset, uint16_t max_size) : listOffset(list_offset), maxListSize(max_size), listSize(0) |
||
91 | { |
||
92 | }; |
||
93 | |||
94 | uint16_t GetValueIndex(uint8_t val) |
||
95 | { |
||
96 | uint16_t addr = GetValueAddress(val); |
||
97 | |||
98 | return (addr == 0xffff) ? addr : addr - listOffset - 1; |
||
99 | }; |
||
100 | |||
101 | void SetSize(uint8_t size) |
||
102 | { |
||
103 | listSize = (size < maxListSize) ? size : maxListSize; |
||
104 | |||
105 | if (eeprom_read_byte((uint8_t*) listOffset) != listSize) |
||
106 | eeprom_write_byte((uint8_t*) listOffset, listSize); |
||
107 | }; |
||
108 | |||
109 | uint8_t GetSize() |
||
110 | { |
||
111 | return listSize; |
||
112 | }; |
||
113 | |||
114 | |||
115 | uint8_t Get(uint8_t i) |
||
116 | { |
||
117 | return (eeprom_read_byte((uint8_t*)(listOffset + 1 + ((i < listSize) ? i : listOffset+listSize-1)))); |
||
118 | }; |
||
119 | |||
120 | void Set(uint8_t i, uint8_t val) |
||
121 | { |
||
122 | if (i < listSize) |
||
123 | { |
||
124 | uint16_t pos = listOffset + i + 1; |
||
125 | |||
126 | if (eeprom_read_byte((uint8_t*) pos) != val) |
||
127 | eeprom_write_byte((uint8_t*) pos, val); |
||
128 | } |
||
129 | }; |
||
130 | |||
131 | uint8_t GetNext(uint8_t val, uint8_t di=1) |
||
132 | { |
||
133 | uint16_t addr = GetValueAddress(val); |
||
134 | |||
135 | uint16_t tail = listOffset+listSize; |
||
136 | |||
137 | if (addr == 0xffff) |
||
138 | return eeprom_read_byte((uint8_t*)tail); |
||
139 | |||
140 | addr += di; |
||
141 | |||
142 | return eeprom_read_byte((uint8_t*)((addr > tail) ? tail : addr)); |
||
143 | }; |
||
144 | |||
145 | uint8_t GetPrev(uint8_t val, uint8_t di=1) |
||
146 | { |
||
147 | uint16_t addr = GetValueAddress(val); |
||
148 | |||
149 | if (addr == 0xffff) |
||
150 | return eeprom_read_byte((uint8_t*)(listOffset+1)); |
||
151 | |||
152 | addr -= di; |
||
153 | |||
154 | return eeprom_read_byte((uint8_t*)((addr <= listOffset) ? listOffset+1 : addr)); |
||
155 | }; |
||
156 | }; |
||
157 | |||
158 | |||
159 | |||
160 | template <class VALUE_TYPE, const uint16_t MAX_LIST_SIZE> |
||
161 | class SRAMValueList |
||
162 | { |
||
163 | VALUE_TYPE theList[MAX_LIST_SIZE]; |
||
164 | uint16_t listSize; |
||
165 | |||
166 | uint16_t GetValueAddress(VALUE_TYPE val) |
||
167 | { |
||
168 | for (uint16_t i=0; i<listSize; i++) |
||
169 | if (theList[i] == val) |
||
170 | return i; |
||
171 | |||
172 | return 0xffff; |
||
173 | }; |
||
174 | |||
175 | public: |
||
176 | SRAMValueList() : listSize(0) |
||
177 | { |
||
178 | }; |
||
179 | |||
180 | uint16_t GetValueIndex(VALUE_TYPE val) |
||
181 | { |
||
182 | return GetValueAddress(val); |
||
183 | }; |
||
184 | |||
185 | void SetSize(uint16_t size) |
||
186 | { |
||
187 | listSize = (size <= MAX_LIST_SIZE) ? size : MAX_LIST_SIZE; |
||
188 | }; |
||
189 | |||
190 | uint16_t GetSize() |
||
191 | { |
||
192 | return listSize; |
||
193 | }; |
||
194 | |||
195 | |||
196 | VALUE_TYPE Get(uint16_t i) |
||
197 | { |
||
198 | return (theList[(i < listSize) ? i : listSize-1]); |
||
199 | }; |
||
200 | |||
201 | void Set(uint16_t i, VALUE_TYPE val) |
||
202 | { |
||
203 | if (i < listSize) |
||
204 | theList[i] = val; |
||
205 | }; |
||
206 | |||
207 | void Append(VALUE_TYPE val) |
||
208 | { |
||
209 | if (listSize < MAX_LIST_SIZE) |
||
210 | theList[listSize++] = val; |
||
211 | }; |
||
212 | |||
213 | uint8_t GetNext(VALUE_TYPE val, uint8_t di=1) |
||
214 | { |
||
215 | uint16_t addr = GetValueAddress(val); |
||
216 | |||
217 | if (addr == 0xffff) |
||
218 | return theList[(addr < listSize) ? addr : listSize - 1]; |
||
219 | |||
220 | addr += di; |
||
221 | |||
222 | return theList[(addr < listSize) ? addr : listSize-1]; |
||
223 | }; |
||
224 | |||
225 | uint8_t GetPrev(VALUE_TYPE val, uint8_t di=1) |
||
226 | { |
||
227 | uint16_t addr = GetValueAddress(val); |
||
228 | |||
229 | if (addr == 0xffff) |
||
230 | return theList[0]; |
||
231 | |||
232 | addr -= di; |
||
233 | |||
234 | return theList[(addr < listSize) ? addr : 0]; |
||
235 | }; |
||
236 | }; |
||
237 | |||
238 | #endif // #define __VALUELIST_H__ |