-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.c
executable file
·232 lines (205 loc) · 5.49 KB
/
config.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <inttypes.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <util/atomic.h>
#include "config.h"
#include "rtc.h"
#include "usart.h"
#include "iocontrol.h"
#define SERIALNUM_LENGTH 8
struct s_config {
uint16_t S1Baud;
uint8_t S1Type;
uint16_t S2Baud;
uint8_t S2Type;
int8_t SerialNumber[SERIALNUM_LENGTH];
uint8_t portconfig[NUM_PORTS];
uint8_t NumEvents;
struct s_mucron EventList[MUCRON_EVENTLIST_SIZE];
};
uint8_t EEPROM_read(uint16_t uiAddress)
{ /* Wait for completion of previous write */ while(EECR & (1<<EEPE)) ; /* Set up address register */
EEAR = uiAddress;
/* Start eeprom read by writing EERE */
EECR |= (1<<EERE);
/* Return data from Data Register */
return EEDR;}
void EEPROM_read_page(uint16_t start_address, uint8_t *data, uint16_t length)
{
uint16_t index = 0;
for (; index < length; ++index)
{
*(data + index) = EEPROM_read(start_address + index);
}
}
void EEPROM_write(uint16_t uiAddress, uint8_t ucData)
{ /* Wait for completion of previous write */
while(EECR & (1<<EEPE));
/* Set up address and Data Registers */
EEAR = uiAddress;
EEDR = ucData;
/* Write logical one to EEMPE */
EECR |= (1<<EEMPE);
/* Start eeprom write by setting EEPE */
EECR |= (1<<EEPE);}
void EEPROM_write_page(uint16_t start_address, uint8_t *data, uint16_t length)
{
uint16_t index = 0;
for(;index < length; ++index)
{
EEPROM_write(start_address + index, *(data + index));
}
}
void config_get_io_types(uint8_t *data)
{
EEPROM_read_page(offsetof(struct s_config, portconfig), data, sizeof(uint8_t) * NUM_PORTS);
}
void config_set_io_types(uint8_t *data)
{
EEPROM_write_page(offsetof(struct s_config, portconfig), data, sizeof(uint8_t) * NUM_PORTS);
}
/* EEPROM memory is much too slow to iterate through every time a timer tick is processed.
* Keep an event list in ram that is initialized everytime the micro starts up
*/
struct s_mucron ramEventList[MUCRON_EVENTLIST_SIZE];
void config_Init()
{
EEPROM_read_page(offsetof(struct s_config, EventList), (void*)ramEventList, sizeof(struct s_mucron) * MUCRON_EVENTLIST_SIZE);
}
uint8_t config_get_protocol_type(uint8_t port)
{
switch(port)
{
case 0: return EEPROM_read(offsetof(struct s_config, S1Type));
case 1: return EEPROM_read(offsetof(struct s_config, S2Type));
}
return 0;
}
void config_set_protocol_type(uint8_t port, uint8_t type)
{
switch(port)
{
case 0:
EEPROM_write(offsetof(struct s_config, S1Type), type);
break;
case 1:
EEPROM_write(offsetof(struct s_config, S2Type), type);
break;
}
}
uint16 config_get_baud(uint8 port)
{
uint16 baud = 0;
switch(port)
{
case 0:
baud = EEPROM_read(offsetof(struct s_config, S1Baud)) << 8;
baud |= EEPROM_read(offsetof(struct s_config, S1Baud) + 1);
break;
case 1:
baud = EEPROM_read(offsetof(struct s_config, S2Baud)) << 8;
baud |= EEPROM_read(offsetof(struct s_config, S2Baud) + 1);
break;
}
return baud;
}
void config_set_baud(uint8 port, uint16 baud)
{
switch (port)
{
case 0:
EEPROM_write(offsetof(struct s_config, S1Baud), baud << 8);
EEPROM_write(offsetof(struct s_config, S1Baud) + 1, baud);
break;
case 1:
EEPROM_write(offsetof(struct s_config, S2Baud), baud << 8);
EEPROM_write(offsetof(struct s_config, S2Baud) + 1, baud);
break;
}
}
struct s_mucron * mucron_get_eventlist()
{
return ramEventList;
}
void blank_eventlist_eeprom()
{
uint8_t tmp[sizeof(struct s_mucron)] = {0};
uint8_t index;
for (index = 0; index < MUCRON_EVENTLIST_SIZE; index++)
{
EEPROM_write_page(offsetof(struct s_config, EventList) + (sizeof(struct s_mucron) * index), tmp, sizeof(struct s_mucron) );
}
}
void mucron_write_mem()
{
EEPROM_write_page(offsetof(struct s_config, EventList), (void*)ramEventList, sizeof(struct s_mucron) * MUCRON_EVENTLIST_SIZE);
}
void mucron_delete_event(uint16_t event_index)
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
// turn off the device when the event is deleted so the device is left on with no way to turn it off
iocontrol((ramEventList + event_index)->port, 0);
*(ramEventList + event_index) = (struct s_mucron){0};
}
EEPROM_write_page(offsetof(struct s_config, EventList) + sizeof(struct s_mucron) * event_index,
(void*)(ramEventList+event_index),
sizeof(struct s_mucron));
}
void mucron_save_event(struct s_mucron *timerblock)
{
uint16_t event_index = 0;
struct s_mucron * event_ptr;
for (event_ptr = ramEventList; event_index < MUCRON_EVENTLIST_SIZE; event_ptr++, event_index++)
{
if (!event_ptr->start_time && !event_ptr->on_len)
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
memcpy(event_ptr, timerblock, sizeof(struct s_mucron));
}
EEPROM_write_page(offsetof(struct s_config, EventList) + sizeof(struct s_mucron) * event_index, (void*)event_ptr, sizeof(struct s_mucron));
break;
}
}
}
uint8_t timer_paused;
void mucron_tick()
{
uint16_t event_index = 0;
struct s_mucron * event_ptr;
time_t timestamp = time();
time_t modsecs;
uint8_t paused_copy;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
paused_copy = timer_paused;
}
for (; event_index < MUCRON_EVENTLIST_SIZE; event_index++)
{
event_ptr = ramEventList + event_index;
if (event_ptr->start_time && event_ptr->on_len && !paused_copy)
{
modsecs = (timestamp - event_ptr->start_time) % (event_ptr->on_len + event_ptr->off_len);
if ( modsecs >= 0 && modsecs < event_ptr->on_len)
{
// on
iocontrol(event_ptr->port, 1);
}
else if (modsecs >= event_ptr->on_len)
{
// off
iocontrol(event_ptr->port, 0);
}
}
}
}