1 /* vim:ts=4 sts=4 et tw=80
5 * for additional information please
6 * see http://lochraster.org/fnordlichtmini
8 * (c) by Alexander Neumann <alexander@bumpern.de>
10 * This program is free software: you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 3 as published by
12 * the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "../common/pt/pt.h"
26 #include <avr/eeprom.h>
27 #include <util/crc16.h>
30 /* global structures */
31 struct storage_config_t startup_config
;
32 EEMEM
struct storage_t eeprom_storage
=
34 /* struct storage_config_t config */
38 /* uint8_t startup_addr */
40 /* struct startup_parameters_t params */
42 /* enum startup_mode_t mode */
46 CONFIG_SCRIPT_DEFAULT
,
47 /* uint8_t program_parameters[PROGRAM_PARAMETER_SIZE] */
48 /* these are taken from script.c */
49 #if CONFIG_SCRIPT_DEFAULT == 0
50 /* parameters for colorwheel */
51 1u, 2u, 0, 0, 0, 0, 60u, 0, 255u, 255u
52 #elif CONFIG_SCRIPT_DEFAULT == 1
53 /* parameters for random */
54 0, 23u, 2u, 1u, 3u, 0, 100u, 255u, 255u, 60u
59 /* struct storage_color_t color[CONFIG_EEPROM_COLORS] */
63 /* uint16_t checksum */
68 struct storage_internal_t
72 /* buffer for nonblocking read/write */
73 uint8_t buf
[STORAGE_BUFFER_SIZE
];
76 uint8_t bytes_remaining
;
85 static struct storage_internal_t storage
;
87 static uint16_t eeprom_checksum(void)
89 uint16_t checksum
= 0;
90 uint8_t *start
= NULL
;
92 for (uint16_t i
= 0; i
< sizeof(struct storage_t
)-2; i
++)
93 checksum
= _crc16_update(checksum
, eeprom_read_byte(start
++));
98 void storage_init(void)
100 /* compare checksum and eeprom configuration content */
101 uint16_t checksum1
= eeprom_checksum();
102 uint16_t checksum2
= eeprom_read_word(&eeprom_storage
.checksum
);
103 storage
.eeprom_good
= (checksum1
== checksum2
);
104 storage_load_config();
107 /* initialize state structure */
108 storage
.state
= STORAGE_IDLE
;
109 PT_INIT(&storage
.thread
);
113 static PT_THREAD(storage_thread(struct pt
*thread
))
118 if (storage
.state
== STORAGE_WRITE
) {
123 while (storage
.bytes_remaining
--) {
124 eeprom_write_byte(storage
.address
++, storage
.buf
[storage
.index
++]);
126 while (!eeprom_is_ready())
130 /* update checksum */
131 eeprom_write_word(&eeprom_storage
.checksum
, eeprom_checksum());
132 while (!eeprom_is_ready())
135 /* release int line */
136 remote_release_int();
138 storage
.state
= STORAGE_IDLE
;
147 void storage_poll(void)
149 /* call storage thread */
150 if (storage
.state
!= STORAGE_IDLE
)
151 PT_SCHEDULE(storage_thread(&storage
.thread
));
154 void storage_save_config(void)
156 if (storage
.state
!= STORAGE_IDLE
)
159 /* set magic byte and save startup_config to EEPROM */
160 startup_config
.magic
= EEPROM_MAGIC_BYTE
;
162 /* copy data to buffer */
163 memcpy(&storage
.buf
[0], &startup_config
, sizeof(struct storage_config_t
));
164 /* set address and bytes_remaining */
166 storage
.bytes_remaining
= sizeof(struct storage_config_t
);
167 storage
.address
= (uint8_t *)&eeprom_storage
.config
;
169 storage
.state
= STORAGE_WRITE
;
171 /* reset magic config and mark EEPROM as good */
172 startup_config
.magic
= 0;
173 storage
.eeprom_good
= true;
176 void storage_load_config(void)
178 if (!storage
.eeprom_good
)
182 eeprom_read_block(&startup_config
, &eeprom_storage
.config
, sizeof(struct storage_config_t
));
185 void storage_save_color(uint8_t position
, struct storage_color_t
*color
)
187 if (storage
.state
!= STORAGE_IDLE
)
190 /* copy data to buffer */
191 memcpy(&storage
.buf
[0], color
, sizeof(struct storage_color_t
));
192 /* set address and bytes_remaining */
194 storage
.bytes_remaining
= sizeof(struct storage_color_t
);
195 storage
.address
= (uint8_t *)&eeprom_storage
.color
[position
];
197 storage
.state
= STORAGE_WRITE
;
200 void storage_load_color(uint8_t position
, struct storage_color_t
*color
)
202 eeprom_read_block(color
, &eeprom_storage
.color
[position
], sizeof(struct storage_color_t
));
205 bool storage_valid_config(void)
207 return (storage
.eeprom_good
&& startup_config
.magic
== EEPROM_MAGIC_BYTE
);