]> git.zerfleddert.de Git - fnordlicht-mini/blame - firmware/fnordlicht-firmware/storage.c
whitespace cleanup, init eeprom for random startup, too
[fnordlicht-mini] / firmware / fnordlicht-firmware / storage.c
CommitLineData
ec1bef8e 1/* vim:ts=4 sts=4 et tw=80
2 *
3 * fnordlicht firmware
4 *
5 * for additional information please
6 * see http://lochraster.org/fnordlichtmini
7 *
8 * (c) by Alexander Neumann <alexander@bumpern.de>
9 *
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.
13 *
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
17 * more details.
18 *
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/>.
21 */
22
23#include "storage.h"
24#include "remote.h"
25#include "../common/pt/pt.h"
26#include <avr/eeprom.h>
27#include <util/crc16.h>
28#include <string.h>
29
30/* global structures */
31struct storage_config_t startup_config;
8bedc79d 32EEMEM struct storage_t eeprom_storage =
33{
34 /* struct storage_config_t config */
35 {
36 /* uint8_t magic */
37 EEPROM_MAGIC_BYTE,
38 /* uint8_t startup_addr */
39 1u,
40 /* struct startup_parameters_t params */
41 {
42 /* enum startup_mode_t mode */
43 STARTUP_PROGRAM,
44 {
45 /* uint8_t program */
937531b6 46 CONFIG_SCRIPT_DEFAULT,
8bedc79d 47 /* uint8_t program_parameters[PROGRAM_PARAMETER_SIZE] */
937531b6 48 /* these are taken from script.c */
49#if CONFIG_SCRIPT_DEFAULT == 0
50 /* parameters for colorwheel */
8bedc79d 51 1u, 2u, 0, 0, 0, 0, 60u, 0, 255u, 255u
937531b6 52#elif CONFIG_SCRIPT_DEFAULT == 1
53 /* parameters for random */
54 0, 23u, 2u, 1u, 3u, 0, 100u, 255u, 255u, 60u
55#endif
8bedc79d 56 }
57 }
58 },
59 /* struct storage_color_t color[CONFIG_EEPROM_COLORS] */
60 {
61 0u,
62 },
63 /* uint16_t checksum */
64 0x2323u /* FIXME */
65};
ec1bef8e 66
67/* internal state */
68struct storage_internal_t
69{
70 bool eeprom_good;
71
72 /* buffer for nonblocking read/write */
73 uint8_t buf[STORAGE_BUFFER_SIZE];
74 uint8_t index;
75 uint8_t *address;
76 uint8_t bytes_remaining;
77 struct pt thread;
78
79 enum {
80 STORAGE_IDLE = 0,
81 STORAGE_WRITE = 1,
82 } state;
83};
84
85static struct storage_internal_t storage;
86
87static uint16_t eeprom_checksum(void)
88{
89 uint16_t checksum = 0;
90 uint8_t *start = NULL;
91
92 for (uint16_t i = 0; i < sizeof(struct storage_t)-2; i++)
93 checksum = _crc16_update(checksum, eeprom_read_byte(start++));
94
95 return checksum;
96}
97
98void storage_init(void)
99{
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();
105
106#ifdef INIT_ZERO
107 /* initialize state structure */
108 storage.state = STORAGE_IDLE;
109 PT_INIT(&storage.thread);
110#endif
111}
112
113static PT_THREAD(storage_thread(struct pt *thread))
114{
115 PT_BEGIN(thread);
116
117 while (1) {
118 if (storage.state == STORAGE_WRITE) {
119 /* pull int line */
120 remote_pull_int();
121
122 /* write data */
123 while (storage.bytes_remaining--) {
124 eeprom_write_byte(storage.address++, storage.buf[storage.index++]);
125
126 while (!eeprom_is_ready())
127 PT_YIELD(thread);
128 }
129
130 /* update checksum */
131 eeprom_write_word(&eeprom_storage.checksum, eeprom_checksum());
132 while (!eeprom_is_ready())
133 PT_YIELD(thread);
134
135 /* release int line */
136 remote_release_int();
137
138 storage.state = STORAGE_IDLE;
139 }
140
141 PT_YIELD(thread);
142 }
143
144 PT_END(thread);
145}
146
147void storage_poll(void)
148{
149 /* call storage thread */
150 if (storage.state != STORAGE_IDLE)
151 PT_SCHEDULE(storage_thread(&storage.thread));
152}
153
154void storage_save_config(void)
155{
156 if (storage.state != STORAGE_IDLE)
157 return;
158
159 /* set magic byte and save startup_config to EEPROM */
160 startup_config.magic = EEPROM_MAGIC_BYTE;
161
162 /* copy data to buffer */
163 memcpy(&storage.buf[0], &startup_config, sizeof(struct storage_config_t));
164 /* set address and bytes_remaining */
165 storage.index = 0;
166 storage.bytes_remaining = sizeof(struct storage_config_t);
167 storage.address = (uint8_t *)&eeprom_storage.config;
168 /* start write */
169 storage.state = STORAGE_WRITE;
170
171 /* reset magic config and mark EEPROM as good */
172 startup_config.magic = 0;
173 storage.eeprom_good = true;
174}
175
176void storage_load_config(void)
177{
178 if (!storage.eeprom_good)
179 return;
180
181 /* load config */
182 eeprom_read_block(&startup_config, &eeprom_storage.config, sizeof(struct storage_config_t));
183}
184
185void storage_save_color(uint8_t position, struct storage_color_t *color)
186{
187 if (storage.state != STORAGE_IDLE)
188 return;
189
190 /* copy data to buffer */
191 memcpy(&storage.buf[0], color, sizeof(struct storage_color_t));
192 /* set address and bytes_remaining */
193 storage.index = 0;
194 storage.bytes_remaining = sizeof(struct storage_color_t);
195 storage.address = (uint8_t *)&eeprom_storage.color[position];
196 /* start write */
197 storage.state = STORAGE_WRITE;
198}
199
200void storage_load_color(uint8_t position, struct storage_color_t *color)
201{
202 eeprom_read_block(color, &eeprom_storage.color[position], sizeof(struct storage_color_t));
203}
204
205bool storage_valid_config(void)
206{
207 return (storage.eeprom_good && startup_config.magic == EEPROM_MAGIC_BYTE);
208}
Impressum, Datenschutz