-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.c
237 lines (196 loc) · 5.36 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
226
227
228
229
230
231
232
233
234
235
236
/*
* config.c
*
* Created on: 01.08.2012
* Author: F. Erckenbrecht
*/
#include <stdint.h>
#include <avr/eeprom.h>
#include <util/crc16.h>
#include <alloca.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "config.h"
#include "macros.h"
#include "pll_freq.h"
#define CONFIG_MAGIC 0x17ef
#define CONFIG_CRC_INIT 0xff;
#define CONFIG_EEPROM_BASE 0x10
#define CONFIG_VERSION 0
static void config_initDefault(T_Config * cfgPtr);
// Radio Configuration
// put in uninitialized space -> do not initialize to be able
// to keep config in RAM during reboots without power-loss
uint8_t config_state = CONFIG_INVALID;
uint16_t config_magic __attribute__ ((section (".noinit")));
T_Config config __attribute__ ((section (".noinit")));
static xQueueHandle xConfigQ;
T_ConfigUpdateMessage cfgUpdate;
/*
* Calculate CRC-8 (x^8 + x^2 + x^1 + 1)
* data = data byte
* crc = ptr to previous crc value or init value
*/
static uint8_t crc8_ccitt(const uint8_t data, const uint8_t crc)
{
//
uint8_t i;
uint8_t r;
r = crc;
r ^= data;
for(i=0;i<8;i++){
if(r & 0x80){
r = (r<<1)^ 0x07;
}else{
r <<= 1;
}
}
return r;
}
uint8_t config_checkConfigCrc( T_Config * cfgPtr){
uint8_t crc = CONFIG_CRC_INIT;
uint8_t * crcPtr = &(cfgPtr->crc);
uint8_t * d = (uint8_t *) cfgPtr;
// calculate CRC for config data in SRAM
while(d <= crcPtr){
crc = crc8_ccitt(*(d++), crc);
}
return crc;
}
void config_calcConfigCrc( T_Config * cfgPtr){
uint8_t crc = CONFIG_CRC_INIT;
uint8_t * crcPtr = &(cfgPtr->crc);
uint8_t * d = (uint8_t *) cfgPtr;
// calculate CRC for config data in SRAM
while(d < crcPtr){
crc = crc8_ccitt(*(d++), crc);
}
cfgPtr->crc = crc;
}
// initialize basic radio configuration
uint8_t config_basicRadio()
{
xConfigQ = xQueueCreate( 1, sizeof( T_ConfigUpdateMessage ) );
// check for magic word in memory
// ( check if there could be a valid config in SRAM)
/*
if(config_magic == CONFIG_MAGIC){
// calculate CRC for config data in SRAM
// if CRC is OK, there is a correct config in SRAM, we are done
if(!config_checkConfigCrc(&config))
return CONFIG_SRAM;
}
*/
config_magic = CONFIG_MAGIC;
// if CRC does not fit (!= 0), try initialization from EEPROM
eeprom_read_block(&config,(void *)CONFIG_EEPROM_BASE, sizeof(config));
if((config.version == CONFIG_VERSION) && !config_checkConfigCrc(&config))
return CONFIG_EEPROM;
// configure from flash
config_initDefault(&config);
return CONFIG_FLASH;
}
// default configuration, use this if EEPROM config is invalid or missing
static void config_initDefault(T_Config * cfgPtr)
{
cfgPtr->version = CONFIG_VERSION;
cfgPtr->controlHead = CONTROL_HEAD3;
cfgPtr->ctcssIndexRx = 1;
cfgPtr->ctcssIndexTx = 1;
cfgPtr->configAutosave = 0;
cfgPtr->powerMode = DEFAULT_RF_PWR;
cfgPtr->reserved = 0;
cfgPtr->squelchMode = SQM_CARRIER;
cfgPtr->f_step = FSTEP;
cfgPtr->frequency = FDEF;
cfgPtr->tx_shift = FTXOFF;
cfgPtr->shift_active = 0;
config_calcConfigCrc(cfgPtr);
}
void config_saveToEeprom(T_Config * cfgPtr)
{
uint8_t data;
uint8_t * bPtr;
uint8_t i;
// update CRC
config_calcConfigCrc(cfgPtr);
bPtr = (uint8_t *) cfgPtr;
for(i=0;i<sizeof(T_Config);i++){
data = eeprom_read_byte((uint8_t *) (CONFIG_EEPROM_BASE+i));
// if EEPROM data and SRAM data don't match, update the whole block
if(data != *bPtr++){
eeprom_update_block(&config,(void *)CONFIG_EEPROM_BASE, sizeof(T_Config));
break;
}
}
}
inline void config_validate()
{
config_state = CONFIG_UPDATED;
config_calcConfigCrc(&config);
config_state = CONFIG_VALID;
}
void config_sendUpdate(){
// block if queue is full
xQueueSendToBack( xConfigQ, &cfgUpdate, portMAX_DELAY);
// wait until message was read by control task
while(uxQueueMessagesWaiting(xConfigQ)){
vTaskDelay( 1 );
}
}
void config_checkForUpdate(portTickType ticksToWait){
T_ConfigUpdateMessage cfgm;
if(xQueueReceive( xConfigQ, &cfgm, ticksToWait) == pdPASS){
if(cfgm.updateMask & CONFIG_UM_TXSHIFT){
config.tx_shift = (int32_t) cfgm.cfgdata;
}
if(cfgm.updateMask & CONFIG_UM_SHIFTACTIVE ){
config.shift_active = cfgm.cfgdata;
}
if(cfgm.updateMask & CONFIG_UM_FREQUENCY){
config.frequency = cfgm.cfgdata;
}
if(cfgm.updateMask & CONFIG_UM_FSTEP){
// TODO: Implement update to frequency spacing
}
// On frequency updates in any case OR
// on shift updates in TX
// set the frequency
if( (cfgm.updateMask & CONFIG_UM_FREQUENCY) ||
(rxtx_state &&
(cfgm.updateMask &(CONFIG_UM_SHIFTACTIVE | CONFIG_UM_TXSHIFT)))){
set_freq(&config.frequency);
}
if(cfgm.updateMask & CONFIG_UM_CONFIGAUTOSAVE){
config.configAutosave = cfgm.cfgdata;
}
if(cfgm.updateMask & CONFIG_UM_SQUELCHMODE){
config.squelchMode = cfgm.cfgdata;
}
if(cfgm.updateMask & CONFIG_UM_POWERMODE){
config.powerMode = cfgm.cfgdata;
// when in TX, apply new setting immediately
if(rxtx_state){
rfpwr_apply();
}
}
if(cfgm.updateMask & CONFIG_UM_CTCSS){
config.ctcssIndexRx = (uint8_t) cfgm.cfgdata;
config.ctcssIndexTx = (uint8_t) ((uint16_t)cfgm.cfgdata >> 8);
// apply CTCSS setting immediately
// but check if we're in TX or RX
if(rxtx_state){
// TX - (re)start CTCSS tone generator
}
else{
// RX - (re)initialize CTCSS detector
}
}
config_calcConfigCrc(&config);
config_state = CONFIG_VALID;
if(cfgm.updateMask & CONFIG_UM_SAVE_TO_EEPROM){
config_saveToEeprom(&config);
}
}
}